diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 00000000..60213d6c --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,44 @@ +name: CI + +on: + push: + branches: + - public-server + - api9 + +jobs: + run_server_binary: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.13' + - name: Set execute permissions for wrapper + run: chmod +x ./bombsquad_server + + - name: Set execute permissions for binary + run: chmod +x ./dist/bombsquad_headless + + - name: Run server binary and capture output + run: | + ./bombsquad_server > server-output.log 2>&1 & + SERVER_PID=$! + sleep 30 # let it run for 30 seconds + kill $SERVER_PID # terminate the server + - name: Check server output for success message + run: | + if grep -E "Exception|RuntimeError" server-output.log; then + echo "Error message found. Check server-output.log for details." + exit 1 + elif ! grep -q "Server started" server-output.log; then + echo "Success message not found in server's output." + exit 1 + fi + - name: Upload server output as artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: server-output + path: ./server-output.log diff --git a/.gitignore b/.gitignore index 7f146b42..8fce3d27 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,11 @@ __pycache__/ *.py[cod] *$py.class .mypy_cache/ -dist/ba_root/mods/playerdata/*.json* +.bsuuid +.bsac2 +dist/ba_root/mods/playersdata/*.json* dist/ba_root/mods/serverdata/*.log dist/ba_root/mods/serverdata/*.log* dist/ba_root/mods/serverdata/*.json +dist/ba_root/mods/stats/*.json + diff --git a/dist/ba_root/mods/.idea/.gitignore b/.idea/.gitignore similarity index 100% rename from dist/ba_root/mods/.idea/.gitignore rename to .idea/.gitignore diff --git a/.idea/Bombsquad-Ballistica-Modded-Server.iml b/.idea/Bombsquad-Ballistica-Modded-Server.iml new file mode 100644 index 00000000..34bf6e3b --- /dev/null +++ b/.idea/Bombsquad-Ballistica-Modded-Server.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/ba_root/mods/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml similarity index 100% rename from dist/ba_root/mods/.idea/inspectionProfiles/profiles_settings.xml rename to .idea/inspectionProfiles/profiles_settings.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..699c5dfc --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..4e55ed65 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..d3e5c734 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.analysis.extraPaths": [ + "./dist/ba_data/python", + "./dist/dummymodules", + "./dist/ba_data/python-site-packages" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 133f8a47..55dde9ed 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,38 @@ # Bombsquad-Ballistica-Modded-Server -Modded server scripts to host ballistica (Bombsquad) server. Running on BS1.7.19. +Modded server scripts to host ballistica (BombSquad) server. Running on BS1.7.41 (API 9) `` -We started working on API 8 , help us to test out and fix bugs +Migrated from API 7 TO API 9 , this might be unstable and missing some features. Use API 7 from this tag `` -[API8 BRANCH](https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server/tree/api8) +[API7 ](https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server/releases/tag/1.7.26) # Prerequisites - Basic knowledge of Linux - A VPS (e.g. [Amazon Web Services](https://aws.amazon.com/), [Microsoft Azure](https://portal.azure.com/)) - Any Linux distribution. - - It is recommended to use Ubuntu. -- Python 3.10 + - It is recommended to use Ubuntu (minimum Ubuntu 22). +- Python 3.13 - 1 GB free Memory (Recommended 2 GB) ## Getting Started This assumes you are on Ubuntu or an Ubuntu based distribution. -Update and install `software-properties-common` +Install `software-properties-common` ``` -sudo apt update; sudo apt install software-properties-common -y +sudo apt install software-properties-common -y ``` Add python Deadsnakes PPA ``` sudo add-apt-repository ppa:deadsnakes/ppa ``` -Install Python 3.10 +Install Python 3.13 ``` -sudo apt install python3-pip python3.10-dev python3.10-venv +sudo apt install python3.13 python3.13-dev python3.13-venv python3-pip -y +``` +Update installed and existing packages +``` +sudo apt update && sudo apt upgrade ``` Create a tmux session. ``` @@ -36,7 +40,7 @@ tmux new -s 43210 ``` Download server files. ``` -git clone https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server +git clone --depth=1 https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server cd Bombsquad-Ballistica-Modded-Server ``` Now edit config.yaml in root dir change server name, port, admins, playlist, team name etc.. @@ -44,6 +48,7 @@ Making the server files executable. ``` chmod 777 bombsquad_server chmod 777 dist/bombsquad_headless +chmod 777 dist/bombsquad_headless_aarch64 ``` Starting the server ``` @@ -85,7 +90,7 @@ Here you can ban players, mute them, or disable their kick votes. - Allow server owners to join even when server is full by looking owner IP address which was used earlier(don't join by queue). - Auto kick fake accounts (unsigned/not verified by master server). - Auto enable/disable public queue when server is full. -- Auto night mode . +- Auto night mode. - Transparent Kickvote , can see who started kick vote for whom. - Kickvote msg to chat/screen , can choose to show kickvote start msg either as screen message or chat message. - Players IP Address and Device UUID tracking and banning. diff --git a/block_banned_ips.py b/block_banned_ips.py new file mode 100644 index 00000000..39143695 --- /dev/null +++ b/block_banned_ips.py @@ -0,0 +1,65 @@ +import urllib.request +import json +import subprocess +import threading + +# URL to fetch banned IPs +BAN_LIST_URL = "https://bcsservers.ballistica.workers.dev/fetchbannedips" + + +def fetch_banned_ips(): + """Fetch the list of banned IPs from the server using urllib.""" + try: + with urllib.request.urlopen(BAN_LIST_URL) as response: + data = response.read().decode('utf-8') + return json.loads(data) + except urllib.error.URLError as e: + print(f"Error fetching banned IPs: {e}") + return {} + + +def is_ip_blocked(ip): + """Check if the IP is already blocked in iptables.""" + try: + result = subprocess.run( + ["iptables", "-L", "-n", "-v"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + return ip in result.stdout + except Exception as e: + print(f"Error checking iptables for IP {ip}: {e}") + return False + + +def block_ip(ip): + """Block the given IP for UDP traffic using iptables.""" + try: + subprocess.run( + ["iptables", "-A", "INPUT", "-s", ip, "-p", "udp", "-j", "DROP"], + check=True, + ) + print(f"Blocked IP: {ip}") + except subprocess.CalledProcessError as e: + print(f"Error blocking IP {ip}: {e}") + + +def main(): + """Main function to fetch banned IPs and block them.""" + banned_ips = fetch_banned_ips() + for ip, details in banned_ips.items(): + if not is_ip_blocked(ip): + print( + f"Blocking IP: {ip} (Reason: {details.get('reason', 'No reason provided')})") + block_ip(ip) + else: + print(f"IP {ip} is already blocked.") + + +def schedule_main(): + """Schedule the main function to run every hour.""" + main() + print("Scheduled to run again in 1 hour...") + # Schedule to run after 1 hour + threading.Timer(3600, schedule_main).start() diff --git a/bombsquad_server b/bombsquad_server index 2ab76150..c82f94d8 100644 --- a/bombsquad_server +++ b/bombsquad_server @@ -1,105 +1,108 @@ -#!/usr/bin/env -S python3.10 -O - +#!/usr/bin/env python3.13 # Released under the MIT License. See LICENSE for details. # -"""BallisticaCore server manager.""" +# pylint: disable=too-many-lines +"""BallisticaKit server manager.""" from __future__ import annotations -import json import os -import signal -import subprocess import sys import time -import _thread +import json +import signal +import tomllib +import subprocess +import platform from pathlib import Path from threading import Lock, Thread, current_thread from typing import TYPE_CHECKING -from nbstreamreader import NonBlockingStreamReader as NBSR - -ERROR_LOGGING=False - - -import os,platform,shutil -def migrate_to_aarch(): - maps = ["BridgitMash.so","FloatingIsland.so","InTheAir.so"] - games = ["CanonFight.so","DuelElimination.so","FlappyBird.so","LaserTracer.so","MonkeyClimb.so","OneNightNoStand.so","RealSoccer.so", - "SquidRace.so","StumbleRace.so","SubwayRun.so","UFOAttackGame.so"] - features = ["StumbledScoreScreen.so"] - tools = ["corelib.so"] - root = os.path.realpath(".")+"/dist/ba_root" - for map in maps: - shutil.copy(root+"/mods/aarch64/"+map,root+'/mods/maps/'+map) - for game in games: - shutil.copyfile(root+"/mods/aarch64/"+game,root+'/mods/games/'+game) - for f in features: - shutil.copyfile(root+"/mods/aarch64/"+f,root+'/mods/features/'+f) - for t in tools: - shutil.copyfile(root+"/mods/aarch64/"+t,root+'/mods/tools/'+t) - with open(".we_are_good","w") as f: - pass -# by default we have x86_64 setup -# if we found aarch64 system copy required files -if platform.processor() == 'aarch64': - print("We are on aarch64 system") - if os.path.exists(".we_are_good"): - pass - else: - migrate_to_aarch() + # We make use of the bacommon and efro packages as well as site-packages -# included with our bundled Ballistica dist, so we need to add those paths -# before we import them. +# included with our bundled Ballistica dist, so we need to add those +# paths before we import them. sys.path += [ str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python')), - str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python-site-packages')) + str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python-site-packages')), ] -from bacommon.servermanager import ServerConfig, StartServerModeCommand -from efro.dataclassio import dataclass_from_dict, dataclass_validate -from efro.error import CleanError from efro.terminal import Clr +from efro.error import CleanError +from efro.dataclassio import dataclass_from_dict, dataclass_validate +from bacommon.servermanager import ServerConfig, StartServerModeCommand if TYPE_CHECKING: - from typing import Optional, Union from types import FrameType from bacommon.servermanager import ServerCommand -VERSION_STR = '1.3' - +VERSION_STR = '1.3.2' # Version history: +# +# 1.3.2 +# +# - Updated to use Python 3.12. +# +# - Server config file is now in toml format instead of yaml. +# +# - Server config can now be set to a .json file OR a .toml file. +# By default it will look for 'config.json' and then 'config.toml' +# in the same dir as this script. +# # 1.3.1 -# Windows binary is now named BallisticaCoreHeadless.exe +# +# - Windows binary is now named 'BallisticaKitHeadless.exe'. +# # 1.3: -# Added show_tutorial config option -# Added team_names config option -# Added team_colors config option -# Added playlist_inline config option +# +# - Added show_tutorial config option. +# +# - Added team_names config option. +# +# - Added team_colors config option. +# +# - Added playlist_inline config option. +# # 1.2: -# Added optional --help arg -# Added --config arg for specifying config file and --root for ba_root path -# Added noninteractive mode and --interactive/--noninteractive args to -# explicitly enable/disable it (it is autodetected by default) -# Added explicit control for auto-restart: --no-auto-restart -# Config file is now reloaded each time server binary is restarted; no more -# need to bring down server wrapper to pick up changes -# Now automatically restarts server binary when config file is modified -# (use --no-config-auto-restart to disable that behavior) +# +# - Added optional --help arg. +# +# - Added --config arg for specifying config file and --root for +# ba_root path. +# +# - Added noninteractive mode and --interactive/--noninteractive args +# to explicitly enable/disable it (it is autodetected by default). +# +# - Added explicit control for auto-restart: --no-auto-restart. +# +# - Config file is now reloaded each time server binary is restarted; +# no more need to bring down server wrapper to pick up changes. +# +# - Now automatically restarts server binary when config file is +# modified (use --no-config-auto-restart to disable that behavior). +# # 1.1.1: -# Switched config reading to use efro.dataclasses.dataclass_from_dict() +# +# - Switched config reading to use +# efro.dataclasses.dataclass_from_dict(). +# # 1.1.0: -# Added shutdown command -# Changed restart to default to immediate=True -# Added clean_exit_minutes, unclean_exit_minutes, and idle_exit_minutes +# +# - Added shutdown command. +# +# - Changed restart to default to immediate=True. +# +# - Added clean_exit_minutes, unclean_exit_minutes, and idle_exit_minutes. +# # 1.0.0: -# Initial release +# +# - Initial release. class ServerManagerApp: - """An app which manages BallisticaCore server execution. + """An app which manages BallisticaKit server execution. Handles configuring, launching, re-launching, and otherwise - managing BallisticaCore operating in server mode. + managing BallisticaKit operating in server mode. """ # How many seconds we wait after asking our subprocess to do an immediate @@ -107,36 +110,37 @@ class ServerManagerApp: IMMEDIATE_SHUTDOWN_TIME_LIMIT = 5.0 def __init__(self) -> None: - self._config_path = 'config.yaml' - self._user_provided_config_path = False + self._user_provided_config_path: str | None = None self._config = ServerConfig() self._ba_root_path = os.path.abspath('dist/ba_root') self._interactive = sys.stdin.isatty() self._wrapper_shutdown_desired = False self._done = False - self._subprocess_commands: list[Union[str, ServerCommand]] = [] + self._subprocess_commands: list[str | ServerCommand] = [] self._subprocess_commands_lock = Lock() - self._subprocess_force_kill_time: Optional[float] = None + self._subprocess_force_kill_time: float | None = None self._auto_restart = True self._config_auto_restart = True - self._config_mtime: Optional[float] = None - self._last_config_mtime_check_time: Optional[float] = None + self._config_mtime: float | None = None + self._last_config_mtime_check_time: float | None = None self._should_report_subprocess_error = False self._running = False - self._interpreter_start_time: Optional[float] = None - self._subprocess: Optional[subprocess.Popen[bytes]] = None - self._subprocess_launch_time: Optional[float] = None + self._interpreter_start_time: float | None = None + self._subprocess: subprocess.Popen[bytes] | None = None + self._subprocess_launch_time: float | None = None self._subprocess_sent_config_auto_restart = False self._subprocess_sent_clean_exit = False self._subprocess_sent_unclean_exit = False - self._subprocess_thread: Optional[Thread] = None - self._subprocess_exited_cleanly: Optional[bool] = None - self.nbsr = None + self._subprocess_thread: Thread | None = None + self._subprocess_exited_cleanly: bool | None = None + self._did_multi_config_warning = False + # This may override the above defaults. self._parse_command_line_args() - # Do an initial config-load. If the config is invalid at this point - # we can cleanly die (we're more lenient later on reloads). + # Do an initial config-load. If the config is invalid at this + # point we can cleanly die; we're more resilient later on reload + # attempts. self.load_config(strict=True, print_confirmation=False) @property @@ -159,14 +163,15 @@ class ServerManagerApp: dbgstr = 'debug' if __debug__ else 'opt' print( - f'{Clr.CYN}{Clr.BLD}Bcs server manager {VERSION_STR}' + f'{Clr.CYN}{Clr.BLD}BCS server manager {VERSION_STR}' f' starting up ({dbgstr} mode)...{Clr.RST}', - flush=True) + flush=True, + ) # Python will handle SIGINT for us (as KeyboardInterrupt) but we - # need to register a SIGTERM handler so we have a chance to clean - # up our subprocess when someone tells us to die. (and avoid - # zombie processes) + # need to register a SIGTERM handler so we have a chance to + # clean up our subprocess when someone tells us to die. (and + # avoid zombie processes) signal.signal(signal.SIGTERM, self._handle_term_signal) # During a run, we make the assumption that cwd is the dir @@ -184,10 +189,12 @@ class ServerManagerApp: assert self._subprocess_thread is not None if self._subprocess_thread.is_alive(): - print(f'{Clr.CYN}Waiting for subprocess exit...{Clr.RST}', - flush=True) + print( + f'{Clr.CYN}Waiting for subprocess exit...{Clr.RST}', flush=True + ) - # Mark ourselves as shutting down and wait for the process to wrap up. + # Mark ourselves as shutting down and wait for the process to + # wrap up. self._done = True self._subprocess_thread.join() @@ -213,15 +220,17 @@ class ServerManagerApp: # Gracefully bow out if we kill ourself via keyboard. pass except SystemExit: - # We get this from the builtin quit(), our signal handler, etc. - # Need to catch this so we can clean up, otherwise we'll be - # left in limbo with our process thread still running. + # We get this from the builtin quit(), our signal handler, + # etc. Need to catch this so we can clean up, otherwise + # we'll be left in limbo with our process thread still + # running. pass self._postrun() def _run_interactive(self) -> None: """Run the app loop to completion interactively.""" import code + self._prerun() # Print basic usage info for interactive mode. @@ -229,7 +238,8 @@ class ServerManagerApp: f"{Clr.CYN}Interactive mode enabled; use the 'mgr' object" f' to interact with the server.\n' f"Type 'help(mgr)' for more information.{Clr.RST}", - flush=True) + flush=True, + ) context = {'__name__': '__console__', '__doc__': None, 'mgr': self} @@ -237,20 +247,24 @@ class ServerManagerApp: self._enable_tab_completion(context) # Now just sit in an interpreter. - # TODO: make it possible to use IPython if the user has it available. + # + # TODO: make it possible to use IPython if the user has it + # available. try: self._interpreter_start_time = time.time() code.interact(local=context, banner='', exitmsg='') except SystemExit: - # We get this from the builtin quit(), our signal handler, etc. - # Need to catch this so we can clean up, otherwise we'll be - # left in limbo with our process thread still running. + # We get this from the builtin quit(), our signal handler, + # etc. Need to catch this so we can clean up, otherwise + # we'll be left in limbo with our process thread still + # running. pass except BaseException as exc: print( f'{Clr.SRED}Unexpected interpreter exception:' f' {exc} ({type(exc)}){Clr.RST}', - flush=True) + flush=True, + ) self._postrun() @@ -267,54 +281,62 @@ class ServerManagerApp: self._block_for_command_completion() def _block_for_command_completion(self) -> None: - # Ideally we'd block here until the command was run so our prompt would - # print after it's results. We currently don't get any response from - # the app so the best we can do is block until our bg thread has sent - # it. In the future we can perhaps add a proper 'command port' - # interface for proper blocking two way communication. + # Ideally we'd block here until the command was run so our + # prompt would print after it's results. We currently don't get + # any response from the app so the best we can do is block until + # our bg thread has sent it. In the future we can perhaps add a + # proper 'command port' interface for proper blocking two way + # communication. while True: with self._subprocess_commands_lock: if not self._subprocess_commands: break time.sleep(0.1) - # One last short delay so if we come out *just* as the command is sent - # we'll hopefully still give it enough time to process/print. + # One last short delay so if we come out *just* as the command + # is sent we'll hopefully still give it enough time to + # process/print. time.sleep(0.1) - def screenmessage(self, - message: str, - color: Optional[tuple[float, float, float]] = None, - clients: Optional[list[int]] = None) -> None: + def screenmessage( + self, + message: str, + color: tuple[float, float, float] | None = None, + clients: list[int] | None = None, + ) -> None: """Display a screen-message. This will have no name attached and not show up in chat history. They will show up in replays, however (unless clients is passed). """ from bacommon.servermanager import ScreenMessageCommand + self._enqueue_server_command( - ScreenMessageCommand(message=message, color=color, - clients=clients)) + ScreenMessageCommand(message=message, color=color, clients=clients) + ) - def chatmessage(self, - message: str, - clients: Optional[list[int]] = None) -> None: + def chatmessage( + self, message: str, clients: list[int] | None = None + ) -> None: """Send a chat message from the server. This will have the server's name attached and will be logged in client chat windows, just like other chat messages. """ from bacommon.servermanager import ChatMessageCommand + self._enqueue_server_command( - ChatMessageCommand(message=message, clients=clients)) + ChatMessageCommand(message=message, clients=clients) + ) def clientlist(self) -> None: """Print a list of connected clients.""" from bacommon.servermanager import ClientListCommand + self._enqueue_server_command(ClientListCommand()) self._block_for_command_completion() - def kick(self, client_id: int, ban_time: Optional[int] = None) -> None: + def kick(self, client_id: int, ban_time: int | None = None) -> None: """Kick the client with the provided id. If ban_time is provided, the client will be banned for that @@ -323,8 +345,10 @@ class ServerManagerApp: ban time. """ from bacommon.servermanager import KickCommand + self._enqueue_server_command( - KickCommand(client_id=client_id, ban_time=ban_time)) + KickCommand(client_id=client_id, ban_time=ban_time) + ) def restart(self, immediate: bool = True) -> None: """Restart the server subprocess. @@ -334,15 +358,19 @@ class ServerManagerApp: the next clean transition point (the end of a series, etc). """ from bacommon.servermanager import ShutdownCommand, ShutdownReason + self._enqueue_server_command( - ShutdownCommand(reason=ShutdownReason.RESTARTING, - immediate=immediate)) + ShutdownCommand( + reason=ShutdownReason.RESTARTING, immediate=immediate + ) + ) - # If we're asking for an immediate restart but don't get one within - # the grace period, bring down the hammer. + # If we're asking for an immediate restart but don't get one + # within the grace period, bring down the hammer. if immediate: self._subprocess_force_kill_time = ( - time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT) + time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT + ) def shutdown(self, immediate: bool = True) -> None: """Shut down the server subprocess and exit the wrapper. @@ -352,18 +380,21 @@ class ServerManagerApp: the next clean transition point (the end of a series, etc). """ from bacommon.servermanager import ShutdownCommand, ShutdownReason + self._enqueue_server_command( - ShutdownCommand(reason=ShutdownReason.NONE, immediate=immediate)) + ShutdownCommand(reason=ShutdownReason.NONE, immediate=immediate) + ) - # An explicit shutdown means we know to bail completely once this - # subprocess completes. + # An explicit shutdown means we know to bail completely once + # this subprocess completes. self._wrapper_shutdown_desired = True - # If we're asking for an immediate shutdown but don't get one within - # the grace period, bring down the hammer. + # If we're asking for an immediate shutdown but don't get one + # within the grace period, bring down the hammer. if immediate: self._subprocess_force_kill_time = ( - time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT) + time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT + ) def _parse_command_line_args(self) -> None: """Parse command line args.""" @@ -386,29 +417,33 @@ class ServerManagerApp: f"Supplied path does not exist: '{path}'.") # We need an abs path because we may be in a different # cwd currently than we will be during the run. - self._config_path = os.path.abspath(path) - self._user_provided_config_path = True + self._user_provided_config_path = os.path.abspath(path) i += 2 elif arg == '--root': if i + 1 >= argc: raise CleanError('Expected a path as next arg.') path = sys.argv[i + 1] - # Unlike config_path, this one doesn't have to exist now. - # We do however need an abs path because we may be in a - # different cwd currently than we will be during the run. + # Unlike config_path, this one doesn't have to exist + # now. We do however need an abs path because we may be + # in a different cwd currently than we will be during + # the run. self._ba_root_path = os.path.abspath(path) i += 2 elif arg == '--interactive': if did_set_interactive: - raise CleanError('interactive/noninteractive can only' - ' be specified once.') + raise CleanError( + 'interactive/noninteractive can only' + ' be specified once.' + ) self._interactive = True did_set_interactive = True i += 1 elif arg == '--noninteractive': if did_set_interactive: - raise CleanError('interactive/noninteractive can only' - ' be specified once.') + raise CleanError( + 'interactive/noninteractive can only' + ' be specified once.' + ) self._interactive = False did_set_interactive = True i += 1 @@ -425,6 +460,7 @@ class ServerManagerApp: def _par(cls, txt: str) -> str: """Spit out a pretty paragraph for our help text.""" import textwrap + ind = ' ' * 2 out = textwrap.fill(txt, 80, initial_indent=ind, subsequent_indent=ind) return f'{out}\n' @@ -434,50 +470,65 @@ class ServerManagerApp: """Print app help.""" filename = os.path.basename(__file__) out = ( - f'{Clr.BLD}{filename} usage:{Clr.RST}\n' + cls._par( - 'This script handles configuring, launching, re-launching,' - ' and otherwise managing BallisticaCore operating' - ' in server mode. It can be run with no arguments, but' - ' accepts the following optional ones:') + f'\n' - f'{Clr.BLD}--help:{Clr.RST}\n' - f' Show this help.\n' - f'\n' - f'{Clr.BLD}--config [path]{Clr.RST}\n' + cls._par( - 'Set the config file read by the server script. The config' - ' file contains most options for what kind of game to host.' - ' It should be in yaml format. Note that yaml is backwards' - ' compatible with json so you can just write json if you' - ' want to. If not specified, the script will look for a' - ' file named \'config.yaml\' in the same directory as the' - ' script.') + '\n' - f'{Clr.BLD}--root [path]{Clr.RST}\n' + cls._par( - 'Set the ballistica root directory. This is where the server' - ' binary will read and write its caches, state files,' - ' downloaded assets to, etc. It needs to be a writable' - ' directory. If not specified, the script will use the' - ' \'dist/ba_root\' directory relative to itself.') + '\n' - f'{Clr.BLD}--interactive{Clr.RST}\n' - f'{Clr.BLD}--noninteractive{Clr.RST}\n' + cls._par( - 'Specify whether the script should run interactively.' - ' In interactive mode, the script creates a Python interpreter' - ' and reads commands from stdin, allowing for live interaction' - ' with the server. The server script will then exit when ' - 'end-of-file is reached in stdin. Noninteractive mode creates' - ' no interpreter and is more suited to being run in automated' - ' scenarios. By default, interactive mode will be used if' - ' a terminal is detected and noninteractive mode otherwise.') + - '\n' - f'{Clr.BLD}--no-auto-restart{Clr.RST}\n' + - cls._par('Auto-restart is enabled by default, which means the' - ' server manager will restart the server binary whenever' - ' it exits (even when uncleanly). Disabling auto-restart' - ' will cause the server manager to instead exit after a' - ' single run and also to return error codes if the' - ' server binary did so.') + '\n' - f'{Clr.BLD}--no-config-auto-restart{Clr.RST}\n' + cls._par( - 'By default, when auto-restart is enabled, the server binary' - ' will be automatically restarted if changes to the server' - ' config file are detected. This disables that behavior.')) + f'{Clr.BLD}{filename} usage:{Clr.RST}\n' + + cls._par( + 'This script handles configuring, launching, re-launching,' + ' and otherwise managing BallisticaKit operating' + ' in server mode. It can be run with no arguments, but' + ' accepts the following optional ones:' + ) + + f'\n' + f'{Clr.BLD}--help:{Clr.RST}\n' + f' Show this help.\n' + f'\n' + f'{Clr.BLD}--config [path]{Clr.RST}\n' + + cls._par( + 'Set the config file read by the server script. The config' + ' file contains most options for what kind of game to host.' + ' It should be in toml or json format. If not specified,' + ' the script will look for a file named \'config.toml\' or' + ' \'config.json\' in the same directory as the script.' + ) + + '\n' + f'{Clr.BLD}--root [path]{Clr.RST}\n' + + cls._par( + 'Set the ballistica root directory. This is where the server' + ' binary will read and write its caches, state files,' + ' downloaded assets to, etc. It needs to be a writable' + ' directory. If not specified, the script will use the' + ' \'dist/ba_root\' directory relative to itself.' + ) + + '\n' + f'{Clr.BLD}--interactive{Clr.RST}\n' + f'{Clr.BLD}--noninteractive{Clr.RST}\n' + + cls._par( + 'Specify whether the script should run interactively.' + ' In interactive mode, the script creates a Python interpreter' + ' and reads commands from stdin, allowing for live interaction' + ' with the server. The server script will then exit when ' + 'end-of-file is reached in stdin. Noninteractive mode creates' + ' no interpreter and is more suited to being run in automated' + ' scenarios. By default, interactive mode will be used if' + ' a terminal is detected and noninteractive mode otherwise.' + ) + + '\n' + f'{Clr.BLD}--no-auto-restart{Clr.RST}\n' + + cls._par( + 'Auto-restart is enabled by default, which means the' + ' server manager will restart the server binary whenever' + ' it exits (even when uncleanly). Disabling auto-restart' + ' will cause the server manager to instead exit after a' + ' single run and also to return error codes if the' + ' server binary did so.' + ) + + '\n' + f'{Clr.BLD}--no-config-auto-restart{Clr.RST}\n' + + cls._par( + 'By default, when auto-restart is enabled, the server binary' + ' will be automatically restarted if changes to the server' + ' config file are detected. This disables that behavior.' + ) + ) print(out) def load_config(self, strict: bool, print_confirmation: bool) -> None: @@ -493,29 +544,35 @@ class ServerManagerApp: for trynum in range(maxtries): try: self._config = self._load_config_from_file( - print_confirmation=print_confirmation) + print_confirmation=print_confirmation + ) return except Exception as exc: - + json_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), 'config.json') + ) print(f'{Clr.RED}Error loading config file:\n{exc}.{Clr.RST}', flush=True) - with open(self._ba_root_path + "/mods/defaults/config.yaml", "r") as infile: + with open(self._ba_root_path + "/mods/defaults/config.json", "r") as infile: default_file = infile.read() - with open(self._config_path, "w") as outfile: + with open(json_path, "w") as outfile: outfile.write(default_file) print("config reset done") + if trynum == maxtries - 1: print( f'{Clr.RED}Max-tries reached; giving up.' f' Existing config values will be used.{Clr.RST}', - flush=True) + flush=True, + ) break print( f'{Clr.CYN}Please correct the error.' f' Will re-attempt load in {retry_seconds}' - f' seconds. (attempt {trynum + 1} of' - f' {maxtries - 1}).{Clr.RST}', - flush=True) + f' seconds. (attempt {trynum+1} of' + f' {maxtries-1}).{Clr.RST}', + flush=True, + ) for _j in range(retry_seconds): # If the app is trying to die, drop what we're doing. @@ -523,50 +580,82 @@ class ServerManagerApp: return time.sleep(1) - def _load_config_from_file(self, print_confirmation: bool) -> ServerConfig: + def _get_config_path(self) -> str: + + if self._user_provided_config_path is not None: + return self._user_provided_config_path + + # Otherwise look for config.toml or config.json in the same dir + # as our script. Need to work in abs paths since we may chdir when + # we start running. + toml_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), 'config.toml') + ) + toml_exists = os.path.exists(toml_path) + json_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), 'config.json') + ) + json_exists = os.path.exists(json_path) + + # Warn if both configs are present. + if toml_exists and json_exists and not self._did_multi_config_warning: + self._did_multi_config_warning = True + print( + f'{Clr.YLW}Both config.toml and config.json' + f' found; will use json.{Clr.RST}', + flush=True, + ) + if json_exists: + return json_path + return toml_path - out: Optional[ServerConfig] = None + def _load_config_from_file(self, print_confirmation: bool) -> ServerConfig: + out: ServerConfig | None = None - if not os.path.exists(self._config_path): + config_path = self._get_config_path() + if not os.path.exists(config_path): # Special case: - # If the user didn't specify a particular config file, allow - # gracefully falling back to defaults if the default one is - # missing. + # + # If the user didn't provide a config path AND the default + # config path does not exist, fall back to defaults. if not self._user_provided_config_path: if print_confirmation: print( f'{Clr.YLW}Default config file not found' - f' (\'{self._config_path}\'); using default' - f' settings.{Clr.RST}', - flush=True) + f' (\'{config_path}\'); using default' + f' config.{Clr.RST}', + flush=True, + ) self._config_mtime = None self._last_config_mtime_check_time = time.time() return ServerConfig() # Don't be so lenient if the user pointed us at one though. - raise RuntimeError( - f"Config file not found: '{self._config_path}'.") + raise RuntimeError(f"Config file not found: '{config_path}'.") - import yaml - with open(self._config_path, encoding='utf-8') as infile: - user_config_raw = yaml.safe_load(infile.read()) + with open(config_path, encoding='utf-8') as infile: + if config_path.endswith('.toml'): + user_config_raw = tomllib.loads(infile.read()) + elif config_path.endswith('.json'): + user_config_raw = json.loads(infile.read()) + else: + raise CleanError( + f"Invalid config file path '{config_path}';" + f" path must end with '.toml' or '.json'." + ) - # An empty config file will yield None, and that's ok. - if user_config_raw is not None: - out = dataclass_from_dict(ServerConfig, user_config_raw) + out = dataclass_from_dict(ServerConfig, user_config_raw) # Update our known mod-time since we know it exists. - self._config_mtime = Path(self._config_path).stat().st_mtime + self._config_mtime = Path(config_path).stat().st_mtime self._last_config_mtime_check_time = time.time() - # Go with defaults if we weren't able to load anything. - if out is None: - out = ServerConfig() - if print_confirmation: - print(f'{Clr.CYN}Valid server config file loaded.{Clr.RST}', - flush=True) + print( + f'{Clr.CYN}Valid server config file loaded.{Clr.RST}', + flush=True, + ) return out def _enable_tab_completion(self, locs: dict) -> None: @@ -574,6 +663,7 @@ class ServerManagerApp: try: import readline import rlcompleter + readline.set_completer(rlcompleter.Completer(locs).complete) readline.parse_and_bind('tab:complete') except ImportError: @@ -585,7 +675,7 @@ class ServerManagerApp: while not self._done: self._run_server_cycle() - def _handle_term_signal(self, sig: int, frame: FrameType) -> None: + def _handle_term_signal(self, sig: int, frame: FrameType | None) -> None: """Handle signals (will always run in the main thread).""" del sig, frame # Unused. sys.exit(1 if self._should_report_subprocess_error else 0) @@ -594,25 +684,35 @@ class ServerManagerApp: """Spin up the server subprocess and run it until exit.""" # pylint: disable=consider-using-with - # Reload our config, and update our overall behavior based on it. - # We do non-strict this time to give the user repeated attempts if - # if they mess up while modifying the config on the fly. + # Reload our config, and update our overall behavior based on + # it. We do non-strict this time to give the user repeated + # attempts if if they mess up while modifying the config on the + # fly. self.load_config(strict=False, print_confirmation=True) self._prep_subprocess_environment() - # Launch the binary and grab its stdin; - # we'll use this to feed it commands. + # Launch the binary and grab its stdin; we'll use this to feed + # it commands. self._subprocess_launch_time = time.time() # Set an environment var so the server process knows its being - # run under us. This causes it to ignore ctrl-c presses and other - # slight behavior tweaks. Hmm; should this be an argument instead? + # run under us. This causes it to ignore ctrl-c presses and + # other slight behavior tweaks. Hmm; should this be an argument + # instead? os.environ['BA_SERVER_WRAPPER_MANAGED'] = '1' + + # Set an environment var to change the device name. Device name + # is used while making connection with master server, + # cloud-console recognize us with this name. os.environ['BA_DEVICE_NAME'] = self._config.party_name + print(f'{Clr.CYN}Launching server subprocess...{Clr.RST}', flush=True) - binary_name = ('BallisticaCoreHeadless.exe' - if os.name == 'nt' else './bombsquad_headless') + binary_name = ( + 'BallisticaKitHeadless.exe' + if os.name == 'nt' + else './bombsquad_headless' + ) if platform.processor() == 'aarch64': binary_name = './bombsquad_headless_aarch64' assert self._ba_root_path is not None @@ -620,51 +720,48 @@ class ServerManagerApp: # Launch! try: - if ERROR_LOGGING: - self._subprocess = subprocess.Popen( - [binary_name, '-cfgdir', self._ba_root_path], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - cwd='dist') - - self.nbsr = NBSR(self._subprocess.stdout) - self.nbsrerr = NBSR(self._subprocess.stderr) - else: - self._subprocess = subprocess.Popen( - [binary_name, '-cfgdir', self._ba_root_path], - stdin=subprocess.PIPE, - cwd='dist') - + self._subprocess = subprocess.Popen( + [binary_name, '--config-dir', self._ba_root_path], + stdin=subprocess.PIPE, + cwd='dist', + ) except Exception as exc: self._subprocess_exited_cleanly = False print( f'{Clr.RED}Error launching server subprocess: {exc}{Clr.RST}', - flush=True) + flush=True, + ) # Do the thing. try: self._run_subprocess_until_exit() - except Exception as exc: - print(f'{Clr.RED}Error running server subprocess: {exc}{Clr.RST}', - flush=True) + print( + f'{Clr.RED}Error running server subprocess: {exc}{Clr.RST}', + flush=True, + ) self._kill_subprocess() assert self._subprocess_exited_cleanly is not None - # EW: it seems that if we die before the main thread has fully started - # up the interpreter, its possible that it will not break out of its - # loop via the usual SystemExit that gets sent when we die. + # EW: it seems that if we die before the main thread has fully + # started up the interpreter, its possible that it will not + # break out of its loop via the usual SystemExit that gets sent + # when we die. if self._interactive: - while (self._interpreter_start_time is None - or time.time() - self._interpreter_start_time < 0.5): + while ( + self._interpreter_start_time is None + or time.time() - self._interpreter_start_time < 0.5 + ): time.sleep(0.1) # Avoid super fast death loops. - if (not self._subprocess_exited_cleanly and self._auto_restart - and not self._done): + if ( + not self._subprocess_exited_cleanly + and self._auto_restart + and not self._done + ): time.sleep(5.0) # If they don't want auto-restart, we'll exit the whole wrapper. @@ -679,10 +776,9 @@ class ServerManagerApp: # If we want to die completely after this subprocess has ended, # tell the main thread to die. if self._wrapper_shutdown_desired: - # Only do this if the main thread is not already waiting for - # us to die; otherwise it can lead to deadlock. - # (we hang in os.kill while main thread is blocked in Thread.join) + # us to die; otherwise it can lead to deadlock. (we hang in + # os.kill while main thread is blocked in Thread.join) if not self._done: self._done = True @@ -703,12 +799,15 @@ class ServerManagerApp: bincfg = {} # Some of our config values translate directly into the - # ballisticacore config file; the rest we pass at runtime. - port = int(os.environ.get('PORT', self._config.port)) - bincfg['Port'] = port + + # ballisticakit config file; the rest we pass at runtime. + bincfg['Port'] = int(os.environ.get('PORT', self._config.port)) + bincfg['Auto Balance Teams'] = self._config.auto_balance_teams bincfg['Show Tutorial'] = self._config.show_tutorial + if self._config.protocol_version is not None: + bincfg['SceneV1 Host Protocol'] = self._config.protocol_version if self._config.team_names is not None: bincfg['Custom Team Names'] = self._config.team_names elif 'Custom Team Names' in bincfg: @@ -737,13 +836,16 @@ class ServerManagerApp: Must be called from the server process thread. """ import pickle + assert current_thread() is self._subprocess_thread assert self._subprocess is not None assert self._subprocess.stdin is not None val = repr(pickle.dumps(command)) assert '\n' not in val - execcode = (f'import ba._servermode;' - f' ba._servermode._cmd({val})\n').encode() + execcode = ( + f'import baclassic._servermode;' + f' baclassic._servermode._cmd({val})\n' + ).encode() self._subprocess.stdin.write(execcode) self._subprocess.stdin.flush() @@ -754,32 +856,21 @@ class ServerManagerApp: assert current_thread() is self._subprocess_thread assert self._subprocess.stdin is not None - # Send the initial server config which should kick things off. - # (but make sure its values are still valid first) + # Send the initial server config which should kick things off + # (but make sure its values are still valid first). dataclass_validate(self._config) self._send_server_command(StartServerModeCommand(self._config)) while True: - # If the app is trying to shut down, nope out immediately. if self._done: break - # output=self._subprocess.stdout.readline() - # print(output) - if ERROR_LOGGING: - out = self.nbsr.readline(0.1) - out2 = self.nbsrerr.readline(0.1) - if out: - sys.stdout.write(out.decode("utf-8")) - _thread.start_new_thread(dump_logs, (out.decode("utf-8"),)) - if out2: - sys.stdout.write(out2.decode("utf-8")) - _thread.start_new_thread(dump_logs, (out2.decode("utf-8"),)) + # Pass along any commands to our process. with self._subprocess_commands_lock: for incmd in self._subprocess_commands: - # If we're passing a raw string to exec, no need to wrap it - # in any proper structure. + # If we're passing a raw string to exec, no need to + # wrap it in any proper structure. if isinstance(incmd, str): self._subprocess.stdin.write((incmd + '\n').encode()) self._subprocess.stdin.flush() @@ -790,28 +881,31 @@ class ServerManagerApp: # Request restarts/shut-downs for various reasons. self._request_shutdowns_or_restarts() - # If they want to force-kill our subprocess, simply exit this - # loop; the cleanup code will kill the process if its still - # alive. - - if (self._subprocess_force_kill_time is not None - and time.time() > self._subprocess_force_kill_time): + # If they want to force-kill our subprocess, simply exit + # this loop; the cleanup code will kill the process if its + # still alive. + if ( + self._subprocess_force_kill_time is not None + and time.time() > self._subprocess_force_kill_time + ): print( f'{Clr.CYN}Immediate shutdown time limit' f' ({self.IMMEDIATE_SHUTDOWN_TIME_LIMIT:.1f} seconds)' f' expired; force-killing subprocess...{Clr.RST}', - flush=True) + flush=True, + ) break # Watch for the server process exiting.. - code: Optional[int] = self._subprocess.poll() + code: int | None = self._subprocess.poll() if code is not None: clr = Clr.CYN if code == 0 else Clr.RED print( f'{clr}Server subprocess exited' f' with code {code}.{Clr.RST}', - flush=True) - self._subprocess_exited_cleanly = (code == 0) + flush=True, + ) + self._subprocess_exited_cleanly = code == 0 break time.sleep(0.25) @@ -824,62 +918,77 @@ class ServerManagerApp: minutes_since_launch = (now - self._subprocess_launch_time) / 60.0 # If we're doing auto-restart with config changes, handle that. - if (self._auto_restart and self._config_auto_restart - and not self._subprocess_sent_config_auto_restart): - if (self._last_config_mtime_check_time is None - or (now - self._last_config_mtime_check_time) > 3.123): + if ( + self._auto_restart + and self._config_auto_restart + and not self._subprocess_sent_config_auto_restart + ): + if ( + self._last_config_mtime_check_time is None + or (now - self._last_config_mtime_check_time) > 3.123 + ): self._last_config_mtime_check_time = now - mtime: Optional[float] - if os.path.isfile(self._config_path): - mtime = Path(self._config_path).stat().st_mtime + mtime: float | None + config_path = self._get_config_path() + if os.path.isfile(config_path): + mtime = Path(config_path).stat().st_mtime else: mtime = None if mtime != self._config_mtime: print( f'{Clr.CYN}Config-file change detected;' f' requesting immediate restart.{Clr.RST}', - flush=True) + flush=True, + ) self.restart(immediate=True) self._subprocess_sent_config_auto_restart = True - # Attempt clean exit if our clean-exit-time passes. - # (and enforce a 6 hour max if not provided) + # Attempt clean exit if our clean-exit-time passes (and enforce + # a 6 hour max if not provided). clean_exit_minutes = 360.0 if self._config.clean_exit_minutes is not None: - clean_exit_minutes = min(clean_exit_minutes, - self._config.clean_exit_minutes) + clean_exit_minutes = min( + clean_exit_minutes, self._config.clean_exit_minutes + ) if clean_exit_minutes is not None: - if (minutes_since_launch > clean_exit_minutes - and not self._subprocess_sent_clean_exit): + if ( + minutes_since_launch > clean_exit_minutes + and not self._subprocess_sent_clean_exit + ): opname = 'restart' if self._auto_restart else 'shutdown' print( f'{Clr.CYN}clean_exit_minutes' f' ({clean_exit_minutes})' f' elapsed; requesting soft' f' {opname}.{Clr.RST}', - flush=True) + flush=True, + ) if self._auto_restart: self.restart(immediate=False) else: self.shutdown(immediate=False) self._subprocess_sent_clean_exit = True - # Attempt unclean exit if our unclean-exit-time passes. - # (and enforce a 7 hour max if not provided) + # Attempt unclean exit if our unclean-exit-time passes (and + # enforce a 7 hour max if not provided). unclean_exit_minutes = 420.0 if self._config.unclean_exit_minutes is not None: - unclean_exit_minutes = min(unclean_exit_minutes, - self._config.unclean_exit_minutes) + unclean_exit_minutes = min( + unclean_exit_minutes, self._config.unclean_exit_minutes + ) if unclean_exit_minutes is not None: - if (minutes_since_launch > unclean_exit_minutes - and not self._subprocess_sent_unclean_exit): + if ( + minutes_since_launch > unclean_exit_minutes + and not self._subprocess_sent_unclean_exit + ): opname = 'restart' if self._auto_restart else 'shutdown' print( f'{Clr.CYN}unclean_exit_minutes' f' ({unclean_exit_minutes})' f' elapsed; requesting immediate' f' {opname}.{Clr.RST}', - flush=True) + flush=True, + ) if self._auto_restart: self.restart(immediate=True) else: @@ -903,13 +1012,12 @@ class ServerManagerApp: print(f'{Clr.CYN}Stopping subprocess...{Clr.RST}', flush=True) - # First, ask it nicely to die and give it a moment. - # If that doesn't work, bring down the hammer. + # First, ask it nicely to die and give it a moment. If that + # doesn't work, bring down the hammer. self._subprocess.terminate() try: self._subprocess.wait(timeout=10) - self._subprocess_exited_cleanly = ( - self._subprocess.returncode == 0) + self._subprocess_exited_cleanly = self._subprocess.returncode == 0 except subprocess.TimeoutExpired: self._subprocess_exited_cleanly = False self._subprocess.kill() @@ -917,26 +1025,16 @@ class ServerManagerApp: def main() -> None: - """Run the BallisticaCore server manager.""" + """Run the BallisticaKit server manager.""" try: ServerManagerApp().run() except CleanError as exc: - # For clean errors, do a simple print and fail; no tracebacks/etc. - # Any others will bubble up and give us the usual mess. + # For clean errors, do a simple print and fail; no + # tracebacks/etc. Any others will bubble up and give us the + # usual mess. exc.pretty_print() sys.exit(1) -def dump_logs(msg): - if os.path.isfile('logs.log'): - size = os.path.getsize('logs.log') - - if size > 2000000: - os.remove('logs.log') - - with open("logs.log", "a") as f: - f.write(msg) - - if __name__ == '__main__': main() diff --git a/config.json b/config.json new file mode 100644 index 00000000..3c0dea94 --- /dev/null +++ b/config.json @@ -0,0 +1,44 @@ +{ + "party_name":"BombSquad Community Server", + "party_is_public":true, + "authenticate_clients":true, + "admins":[ + "pb-yOuRAccOuNtIdHErE", + "pb-aNdMayBeAnotherHeRE" + ], + "enable_default_kick_voting":true, + "port":43210, + "max_party_size":6, + "session_max_players_override":8, + "session_type":"ffa", + "playlist_code":12345, + "playlist_shuffle":true, + "auto_balance_teams":true, + "enable_telnet":false, + "teams_series_length":7, + "ffa_series_length":24, + "stats_url":"https://discord.gg/ucyaesh", + "clean_exit_minutes":60, + "unclean_exit_minutes":90, + "idle_exit_minutes":20, + "show_tutorial":false, + "team_names":[ + "ladoo", + "barfi" + ], + "team_colors":[ + [ + 0.8, + 0.0, + 0.6 + ], + [ + 0, + 1, + 0.8 + ] + ], + "enable_queue":true, + "protocol_version":35, + "player_rejoin_cooldown":10.0 +} \ No newline at end of file diff --git a/config.yaml b/config.yaml deleted file mode 100644 index bfcda9b2..00000000 --- a/config.yaml +++ /dev/null @@ -1,134 +0,0 @@ -# To configure your server, create a config.yaml file in the same directory -# as the ballisticacore_server script. The config_template.yaml file can be -# copied or renamed as a convenient starting point. - -# Uncomment any of these values to override defaults. - -# Name of our server in the public parties list. -party_name: "BombSquad Community Server" - -# If true, your party will show up in the global public party list -# Otherwise it will still be joinable via LAN or connecting by IP address. -#party_is_public: true - -# If true, all connecting clients will be authenticated through the master -# server to screen for fake account info. Generally this should always -# be enabled unless you are hosting on a LAN with no internet connection. -authenticate_clients: true - -# IDs of server admins. Server admins are not kickable through the default -# kick vote system and they are able to kick players without a vote. To get -# your account id, enter 'getaccountid' in settings->advanced->enter-code. -admins: -- pb-yOuRAccOuNtIdHErE -- pb-aNdMayBeAnotherHeRE - -# Whether the default kick-voting system is enabled. -enable_default_kick_voting: true - -# UDP port to host on. Change this to work around firewalls or run multiple -# servers on one machine. -# 43210 is the default and the only port that will show up in the LAN -# browser tab. -port: 43210 - -# Max devices in the party. Note that this does *NOT* mean max players. -# Any device in the party can have more than one player on it if they have -# multiple controllers. Also, this number currently includes the server so -# generally make it 1 bigger than you need. Max-players is not currently -# exposed but I'll try to add that soon. -max_party_size: 6 - -# Options here are 'ffa' (free-for-all), 'teams' and 'coop' (cooperative) -# This value is ignored if you supply a playlist_code (see below). -#session_type: ffa - -# Playlist-code for teams or free-for-all mode sessions. -# To host your own custom playlists, use the 'share' functionality in the -# playlist editor in the regular version of the game. -# This will give you a numeric code you can enter here to host that -# playlist. -playlist_code: 412158 - -# Alternately, you can embed playlist data here instead of using codes. -# Make sure to set session_type to the correct type for the data here. -#playlist_inline: [] - -# Whether to shuffle the playlist or play its games in designated order. -#playlist_shuffle: true - -# If true, keeps team sizes equal by disallowing joining the largest team -# (teams mode only). -#auto_balance_teams: true - -# The campaign used when in co-op session mode. -# Do print(ba.app.campaigns) to see available campaign names. -#coop_campaign: Easy - -# The level name within the campaign used in co-op session mode. -# For campaign name FOO, do print(ba.app.campaigns['FOO'].levels) to see -# available level names. -#coop_level: Onslaught Training - -# Whether to enable telnet access. -# IMPORTANT: This option is no longer available, as it was being used -# for exploits. Live access to the running server is still possible through -# the mgr.cmd() function in the server script. Run your server through -# tools such as 'screen' or 'tmux' and you can reconnect to it remotely -# over a secure ssh connection. -#enable_telnet: false - -# Series length in teams mode (7 == 'best-of-7' series; a team must -# get 4 wins) -teams_series_length: 7 - -# Points to win in free-for-all mode (Points are awarded per game based on -# performance) -ffa_series_length: 24 - -# If you have a custom stats webpage for your server, you can use this -# to provide a convenient in-game link to it in the server-browser -# alongside the server name. -# if ${ACCOUNT} is present in the string, it will be replaced by the -# currently-signed-in account's id. To fetch info about an account, -# your back-end server can use the following url: -# http://bombsquadgame.com/accountquery?id=ACCOUNT_ID_HERE -stats_url: https://discord.gg/ucyaesh - -# If present, the server subprocess will attempt to gracefully exit after -# this amount of time. A graceful exit can occur at the end of a series -# or other opportune time. Server-managers set to auto-restart (the -# default) will then spin up a fresh subprocess. This mechanism can be -# useful to clear out any memory leaks or other accumulated bad state -# in the server subprocess. -#clean_exit_minutes: 60 - -# If present, the server subprocess will shut down immediately after this -# amount of time. This can be useful as a fallback for clean_exit_time. -# The server manager will then spin up a fresh server subprocess if -# auto-restart is enabled (the default). -#unclean_exit_minutes: 90 - -# If present, the server subprocess will shut down immediately if this -# amount of time passes with no activity from any players. The server -# manager will then spin up a fresh server subprocess if auto-restart is -# enabled (the default). -#idle_exit_minutes: 20 - -# Should the tutorial be shown at the beginning of games? -#show_tutorial: false - -# Team names (teams mode only). -team_names: -- ladoo -- barfi - -# Team colors (teams mode only). -team_colors: -- [0.8, 0.0, 0.6] -- [0, 1, 0.8] - -# Whether to enable the queue where players can line up before entering -# your server. Disabling this can be used as a workaround to deal with -# queue spamming attacks. -#enable_queue: true \ No newline at end of file diff --git a/dist/ba_data/data/langdata.json b/dist/ba_data/data/langdata.json index 8da0fc08..42862cf0 100644 --- a/dist/ba_data/data/langdata.json +++ b/dist/ba_data/data/langdata.json @@ -3,16 +3,17 @@ "Arabic": "العربية", "Belarussian": "Беларуская", "Chinese": "简体中文", + "ChineseSimplified": "简体中文", "ChineseTraditional": "繁體中文", "Croatian": "Hrvatski", "Czech": "Čeština", "Danish": "Dansk", "Dutch": "Nederlands", "Esperanto": "Esperanto", - "Filipino": "Tagalog ", + "Filipino": "Wikang Pilipino", "French": "Français", "German": "Deutsch", - "Gibberish": "Gibberish", + "Gibberish": "Abuktarika", "Greek": "Ελληνικά", "Hindi": "हिंदी", "Hungarian": "Magyar", @@ -21,14 +22,19 @@ "Japanese": "日本語", "Korean": "한국어", "Malay": "Melayu", - "Persian": "فارسی‎", + "Persian": "⁦فارسی‎", + "PirateSpeak": "Pirate Speak", "Polish": "Polski", "Portuguese": "Português", + "PortugueseBrazil": "Português - Brasil", + "PortuguesePortugal": "Português - Portugal", "Romanian": "Română", "Russian": "Русский", "Serbian": "Српски", "Slovak": "Slovenčina ", "Spanish": "Español", + "SpanishLatinAmerica": "Español - Latinoamerica", + "SpanishSpain": "Español - España", "Swedish": "Svenska", "Tamil": "தமிழ்", "Thai": "ภาษาไทย", @@ -38,69 +44,104 @@ "Vietnamese": "Tiếng Việt " }, "translation_contributors": [ + "!101Asulil", "!edMedic💊", + "!ggMustaGD1", + "!GummyBoiYT", + "!nobal", "!ParkuristTurist!", + "!яебалфантуврот!", "\"9۝ÅℳЇℜρℜѺ۝ƬǀGΞЯ", + "\"Unknown\"", + "!SlashByte (Mass)", + "3alTemp (Temp)", "/in/dev/", + "09332509847", + "0Globalsters", "1.4.139", + "10009did", + "11", "123", "123123123", + "1234abcdS", + "1Kirito", + "1Platinumpatty", + "1SpaZ", "228варенье", "233", "26885", + "3alTemp", "43210", + "4e6yre4ek", "5PH3X", "99", + "@bombsquad_mkhuhgjaj", "@sametsunal", + "[<>]", "_DraXX", "_Fami", "Omar a", "Bruno A.", + "Abdullah A.S", + "A296", "aaalligator", "aadesh", "Aaron", "Erik Abbevik", + "Abcd", "Abdo", "Abduh", "Abdul", + "Abdulaziz", "Abdulloh", "Abe", "Ahmed abed", + "Abhay", "abhi", "AbhinaY", "Gifasa abidjahsi", "Abinav", "Abir", + "ABITDANTON", + "Abne", "Abolfadl", "Abolfazl", "Abraham", "Roman Abramov", "AC", "Achref", + "ACrazyPenguin", "adan", "Adeel (AdeZ {@adez_})", "Adel", - "Rio Adi", + "AdemYzz", + "Rio adi", "Rayhan Adiansyah", "Yonas Adiel", "admin", "Adonay", "AdOwn69", "Adrián", + "Aeliux", "Aely", "Aenigmus", "Aether", + "AFKNoName", "Afrizal", "Aga<3", "Carlos Mario Agamez", "ageng", + "Agenteby20", "Dimitris Aggelou", + "AGØTI", "ariyan ahir", "AHMAD", "Aufan Ahmad", - "Ahmed", + "ahmed", "ahmedzabara", + "Aikx", "Collin Ainge", + "Ajnaz", "Akash", "Akbar", "Bekir Akdemir", @@ -108,6 +149,8 @@ "Aki", "Abdullah Akkan", "Berk Akkaya", + "Akmuhammet", + "AkVoN", "AKYG", "mohammed al-abri", "Ali Al-Gattan", @@ -116,28 +159,39 @@ "Anna Alanis", "Manuel Alanis", "alanjijuoo7fudu@gmail.com", + "alanjosue", + "alayoupy", "albertojesusvaldesdelrey@gmail.com", + "Albrtz", "Alej0hio", "Pedro Alejandro", "Gabrijel Aleksić", "Alex", "Alexander", "Gros Alexandre", + "AlexBx", "Alexey", "Alexgmihai", "Alexis", "Alexistb2904", "Alexyze", "Algene123456", - "ALI", + "Algerino", + "Alguien_201", + "ali", + "Mohamed ali", "Shadiq Ali", + "Alievil1", "alireza", "alirezaalidokht", + "AliSh8787", "ALISSON", "Virgile Allard", "Allinol", "ahmed alomari", - "Alonso", + "alonso", + "Alp", + "Alpcik910", "Alper", "Alpha", "AlphaT", @@ -151,15 +205,21 @@ "Amedeo", "ameen", "Kidane Amen-Allah", + "Amin", "amin.ir", - "Amir", + "amir", + "amir0799@gmail.com", "amir22games", "amir234", "amir80sas", "AmirMahdi.D :P", + "Amirreza", + "amirsaman050", "Amirul", "Ange Kevin Amlaman", + "AMOGUSS85", "amr", + "AN218", "Anandchaursiya", "Anas", "Anastasija", @@ -185,6 +245,7 @@ "krish angad", "Krishna D Angad", "vân anh", + "ANILBABATRPRO", "Aniol", "Daniel Felipe Silva dos Anjos", "Anmol", @@ -193,22 +254,29 @@ "Antonio", "Antoniom", "Lucas Antunes", + "AOMAD1987", "wassim aoufi", "apis", "Sagar April", + "AquaQw11", "Fernando Araise", "arda", "Hellmann Arias", "Muhammad Arief", + "Arihant", "Arimaru", + "Arimo", "Arin", "arjanex", + "Armando", "Arroz", "ARSHAD", + "Arshia", "ArshiyDLn", "Artem", "Valentino Artizzu", "Arxyma", + "Ashes", "Ashik", "Ashish", "AskarBink", @@ -218,27 +286,34 @@ "Atalanta", "Atilla", "Atom", + "Attila", "Audacious7214", "Aufaghifari", + "Aulia", "Ausiàs", "autismo", "Autoskip", "Ryan Auxil", "Avamander", + "AvianJay", "Tel Aviv", "awase2020@gmail.com", - "sev alaslam Awd", + "sev alaslam awd", "Axel", + "Aynursargi", "ayub", "masoud azad(fireboy)", "Md azar", "Azlan", "Azoz", "Burak Karadeniz (Myth B)", + "Leonan B.", "Myth B.", "B4likeBefore", "Praveen Babu", + "Badmoss", "Baechu", + "bag", "Balage8", "BalaguerM", "Peter Balind", @@ -250,7 +325,7 @@ "Ryan Bandura", "Bank", "Ibrahim Baraka", - "Kamil Barański", + "Kamil Barański (Limak09)", "Leonan Barcelos", "Bardiaghasedipour", "William Barnak", @@ -267,10 +342,13 @@ "Bato", "Florian Bauernfeind", "David BAUMANN", + "Bauti", + "bautielpro", "bayanus", "Wojtek Bałut", "Hi bbbbbbbbb", "Eduardo Beascochea", + "Keyhan Behzadi", "Eduan Bekker", "бравлер Андрей Belarus", "ben", @@ -278,48 +356,64 @@ "Bendy", "Sérgio Benevides", "Simon Bengtsson", + "Beniamino", "Alfano Beniamino", "Benjamin", "Benjamín", "benjapol", "Ori bennov", "BenVectorgames", + "Benyamin", "benybrot96", + "BERAT01", "berkay", "Silvio Berlusconi", "Bernardiny", "Anton Bang Berner", "Felix Bernhard", + "Beroudzin", + "Abhishek Bhardwaj", + "Bhxyu", + "Arthur Bianco", "Davide Bigotto", "bilibili@Medic药", "Bima", "Biytremni", "Blackcat2960", "BlackShadowQ", + "Bleed", "Daniel Block", "BlueBlur", + "bob", "bob bobber", + "Bobr", + "Bombay De Bom", "BomBillo", "The Bomboler 💣", "bombsquad", + "El Furrito de BombSquad", + "Wheezy bombsquad", "Bombsquadzueira", "Bomby", "Zeleni bomby", - "Alex BONYOMA", + "Alex Bonyoma", "Book", "Guilherme Borges", "Lucas Borges", "Gianfranco Del Borrello", "Abel Borso", "Plasma Boson", - "Cristian Bote", + "Cristian Bote \"ZZAZZ\"", "Cristián Bote", "botris", "Botte", "bouabdellah", "Antoine Boulanger", "Thomas Bouwmeester", + "Boxan", "Ali x boy", + "boyhero7779", + "Hamza Baybars Boyraz", "Bořivoj", "Paul braga", "Sammy Braun", @@ -327,6 +421,7 @@ "Brendan", "Federico Brigante", "Anderson Brito", + "Nah bro", "Broi", "Brojas", "Brojasko", @@ -334,8 +429,12 @@ "Brunoazocar", "bsam", "Bsamhero", - "BSODPK", + "Bsodpk", + "Bub", + "Bubas", "Marvin Bublitz", + "BudaCcm", + "Buddypall", "Vincent R. Buenaventura", "Buskebam", "Buto11", @@ -345,6 +444,7 @@ "Christoffer Bünner", "mvp aka cactus", "mvp aka legend (aka cactus) 🌵", + "Levi Cadimiel", "Cadødø", "Chris Laurence Cagoco", "Calet", @@ -356,19 +456,26 @@ "Fabio Cannavacciuolo", "CANOVER", "Fedrigo Canpanjoło", + "carl", "Yan Carlos", "CarlosE.", "mark Dave a carposo", "Fabricio de Carvalho", "Joshua Castañeda", "Lisandro Castellanos", + "Conroy Cat 2011", "Catjuanda05", "CatMax", + "Cattest", "Arthur Cazes", + "Ceaser", "CerdoGordo", "Ceren", + "cflagos", + "cgaming", "chang", "Charlie", + "Pradip Chaudhari", "kalpesh chauhan", "chausony", "CheesySquad", @@ -378,6 +485,7 @@ "Vadim Choi", "Chris71/Chris71x", "Hans Christensen", + "Christian", "Attilio Cianci", "Kajus Cibulskis", "Mateusz Ciochoń", @@ -386,17 +494,21 @@ "Jerome Collet", "probably my. com", "Comrade", + "Blaze Corderz", "Stefano Corona", "Corrolot", "Francisco Law Cortez", "David Cot", "Nayib Méndez Coto", "Dylan cotten", + "Coutinho", "covcheg", "COVER", "crac", "CrazyBear", + "CRAZYCHEF", "Frederick Cretton", + "Crispiymini", "crisroco10", "Cristhian", "Cristian", @@ -406,20 +518,27 @@ "Prashanth CrossFire", "Cryfter", "cuddles98", + "El famoso cukito", "cukomus", "CYCL0YT", + "Filipec CZ", "D", "D-Mega", "Dada", + "daG0AT", + "Daichi", "Daivaras", "Dajo6596YT", "Dakkat", "Mikkel Damgaard", + "DanAlfred (SUBC1PYZH)", "Danco", "Dani", "Daniel", "Daniel3505", "DaniesAlex007", + "Danilix365", + "Daniozo", "Dančo", "Iman Darius", "DarkAnarcy", @@ -427,27 +546,42 @@ "DarshaN", "Shibin das", "Dasto", + "Davi", "David", "Davide", "DavidPlayzLol", - "DavidPlayzloll", + "Davidplayzloll", "DaymanLP", + "DD87", "Ddávid", "Die or Dead", "Привет от детей DeadLine", + "DEATH", + "DEATHSTU/DJSTU", + "DEBANNER", "deepjith", + "DEFENDER", + "Defiant", "dekarl", "deliciouspudding43", + "deliplayer", "delshe", "Denis", "Dennis", "Dennys", "Alex Derbenew", + "Ingegner Devecchi", + "Dr : developer", "df", + "DFгульСпачибо", "Santanu Dhar", + "DHRUVIL", + "DIAbli", + "Diablo", "Guilherme Dias", "Diase7en", "ferbie Dicen", + "Diego", "Diego788", "DiegoGD", "DiGGDaGG", @@ -458,7 +592,9 @@ "Diprone", "djaber djafer", "Fadhil djibran", + "DJSTU", "Alexis Dk", + "dkod9vZ", "DKua", "dlw", "DMarci", @@ -466,11 +602,17 @@ "Dmitriy", "Savchenko Dmitriy", "Count Su Doku", + "Giuseppe Valerio Dominici", "DominikSikora!", "Kai Dominique", "Gerardo Doro", "DottorMorte", + "Doubleknig", + "Atakan Doğrul", + "Dr", "Dragomir", + "Dragon", + "Dreaming", "Drellsan", "DrGhast", "Dron009", @@ -482,61 +624,94 @@ "Dustin", "Paul Duvernay", "Emir İslam Dündar", + "Beny (Goofy e-mail)", "E.R.A.L", "Ebutahapro07tr", + "Ed89631", + "Eder", + "Vishal from Eric's language edit", + "EditYusuFD", + "Edrees", "Edson", "Glen Edwards", "Amr Wassiem Eessa", + "Eeveelution", "ef", + "EgorZH", "Ali ehs", + "eightyfoahh", "Eiva", "EK", "EKFH", "avatar por reina del carnaval en la que te lo mando el", "Rezk ElAdawy", + "ElAlienPVZ", + "Elbol19", "ElCatCaesar", + "ElCrashBndct173", + "ElDemon", "ElderLink", "elfree", "Elian", + "Elmakyt", + "ELMEX95", "Elsans320_YT", + "Mahmoud elshayeb", "Elskoser", "ElVolKo", "ali emad", "Ramy Emad", + "Emanuel_12", "Emil", "Kürti Emil", + "55Hamza Emin", "Muhammed emir", "Muhammet Emir", "EmirSametEr", "emm", "EnderDust123", "EnderKay", + "Endless_jk", "EnglandFirst", "Enrico", + "Entakos", "enzo", - "Era", + "era", + "Bueno pero igual era", + "Era0S (Spazton)", + "EraOS", + "Erfan", + "Eric-fan", "Erick", + "Erik", "Erkam", "Jonas Ernst", "NO es", "Shayan Eskandari", - "Esmael", + "esmael", "Jose espinoza", "ethanmigueltrinidad", + "Eugen", "ExaYT", "Exelendary", "Abdullatif Badinjki ExPeRt 1420", "ExplosiveDinosaurs.com", "EXTENDOO", "Eyder", + "Eymen", + "F15fahd_lol", "fa9oly9", "Fabian", "Luca Facchinetti", "Facundo", "Jakub Fafek", + "Fahd", "Syed Fahrin (Mr.Lemoyne)", "faizal.faiz.ms@gmail.com", "Fakih", + "A BombSquad Fan", + "Eric I'm your number 1 fan", + "fancy", "FanDolz.", "Faqih", "Muhammad Faqih ''None''", @@ -550,12 +725,15 @@ "Shaikh Fazal", "Fea", "FearLessCuBer", + "Feder-28", + "Feder28", "Federico", "Fedrigo", "Marco Fabián Feijoó", "Fenyx", "Fernando", "David Fernández", + "Rashell Fernández", "FerranC", "FertileChannelHD", "FightBiscuit", @@ -567,20 +745,26 @@ "Aldereus Fire", "Robert Fischer", "Kai Fleischmann", + "FLOKI", "Iancu Florin", "FluffyPal", "FLᎧRᏋᏁTIᏁᎧ", "Angelo Fontana", + "Forcedpood", "FortKing", "Freaku", "Golden Freddy", "FREÂK", "Andrey Fridholm", "FriskTheHuman303", + "FRM1235", "Froshlee14", + "FrostyXD", "FuckIndoDick", "Lukas Funk", "Gustavo FunnyGuard28", + "fyroove", + "fyrooveCZ", "Erick G", "Roberto G", "George G.", @@ -591,23 +775,31 @@ "João Gabriel", "Gabriele", "Nihar Gajare", + "GalaxyM4", "GalaxyNinja2003", "AP - Pro Gamer", "Proff Gamer", "Eduardo Gamer05", + "Gamer2809", "Taufiq Gamera", "Altangerel Ganbaatar", "Quentin Gangler", "RUSLAN ABDUL GANI", + "Garou", "Gaspard", "krish gator", "gene.mTs", "GeoMatHeo", + "Gerakl", "Gerry", "GG (9.2)", + "ggMustaGD0", + "! ggMustaGD1", + "Mohammad gh", "Onkar Ghagarum", "GHAIS", "Omar Ghali", + "Ghost 👿", "GhOsT_St3p", "GhostGamer", "Gian", @@ -615,10 +807,14 @@ "Gianluca11", "Aldi gibran", "Aidan Gil", + "Jorge Giménez", "Noe Marley Ginting", "Giovalli99", + "Devecchi Giovanni", + "DEVEGGHI GIOVANNI", "Giovanny", "Dc superhero girl", + "giuppy", "Givij", "Gleb", "Glu10free", @@ -627,24 +823,34 @@ "gman_4815", "God丶烛龙", "Colin Goeieman", + "golmanx", "박준서(PJS GoodNews)", "gowthamvelkarthik.k", "Nicola Grassi", + "Dario Greggio", "Gerrit Grobler", "Oliver Grosskloss", + "gtex", + "gtexAndSoby", "Alexis Guijarro", "Guilherme", "Victor Guillemot", "Guillermo", + "GummyBoiYT", "SHOBHIT GUPTA", "Gurad", "Max Guskov", + "Gustavo", "Rachmat Gusti", "Aditya Gwala", - "Tódor Gábor", + "Tódor Gábor (Joshua)", "Tymoteusz Górski", "Thomas Günther", + "Hamza Emin GÜRLER", + "Paşa Güven", + "Muhammad H", "H.J.N", + "h4Nk1oZz", "Haasaani", "Hack", "HackPlayer697", @@ -653,11 +859,14 @@ "Haidar", "Joud haidar", "جود حيدر/joud haidar", + "Hajmoein", "Halox", "HamCam1015", "hamed", + "Alhasan Hamoud/Alretrox ❤️‍🔥🖤", "Zulfikar Hanif", "Happaphus", + "Franschieko Satya Haprabu", "Hariq", "harojan", "Harsh", @@ -671,6 +880,7 @@ "Florian Haxhijaj", "Hayate", "Hayate16", + "hcy_2022", "hehhwushh", "Lukas Heim", "Hugues Heitz", @@ -679,51 +889,77 @@ "Christoffer Helmfridsson", "Hemra", "Julian Henkes", + "Henq", "henry", "Heraltes", "boy hero", "bsam hero", "herosteve22jajs", + "Charles hewitt", + "Heydeyl", + "HeyFang", "heymaxi", "HiImBrala", "Ayra Hikari", "Hiking", "Himesh", + "Himo", + "Himo381", "Yazan Hinnawi", "Daffaa Hisyaam", "Trung Hiếu", + "hbi78889999gj b hj", + "hj5700", "Nabil Hm", "Nguyen Dang Hieu Hoa", "Minh Hoang", + "Phan Le Minh Hoang", "Robin Hofmann", "hola", + "holasoycuyo", "Sebasian Varela Holguin", "Holystone", "Jeremy Horbul", - "Hosein", + "hosein", "hoseinا", + "HOSSAM", + "Ahmed Hossam", "Phan Lê Minh Hoàng", + "Hrach", + "Hubert", "Jorge Isaac Huertero", "Hussain", + "Hassan Samir Hussain", "Umair Hussain", "Hussam", + "Huy", + "HyMr", + "HYr", "Adrian Höfer", "Davide Iaccarino", + "Ian", "iBearzGaming", "Iboyindyza", "Ibrahim", + "ForestORIG из IcE", + "Iddrejiot", + "idiomat738", "Ignacio", "IgnUp21", "Igomen15", "Igor", + "Ihan", + "Ihan7", "IL_SERGIO", "!YamGila (Syed Ilham)", "Iliya_bomB", + "Iliyafeili", "illonis", "Syed Ilham Ilman", "Ily77788", "Ilya", "IlyxaGold", + "Imad", "d imitris", "Nik ali imran", "IND_PIYUSH", @@ -731,31 +967,45 @@ "indieGEARgames", "Darkness indo", "Indohuman", + "Inicio", "IniSaya6666", "inkMedic", "inkMedic💊", "InvisibleDude", "Anestis Ioakimidis", "Dragomir Ioan", + "IorYou4600 (V2)", "Isa", + "IsaacStar ★", "Israelme03", "Tobias Dencker Israelsen", "Kegyes István", + "Fritz IT", "Itamar", "ivan", + "Ivanpinheiro", "iViietZ", "MOHD IZWAN", + "J3zrel", "JaaJ", "Al jabbar", "Jacek", + "Jack", "Jack556", + "Jacob213", + "Jahnmi", "Jhon Jairo", + "jakecato1602@gmail.com", "wahid jamaludin", + "Jameszambrana", + "jamilgamer", "Tarun Jangra", "Aleksandar Janic", + "janobaez22", "Martin Jansson", "JasimGamer", - "Jason", + "Jasmine (kijiko)", + "jason", "Javvaed", "Jbo", "JCIBravo", @@ -772,10 +1022,14 @@ "Jeulis", "Jewellbenj", "jgst2007@gmail.com", + "Jhon", + "Jhoncat086@gmail.com", "Zhou Jianchu", "jimmy", + "JimmyYT", "Jiren", "jitues", + "JJ", "JM", "Joan", "JoaoVitorBF", @@ -785,9 +1039,13 @@ "Ksteven john", "Steven john", "Johnny", + "Johnwick", "joke", + "jonas-bonas", "Jonatas", + "Jonathan", "Jop", + "Jor", "JoseANG3L", "Joseetion", "Joseph", @@ -795,8 +1053,10 @@ "Rudransh Joshi (FireHead)", "joshuapiper", "Jossiney", + "Juangame65", "juanramirez", "Jules", + "Junior4pro", "juse", "Justine", "JYLE", @@ -811,9 +1071,10 @@ "kadaradam", "Efe Kahraman", "KalakCZ", + "kalenk", "Adam Kalousek", "kalpesh", - "Kalyan", + "kalyan", "Kamal", "Aiman Aryan Kamarajan", "Kamil (Limak09)", @@ -826,11 +1087,19 @@ "Burak Karadeniz(MythB)", "Daniel Karami", "Karim", + "Karlimero", + "shemas - Ebrahim Karram", "Kasra", + "katon", + "Kau5hik", + "Kaunyt", "Kaushik", "KawaiiON", + "kazoo081", + "kazooicek", "KD", "Kejuxs", + "Mahmut Keleşyılmaz", "Mani kelidari", "Kelly", "Kelmine", @@ -845,23 +1114,31 @@ "khalio", "$RICO$ KhevenMito", "Khwezi", + "Kian", + "kiasha", "kibro", + "Kicken07", "Joop Kiefte", "killer", "killer313", + "Killerfox...Nima", "King", "KingCreeps", "kinnie", "kira", "kirill", "KirillMasich", + "Piotr Kiryk", "Kittycat41", + "Dominic Klein", "Andrew Kmitto", "Philipp Koch", + "Koentro", "Kolmat", "komasio", "komasio71", "KomodoRec", + "koolych (Николай)", "Niko Koren", "Nikolay Korolyov", "Kostas", @@ -873,9 +1150,13 @@ "krishAngad", "krishuroy", "kroш)", + "Mikuláš Krtička", "Patel krumil", "Krunal", + "Kubixpro1", + "kueue", "Alok Kumar", + "Parth Kumar", "sarath kumar", "Aapeli Kumpulainen", "Aldhiza Kurniawan", @@ -887,10 +1168,15 @@ "Kyle", "Jan Kölling", "L_JK", + "Laaziz", + "Labrador", + "labrosggv", "John Patrick Lachica", + "Osama bin ladin", "laikrai", "m a lakum", "Dmitry Lamperujev", + "Language", "K. Larsen", "Nicklas Larsen", "Shin Lasung", @@ -898,12 +1184,20 @@ "Lazered", "Lazydog", "Elia Lazzari", + "LEANKEAN", "이지민 (Ji-Min Lee)", + "legended", "Mick Lemmens", + "Lemon4ik", "Leo", + "Mr. LeoLeo", + "Leonid", + "Lepixhd", "Lester", + "Letrixito", "Szajkajkó Levente", "Szajkajó Levente", + "Levi (Ashes)", "Johannes Lex", "Gastón Lezcano", "Shuaibing Li", @@ -911,33 +1205,47 @@ "Juan Liao", "LickyBeeYT", "Nicola Ligas", + "Alef costa lima", "Limak09", + "LimonAga", "lin", "Dustin Lin", "Kyle Lin", "Linus", "Linux44313", + "LioLioFlo", + "Lionel", + "Lippu", + "Lisavidxxxxxxx5", "LiteBalt", "LittleNyanCat", "Juunhao Liu", + "LivezynBR", + "Lixar", "Lizz", "Lizzetc", "Lkham", "Lobinhofs", "Loex", "Loko", + "LoliPopa", "Longkencok", + "longmouses", + "杰瑞 longmouses", "looooooooou", "LordHiohi", "Lordigno", "lorenzo", "Lostguybrazil", + "Loup", "mian louw", "69 lover", "Jordan Vega Loza", + "lshndnglnt", "Chenging Lu", "Chengming Lu", "João Lucas", + "Pedro Lucas", "Simone Luconi", "Ludicrouswizard", "satrio ludji", @@ -947,52 +1255,75 @@ "Luis(GalaxtM4)", "luislinares", "luispro25", + "Luiz", "Luka", "Luke", "Luke994", + "lukerloker", "Lukman", "Hermanni Luosujärvi", "Lurã", "Luthy", + "Luy", + "Luytaris", "Geogre Lyu", "Be aware that m", + "Matias M.", "M.R.T", "M5TF4", "Mac 143338", "MaceracıMS", "Samuel Maciel", "Djawad madi", + "MadNightr", "Mads Beier Madsen", + "Magomed", + "Magorik", "Mahan", "Ondřej Mahdalík", "mahdi", "mahdimahabadi", + "Mose saef maher", "Mahmoud", + "Mahmoudrabe", + "Mahziyar", "maicol", "Majestozão", "Makar", "Maks1212", "Malaysian", + "Amirali Malekshahi", "EMILIO MALQUIN", "MAMAD", + "mamali", + "Mamax400", + "Wagdy mamdouh", + "mandarin", "Mani", "Manimutharu", + "Manmath", + "ManmathTheGreat", "Ahmed Mansy", "Manu", + "Leonardo Manuel", "Mapk58", + "Van Mapper", "Marcel", "Marchella", "Marcin", "Marco", "Marcolino", - "Filip Marek", + "filip marek", "Marcin Marek", + "Margarrom", "Mariel", "Marin", "mariuxoGaming", "Stefan Markovic", "Marouene", "Marošsko", + "MarshMallon", + "Marshmellon", "martin", "Philip Martin", "MartinZG007", @@ -1004,25 +1335,43 @@ "Mathias", "Mathieu", "matias", + "Matias26157", + "MatiasCW (MatiasMGz)", + "MatiasMG", + "MatiasMGz", + "MatiasOMG", + "MatiasOMGz", "matj1", "Eduardo de Matos", "Matteo", "Matthias", + "Nepote Mattia", + "MatzE", "Ihsan Maulana ( @ihsanm27)", "Muhammad Akbar Maulana", + "MAVIS", "Mavook", + "MaximohFox", + "MazeMan111", "Federico Mazzone", "Andrea Mazzucchelli", + "McFer256", + "MCW", "Medic", "Medic别闹我有药", + "Medic药", "German Medin", "Martin Medina", "Mehret Mehanzel", + "Mobin Mehdizadeh", "Mehmet", "Mehrdad", "Kevin Mejía", "Mell", + "Melt1ngAis", + "Meraj", "MereCrack", + "Merengue", "Mert", "Meryu07", "Meysam", @@ -1030,17 +1379,23 @@ "Davis Michelle", "Mick", "Miguel", + "Luiz \"Foxy\" Miguel", "Miguelterrazas123", "Mikael", "mike", + "MIKEFOKING", + "Mikserol", "Milaner", "Milk3n", "Fabio Milocco", "mimis", + "mimomandi", "Mina", "minh123456789thcsvk", "MinhAn19203", + "Michael J. Soto Miranda", "Azfar Ahmed Mirza", + "misael", "Deepak Mishra", "Mistetas3002", "Skramh Miugrik", @@ -1049,33 +1404,52 @@ "MKG", "mobin", "Mobina", + "Mochosquad", + "Haj moein", "Moh", "Mohamadali", "Mohamadamin", "Mohamed", - "Mohammad", + "seif mohamed", + "mohammad", + "Mohammad.cur", "Mohammad11dembele", "MOHAMMADERFAN", "Mohammadhosain", + "Mohammadpl", "Mohammed", - "MOHAMMEDTALAL1ST", + "MohammedTalal1st", "1n Mohhaamad", + "Ali Mohseni", + "Shaygan mohsenian", "Moin", + "momo", + "pOpsi mOn", + "Popsie (or pOpsi mOn)", + "Ahmed this money", "MONIRIE", - "Carlos Montalvo", + "Charles Andrew Montalbo", + "carlos montalvo", "Ederson Moraes", "Eduardo Moreira", "Danteo Moriarty", "Kabir morya", + "Morybuzz", "Moses", + "Cauã Moura", + "Iasonasss Mourelatos", "mr", "mr.Dark", "Mr.Smoothy", + "MR0000000001", + "mradio", + "mrbebra333", "MrDaniel715", "MrGlu10free", "Mrmaxmeier", "MrNexis", "MrS0meone", + "MrSaster2024", "Ivan Ms", "MSampic", "Msta", @@ -1084,6 +1458,8 @@ "Muhammed Muhsin", "MujtabaFR", "Muni", + "Munizxn", + "Mush", "mustardb", "Hisham Musthafa", "Mohammed Musthafa", @@ -1091,12 +1467,17 @@ "Mwss", "MYSENIOR", "mythbrk00@gmail.com", + "محمدحسین MZZ", + "Mzz85moh", "Sajti Márk", "Samuel Mörling", "Luca Müller", + "Nabil", + "Omar Nabil", "nacho", "Nagaarjun(pongal)", "Nahuelgomez1607", + "Your name", "Nasser", "Natasja", "Nathan", @@ -1109,10 +1490,14 @@ "nazroy", "Ndrio°o", "NecroMeerkat", + "nectio", "Neel", "Nel", "Nemeil", - "Era (Spazton neo)", + "E0/Era0S/Spazton neo", + "Era (Spazton neo) (e)", + "Era0S (Spazton neo)", + "Era0S/Spazton neo/E0", "Mattia Nepote", "The nerd", "Gabriel Del Nero", @@ -1129,12 +1514,15 @@ "Niels", "Frederik Nielsen", "Nifujini", + "Lorenzo (aka night_skiesRBLX)", "Nikali2007", + "NikeOvSky", "Nima", "XU NING", "طارق محمد رضا سعيد NinjaStarXD", "nino", "Nintendero65", + "Nithish (Rookie)", "Nizril", "Nnubes256", "Bu nny", @@ -1143,36 +1531,58 @@ "NofaseCZ", "Max Noisa", "Noisb", + "NoNameA14171274.", + "NoNameC3698241", "None", + "NOOBPEDAR", + "NoobPilotPlayz", "Noobslaya101", "noorjandle1", "Petter Nordlander", + "Nose", + "NoTag", "NotBrojasAgain", + "NotDiegoGD", "Ntinakos555", "NullWizard", "Dhimas Wildan Nz", "*** Adel NZ. ***", + "O.T.S.K.", + "Obada55555", + "Odhalit", + "TORK OGHLAN", "Ognjen", + "ogre19", "okko", "Bastián Olea", "Nikita Oleshko", - "Omar", + "omar", "OmarBv", + "omgxd5", "On3GaMs", - "No One", + "No one", + "oneman", "Adam Oros", "Andrés Ortega", "Zangar Orynbetov", + "Oscar", "Osmanlı2002", "Osmanys", + "Ossd", + "otd", + "oualiabdou", "OyUnBoZaN (NEMUTLUTURKUMDİYENE)", + "Dmitry P.", + "pablo", "pack", "PALASH", + "Buddy pall", "Giorgio Palmieri", "Abhinay Pandey", "PangpondTH", "PanKonKezo", "PantheRoP", + "Pappoliver72", "ParadoxPlayz", "Gavin Park", "Parkurist", @@ -1185,25 +1595,34 @@ "Dominik Pavešić", "BARLAS PAVLOS-IASON", "Payu", + "PC1003436", + "pc100756", "PC189085", "PC192082", "pc192089", "PC261133", "PC295933", "PC432736", + "PC607666", + "PC912334", + "PC965064", + "PC979802", "pebikristia", "Pedro", "Jiren/Juan Pedro", + "João Pedro", "Penta :D", + "Peppone0071", "Peque", "Rode Liliana Miranda Pereira", "Jura Perić", "Panumas Perkpin", "Pero", + "persian", "Khoi Pete", "Kacper Petryczko", "pett", - "Petulakulina", + "petulakulina", "Pez", "PGIGM", "Đào Xuân Phi", @@ -1212,8 +1631,11 @@ "piga", "Stefano Pigozzi", "Mario Donato Pilla", + "PillTek", "Pinchidino", + "pinguino", "Danilo \"Logan\" Pirrone", + "heorhii pitukh", "PivotStickfigure12", "Pixelcube", "PixelStudio", @@ -1222,16 +1644,20 @@ "Elian Pj", "Broi PL", "Ziomek PL", + "George Play's", "Anestis Plithos", "Pluisbaard", "Jaideep Kumar PM", + "Pmans", "podolianyn", + "Pofani", "poggersCat", "Pong", + "Lehlogonolo \"YetNT\" Poole", "Pooya", "pouriya", "Pouya", - "Pranav", + "pranav", "Luca Preibsch", "Prem", "Fabian Prinz", @@ -1242,16 +1668,26 @@ "psychatrickivi12", "pszlklismo", "Pulidomedia.com", + "PUNKBR", "haris purnama", + "Deva Puspita", "GABRIEL PUTRICK", "Bodnár Péter", + "P💊llTek", + "药丸科技 | P💊llTek.cn", + "Qellow", + "qoweawi", "Gangler Quentin", + "Quezz3x", + "Qwerty15", "Qwsa", "QŴE", "Anbarasan R", "efvdtrrgvvfygttty5 5 r", "Felo Raafat", "Tim Rabatr", + "Vinni The Rabbit", + "rabbitboom", "Radfrom", "RadicalGamer", "Radicool", @@ -1259,6 +1695,9 @@ "raghul", "khaled rahma", "Rayhan Rahmats", + "RaichuNc2008", + "Raiyan", + "Babang Raja", "Ralfreengz", "1. Ramagister", "Rostislav RAMAGISTER", @@ -1267,8 +1706,10 @@ "Rahul Raman", "Vicente Ramirez", "ramon", + "Ramzy", "Randlator", "Random_artz__", + "Ranera <3", "Rares", "rashid", "Yudha Febri Rastuama", @@ -1288,6 +1729,7 @@ "REDEJCR", "redyan", "De'Viren Reed", + "Ali Rehab", "Cornelius Reimann", "releaseHUN", "renas", @@ -1308,11 +1750,15 @@ "Ridzuan", "Samuel Rieger", "RieJoemar", + "RiLa", + "Rings3467", + "Ringsoul", "Jeroen Rinzema", "RioAdir", "Max Rios", "Rio枫叶", "RiPe16", + "riphoopfun", "Rishabh", "Rivki", "rizaldy", @@ -1331,13 +1777,17 @@ "Ronianagranada", "roninjhie@gmail.com", "Rori", + "Rottlez", "Mario Roveda", "Roy", "Rubanen", - "Kaj Rumpff", + "Joris de Ruiter", + "kaj rumpff", "Dosta Rumson", "Hong Ruoyong", "Philip Ruppert", + "Language Russia", + "RussianLover2008", "Ryan", "LiÇViN:Cviatkoú Kanstançin Rygoravič", "Ricky Joe S.Flores", @@ -1345,18 +1795,32 @@ "Justin Saephan", "sahel", "Abdullah Saim", + "Saints557", + "sakhayan741", "Audinta Sakti", + "Saldanha", + "saleh", "Bassam bu salh", "Bsam bu salh", "M. Rizki Agus Salim", "Salted", "Matteo Salvini", "Salvo04", + "SamComeli", + "Ali Sameer", + "Samen", + "samin", + "Samir", + "Sakude sammeel", + "Samsep10l", + "Samuel", "San", + "Sanou", "SaNt0RiNiKits577YT", "Guilherme Santana", "Santiago", "Ivan Santos :)", + "santosamerica880@gmail.com", "Diamond Sanwich", "SAO_OMH", "Dimas Saptandi", @@ -1366,35 +1830,59 @@ "sattar", "Saverio", "Jhon Rodel Sayo", + "Daniel Schniepp", "Christiaan Schriel", "Hendrik Schur", + "Scratchyli", + "SDIP_FGV", "SEBASTIAN2059", "Semen", + "semethers", + "SENSEI", + "JIN SEOWOO", "Mihai Serbanica", "Daniel Balam Cabrera Serrano", "Yefta Aditya Setiawan", + "Seyed", "Sg", "sgx", "Black Shadow", "ShadowQ", "shafay", "Manan Shah", + "Fares Shaheen", + "Shahin", "shakesm", + "Mester Shams 🇮🇷", "Sharvesh", "Nalam Shashwath", + "A sheep", + "A small sheep", + "shemas", "Haige Shi", "ShockedGaming", "Shogun", "Shayan Shokry", + "Alonso Sierra", "Dominik Sikora", + "Siltal", + "Erick Silva", "Leonardo Henrique da Silva", + "Lucas Silva", "Sebastian Silva", + "silver_volt4", + "Aviv Simel", "Simotoring", + "SIRTACOOOOO", "Pawan Singh sisodiya", + "skibidibambam", "Skick", + "SkillPro", "sks", "Max Sky", + "Slavik❤", "SlayTaniK", + "slcat", "Igor Slobodchuk", "Rasim Smaili", "Nicola Smaniotto", @@ -1409,6 +1897,8 @@ "SoK", "SoldierBS", "Unnamed Solicitude", + "Some1", + "SorenaPV", "SPT Sosat", "Soto", "spacechase26", @@ -1417,8 +1907,10 @@ "speddy16", "Spielfreake (Garke)", "Spielfream", + "Spooc", "Spy", "SqdDoom", + "Sreejith", "sss", "ST", "Danny Stalman", @@ -1426,6 +1918,7 @@ "Bartosz Staniszewski", "Stare", "StarFighter", + "Artem Stasyuk", "Rz Stazzy", "Stealives", "Steffo", @@ -1438,22 +1931,30 @@ "STPayoube", "Stratex", "SYED EPIC STUDIOS", + "SUBC1PYZH", + "suhail", "sun.4810", "Samet Sunal", "sundar", "Suprcat", "Indo sus", - "Sven", + "sven", "Shannon Sy", "syaifudib", "Daniel Sykora", + "Sylveon", + "SYSTEM-D-WIN", + "Syumza", + "syxznb", "Sz™", "Jorge Luis Sánchez", + "Kevin Nicola Ríos Sánchez", "Daniel Sýkora", "Aleksandar Tadic", "Arung Taftazani", "taha", "Rasim Eren TAHMAZ", + "Tails", "Juancho Talarga", "Emre Talha(Alienus)", "talopl123", @@ -1461,10 +1962,12 @@ "Kaustubh Tando", "Kaustubh Tandon", "Tania", + "tank-sman", "Dmytro Tarasenko", "Tarma", "tarun", "Tauras", + "TAWILE", "tcnuhgv", "tdho", "Teals53", @@ -1480,6 +1983,7 @@ "TestGame1", "TestGame1👽🔥", "testwindows8189", + "tetee}", "tgd4", "Than", "Thanakorn7215", @@ -1490,51 +1994,78 @@ "thejoker190101", "TheLLage", "TheMikirog", + "Thenoroozi", + "thenoteasy", "Theo", "Thiago_TRZ", + "Thiosinaine", + "ThirdStar248", "ThisIsBad", "Trevon Thrasher", "Tiberiu", "Cristian Ticu", "Robert Tieber", + "TieDan", + "Tigas", "TIGEE", "Tim", "Tingis2", "Thura Tint", "Nishant Tiwari", "tjkffndeupwfbkh", + "Juraj Tlach", + "TM-DoDo", "Toloche", "Tom", "Juan Pablo Montoya Tomalá", + "Tomasekvata", "TomasNoobCz", + "Tommaso", "tomo", "tongtong", "Top 999", "Tory", - "TozeLeal", + "tozeleal", "Trung Hieu Le Tran", + "Small Translation", "Translator", + "TrialTemp (3alTemp)", "Trivago", "El Trolax", + "truong", + "Quang Truøng", "tseringlama", "Konstantin Tsvetkov", "Kontantin Tsvetkov", "Tudikk", + "José Tumpay", + "Romioza TV", "Jan Tymll", "Zacker Tz", "Zoltán Tóth", + "Buğra Türksal", "uDinnoo", "Cristian Ugalde", + "uhhihhycoo", "Atchy-Dalama--Ancelly Ulrich", "Syed Umar", + "Sylveon X Umbreon", + "Unarium", "Unknown", + "Unlette659", + "uoniak", + "Cristopher Uriel", "Uros", "clarins usap", + "Usishshsis", "utyrrwq", "Uzinerz", + "Uładzisłaŭ", "Shohrux V", "Vader", + "VadimChoi", "Valentin", + "Valentino", "Valkan1975", "Ante Vekić", "Malte van het Veld", @@ -1543,16 +2074,25 @@ "Dmitry \"SqdDoom\" Verigo", "Deepanshu Verma", "Jop Vernooij", + "Veroyatnolevlev", + "Veve", "Via", + "Vickey", "Victor", "paulo victor", + "VieAFKNoName", "Vigosl", "vijay", "vinicius", "Robin Vinith", "vinoth", "Vishal", + "VISHUUU", + "Vishuuu/Vishal3308", + "Vitorinox", + "Vixyd_MamaTvoya", "VoidNumberZero", + "Vovchik", "Voxel", "Voxel25", "VTOR", @@ -1566,11 +2106,14 @@ "Shaiful Nezan Bin Abdul Wahid", "wahyu", "Vaibhav Wakchaure", + "Wakefield", "Simon Wang", "Will Wang", + "WeanCZ", "Tilman Weber", "webparham", "Wesley", + "Whezzy", "whitipet", "wibi9424", "Wido2000", @@ -1581,44 +2124,67 @@ "wither", "Tobias Wohlfarth", "wojtekpolska", + "Wolf", "Doni Wolf", "Tommy Wong", "WonkaWoe", "Moury ji world", + "worldbiomusic", + "wsdx233", "wsltshh", "Wurstkatze", "WurstSaft", + "WynB", + "x7", "Xavier", "Francisco Xavier", "xbarix123897", "Peque XD", + "RompeCachetes XD", "Xem", + "Xetwy21", + "Xgyol", "Xizruh", "xxonx8", "Ajeet yadav", + "Taha yaghobi", "yahya", "Arda Yalın", "Yamir", "YannSonic", "Yantohrmnt401", + "Yarikent02", + "YarikMajorik", "Halil Yarkin", + "Yaromir", + "Yaroslav (Spaz1)", + "YaroslavBu", "amr yasser", + "Yatoku", + "Yeiberth", "YellowTractor", + "YelowGlow", "Yasin YILMAZ", + "ykkaf", "Ymgfr", + "yo", "yoksoudraft", + "Yones", "Kenneth Yoneyama", "yossef", "youcef", "Youssef", + "ahmed youssef", "Yousuf", "Yovan182Sunbreaker", "Yrtking", "All Star YT", "Dark Fgg5 YT", "Yudhis", + "Yugicchi", "yugo", "yullian", + "YuriBombSquad", "Yuslendo", "NEEROOA Muhammad Yusuf", "Yuuki", @@ -1629,6 +2195,7 @@ "Z@p€g@m€r", "Zac", "Dawn Zac", + "zahra", "Zaidan64GT", "Zain", "Zajle", @@ -1637,11 +2204,18 @@ "Zangar", "ZaraMax", "zecharaiah", + "ArShAm ZED", + "Zeinab1391", + "Zen78905tyr", "Daniele Zennaro", + "Zenotaiko", + "Zephyro", + "zFliws", "zfuw668", "Alex Zhao", "Doge Zhao", "Riven Zhao", + "Liubomyr Zheltova", "jim ZHOU", "Mohammad ziar", "ZioFesteeeer", @@ -1649,37 +2223,56 @@ "ZkyweR", "Nagy Zoltán", "Lukáš Zounek", + "ZOUZ", + "zPanxo", "ZpeedTube", + "Krivoy Zub", + "Zwizard", + "zx4571", "|_Jenqa_|", "¥¥S.A.N.A¥", + "GURLER Çeviri", + "Éleftheros", "Danijel Ćelić", "Štěpán", "Cristian Țicu", "Μπαρλάς Παύλος-Ιάσονας", "Ανέστης Πλήθος", + "Яркин Абдулхалил", "Роман Абрамо", "Роман Абрамов", + "айтаана", "Андрей (Krays)", "Андрій", + "опять сахаян бахаян", + "сахаян бахаян", + "эмиэ сахаян бахаян", "Богдан", "опять Вильян", "Тот самый Вильян", "Влад", + "Віктор", "Даниил", "данил", "дибисяра", "Дмитрий 228", "Евгений(Eugene)", "Артём Зобков (KoLenka)", + "Иван", "Юстин Иглин", "Игор", + "ИльяПро832", "Кирилл", + "саха тылыгар тылбаастаабыт киһи", "клаудкубес", "Климов", "Кирилл Климов", "Андрей Коваленко", "куатжан", + "сахаян лох", + "Марк", "Ваня Марков", + "маталка", "Драган Милановић", "Игор Милановић", "Марко Милановић", @@ -1687,6 +2280,7 @@ "михаил", "boba (Бодік) доперекладав Укр мову", "Арсений Мостовщиков", + "ПашаСосиХуй", "Принцип", "Пук-пук пук-пук", "Пупсєль", @@ -1696,11 +2290,33 @@ "Рома", "Ромашка :3", "Кирилл Рябцев", + "ААААААА САХАЯН", + "айуу айа эмиэ сахаян", + "надоел уже этот сахаян", + "сахаян да сахаян", + "в смысле опять сахаян?", + "сахаян тугу да кынара суох", + "-конкретно сылайдым", + "сахаянтан мин конкретно сылайдым", + "ханнык дундук гугл переводчик туттубутуй?", + "ТыНяшкаЕслиЧитаешьЭто :>", + "улыbHuсь", + "Ерасыл Фазылов (Paraxilius)", "ZEPT\"Александр Фартунов\"", + "ФОРЕСТ", + "Фортик", + "!SW сосут мой член!", "Эмир", + "мин эмиэ", "Өмүрзаков Эрсултан", + "сахаян бүт эрэ", + "сахаян уоскуй эрэ", + "Forton123 ютубер", + "Яромир", "Ярослав \"Noiseaholic\"", + "Б. Ярослав", "қуатжан", + "أيمن أبومايله", "اا", "احمدرضا", "احمد اسامه", @@ -1714,16 +2330,21 @@ "عبدالرحمن النجم", "امیرعلی", "اوتاكوDZ", + "ایرانی", "ایلی", + "ایهان", "بساام", + "تستپط", "جود", "حسين حساني", "جود حيدر", "محمد خالد", "امیرحسین دهقان", "امید رضازاده", + "كريستيانو رونالدو", "فاطمه عباس زاده ۸۴", "فاطمه عباس زاده۸۴", + "زينب", "ستسپ", "سلطان سروش", "محمد وائل سلطان", @@ -1737,14 +2358,17 @@ "علی", "سيد عمر", "عيسى", + "مجتبی", "اللهم صل على محمد وآل محمد", "امیر محمد", "هادی مرادی", + "مملی", "سعید مهجوری", "مهدی", "سید احمد موسوی", "عادل ن.", "نریمان", + "آرشا نظری", "عادل نوروزی", "ه۶۹", "حسین وفایی‌فرد", @@ -1752,12 +2376,15 @@ "١٢٣٤٥", "٦٤٦٦٤٦٤٦", "علیرضا پودینه", + "۱وقحی.", "वेदाँश त्यागी", + "லோகேஷ்", "അർഷഖ് ഹസ്സൻ", "วีรภัทร", "แมวผงาด(JuniorMeowMeow)", "๖̶ζ͜͡zephyro", "ᗪ|乃|丂Я尺卂", + "₹alph‽", "✰ℭØØҜĬ£$✰", "JPnatu なつ", "クリーバー", @@ -1772,32 +2399,41 @@ "南宫銷子()", "哔哩哔哩@Medic药", "夏神(后期汉化修正)", + "大笨蛋susu", "小黑猫", "张帅", "徐安博", "志夏", "志夏。", "志夏君deron", + "扎卡拉Zakara", + "月镜", + "杰瑞longmouses", "枫夜", "毛毛毛大毛", "炸弹朋友和Medic药", "熊老三", "盐焗汽水er", "神仙", + "纳皮猪NapPig.com", + "药丸科技|PillTek.cn", "药药Medic", "蔚蓝枫叶", "陈星宇你就是歌姬吧", "随风飘姚", + "鲨鱼俱乐部", "鲨鱼服·Medic", "鲲鹏元帅", "꧁ℤephyro꧂", "가라사대", "공팔이", "권찬근", + "김두한", "김원재", "넌", "먹꾸리", "박건희", + "배추", "김대중 부관참시", "붐추", "사람사는 세상", @@ -1806,8 +2442,11 @@ "일베저장소", "전감호", "BombsquadKorea 네이버 카페", + "F҉a҉d҉l҉i҉n҉e҉t҉", "Zona-BombSquad", + "‎༺Leͥgeͣnͫd༻", "CrazySquad", - "Stazzy" + "Stazzy", + "slida" ] } diff --git a/dist/ba_data/data/languages/arabic.json b/dist/ba_data/data/languages/arabic.json index 974917c1..f4d642b2 100644 --- a/dist/ba_data/data/languages/arabic.json +++ b/dist/ba_data/data/languages/arabic.json @@ -1,20 +1,22 @@ { "accountSettingsWindow": { - "accountNameRules": "لا يمكن لاسماء الحِسابَات أن تحتوي على رموز تعبيرية أو حروف غير ألفبائية", + "accountNameRules": "اسماء الحسابات لا يمكن أن تحتوي على رموز تعبير، أو حروف خاصة", "accountProfileText": "معلومات اللاعبين", "accountsText": "حسابات", "achievementProgressText": "${TOTAL} من أصل ${COUNT} إنجازاتك: أنجزت", - "campaignProgressText": "تقدم الحملة [HARD]:${PROGRESS}", + "campaignProgressText": "تقدمك في المعسكر(في الوضع الصعب): ${PROGRESS}", "changeOncePerSeason": "يمكنك تغييره مرة واحدة في الموسم", "changeOncePerSeasonError": "يجب عليك الانتظار حتى الموسم القادم لتغيير هذا مجددا (${NUM} أيام )", + "createAnAccountText": "اصنع حساب", "customName": "الاسم المخصص", - "googlePlayGamesAccountSwitchText": "اذا اردت استخدام حساب غوغل بلاي اخر،\nقم بإستعمال تطبيق غوغل بلاي العاب لتحويله.", + "deleteAccountText": "حذف الحساب", + "googlePlayGamesAccountSwitchText": "اذا اردت استخدام حساب غوغل بلاي اخر،\nقم بإستعمال تطبيق العاب غوغل بلاي لتحويله.", "linkAccountsEnterCodeText": "ادخل الرمز", "linkAccountsGenerateCodeText": "انشئ رمز", "linkAccountsInfoText": "(مشاركة تقدمك مع الاجهزة الاخرى)", "linkAccountsInstructionsNewText": "لربط حسابين،- انشئ رمز من الجهاز المراد انشاء الحساب فيه\n- وقم بإدخال الرمز في الجهاز الآخر\n\nالبيانات من الحساب الأول سوف يتم مشاركتها بين الجهازين\n\n من الحسابات كحد أقصى ${COUNT} يمكنك انشاء\n\n تنويه : فقط اربط الحسابات التي تملكها، إذا ربطت حسابك مع الأصدقاء،\n\n .لن يمكنكما اللعب معًا في نفس الوقت", "linkAccountsInstructionsText": "لربط حسابين, انتج كود على احد الحسابين \nو ادخل هذا الكود على الاخر.\nالتقدم و المخزون سيشتركا.\nيمكنك ربط حتى ${COUNT} حسابات.\n\nكن حذراً; هذا لا يمكن استرجاعه", - "linkAccountsText": "ربط حساب", + "linkAccountsText": "ربط الحسابات", "linkedAccountsText": ": حساباتي المرتبطة", "manageAccountText": "إدارة الحساب", "nameChangeConfirm": "هل تريد تغيير اسم حسابك إلى ${NAME}؟", @@ -25,25 +27,27 @@ "setAccountNameDesc": "اختر اسم لحسابك\nيمكنك استعمال الاسم من أحد حساباتك المرتبطة\nأو إنشاء اسم فريد.", "signInInfoText": "،قم بتسجيل دخولك لتجمع بطاقات، وتتحدى اللاعبين حول العالم\n.ولمشاركة تقدمك عبر الأجهزة", "signInText": "تسجيل الدخول", + "signInWithAnEmailAddressText": "سجل الدخول بالبريد الألكتروني", "signInWithDeviceInfoText": "الحساب التلقائي متوفر فقط على هذا الجهاز", "signInWithDeviceText": "سجل دخولك بحساب الجهاز", "signInWithGameCircleText": "Game Circle سجل دخولك بواسطة", - "signInWithGooglePlayText": "Google Play سجل دخولك عبر", + "signInWithGooglePlayText": "Google Play سجل دخولك عبر ", "signInWithTestAccountInfoText": "(حساب موجود على هاتفك; استخدم حساب الهاتف للمتابعة)", "signInWithTestAccountText": "تسجيل الدخول بحساب تجريبي", + "signInWithText": "تسجيل دخول مع ${SERVICE}", "signInWithV2InfoText": "حساب يعمل على جميع المنصات", - "signInWithV2Text": "قم بتسجيل الدخول باستخدام حساب BombSquad", + "signInWithV2Text": "قم بتسجيل الدخول باستخدام حساب ${APP_NAME}", "signOutText": "تسجيل الخروج", "signingInText": "...جارٍ تسجيل دخولك", "signingOutText": "...جارٍ تسجيل خروجك", "testAccountWarningOculusText": "تحذير: انت تقوم بتسجيل الدخول باستخدام حساب تجريبي.\nسيستبدل بحساب حقيقي خلال هذا العام الذي من خلاله\nسوف تقدر على شراء البطاقات ومزايا أخرى.\n\nإلى الان يمكنك الحصول على جميع البطافات في اللعبة.\n(على الرغم من ذلك، قم بالحصول على حساب متقدم مجانا)", - "ticketsText": "بطاقاتك الحالية:${COUNT}", - "titleText": "الحساب", + "ticketsText": "${COUNT} :عدد روانقك", + "titleText": "حسابك", "unlinkAccountsInstructionsText": "حدد حسابا لإلغاء ربطه", "unlinkAccountsText": "إلغاء ربط الحسابات", - "unlinkLegacyV1AccountsText": "إلغاء ربط الحسابات القديمة (V1)", + "unlinkLegacyV1AccountsText": "إلغاء ربط الحسابات من الإصدار القديم (V1)", "v2LinkInstructionsText": "استخدم هذا الارتباط لإنشاء حساب أو تسجيل الدخول.", - "viaAccount": "(${NAME} عبر الحساب)", + "viaAccount": "(وهو ${NAME})", "youAreSignedInAsText": ": قمت بتسجيل الدخول كـ" }, "achievementChallengesText": "إنجازات التحديات", @@ -78,7 +82,7 @@ "Free Loader": { "descriptionFull": "ابدأ بلعب الوضع الحر للجميع مع لاعبين أو أكثر", "descriptionFullComplete": "تم بدء لعبة بوضع الحرية للجميع مع لاعِبَيْنْ أو أكثر", - "name": "الفريق المجاني" + "name": "محمل مجاني" }, "Gold Miner": { "description": "اقتل 6 خصوم بأستخدام الألغام الأرضيَّة", @@ -111,7 +115,7 @@ "descriptionComplete": "!سجلت 250 نقطة", "descriptionFull": "${LEVEL} سجِّل 250 نقطة في", "descriptionFullComplete": "${LEVEL} لقد سجَّلت 250 نقطة في", - "name": "معَلِّم ${LEVEL}" + "name": "اسطوري!! ${LEVEL}" }, "Last Stand Wizard": { "description": "سجل 500 نقطة", @@ -166,7 +170,7 @@ "description": "فُزْ بدون اي قوى خارقة", "descriptionComplete": "لقد فزتَ بدون أي قوى خارقة", "descriptionFull": "بدون اي قوى خارقة${LEVEL} فز في", - "descriptionFullComplete": "بدون اي قوى خارقة${LEVEL} لقد فزتَ في", + "descriptionFullComplete": "بدون اي تعزيزات${LEVEL} لقد فزتَ في", "name": "دقة القصف" }, "Pro Boxer": { @@ -195,7 +199,7 @@ "descriptionComplete": "لقد هزمْتَ كل الموجات", "descriptionFull": "${LEVEL} اهزم كل الموجات في", "descriptionFullComplete": "${LEVEL} لقد هزمتَ كل الموجات في", - "name": "${LEVEL} نصر" + "name": "${LEVEL} إنتصار" }, "Pro Runaround Victory": { "description": "اكمل كل الموجات", @@ -237,7 +241,7 @@ "descriptionComplete": "أحرزت 500 نقطة", "descriptionFull": "${LEVEL} أحرز 500 نقطة في", "descriptionFullComplete": "${LEVEL} أحرزت 500 نقطة في", - "name": "${LEVEL} استاذ" + "name": "${LEVEL} اسطوري" }, "Runaround Wizard": { "description": "أحرز 1000 نقطة", @@ -255,7 +259,7 @@ "description": "فز بدون أن تموت", "descriptionComplete": "لقد فُزت بدون ان تموت", "descriptionFull": "بدون أن تموت ${LEVEL} فز", - "descriptionFullComplete": "بدون أن يموت ${LEVEL} لقد فزت", + "descriptionFullComplete": "بدون أن تموت ${LEVEL} لقد فزت", "name": "البقاء حيا" }, "Super Mega Punch": { @@ -335,19 +339,24 @@ "getMoreGamesText": "الحصول على المزيد من الألعاب", "titleText": "إضافة لعبة" }, + "addToFavoritesText": "الإضافة إلى المفضلات", + "addedToFavoritesText": ".إلى المفضلات '${NAME}' تمت إضافة", + "allText": "الكل", "allowText": "السماح", "alreadySignedInText": "تم تسجيل الدخول من حسابك من جهاز آخر.\n يرجى تبديل الحسابات أو إغلاق اللعبة على الأجهزة الأخرى\n وحاول مرة أخرى.", "apiVersionErrorText": "خطأ في تحميل الجزء ${NAME}; انه مخصص للإصدار رقم ${VERSION_USED}; يجب استخدام الإصدار ${VERSION_REQUIRED}.", + "applyText": "يختار", + "areYouSureText": "هل انت متأكد؟", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"ذاتي\" فعله فقط عندما تكون سماعات الأذن موصولة", "headRelativeVRAudioText": "صوت VR موافق مع حركة الرأس", - "musicVolumeText": "مستوى الموسيقى", - "soundVolumeText": "مستوى الموسيقى", - "soundtrackButtonText": "المقاطع الصوتية", - "soundtrackDescriptionText": "(اختر موسيقاك الخاصة لتعمل خلال اللعب)", + "musicVolumeText": "صوت المعازف", + "soundVolumeText": "صوت الأشياء", + "soundtrackButtonText": "المقطوعات الصوتية", + "soundtrackDescriptionText": "(أضف مقاطع صوتية لتسمعها أثناء لعبك)", "titleText": "الصوت" }, - "autoText": "ذاتي الاختيار", + "autoText": "تلقائي", "backText": "للخلف", "banThisPlayerText": "حظر هاذا الاعب", "bestOfFinalText": "الافضل في ${COUNT}", @@ -360,39 +369,49 @@ "boostText": "تقوية", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} تمّ ضبطه بالتطبيق ذاته", "buttonText": "زر", - "canWeDebugText": "هل ترغب ان تقوم فرقة القنبلة تلقائيا بالتبليغ عن المشاكل والاخطاء التقنية \nوالفنيه وبعض المعلومات الاساسية الى موفر اللعبة ؟ \n\nهذه البيانات لا تحتوي على اي معلومات شخصيه و هي تساعد على ابقاء\n اللعبه تعمل بشكل سلس و بدون اخطاء.", + "canWeDebugText": "هل ترغب ان تقوم ${APP_NAME} تلقائيا بالتبليغ\nعن الأخطاء التقنية، الفنية وبعض المعلومات الاساسية لمطور اللعبة؟\n\nهذه البيانات لا تحتوي على اية معلومات شخصية وهي تساعد\nعلى ابقاء العبة بشكل سلس وبدون أخطاء.", "cancelText": "إلغاء الأمر", "cantConfigureDeviceText": "المعذرة، ${DEVICE} لا يمكن تخصيصه", "challengeEndedText": "هذا التحدي قد انتهى", - "chatMuteText": "اسكات الدردشة", - "chatMutedText": "تم اسكات الدردشة", - "chatUnMuteText": "تحرير الدردشة", + "chatMuteText": "كتم المحادثة", + "chatMutedText": "المحادثة مكتومة", + "chatUnMuteText": "الغ كتم المحادثة", + "chests": { + "prizeOddsText": "احتمالات الجائزة", + "reduceWaitText": "قلل الانتظار", + "slotDescriptionText": "هذه الفتحة يمكنها أن تحمل كنزاً.\n\nاحصل على الكنوز عن طريق لعب مستويات في الحملات، الترتب في البطولات، و إكمال الانجازات.", + "slotText": "فتحة كنز ${NUM}", + "slotsFullWarningText": "تحذير: كل فتحات الكنوز ممتلئة.\nأي كنوز ستحصل عليها في هذه اللعبة سيتم خسارتها.", + "unlocksInText": "يُفتح في" + }, "choosingPlayerText": "<يختار لاعب>", + "claimText": "مطالبة", + "codesExplainText": "يتم توفير الرموز من قبل المطور\n.لتحليل مشاكل الحساب وتصحيحها", "completeThisLevelToProceedText": "يجب أن تكمل هذه المرحلة ليتم الاجراء", "completionBonusText": "علاوة الاكمال", "configControllersWindow": { - "configureControllersText": "ضبط قبضات التحكّم", + "configureControllersText": "إعداد وحدات التحكم", "configureKeyboard2Text": "ضبط لوحة مفاتيح اللاعب الثاني", - "configureKeyboardText": "ضبط لوحة المفاتيخ", - "configureMobileText": "أجهزة المحمول كقبضة تحكّم", - "configureTouchText": "ضبط شاشة اللمس", + "configureKeyboardText": "ضبط لوحة المفاتيح", + "configureMobileText": "إعداد هاتف كذراع تحكم", + "configureTouchText": "إعداد أزرار اللمس", "ps3Text": "قبضات تحكّم PS3", - "titleText": "قبضات التحكم", + "titleText": "إعداد المُتَحكِمات", "wiimotesText": "Wiimotes", "xbox360Text": "يد ألعاب أكس بوكس 360" }, "configGamepadSelectWindow": { - "androidNoteText": "ملاحظة: إن دعم قبضات التحكم يتباين تبعاً للجهاز و نظام ال Android", + "androidNoteText": "لتعلم: أن وحدات التحكم المدعومة تتباين حسب الجهاز وإصدار الأندرويد.", "pressAnyButtonText": "اضغط أيّ زر على قبضة التحكّم التي تريد أن تضبطها", - "titleText": "ضبط قبضات التحكّم" + "titleText": "هيئ وحدات التحكم" }, "configGamepadWindow": { "advancedText": "خيارات متطوّرة", "advancedTitleText": "اعداد متقدم ليد الألعاب", - "analogStickDeadZoneDescriptionText": "(فعّل هذه إذا كانت شخصيّتك 'تنحرف' تحرّر عصى التحكّم)", + "analogStickDeadZoneDescriptionText": "(فعّل هذه إذا كانت شخصيّتك 'تنحرف' عندما تحرّر عصا التحكّم)", "analogStickDeadZoneText": "مجال الموت للعصى التماثلية", "appliesToAllText": "(تنطبق على جميع قبضات التحكّم من هذا النوع)", - "autoRecalibrateDescriptionText": "(فعّل هذه إذا كانت شخصيّتك لاتتحرّك بالسرعة العظما)", + "autoRecalibrateDescriptionText": "(فعّل هذه إذا كانت شخصيّتك لاتتحرّك بالسرعة العظمى)", "autoRecalibrateText": "ضبط آلي للعصى التماثلية", "axisText": "محور", "clearText": "محو", @@ -435,26 +454,27 @@ "keyboard2NoteText": "ملاحظة: يمكن لمعظم لوحات المفاتيح تسجيل عدد قليل من ضغطات المفاتيح في\nمرة واحدة، لذلك وجود لاعب لوحة المفاتيح الثانية قد تعمل بشكل أفضل\nإذا كان هناك لوحة مفاتيح منفصلة تعلق لهم لاستخدامها.\nلاحظ أنك ستظل بحاجة إلى تعيين مفاتيح فريدة إلى\nلاعبين اثنين حتى في هذه الحالة." }, "configTouchscreenWindow": { - "actionControlScaleText": "مقياس التحكم في العمل", - "actionsText": "أفعال", - "buttonsText": "الأزرار", - "dragControlsText": "< اسحب عناصر التحكم لإعادة وضعها >", - "joystickText": "عصا التحكم", - "movementControlScaleText": "مقياس مراقبة الحركة", - "movementText": "حركة", - "resetText": "إعادة تعيين", - "swipeControlsHiddenText": "إخفاء أيقونات السحب", - "swipeInfoText": "'انتقاد' الضوابط أسلوب تأخذ قليلا التعود على ولكن\nتجعل من السهل للعب دون النظر إلى الضوابط.", - "swipeText": "مسحة", - "titleText": "تهيئة شاشة اللمس" + "actionControlScaleText": "حجم المُفَعِّل", + "actionsText": "المُفعِّل", + "buttonsText": "زرّي", + "dragControlsText": "{ غير مكان أداتي التحكم بنقرهما وسحبهما حيث تشاء }", + "joystickText": "مُدور", + "movementControlScaleText": "حجم المُحرِك", + "movementText": "المُحرِك", + "resetText": "إعادة الأصل", + "swipeControlsHiddenText": "اخفِ أزرار التحكم", + "swipeInfoText": "اختيار الزر الـ\"مربع\" سيأخذ وقتك للتعود عليه\nإلا أنه يسهل اللعب دون النظر لزر التحكم.", + "swipeText": "مربع", + "titleText": "إعداد التحكم باللمس" }, + "configureDeviceInSystemSettingsText": "${DEVICE} يُمكن تعديله في تطبيق إعدادات النظام.", "configureItNowText": "هل تريد تهيئته الآن؟", "configureText": "تهيئة", "connectMobileDevicesWindow": { "amazonText": "متجر تطبيقات أمازون", "appStoreText": "المتجر", - "bestResultsText": "لتحقيق أفضل النتائح ستحتاج اتصال انترنت سريع .. يمكنك \nزيادة السرعة بايقاف الاجهزة الاخرة المتصلة بالشبكة، أو اللعب \nقرب موزع الشبكة، أو الاتصال بمخدم اللعبة باستخدام الكابل \nالمباشر الى الشبكة", - "explanationText": "لاستخدام الهاتف الذكي أو الكمبيوتر اللوحي باعتبارها وحدة تحكم لاسلكية،\nتثبيت التطبيق \"${REMOTE_APP_NAME}\"عليه. أي عدد من الأجهزة\nيمكن الاتصال لعبة ${APP_NAME}عبر واي-في، وأنه مجاني!", + "bestResultsText": "لأداء أفضل يستحسن استعمال شبكة لاسلكية مستقرة ويمكنك زيادة \nاستقرار الشبكة بإطفاء الأجهزة اللاسلكية الأخرى(كالهواتف) واللعب\nقريبًا من موجهك(الراوتر) وكذا توصيل الجهاز المُستَضيف للمُلَاعَبَة\nبسلك إيثرنت متصل بالشبكة(الموجه) لزيادة سرعة الاتصال وتحسينه.", + "explanationText": "لاستعمال جوال أو لوحي(تابلت) كذراع تحكم لاسلكي فعليك\nبتثبيت تطبيق \"${REMOTE_APP_NAME}\" على الجهاز المراد استعماله كذراع.\nوهكذا يمكنك توصيل أكثر من جوال/لوحي بـ${APP_NAME} عبر الشبكة اللاسلكية.", "forAndroidText": "لأجهزة الأندرويد:", "forIOSText": "لنظام التشغيل أيفون:", "getItForText": "احصل على ${REMOTE_APP_NAME} لنظام التشغيل يوس في أبل أب ستور\nأو للأندرويد في متجر جوجل بلاي أو الأمازون أبستور", @@ -491,7 +511,7 @@ "powerRankingPointsToRankedText": "{اجمع} من {المتبقي} النقاط", "powerRankingText": "ترتيب الطاقة", "prizesText": "الجوائز", - "proMultInfoText": "اللاعبين الذين لديهم الترقية ${PRO}\nالحصول على ${PERCENT}٪ بوينت بوست هنا.", + "proMultInfoText": "يحصل اللاعبين المشتركين في ${PRO}\nعلى زيادة قدرها ${PERCENT}% في نقاطهم.", "seeMoreText": "المزيد . . .", "skipWaitText": "تخطي الإنتظار", "timeRemainingText": "الوقت المتبقي", @@ -504,24 +524,24 @@ }, "copyConfirmText": "نسخ إلى اللوحة", "copyOfText": "${NAME} نسخ", - "copyText": "ينسخ", + "copyText": "نسخ", "createEditPlayerText": "<اصنع او عدل حساب>", "createText": "اصنع", "creditsWindow": { - "additionalAudioArtIdeasText": "الأصوات الإضافية، الأعمال المبتكرة، والأفكار من قبل ${NAME}", - "additionalMusicFromText": "المعازف الإضافية من ${NAME}", + "additionalAudioArtIdeasText": "${NAME} الأصوات الإضافية، الأعمال المبتكرة، والأفكار من قبل", + "additionalMusicFromText": "${NAME} المعازف الإضافية من", "allMyFamilyText": "كل أصدقائي وعائلتي التي ساعدتني لتجربة اللعبة", - "codingGraphicsAudioText": "البرمجة، والرسومات، والأصوات انشأها ${NAME}", + "codingGraphicsAudioText": "${NAME} البرمجة، والرسومات، والأصوات انشأها", "languageTranslationsText": "مترجمي اللُّغات", "legalText": ":الحقوق القانونية", - "publicDomainMusicViaText": "معازف النطاق العام بواسطة ${NAME}", - "softwareBasedOnText": "هذه البرمجيات تعتمد على جزء من عمل ${NAME}", - "songCreditText": "${PERFORMER} تم تأديتها من قبل ${TITLE}\n نشر بواسطة ${PUBLISHER}،توزيع ${ARRANGER}، تم التأليف من قبل ${COMPOSER}\nبتصريح من ${SOURCE}", + "publicDomainMusicViaText": "${NAME} معازف النطاق العام بواسطة", + "softwareBasedOnText": "${NAME} هذه البرمجيات تعتمد على جزء من عمل", + "songCreditText": "${PERFORMER} تم تأديتها من قبل ${TITLE} \n ${PUBLISHER} نشر بواسطة ،${ARRANGER} توزيع ،${COMPOSER} تم التأليف من قبل \n ${SOURCE} بتصريح من", "soundAndMusicText": "الأصوات والمعازف:", - "soundsText": "تأثيرات الصوت من: (${SOURCE})", + "soundsText": "(${SOURCE}) :تأثيرات الصوت من", "specialThanksText": "شكر خاص:", - "thanksEspeciallyToText": "والشكر خاصةً لـ${NAME}", - "titleText": "فريق عمل ${APP_NAME}", + "thanksEspeciallyToText": "${NAME} والشكر خاصةً لـ", + "titleText": "مُساهِمي ${APP_NAME}", "whoeverInventedCoffeeText": "الشخص الذي اخترع القهوة" }, "currentStandingText": "تصنيفك الحالي هو #${RANK}", @@ -531,18 +551,18 @@ "debugText": "التصحيح", "debugWindow": { "reloadBenchmarkBestResultsText": "ملاحظة: فمن المستحسن أن قمت بتعيين إعدادات-> الرسومات-> القوام إلى 'عالية' أثناء اختبار هذا.", - "runCPUBenchmarkText": "قياس أداء المعالج", - "runGPUBenchmarkText": "قياس أداء معالج الرسوميات", - "runMediaReloadBenchmarkText": "قياس أداء وحدة تحميل الوسائط", - "runStressTestText": "تشغيل اختبار الإجهاد", + "runCPUBenchmarkText": "قس أداء المُعالج المركزي", + "runGPUBenchmarkText": "قس أداء معالج الرسوميات", + "runMediaReloadBenchmarkText": "قس أداء تحميل المحتوى", + "runStressTestText": "شغل الاختبار", "stressTestPlayerCountText": "عدد اللاعبين", "stressTestPlaylistDescriptionText": "اختبار الإجهاد قائمة التشغيل", - "stressTestPlaylistNameText": "اسم قائمة التشغيل", - "stressTestPlaylistTypeText": "نوع قائمة التشغيل", - "stressTestRoundDurationText": "مدة الجولة", - "stressTestTitleText": "اختبار الإجهاد", - "titleText": "معايير واختبارات الإجهاد", - "totalReloadTimeText": "إجمالي وقت إعادة التحميل: ${TIME} (راجع سجل للحصول على التفاصيل)" + "stressTestPlaylistNameText": "اسم قائمة الألعاب", + "stressTestPlaylistTypeText": "نوع قائمة الألعاب", + "stressTestRoundDurationText": "مدة الدورة الواحدة", + "stressTestTitleText": "محاكاة الضغط والإجهاد", + "titleText": "قياس الأداء والإجهاد والتحميل", + "totalReloadTimeText": "(راجع السجل للتفاصيل) ${TIME} :إجمال وقت إعادة تحميل الوسائط" }, "defaultGameListNameText": "الافتراضي ${PLAYMODE} قائمة التشغيل", "defaultNewGameListNameText": "قائمة تشغيل ${PLAYMODE}", @@ -550,6 +570,7 @@ "demoText": "عرض", "denyText": "رفض", "deprecatedText": "إهمال", + "descriptionText": "الوصف", "desktopResText": "جودة سطح المكتب", "deviceAccountUpgradeText": "تحذير:\nانت مسجل الدهول بحساب الجهاز (${NAME}).\nحسابات الجهاز (Device) سيتم حذفها في المستقبل.\nقم بالتطوير الى حساب V2 اذا اردت ان تقوم بحفظ تقدمك.", "difficultyEasyText": "سهل", @@ -557,9 +578,13 @@ "difficultyHardText": "صعب", "difficultyHardUnlockOnlyText": "لا يمكن فتح هذا المستوى إلا في الوضع الصعب.\n هل تعتقد أن لديك ما يلزم!؟!؟!", "directBrowserToURLText": "وجه متصفح الشابكة إلى العنوان التالي:", - "disableRemoteAppConnectionsText": "تعطيل اتصالات التطبيق عن بعد", + "disableRemoteAppConnectionsText": "منع الأجهزة المستعملة لتطبيق الحاكوم من الاتصال", "disableXInputDescriptionText": "يسمح أكثر من 4 وحدات تحكم ولكن قد لا تعمل كذلك.", "disableXInputText": "xinput تعطيل", + "disabledText": "مُعطّّل", + "discardText": "تجاهل", + "discordFriendsText": "أتبحث عن رفيق لتلعب معه؟\nإذن عليك بالديسكورد فإنه حيث تجد رفيقًا للعب!", + "discordJoinText": "انضم للديسكورد", "doneText": "تم", "drawText": "تعادل", "duplicateText": "مكرر", @@ -576,57 +601,59 @@ "titleText": "قائمة تشغيل محرر" }, "editProfileWindow": { - "accountProfileInfoText": "يحتوي هذا الملف الشخصي الفريد على اسم\nوأيقونة تعتمد على حسابك.\n\n${ICONS}\n\nانشئ ملف شخصي مخصص لاستعمال\nاسماء مختلفة أو أيقونات مخصصة.", - "accountProfileText": "(ملف تعريف الحساب)", - "availableText": "الاسم \"${NAME}\" متاح.", + "accountProfileInfoText": "يظهر هذا الـمُـعـرِّف اسـم الحـسـاب\nمع شارة تظهر نوع الحساب كهذه:\n\n${ICONS}\n\nانشئ مُعـرِّف جـديـد مـن الـقـائـمـة\nالسابقة لتغيير الاسم وتغيير الشارة.", + "accountProfileText": "(مُعرِّف حسابي)", + "availableText": ".متاح \"${NAME}\" الاسم", "characterText": "الشخصية", - "checkingAvailabilityText": "جار التحقق من التوفر ل \"${NAME}\" ...", - "colorText": "اللون", + "checkingAvailabilityText": "...\"${NAME}\" يُبحث عن توفر الاسم", + "colorText": "اللون الجذري", "getMoreCharactersText": "الحصول على المزيد من الشخصيات ...", "getMoreIconsText": "الحصول على المزيد من الرموز ...", - "globalProfileInfoText": "ملفات اللاعب العالمية مصممة لتملك\nاسم عالمي فريد. وأيضًا تتضمن أيقونات مخصصة", - "globalProfileText": "(ملف شخصي عالمي)", - "highlightText": "تسليط الضوء", - "iconText": "أيقونة", - "localProfileInfoText": "ملامح لاعب المحلي ليس لديهم رموز وأسمائهم\nغير مضمونة لتكون فريدة من نوعها. الترقية إلى ملف شخصي عام\nلحجز اسم فريد وإضافة رمز مخصص.", - "localProfileText": "(الملف الشخصي المحلي)", + "globalProfileInfoText": "تحجز المُعرّفات العالمية اسمًا فريدًا لك عالميًا\nوتـسـمـح لـك بإضــافــة شـارة أعــلـى اسـمـك.", + "globalProfileText": "(مُعرّف عالمي)", + "highlightText": "اللون الفرعي", + "iconText": "الشارة", + "localProfileInfoText": "المعرف المحلي هو معرف خاص على جهازك، ولا يخزن في الخوادم،\nحتى أن اسمه لا يكون فريدًا ومحجوزًا. ولا يمكنك إضافة شارات.\nفإن كنت تريد تلك الميزات فاجعل مُعرّفك عالميًا لتحجز اسمًا وتضيف شارة.", + "localProfileText": "(مُعَرِّف محلي)", "nameDescriptionText": "اسم اللاعب", "nameText": "الاسم", + "profileAlreadyExistsText": ".يوجد ملف شخصي بهذا الإسم بالفِعل", "randomText": "عشوائي", - "titleEditText": "تعديل الملف الشخصي", - "titleNewText": "ملف شخصي جديد", - "unavailableText": "\"${NAME}\" غير متوفر؛ حاول اسم آخر.", - "upgradeProfileInfoText": "هذا سيحفظ اسم لاعب في جميع أنحاء العالم\nوتسمح لك بتعيين رمز مخصص لها.", - "upgradeToGlobalProfileText": "الترقية إلى الملف الشخصي العالمي" + "titleEditText": "عدل المُعرِّف", + "titleNewText": "أنشئ مُعرفًا", + "unavailableText": "\"${NAME}\" معرف محجوز، جرب اسمًا آخر.", + "upgradeProfileInfoText": "هذا سيحجز اسم المعرف عالميًا\nوسيسمح لك بوضع شارة على المعرف.", + "upgradeToGlobalProfileText": "جعل الملف عالميًا" }, "editSoundtrackWindow": { "cantDeleteDefaultText": "لا يمكنك حذف الصوت الافتراضي.", "cantEditDefaultText": "لا يمكن التعديل على تسجيل الصوت الاساسي. قم بنسخه او أنشئ واحدا جديدا", "cantOverwriteDefaultText": "لا يمكن الكتابة فوق الصوت الافتراضي", - "cantSaveAlreadyExistsText": "يوجد مقطع صوتي بهذا الاسم من قبل.", + "cantSaveAlreadyExistsText": "يوجد مقطع صوتي بهذا الاسم.", "defaultGameMusicText": "<موسيقى اللعبة الافتراضية>", "defaultSoundtrackNameText": "الصوت الافتراضي", - "deleteConfirmText": "حذف الموسيقى التصويرية:\n\n'${NAME}'؟", - "deleteText": "حذف\nتسجيل صوتي", - "duplicateText": "مكرر\nتسجيل صوتي", - "editSoundtrackText": "محرر الموسيقى التصويرية", - "editText": "تصحيح\nتسجيل صوتي", + "deleteConfirmText": "حذف مسار الصوت:\n\n'${NAME}'؟", + "deleteText": "احذف\nالمقطع", + "duplicateText": "كرر\nالمقطع", + "editSoundtrackText": "محرر مسار الصوت", + "editText": "غير\nالمقطع", "fetchingITunesText": "جارٍ جلب قوائم تشغيل تطبيق الموسيقى ...", "musicVolumeZeroWarning": "تحذير: يتم ضبط مستوى صوت الموسيقى على 0", "nameText": "اسم", - "newSoundtrackNameText": "الموسيقى التصويرية ${COUNT}", + "newSoundtrackNameText": "${COUNT} مقطعي رقم", "newSoundtrackText": "موسيقى تصويرية جديدة:", - "newText": "الجديد\nتسجيل صوتي", + "newText": "اضف\nمقطعًا", "selectAPlaylistText": "حدد قائمة تشغيل", "selectASourceText": "مصدر الموسيقى", "testText": "اختبار", - "titleText": "الموسيقى التصويرية", + "titleText": "مسار الصوت", "useDefaultGameMusicText": "الافتراضي لعبة الموسيقى", "useITunesPlaylistText": "قائمة تشغيل تطبيق الموسيقى", "useMusicFileText": "ملف الموسيقى (mp3، الخ)", "useMusicFolderText": "مجلد ملفات الموسيقى" }, "editText": "تعديل", + "enabledText": "مُفعّل", "endText": "إنهاء", "enjoyText": "استمتع", "epicDescriptionFilterText": "${DESCRIPTION} بحركة ملحمية بطيئة", @@ -638,6 +665,8 @@ "errorText": "خطا", "errorUnknownText": "خطا غير معروف", "exitGameText": "هل تريد الخروج من ${APP_NAME}؟", + "expiredAgoText": "تم انتهاء صلاحية ${T} منذ", + "expiresInText": "تنتهي صلاحيته في ${T}", "exportSuccessText": "تم تصدير ${NAME} '.", "externalStorageText": "تخزين خارجي", "failText": "فشل", @@ -648,7 +677,7 @@ "titleFolderText": "اختر مجلد", "useThisFolderButtonText": "استخدم هاذا المجلد" }, - "filterText": "مصفاة", + "filterText": "البحث", "finalScoreText": "النتيجة النهائية", "finalScoresText": "النتيجة النهائية", "finalTimeText": "الوقت النهائي", @@ -672,6 +701,8 @@ "duplicateText": "مكرر\nقائمة التشغيل", "editText": "تصحيح\nقائمة التشغيل", "newText": "الجديد\nقائمة التشغيل", + "pointsToWinText": "نقاط للفوز", + "seriesLengthText": "طول السلسلة", "showTutorialText": "عرض البرنامج التعليمي", "shuffleGameOrderText": "ترتيب لعبة المراوغة", "titleText": "تخصيص ${TYPE} قوائم تشغيل" @@ -682,8 +713,8 @@ "gamesToText": "${WINCOUNT} من الألعاب إلى ${LOSECOUNT}", "gatherWindow": { "aboutDescriptionLocalMultiplayerExtraText": "تذكر: يمكن لأي جهاز في الحفلة الحصول علي\nاكثر من لاعب واحد إذا كان لديك ما يكفي من وحدات التحكم.", - "aboutDescriptionText": "استخدم علامات التبويب هذه لتجميع أحد الحفلات.\n\nتتيح لك الأطراف لعب الألعاب والبطولات\nمع أصدقائك عبر الأجهزة المختلفة.\n\nاستخدم الزر ${PARTY} في أعلى اليسار\nدردشة والتفاعل مع حزبكم.\n(على وحدة تحكم، اضغط ${BUTTON} بينما في القائمة)", - "aboutText": "حول", + "aboutDescriptionText": "استخدم علامات التبويب هذه لتجميع أحد الحفلات.\n\nتتيح لك الأطراف لعب الألعاب والبطولات\nمع أصدقائك عبر الأجهزة المختلفة.\n\nاستخدم الزر ${PARTY} في أعلى اليمين\nدردشة والتفاعل مع حزبكم.\n(على وحدة تحكم، اضغط ${BUTTON} بينما في القائمة)", + "aboutText": "الشرح", "addressFetchErrorText": "<خطأ في جلب العناوين>", "appInviteMessageText": "أرسل ${NAME} تذاكر ${COUNT} في ${APP_NAME}", "appInviteSendACodeText": "إرسال لهم رمز", @@ -696,10 +727,11 @@ "checkingText": "تدقيق...", "copyCodeConfirmText": "تم نسخ الرمز الى الحافظة", "copyCodeText": "نسخ الرمز", - "dedicatedServerInfoText": "للحصول على أفضل النتائج، قم بإعداد خادم مخصص. اطلع على bombsquadgame.com/server لمعرفة كيفية إجراء ذلك.", + "dedicatedServerInfoText": ".لتعرف كيف bombsquadgame.com/server لأداء أفضل، استضف المُلَاعَبة بخادم مخصص لذلك. راجع", + "descriptionShortText": "استخدم نافذة التجمع لكي تصنع حفلة", "disconnectClientsText": "سيؤدي هذا إلى فصل المشغل ${COUNT}\nفي حزبكم. هل أنت واثق؟", "earnTicketsForRecommendingAmountText": "سيتلقى الأصدقاء تذاكر بقيمة ${COUNT} إذا جربو اللعبة\n(وستتلقى ${YOU_COUNT} لكل من يفعل)", - "earnTicketsForRecommendingText": "مشاركة اللعبة\nلتذاكر مجانية ...", + "earnTicketsForRecommendingText": "شارك اللعبة\nمقابل الروانق...", "emailItText": "البريد الإلكتروني", "favoritesSaveText": "حفظ كمفضلة", "favoritesText": "المفضلة", @@ -709,10 +741,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} تذاكر من ${NAME}", "friendPromoCodeAwardText": "سوف تتلقى تذاكر ${COUNT} في كل مرة يتم استخدامها.", "friendPromoCodeExpireText": "ستنتهي صلاحية الشفرة خلال ${EXPIRE_HOURS} ساعة وتعمل فقط للاعبين الجدد.", - "friendPromoCodeInstructionsText": "لاستخدامها ، افتح ${APP_NAME} وانتقل إلى \"الإعدادات-> متقدم-> إدخال الرمز\".\nانظر bombsquadgame.com للحصول على روابط التحميل لجميع المنصات المدعومة.", - "friendPromoCodeRedeemLongText": "ويمكن استرداد قيمتها بمبلغ ${MAX_USES} من التذاكر المجانية بقيمة ${COUNT}.", + "friendPromoCodeInstructionsText": "لاستخدامها ، افتح ${APP_NAME} وانتقل إلى \"الإعدادات-> متقدم->إرسال المعلومات\".\nانظر bombsquadgame.com للحصول على روابط التحميل لجميع المنصات المدعومة.", + "friendPromoCodeRedeemLongText": "شخص كحد أقصى ${MAX_USES} رونقة ويمكن أن إرساله لـ ${COUNT} فهذا الرمز يعطيهم", "friendPromoCodeRedeemShortText": "ويمكن استبدالها ل ${COUNT} تذاكر في اللعبة.", - "friendPromoCodeWhereToEnterText": "(في \"الإعدادات -> متقدم -> أدخل الرمز\")", + "friendPromoCodeWhereToEnterText": "(في \"الإعدادات -> متقدم -> أرسل المعلومات\")", "getFriendInviteCodeText": "احصل على كود دعوة من صديق", "googlePlayDescriptionText": "دعوة لاعبين غوغل بلاي لحزبكم:", "googlePlayInviteText": "دعوة", @@ -720,17 +752,17 @@ "googlePlaySeeInvitesText": "راجع الدعوات", "googlePlayText": "غوغل بلاي", "googlePlayVersionOnlyText": "(الروبوت / جوجل اللعب الإصدار)", - "hostPublicPartyDescriptionText": "صنع حفلة عامة", + "hostPublicPartyDescriptionText": "استضافة مُلَاعَبَة عامة", "hostingUnavailableText": "صنع السيرفر غير متوفر", "inDevelopmentWarningText": "ملحوظة:\n\nاللعب عبر الإنترنت هي ميزة لا تزال تحت التطوير.\nحاليًا، يفضل أن يكون جميع اللاعبين\nمتصلين على نفس شبكة WI-FI.", "internetText": "انترنت", - "inviteAFriendText": "الأصدقاء ليس لديهم اللعبة؟ يمكنك دعوتهم إلى\nجربها وسيحصلون على ${COUNT} من التذاكر المجانية.", - "inviteFriendsText": "دعوة الاصدقاء", - "joinPublicPartyDescriptionText": "الإنضمام الى سيرفر عام", + "inviteAFriendText": "إن كان أصدقاؤك ليست لديهم اللعبة، فادعهم لتجربتها\nرونقة مجانية ${COUNT} وسيحصلون على", + "inviteFriendsText": "ادع أصدقائك", + "joinPublicPartyDescriptionText": "الانضمام لمُلَاعَبَة عامة", "localNetworkDescriptionText": "(الإنضمام الى سيرفر بالقرب منك (وايفاي,بلوتوث,الخ", "localNetworkText": "شبكة محليه", - "makePartyPrivateText": "اصنع حفلة خاصة", - "makePartyPublicText": "اصنع حزب بلدي العامة", + "makePartyPrivateText": "اجعل المُلَاعَبَة سريّة", + "makePartyPublicText": "اجعل المُلَاعَبَة عامة", "manualAddressText": "العنوان", "manualConnectText": "الاتصال", "manualDescriptionText": "الانضمام إلى الحزب عن طريق العنوان:", @@ -738,12 +770,13 @@ "manualJoinableFromInternetText": "هل أنت مشترك من الإنترنت ؟:", "manualJoinableNoWithAsteriskText": "لا*", "manualJoinableYesText": "نعم", - "manualRouterForwardingText": "* لإصلاح ذلك، حاول تهيئة الموجه لإعادة توجيه منفذ أودب ${PORT} إلى عنوانك المحلي", + "manualRouterForwardingText": "لعنوان جهازك UDP من نوع ${PORT} لإصلاح هذه المشكلة وجه المنفذ *", "manualText": "يدوي", "manualYourAddressFromInternetText": "عنوانك من الإنترنت:", "manualYourLocalAddressText": "عنوانك المباشر", "nearbyText": "الأقرب", "noConnectionText": "<لا يوجد اتصال>", + "noPartiesAddedText": "لا مجموعات مضافة", "otherVersionsText": "(اصدارات اخرى)", "partyCodeText": "رمز السيرفر", "partyInviteAcceptText": "قبول", @@ -751,34 +784,34 @@ "partyInviteGooglePlayExtraText": "(see the 'Google Play' tab in the 'Gather' window)", "partyInviteIgnoreText": "موافق", "partyInviteText": "تمت دعوة ${NAME}\nلك للانضمام إلى حزبهم!", - "partyNameText": "اسم المجموعة", + "partyNameText": "اسم المُلَاعَبَة", "partyServerRunningText": "سيرفرك يعمل", - "partySizeText": "حجم المجموعه", - "partyStatusCheckingText": "جار التحقق من الحالة ...", - "partyStatusJoinableText": "حزبك الآن غير قابل للانضمام من الإنترنت", + "partySizeText": "عدد الأشخاص", + "partyStatusCheckingText": "يُتحقق من الفعالية...", + "partyStatusJoinableText": "مُلَاعَبَتك ليست عامة ولا يمكن الانضمام لها", "partyStatusNoConnectionText": "غير قادر على الإتصال بالسيرفر", - "partyStatusNotJoinableText": "حزبكم ليست قابلة للانضمام من الإنترنت", - "partyStatusNotPublicText": "حزبكم ليس عام", - "pingText": "Ping", + "partyStatusNotJoinableText": "مُلَاعَبَتك ليست عامة ولا يمكن الانضمام لها", + "partyStatusNotPublicText": "مُلَاعَبَتك ليست عامة بعد", + "pingText": "الاستجابة", "portText": "البوابة", "privatePartyCloudDescriptionText": "السيرفرات الخاصة تعمل على خادم في الهواء؛ لا تحتاج تجهيز الراوتر اودي بي", "privatePartyHostText": "صنع حفلة خاصة", "privatePartyJoinText": "دخول حفلة خاصة", "privateText": "الخاص", - "publicHostRouterConfigText": "هذا قد يحتاج تجهيز منفذ اودي پي في الراوتر. لعمل اسهل، يمكنك صنع حفلة خاصة", + "publicHostRouterConfigText": "انشاء مُلَاعَبَة عامة يتطلب فتح بعض المنافذ في موجِهك(الراوتر). لتسهيل الأمر يمكنك استضافة مُلَاعَبَة سرية دون هذا التعقيد.", "publicText": "عام", "requestingAPromoCodeText": "جار طلب رمز ...", "sendDirectInvitesText": "إرسال دعوات مباشرة", - "shareThisCodeWithFriendsText": "شارك هذا الرمز مع الأصدقاء:", + "shareThisCodeWithFriendsText": "أرسل هذا الرمز لصديقك:", "showMyAddressText": "عرض عنواني", "startHostingPaidText": "صنع الحفلة الأن ب ${COST}", "startHostingText": "صنع الحفل", "startStopHostingMinutesText": "يمكنك بدأ وايقاف الحفلة مجانا خلال ${MINUTES} من الدقائق", "stopHostingText": "ايقاف التشغيل", - "titleText": "متعدد الاعبين", + "titleText": "الخوادم", "wifiDirectDescriptionBottomText": "إذا كانت جميع الأجهزة تحتوي على لوحة \"واي-في مباشر\"، فيجب أن تكون قادرة على استخدامها للعثور عليها\nوالتواصل مع بعضها البعض. مرة واحدة يتم توصيل جميع الأجهزة، يمكنك تشكيل الأطراف\nهنا باستخدام علامة التبويب \"الشبكة المحلية\"، تماما كما هو الحال مع شبكة واي فاي العادية.\n\nللحصول على أفضل النتائج، يجب أن يكون مضيف واي-في ديريكت أيضا مضيف الطرف ${APP_NAME}.", "wifiDirectDescriptionTopText": "واي فاي المباشر يمكن استخدامها لتوصيل أجهزة الروبوت مباشرة دون\nوالتي تحتاج إلى شبكة واي فاي. هذا يعمل بشكل أفضل على الروبوت 4.2 أو أحدث.\n\nلاستخدامه، افتح إعدادات واي-في وابحث عن \"واي-في ديريكت\" في القائمة.", - "wifiDirectOpenWiFiSettingsText": "افتح إعدادات واي-في", + "wifiDirectOpenWiFiSettingsText": "افتح إعدادات واي-فاي", "wifiDirectText": "واي فاي مباشر", "worksBetweenAllPlatformsText": "(يعمل بين جميع المنصات)", "worksWithGooglePlayDevicesText": "(يعمل مع الأجهزة التي تعمل على جوجل بلاي (أندرويد) نسخة من اللعبة)", @@ -797,17 +830,23 @@ "ticketPack4Text": "جمبو تذكرة حزمة", "ticketPack5Text": "ماموث تذكرة حزمة", "ticketPack6Text": "تذكرة حزمة هائلة", - "ticketsFromASponsorText": "شاهد اعلانا\nمن التذاكر ${COUNT} للحصول على", - "ticketsText": "${COUNT} بطاقات", - "titleText": "أحصل على تذاكر", + "ticketsFromASponsorText": "شاهد إعلانًا\nرونقة ${COUNT} لتحصيل", + "ticketsText": "رونقة ${COUNT}", + "titleText": "احصل على الروانق", "unavailableLinkAccountText": "عذرا، لا تتوفر عمليات الشراء على هذا النظام الأساسي.\nوكحل بديل، يمكنك ربط هذا الحساب بحساب في\nمنصة أخرى وجعل عمليات الشراء هناك.", "unavailableTemporarilyText": "هذا غير متوفر حاليا؛ الرجاء معاودة المحاولة في وقت لاحق.", "unavailableText": "عذرا، هذا غير متوفر.", "versionTooOldText": "عذرا، هذا الإصدار من اللعبة قديم جدا؛ يرجى تحديث إلى أحدث واحد.", - "youHaveShortText": "لديك ${COUNT}", - "youHaveText": "لديك ${COUNT} تذاكر" + "youHaveShortText": "${COUNT} تملك", + "youHaveText": "عندك ما عدده ${COUNT} رونقة" + }, + "goldPass": { + "desc1InfTokensText": "عملة رمزية لا نهائية", + "desc2NoAdsText": "لا إعلانات", + "desc3ForeverText": "إلى الأبد", + "goldPassText": "بطاقة المرور الذهبية" }, - "googleMultiplayerDiscontinuedText": "عذرًا ، خدمة جوجل متعددة اللاعبين لم تعد متاحة.\n أنا أعمل على بديل بأسرع وقت ممكن.\n حتى ذلك الحين ، يرجى تجربة طريقة اتصال أخرى.\n -إريك", + "googleMultiplayerDiscontinuedText": "\nعذرًا ، خدمة جوجل متعددة اللاعبين لم تعد متاحة.\n أنا أعمل على بديل بأسرع وقت ممكن.\n حتى ذلك الحين ، يرجى تجربة طريقة اتصال أخرى.\n -إريك", "googlePlayPurchasesNotAvailableText": "عمليات شراء جوجل بلاي غير متوفرة.\nقد تحتاج لتحديث تطبيق المتجر.", "googlePlayServicesNotAvailableText": "غوغل بلاي العاب غير متوفر.\nبعض المزايا لن تكون متوفرة.", "googlePlayText": "جوجل بلاي", @@ -815,35 +854,37 @@ "alwaysText": "دائما", "fullScreenCmdText": "ملء الشاشة (Cmd-F)", "fullScreenCtrlText": "الشاشه كامله (Ctrl-F)", + "fullScreenText": "تكبير الشاشة", "gammaText": "غاما", - "highText": "متوسط", - "higherText": "العالي", - "lowText": "منخفض", - "mediumText": "متوسط", + "highText": "عالية", + "higherText": "أقصى جودة", + "lowText": "منخفضة", + "maxFPSText": "أعلى معدل إطارات", + "mediumText": "متوسطة", "neverText": "أبدا", - "resolutionText": "القرار", - "showFPSText": "اظهار عدد الكدرات في الثانية", - "texturesText": "القوام", - "titleText": "الرسومات", - "tvBorderText": "TV الحدود", + "resolutionText": "أبعاد الشاشة", + "showFPSText": "أظهر معدل الإطارات", + "texturesText": "الأسطح والمواد", + "titleText": "جودة المرئيات", + "tvBorderText": "تكبير الحواف", "verticalSyncText": "تزامن عمودي", - "visualsText": "صور" + "visualsText": "التأثيرات والمرئيات" }, "helpWindow": { - "bombInfoText": "القنبلة\nأقوى من اللكمات، لكن من\nالممكن أن تؤدي لإيذاء النفس\nلأفضل النتائج، ارمها\nنحو العدو قبل أن ينفذ الفتيل.", - "canHelpText": "تستطيع مساعدتك ${APP_NAME}.", - "controllersInfoText": "يمكنك لعب ${APP_NAME} مع أصدقائك عبر الشبكة، أو يمكنكم\nجميعًا اللعب على نفس الجهاز إذا كنت تمتلك أذرع تحكم كافية.\n${APP_NAME} تدعم أنواع متعددة من أذرع التحكم؛ حتى الهواتف يمكن استعمالها\nكذراع تحكم من خلال تطبيق ${REMOTE_APP_NAME}.\nلمزيد من المعلومات اذهب للإعدادات>التحكم.", - "controllersInfoTextRemoteOnly": "You can play ${APP_NAME} with friends over a network, or you\n can all play on the same device by using phones as\n controllers via the free '${REMOTE_APP_NAME}' app.", - "controllersText": "التحكم", - "controlsSubtitleText": "شخصية ${APP_NAME} الخاصة بك تحتوي على العديد من الخصائص أهمها:", - "controlsText": "وحدات التحكم", + "bombInfoText": "[القنبلة]\nيشـعل فتيل القنبلة فـي مخبأتك ويرمـي بأسـك.\nإلا أنـه قد يـقـتلـك أو يـجـرحـك، ولا يرضيك.\nفارم القنبلة قبل الفتيل، تنجو وتقتل من يرديك.\nإذا كنت يا قُنبل مستعدًا، فأهلك أعدائك مستبدًا.", + "canHelpText": "ولهذا وُجِدَت ${APP_NAME} لتساعدك.", + "controllersInfoText": "العب ${APP_NAME} عبر الشبكة مع أصدقائك، وإلا فيمكنك لعبها محليًا\nبنفس الجهاز مع أصدقائك إذا كان لديك وحدات تحكم كافية(أذرع البلايستيشن مثلًا)\n${APP_NAME} تدعم أغلبهم. بل حتى يمكنك استعمال جهازك الآخر كذراع تحكم\nعبر تحميل تطبيق \"${REMOTE_APP_NAME}\" الموجود في المتجر عليه.\nاطلع على الإعدادات -> المتحكمات للاستزادة.", + "controllersInfoTextRemoteOnly": "بالإمكان لعب ${APP_NAME} عبر الشبكة\nأو يمكنكم جميعًا اللعب بنفس الجهاز\nباستعمال تطبيق \"${REMOTE_APP_NAME}\" في المتجر.", + "controllersText": "أذرع اللعب", + "controlsSubtitleText": "في ${APP_NAME} لا تحتاج المشي على أربع لتفوز، هناك أربع أزرار تغنيك عن هذا وهي:", + "controlsText": "المُفعِّلات", "devicesInfoText": "يمكن تشغيل إصدار فر الذي يبلغ ${APP_NAME} عبر الشبكة\nالنسخة العادية، حتى سوط خارج الهواتف الإضافية، وأقراص،\nوأجهزة الكمبيوتر والحصول على اللعبة الخاصة بك على. بل يمكن أن يكون مفيدا ل\nربط نسخة منتظمة من اللعبة إلى الإصدار فر فقط ل\nالسماح للناس خارج لمشاهدة العمل.", "devicesText": "الأجهزة", - "friendsGoodText": "من الرائع أن تحظى بهم. ${APP_NAME} أكثر متعة عندما تلعب مع عدة لاعبين\nواللعبة تدعم اللعب مع 8 لاعبين في وقت واحد، مما يقودنا إلى:", - "friendsText": "الاصدقاء", - "jumpInfoText": "القفز\nقم بالقفز لعبور الحفر الصغيرة،\nولرمي الأشياء أبعد،\nوللتعبير عن مشاعر الفرح.", - "orPunchingSomethingText": ".أو ضرب شيء، ورميه من على الجرف، وتفجيره بالمرة بقنبلة لزجة", - "pickUpInfoText": "- امسك -\nالاستيلاء على الأعلام، والأعداء، أو أي شيء\nوإلا لا انسحب على الأرض.\nاضغط مرة أخرى لرمي.", + "friendsGoodText": "وما أحسن رفقتهم. فإنما تكمن متعة عالم ${APP_NAME} في\nأن تلعب مع صديق، وليس واحد، بل 8، فهم خير عون في قُنبلاء", + "friendsText": "أصدقائك", + "jumpInfoText": "[الوثبة]\nيستعمل للقفز وتخطي الصعاب.\nولرمي الأشياء لأعلى والمرور.\nوللتـعبير عن الفرحة والسـرور.", + "orPunchingSomethingText": "أو لكم شيء، وجعله يهوي من مكانِ سحيق، وألا تخطئه قنابلك بأن تلصق به هذه القنابل وتلاحقه بلا مهرب.", + "pickUpInfoText": "[المسكة]\nيمكنك إمساك الأعلام، أو أعاديك، أو\nأي شيء غير ثابت أو مثبت بالأرض\nاضغط الزر مجددًا لإفلات الشيء.", "powerupBombDescriptionText": "يتيح لك سوط من ثلاث قنابل\nفي صف واحد بدلا من واحد فقط.", "powerupBombNameText": "قنابل ثلاثية", "powerupCurseDescriptionText": "أعتقد من الجيد الإبتعاد عن هذا.\nإلا إذا كنت ستقوم بـ..؟", @@ -864,12 +905,12 @@ "powerupStickyBombsNameText": "قنابل لاصقة", "powerupsSubtitleText": "وبلا شك، لا توجد لعبة تكتمل بلا قدرات تعزيزية إضافية:", "powerupsText": "حزم تعزيزية", - "punchInfoText": "اللكم\nعندما تجري بسرعة\nتعطي اللكمات ضرر أكبر،\nلذا اركض وقم بالدوران كالرجل المجنون.", - "runInfoText": "الركض\nاضغط مطولًا على أي زر أعلاه لتشغيله، أيضًا بإمكانك استعمال الزر الخلفي لذراع التحكم للركض.\nيُمكنك الركض من الوصول للأماكن بشكل أسرع لكنه يصعب الإستدارة، لذا انتبه من المنحدرات.", - "someDaysText": "في بعض الأحيان تشعر وكأنك تريد ضرب شيء ما. تفجير شيء ما.", + "punchInfoText": "[القبضة]\nبقبضتك يمكنك ضرب ما تشاء، وكلما زاد\nزخم حركتك(بزيادة سرعتك مثلًا) زادت قوتها\nلذا دُر حول نفسك ثم اضرب بيد من حديد.", + "runInfoText": "[الركض]\nعلق يدك على أحد الأزرار الأربعة للركض بسرعة. ويمكنك الضغط على أزرار الكتف في أذرع الألعـاب للركض.\nيسرع الركض هروبك من مخاوفك، ووصولك لأرض أحلامك، لكن يصعب توجهك يمنة ويسرة لذا احذر المنحدرات.", + "someDaysText": "أحيانًا تشعر برغبة في تفريغ غضبك، أحزانك، والتخلص من مآسيك وهمومك. وتريد تفجير شيء ما.", "titleText": "${APP_NAME} كيفية لعب", - "toGetTheMostText": "للحصول على أقصى استفادة من هذه اللعبة، ستحتاج إلى:", - "welcomeText": "مرحبا بك في ${APP_NAME}!" + "toGetTheMostText": "ولتفعل ذلك، ولا تخطئ هدفك، فإنك ستحتاج لما يلي:", + "welcomeText": "حللت أهلًا وسهلًا في ${APP_NAME}!" }, "holdAnyButtonText": "<اضغط على أي زر>", "holdAnyKeyText": "<اضغط على أي مفتاح>", @@ -878,14 +919,15 @@ "importPlaylistSuccessText": "تم استيراد ${TYPE} قائمة تشغيل \"${NAME}\"", "importText": "استيراد", "importingText": "استيراد ...", - "inGameClippedNameText": "في اللعبة سوف يكون\n\"${NAME}\"", + "inGameClippedNameText": "هذا اسمك في اللعبة\n\"${NAME}\"", + "inboxText": "صندوق الوارد", "installDiskSpaceErrorText": "خطأ: تعذر إكمال التثبيت.\nقد تكون نفذت مساحه التخزين على جهازك.\nامسح بعض المساحة وحاول مرة أخرى.", "internal": { "arrowsToExitListText": "اضغط ${LEFT} أو ${RIGHT} للخروج من القائمة", "buttonText": "زر", "cantKickHostError": "لا يمكنك طرد المضيف.", "chatBlockedText": "${NAME} تم حظر الدردشة لمدة ${TIME} ثانية.", - "connectedToGameText": "انضم '${NAME}'", + "connectedToGameText": "\"${NAME}\"انضممت لـ", "connectedToPartyText": "انضم إلى حفلة ${NAME}!", "connectingToPartyText": "توصيل...", "connectionFailedHostAlreadyInPartyText": "فشل الاتصال؛ المضيف في حفله اخرى.", @@ -919,10 +961,10 @@ "kickIdlePlayersKickedText": "الركل ${NAME} لكونه خاملا.", "kickIdlePlayersWarning1Text": "سيتم ركل ${NAME} بمبلغ ${COUNT} ثانية إذا ظلت خاملة.", "kickIdlePlayersWarning2Text": "(يمكنك إيقاف هذا في إعدادات -> متقدم)", - "leftGameText": "يسار '${NAME}'.", + "leftGameText": "غادر '${NAME}'.", "leftPartyText": "غادر ${NAME} من الحفله.", "noMusicFilesInFolderText": "المجلد لا يحتوي على ملفات الموسيقى.", - "playerJoinedPartyText": "انضم ${NAME} إلى الحفله!", + "playerJoinedPartyText": "!لمُلَاعَبَتِك ${NAME} دخل", "playerLeftPartyText": "غادر ${NAME} الحفله.", "rejectingInviteAlreadyInPartyText": "رفض الدعوة (موجود بالفعل في أحد الحفلات).", "serverRestartingText": "السيرفر يعاد تشغيله . يرجى إعادة الدخول بعد لحظة ...", @@ -933,12 +975,14 @@ "timeOutText": "(من المرات في ${TIME} ثانية)", "touchScreenJoinWarningText": "لقد انضممت مع شاشة اللمس.\nإذا كان هذا خطأ، اضغط 'القائمة-> ترك لعبة' معها.", "touchScreenText": "شاشة اللمس", + "unableToCompleteTryAgainText": "عدم القدرة على إكمال هذا الآن.\nحاول لاحقاً.", "unableToResolveHostText": "خطأ: غير قادر على حل المضيف.", "unavailableNoConnectionText": "هذا غير متاح حاليا (لا يوجد اتصال بالإنترنت؟)", "vrOrientationResetCardboardText": "استخدام هذا لإعادة توجيه فر.\nللعب اللعبة سوف تحتاج إلى وحدة تحكم خارجية.", "vrOrientationResetText": "فر توجيه إعادة تعيين.", "willTimeOutText": "(سوف تنقضي المهلة إذا توقفت عن الحركة)" }, + "inventoryText": "المخزون", "jumpBoldText": "اقفز", "jumpText": "قفز", "keepText": "احتفظ", @@ -968,7 +1012,7 @@ "singlePlayerExamplesText": "لاعب واحد / التعاونية أمثلة", "versusExamplesText": "مقابل أمثلة" }, - "languageSetText": "اللغة الآن \"${LANGUAGE}\".", + "languageSetText": ".لغة للعبة \"${LANGUAGE}\" أصبحت", "lapNumberText": "جوله ${CURRENT}/${TOTAL}", "lastGamesText": "(آخر ${COUNT} مباراة)", "leaderboardsText": "المتصدرين", @@ -985,8 +1029,11 @@ "seasonEndsMinutesText": "ينتهي الموسم بعد ${NUMBER} من الدقائق.", "seasonText": "الموسم ${NUMBER}", "tournamentLeagueText": "يجب أن تصل إلى الدوري ${NAME} للدخول في هذه البطولة.", - "trophyCountsResetText": "سيتم إعادة تعيين عدد الكوؤس في الموسم المقبل." + "trophyCountsResetText": "سيتم إعادة تعيين عدد الكوؤس في الموسم المقبل.", + "upToDateBonusDescriptionText": "اللاعبون الذين يستخدمون النسخة الحديثة من اللعبة سوف يحصلون على مكافأة بنسبة تقدر ${PERCENT}% هنا. سمينميني", + "upToDateBonusText": "مكافأة محدثة" }, + "learnMoreText": "معلومات أكثر", "levelBestScoresText": "أفضل النقاط على ${LEVEL}", "levelBestTimesText": "أفضل الأوقات على ${LEVEL}", "levelIsLockedText": "تم قفل ${LEVEL}.", @@ -1003,7 +1050,7 @@ "macControllerSubsystemMFiText": "المصممة خصيصا اي او اس / ماك", "macControllerSubsystemTitleText": "دعم جهاز التحكم", "mainMenu": { - "creditsText": "معلومات", + "creditsText": "عن قنبلاء", "demoMenuText": "عرض القائمة", "endGameText": "نهاية لعبة", "endTestText": "الاختبار النهائي", @@ -1024,12 +1071,14 @@ "mapSelectTitleText": "${GAME} خرائط", "mapText": "خرائط", "maxConnectionsText": "اتصالات مكتمل", - "maxPartySizeText": "أقصى حجم للحفلة", + "maxPartySizeText": "أقصى عدد للاعبين", "maxPlayersText": "عدد لاعبين مكتمل", "merchText": "ميرش!", "modeArcadeText": "وضع اللهو", "modeClassicText": "الوضع التقليدي", "modeDemoText": "الوضع التجريبي", + "moreSoonText": "سيأتي أكثر قريباً...", + "mostDestroyedPlayerText": "اللاعب الأكثر تضرراً", "mostValuablePlayerText": "أفضل لاعب", "mostViolatedPlayerText": "اللاعب الأكثر انتهاكاً", "mostViolentPlayerText": "أعنف اللاعبين", @@ -1045,7 +1094,8 @@ "nameSuicideKidFriendlyText": "${NAME} توفي عن طريق الخطأ.", "nameSuicideText": "${NAME} انتحر.", "nameText": "اسم", - "nativeText": "محلي", + "nativeText": "الدقة الأساسية", + "newExclaimText": "!جديد", "newPersonalBestText": "أفضل شخصية جديدة!", "newTestBuildAvailableText": "يتوفر اختبار اختبار أحدث! (${VERSION} بناء ${BUILD}).\nاحصل على ${ADDRESS}", "newText": "الجديد", @@ -1056,24 +1106,31 @@ "noContinuesText": "(لا يستمر)", "noExternalStorageErrorText": "لم يتم العثور على وحدة تخزين خارجية على هذا الجهاز", "noGameCircleText": "خطأ: لم يتم تسجيل الدخول الئ gamecircle", + "noMessagesText": "لا رسائل", + "noPluginsInstalledText": "لا إضافات مثبتة", "noScoresYetText": "لا نقاط حتى الآن.", + "noServersFoundText": "لا توجد اي سيرفرات.", "noThanksText": "لا شكرا", "noTournamentsInTestBuildText": "تحذير: سيتم تجاهل نقاط البطولات في النسخة التجريبية", "noValidMapsErrorText": "لا خرائط صالحة وجدت لهذا النوع اللعبة.", "notEnoughPlayersRemainingText": "لا يكفي اللاعبين المتبقين؛ الخروج وبدء لعبة جديدة.", "notEnoughPlayersText": "تحتاج على الأقل ${COUNT} لاعبين لبدء هذه اللعبة!", + "notEnoughTicketsText": "ليست تذاكر كافية!", "notNowText": "ليس الآن", - "notSignedInErrorText": "يجب ان تسجل الدخول لتفعل هذا", + "notSignedInErrorText": "سجّل الدخول بحساب للدخول لهذا.", "notSignedInGooglePlayErrorText": "عليك تسجيل الدخول لجوجل بلاي لتفعل هذا", - "notSignedInText": "لم تقم بتسجيل الدخول", + "notSignedInText": "أنت غير مُسجَّل", "notUsingAccountText": "ملاحظة: حساب ${SERVICE} متجاهل.\nقم بالتوجه الى 'الحساب -> تسجيل الدخول بواسطة ${SERVICE}' اذا اردت استعماله.", "nothingIsSelectedErrorText": "لا شئ تم اختياره!", "numberText": "#${NUMBER}", "offText": "إيقاف", - "okText": "حسنا", + "okText": "حسناً", "onText": "تشغيل", "oneMomentText": "لحظة واحدة...", "onslaughtRespawnText": "${PLAYER} سيخرج مجددا في الموجة ${WAVE}", + "openMeText": "افتحني!", + "openNowText": "افتح الآن", + "openText": "افتح", "orText": "${A} أو ${B}", "otherText": "آخر...", "outOfText": "(#${RANK} خرج من ${ALL})", @@ -1084,23 +1141,23 @@ "emptyText": "حفلتك فارغة", "hostText": "(مضيف)", "sendText": "إرسال", - "titleText": "الحفلة الخاصة بك" + "titleText": "مُلَاعَبَتُك" }, "pausedByHostText": "(متوقف مؤقتا من قبل المضيف )", "perfectWaveText": "المرحله المثالية", "pickUpText": "إلتقط", "playModes": { - "coopText": "اللعب التعاوني", - "freeForAllText": "الحرية-للجميع", - "multiTeamText": "فرق متعددة", - "singlePlayerCoopText": "لعب فردي / لعب تعاوني", - "teamsText": "فرق" + "coopText": "تَعاوُني", + "freeForAllText": "فَردانية جماعية", + "multiTeamText": "فِرَق", + "singlePlayerCoopText": "اللعب ضد الآلة(فرديًا أو تعاونيًا)", + "teamsText": "فريقين" }, - "playText": "لعب", + "playText": "أشكال اللعب", "playWindow": { - "oneToFourPlayersText": "1-4 لاعبين", - "titleText": "إلعب", - "twoToEightPlayersText": "2-8 لاعبين" + "oneToFourPlayersText": "١-٤ لاعبين", + "titleText": "اِلعب", + "twoToEightPlayersText": "٢-٨ لاعبين" }, "playerCountAbbreviatedText": "${COUNT}p", "playerDelayedJoinText": "${PLAYER} سيدخل ببداية الجولة القادمة", @@ -1109,28 +1166,32 @@ "playerLimitReachedText": "حد اللاعب ${COUNT} وصل", "playerProfilesWindow": { "cantDeleteAccountProfileText": "لايمكنك حذف حساب الملف الشخصي الخاص بك", - "deleteButtonText": "حذف\nالملف الشخصي", - "deleteConfirmText": "حذف '${PROFILE}'?", - "editButtonText": "تعديل\nالملف الشخصي", - "explanationText": "(اللاعب المخصص و المباراة لهذا الحساب)", - "newButtonText": "ملف شخصي\nجديد", - "titleText": "ملفات اللاعب الشخصي" + "deleteButtonText": "احذف\nالمُعرِف", + "deleteConfirmText": "؟'${PROFILE}' حذف", + "editButtonText": "عدِّل\nالمُعرِّف", + "explanationText": "(هذه هي الاسماء والمظاهر التي ستظهر بها للآخرين وتُحفَظ في حسابك)", + "newButtonText": "أنشئ\nمُعرِّفًا", + "titleText": "مُعرفات اللاعب" }, "playerText": "لاعب", "playlistNoValidGamesErrorText": "قائمة التشغيل هذه لا تحتوي على ألعاب مفتوحة صالحة", "playlistNotFoundText": "لم يتم العثور على قائمة التشغيل", "playlistText": "قائمة التشغيل", "playlistsText": "قائمة العب", - "pleaseRateText": "يرجى اتخاذ لحظة وتقييمه ${APP_NAME} اذا كنت تستمتع بلعبة\nاو كتابة مراجعة فهاذا يوفر معلومات مفيدة ويوفر التطوير\nفي المستقبل\n\n!شكرًا\nاريك—", - "pleaseWaitText": "الرجاء الانتظار . . .", + "pleaseRateText": "أهلًا!\nإن كنت مستمتعًا بلعب ${APP_NAME} فقيمها على المتجر\nفإن ذلك يحسّن اللعبة ويدعم تطويرها بانتشارها ويسعدنا سماع رأيك.\n\nوشكرًا\n-مطور اللعبة إيريك", + "pleaseWaitText": "انتظر...", "pluginClassLoadErrorText": "فشل في تشغيل الاضافة '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "خطأ في بدء الاضافة '${PLUGIN}: ${ERROR}", + "pluginSettingsText": "إعدادات الإضافات", + "pluginsAutoEnableNewText": "فعِّل الإضافات الجديدة تلقائيًا", "pluginsDetectedText": "تم العثور على اضافات جديدة. اعد التشغيل لتفعيلها، او قم بتخصيصها في الاعدادات.", + "pluginsDisableAllText": "عطِّل كل الإضافات", + "pluginsEnableAllText": "فعِّل كل الإضافات", "pluginsRemovedText": "${NUM} لم تعد الاضافة موجودة.", - "pluginsText": "اضافات", + "pluginsText": "الإضافات والتعديلات", "practiceText": "تدريب", "pressAnyButtonPlayAgainText": "اضغط اي زر للعب مجددا...", - "pressAnyButtonText": "اظغط اي زر للإستمرار...", + "pressAnyButtonText": "اضغط أي زر للاستمرار...", "pressAnyButtonToJoinText": "اضغط اي زر للإنضمام", "pressAnyKeyButtonPlayAgainText": "اضغط اي زر /اي مفتاح للعب مجددا...", "pressAnyKeyButtonText": "اضغظ اي مفتاح/زر للإستمرار", @@ -1155,10 +1216,12 @@ "punchText": "لكمة", "purchaseForText": "${PRICE} إشتري اللعبة", "purchaseGameText": "إشتري اللعبة", + "purchaseNeverAvailableText": "عذرًا، المشتريات غير متوفرة في هذا الإصدار.\n حاول تسجيل الدخول إلى حسابك على منصة أخرى وإجراء عمليات شراء من هناك.", + "purchaseNotAvailableText": "عملية الشراء غير متوفرة", "purchasingText": "شراء...", "quitGameText": "خروج ${APP_NAME}?", "quittingIn5SecondsText": "جار الإقلاع خلال 5 ثوان ...", - "randomPlayerNamesText": "الأسماء الافتراضية", + "randomPlayerNamesText": "سويلم, هوازن, عود الحشى, ليلى, ديجور الليل, سارة, ضرغام, قطر الندى, قُطُز, الحسناء, تميم, السيف المهند, تمر, لؤلؤة, امرؤ القيس, زُهير, عدنان, الأحنف, السُلَيك, عنترة, أمير الصعاليك, سيبويه, عُروة, قُمري, زرزور, قيقب, جليبيب, حنظلة العدا, سكاكر, ياسمين, ملآن, جيّان, سليم, ليان, وردة المحبين, الفاتنة, العذراء, الخنساء, صخرة الوادي, الجوزاء, قُنبُل, صخر, إكليل الجبل, تماضر, تأبط شرًّا, فتّاك, راعية الفتنة, جرير, جسّاس, جميلة بنت جميل, زهران, الطائر الصدوح, الطائر بن لا أحد, غالب, دوحة, ديمة, وردة الوادي, رونقة المحبين, سكرة المحبين, جميلة النساء, المؤنسة, المهرة, الحُلوة, صهيب, فستق, موزة, عين السيح, لؤلؤ, جوهرة, لولو, الجميلة, وردة البستان, العنقاء, الشعرى اليمانية, سنونو شاحب الزور, الكريهة, الدرة المكنونة, سمكة النهر, سمسم, روعة, الدعسوقة, خنفساء, لجين, جيدانة, كلكع بن مُلكلع, سيف الدولة, وسوسة بنت موسوس, ابنة النهر, سُكَامة, سمرقند, زُحلوقة, عبير", "randomText": "عشوائي", "rankText": "مرتبة", "ratingText": "تقييم", @@ -1178,7 +1241,7 @@ "disconnected": "قطع الاتصال من السيرفر.", "dpad_fixed": "تم الاصلاح", "dpad_floating": "يطفو على السطح", - "dpad_position": "D- الوسادة الموقف", + "dpad_position": "D-Pad Position", "dpad_size": "قياس اللوحة", "dpad_type": "D- الوسادة نوع", "enter_an_address": "أدخل عنوانا", @@ -1193,9 +1256,10 @@ "searching": "جار البحث عن ألعاب بومبسكاد ...", "searching_caption": "اضغط على اسم لعبة للانضمام إليه.\nتأكد من أنك على نفس شبكة واي فاي مثل اللعبة.", "start": "بداية", - "version_mismatch": ".الإصداران لا يتطابقان\nتأكد من أن فرقة القنبلة و فرقة القنبلة للتحكم عن بعد\n.تم تحديثهما لآخر إصدار وحاول مجددًا" + "version_mismatch": "رقمي الإصدار لا يتطابقان\nتأكد أن رقم إصدار قُنبلاء وحاكوم قنبلاء\nبنفس رقم الإصدار ثم حاول ثانية." }, - "removeInGameAdsText": "إلغاء تأمين \"${PRO}\" في المتجر لإزالة الإعلانات داخل اللعبة.", + "removeInGameAdsText": ".من المتجر \"${PRO}\"إن أردت التخلص من هذه الإعلانات المزعجة فاشترك في", + "removeInGameAdsTokenPurchaseText": "عرض محدود: ادفع اي حزمة نقود لكي تزيل الاعلانات داخل اللعبة.", "renameText": "إعادة تسمية", "replayEndText": "نهاية الإعادة", "replayNameDefaultText": "إعادة اللعبة الأخيرة", @@ -1216,7 +1280,9 @@ "revertText": "العودة", "runText": "ركض", "saveText": "حفظ", - "scanScriptsErrorText": "حدث خطأ (أخطاء) في مسح النصوص البرمجية ؛ انظر السجل للحصول على التفاصيل.", + "scanScriptsErrorText": "حدث خطأ أو أخطاء في مسح النصوص البرمجية. اظر إلى السجل لمعرفة التفاصيل.", + "scanScriptsMultipleModulesNeedUpdatesText": "${API} apiواخرى يجب تحديثها ل ${PATH} و ${NUM}", + "scanScriptsSingleModuleNeedsUpdatesText": "${API} api يجب تحديثها ل ${PATH}", "scoreChallengesText": "نقاط التحديات", "scoreListUnavailableText": ".قائمة النقاط غير متاحة", "scoreText": "نتيجة", @@ -1227,48 +1293,58 @@ }, "scoreWasText": "(كان ${COUNT})", "selectText": "اختيار", + "sendInfoDescriptionText": "ما سترسله سيرسل معه بيانات التطبيق والجهاز للمطور.\nيُرجى منك كتابة اسمك وسبب الإرسال.", "seriesWinLine1PlayerText": "الفوز", "seriesWinLine1TeamText": "الفوز", "seriesWinLine1Text": "الفوز", "seriesWinLine2Text": "سلسلة", "settingsWindow": { "accountText": "الحساب", - "advancedText": "المتقدمة", - "audioText": "صوت", - "controllersText": "التحكم", - "graphicsText": "رسوميات", + "advancedText": "الإعدادات الأخرى", + "audioText": "الأصوات", + "controllersText": "المُتَحكِمات", + "graphicsText": "المرئيات", "playerProfilesMovedText": "ملاحظة: انتقلت ملفات تعريف اللاعب إلى نافذة الحساب في القائمة الرئيسية.", - "titleText": "اعدادات" + "titleText": "الإعدادات" }, "settingsWindowAdvanced": { - "alwaysUseInternalKeyboardDescriptionText": "(بسيطة، وحدة تحكم ودية على الشاشة لوحة المفاتيح لتحرير النص)", - "alwaysUseInternalKeyboardText": "استخدم لوحة المفاتيح الداخلية دائما", - "benchmarksText": "المعايير و الإجهاد الاختبارات", - "disableCameraGyroscopeMotionText": "تعطيل الكاميرا جيروسكوب الحركة", + "alwaysUseInternalKeyboardDescriptionText": "(مُدمَجة ضمن اللعبة، جميلة، ويسهل استعمالها مع الأذرع، ولا تدعم العربية)", + "alwaysUseInternalKeyboardText": "استعمل لوحة المفاتيح المدمجة باللعبة", + "benchmarksText": "اختبارات الأداء", + "devToolsText": "أدوات المطورين", + "disableCameraGyroscopeMotionText": "تعطيل حركه الجيروسكوب للكاميرا", "disableCameraShakeText": "تعطيل اهتزاز الكاميرا", "disableThisNotice": "(يمكنك تعطيل هذا الإشعار في الإعدادات المتقدمة)", "enablePackageModsDescriptionText": "(تمكن قدرات التعديل الإضافية ولكن تعطيل شبكة اللعب)", "enablePackageModsText": "تمكين تعديل الحزمة المحلية", "enterPromoCodeText": "ادخل الرمز", - "forTestingText": "ملاحظة: هذه القيم هي فقط للاختبار وسيتم فقدانها عند خروج التطبيق.", - "helpTranslateText": "هي عبارة عن ترجمة ​${APP_NAME}الترجمات غير الإنجليزية ل\nجماعية، إذا أردت المساهمة أو تصحيح الأخطاء اللغوية والإملائية\n!قم بزيارة الرابط أدناه، وشكرًا لكم مقدمًا", - "kickIdlePlayersText": "طرد اللاعبين غير النشطين", + "forTestingText": "اعلم: أن الأرقام التي تعدلها هنا لن تحفظ، وإنما عدل هذه الأرقام لتُجرب", + "helpTranslateText": "ترجمات ${APP_NAME} اللاإنجليزية هي اجتهاد مجتمع مترجمي\nكل لغة. فإن كنت تريد المُساهمة في الترجمة وتصحيحها فانقر على\nالزر بالأسفل والذي سيوجهك لرابط الترجمان. هذا وكان سعيكم مشكورًا!", + "insecureConnectionsDescriptionText": "غير موصى به، لكن قد يسمح باللعب عبر الإنترنت\nمن البلدان أو الشبكات المقيدة", + "insecureConnectionsText": "استخدم الاتصالات غير الآمنة", + "kickIdlePlayersText": "اطرد اللاعبين الخاملين", "kidFriendlyModeText": "وضع الأطفال (يقلل العنف، إلخ)", - "languageText": "لغة", - "moddingGuideText": "دليل التعديلات البرمجية", - "mustRestartText": ".يجب أن تقوم بإعادة تشغيل اللعبة لكي يعمل هذا", - "netTestingText": "اختبار الشبكة", - "resetText": "إعادة تعيين", + "languageText": "اللغة", + "moddingGuideText": "مرشد تصميم الإضافات", + "moddingToolsText": "أدوات التعديل", + "mustRestartText": "ليعمل هذا أغلق اللعبة وافتحها ثانية.", + "netTestingText": "اختبار الشبكة/الاتصال", + "resetText": "إعادة للأصل", + "sendInfoText": "إرسال بيانات", "showBombTrajectoriesText": "عرض مسارات القنبلة", + "showDemosWhenIdleText": "شغل شروحات اللعب عندما أخمل", + "showDeprecatedLoginTypesText": "أظهر أنواع تسجيلات الدخول القديمة", + "showDevConsoleButtonText": "أظهر زر فتح طرفية الأوامر", + "showInGamePingText": "أظهر سرعة الاتصال أثناء اللعب", "showPlayerNamesText": "إظهار اسماء اللاعبين", - "showUserModsText": "عرض مجلد التعديل", - "titleText": "المتقدمة", - "translationEditorButtonText": "${APP_NAME} محرر الترجمة", + "showUserModsText": "أخبرني بمكان إضافة التعديلات", + "titleText": "المزيد", + "translationEditorButtonText": "أداة ترجمة ${APP_NAME}", "translationFetchErrorText": "حالة الترجمة غير متاحة", - "translationFetchingStatusText": "جار التحقق من حالة الترجمة ...", - "translationInformMe": "ابلغني عندما تحتاج لغتي للتحديث", - "translationNoUpdateNeededText": "!اللُّغة العربية حتى الآن محدثة، هنيئًا لك", - "translationUpdateNeededText": "** !!اللُّغة الحالية بحاجةٍ إلى تحديث **", + "translationFetchingStatusText": "يُتحقق من حال الترجمة...", + "translationInformMe": "أبلغني برسالة عندما تحتاج العربية لتحديث", + "translationNoUpdateNeededText": "العربية محدثة، مرحى يا أخا العرب !", + "translationUpdateNeededText": "** العربية بحاجةٍ إلى تحديث لتحسينها **", "vrTestingText": "تجربة الواقع الإفتراضي" }, "shareText": "شارك", @@ -1278,6 +1354,9 @@ "signInWithGameCenterText": "لاستخدام حساب مركز الألعاب،\nسجل الدخول باستخدام تطبيق مركز الألعاب.", "singleGamePlaylistNameText": "فقط ${GAME}", "singlePlayerCountText": "1 لاعب", + "sizeLargeText": "كبير", + "sizeMediumText": "وسط", + "sizeSmallText": "صغير", "soloNameFilterText": "منفردا ${NAME}", "soundtrackTypeNames": { "CharSelect": "اختر شخصية", @@ -1292,7 +1371,7 @@ "Hockey": "الهوكي", "Keep Away": "ابتعد", "Marching": "يركض حول", - "Menu": "القائمة الرئيسية", + "Menu": "قائمة اللعبة", "Onslaught": "هجوم", "Race": "سباق", "Scary": "ملك التل", @@ -1303,25 +1382,26 @@ }, "spaceKeyText": "مسافة", "statsText": "النتائج", + "stopRemindingMeText": "توقف عن تذكيري", "storagePermissionAccessText": "وهذا يتطلب الوصول إلى التخزين", "store": { "alreadyOwnText": "!${NAME}أنت بالفعل تملك", - "bombSquadProNameText": "للمحترفين ${APP_NAME}", - "bombSquadProNewDescriptionText": "يزيل الإعلانات في اللعبة والشاشات المزعجة •\nيفتح المزيد من إعدادات اللعبة •\n:يتضمن هذا العرض أيضًا •", + "bombSquadProNameText": "${APP_NAME} الذهبية", + "bombSquadProNewDescriptionText": "• تفتح الكثير من الإعدادات والأشياء\n• تزيل الإعلانات والإزعاجات\nوستأخذ مع اشتراكك:", "buyText": "شراء", "charactersText": "الشخصيات", "comingSoonText": "قريبا...", - "extrasText": "إضافات", + "extrasText": "أخرى", "freeBombSquadProText": "فرقة القنبلة الآن أصبحت مجانية، لكن بما أنك اشتريتها\nبطاقات كشكر لك ​${COUNT} ستتلقى فرقة القنبلة القنبلة للمحترفين و\n!استمتع بالميزات الجديدة، وشكرًا لدعمك\n-إيريك", "holidaySpecialText": "خاص بالعطل", - "howToSwitchCharactersText": "(توجه الى \"${SETTINGS} -> ${PLAYER_PROFILES}\" لتخصيص الشخصيات)", - "howToUseIconsText": "(إنشاء ملفات تعريف لاعب العالمية (في إطار الحساب) لاستخدام هذه)", - "howToUseMapsText": "(استخدم هذه الخرائط في فرقك الخاصة / قوائم التشغيل المجانية للجميع)", - "iconsText": "رموز", + "howToSwitchCharactersText": "(${PLAYER_PROFILES} <- ${SETTINGS}لتغيير شخصيتك وتلوينها انتقل لـ)", + "howToUseIconsText": "(انشئ مُعرِّف عالمي لإضافة هذه لمظهر مُعرِّفك في الحساب)", + "howToUseMapsText": "(يمكنك استعمال هذه الأماكن في قوائم ألعابك التي أنشئتها)", + "iconsText": "الشارات", "loadErrorText": "تعذر تحميل الصفحة.\nتحقق من اتصالك بالإنترنت.", "loadingText": "جار التحميل", - "mapsText": "خرائط", - "miniGamesText": "ألعاب مصغرة", + "mapsText": "أماكن", + "miniGamesText": "اللُعَيبات", "oneTimeOnlyText": "(مرة واحدة فقط)", "purchaseAlreadyInProgressText": "هناك شراء لهذا العنصر قيد التقدم.", "purchaseConfirmText": "هل تريد شراء ${ITEM}؟", @@ -1333,23 +1413,25 @@ "saleText": "تخفيض السعر", "searchText": "بحث", "teamsFreeForAllGamesText": "فرق / مجانا للجميع الألعاب", - "totalWorthText": "*** ${TOTAL_WORTH} قيمة! ***", - "upgradeQuestionText": "ترقية؟", - "winterSpecialText": "عرض الشتاء", + "totalWorthText": "( !${TOTAL_WORTH} ما يعادل )", + "upgradeQuestionText": "هلّا اشتركت؟", + "winterSpecialText": "معروض الشتاء", "youOwnThisText": "- انت تملك هذا -" }, "storeDescriptionText": "لعبة لأكثر من 8 لاعبين!\n\nالعب مع اصدقائك (او الحاسوب) في بطولات من الميني جيمز المتفجرة كــإمساك بالعلم، الهوكي و المعركة البطيئة!\n\nتحكم بسيط و لعب باجهزة تحكم يجعلها سهلة لأكثر من 8 لاعبين ليدخلو المعركة; تستطيع ايضا استعمال اجهزة الهاتف كاجهزة تحكم من خلال التطبيق المجاني 'BombSquad Remote' !\n\nوقت رمي القنابل!\n\nتفقد www.froemling.net/bombsquad للمزيد من المعلومات.", "storeDescriptions": { "blowUpYourFriendsText": ".فجر أصدقائك", "competeInMiniGamesText": "تنافس في الألعاب المصغرة بدءا من السباق للطيران.", - "customize2Text": "تخصيص الشخصيات، الألعاب المصغرة، وحتى الموسيقى التصويرية.", + "customize2Text": "تخصيص الشخصيات، الألعاب المصغرة، وحتى مسارات الصوت.", "customizeText": "تخصيص الشخصيات وإنشاء قوائم التشغيل الخاصة بك لعبة صغيرة.", "sportsMoreFunText": "الرياضة أكثر متعة مع المتفجرات.", "teamUpAgainstComputerText": ".قم بالتعاون كفريق ضد الحاسوب" }, - "storeText": "متجر", + "storeText": "المتجر", "submitText": "ارسال", "submittingPromoCodeText": "تقديم الكود ...", + "successText": "نجحت!", + "supportEmailText": "ايذا لديك اي مشكلة تقنية مع\nالبرنامح, يرجى استخدام البريد إلكتروني للدعم ${EMAIL}.", "teamNamesColorText": "اسماء/الوان الفرق...", "telnetAccessGrantedText": "تم تمكين الوصول تلنيت.", "telnetAccessText": "تم الكشف عن الوصول تلنيت. السماح؟", @@ -1359,20 +1441,35 @@ "testBuildValidatedText": "اختبار بناء تم التحقق منه؛ استمتع!", "thankYouText": "شكرا لدعمكم! استمتع باللعبة!!", "threeKillText": "القتل الثلاثي", + "ticketsDescriptionText": "يمكنك استخدام التذاكر لتقوم بإلغاء قفل الشخصيات، الخرائط، الألعاب المصغرة، و اكثر في المتجر.\n\nباستطاعتك العثور على التذاكر في الكنوز التي يتم كسبها في الحملات، البطولات، و الانجازات.", "timeBonusText": "مكافأة الوقت", "timeElapsedText": "الوقت المنقضي", "timeExpiredText": "انتهى الوقت", - "timeSuffixDaysText": "${COUNT}ي", - "timeSuffixHoursText": "${COUNT}س", - "timeSuffixMinutesText": "${COUNT}د", - "timeSuffixSecondsText": "${COUNT}ث", + "timeSuffixDaysText": "ي ${COUNT}", + "timeSuffixHoursText": "س ${COUNT}", + "timeSuffixMinutesText": "د ${COUNT}", + "timeSuffixSecondsText": "ث ${COUNT}", "tipText": "تلميح", - "titleText": "فرقة القنبلة", - "titleVRText": "فرقة القنبلة وا", + "titleText": "فرقه القنبله", + "titleVRText": "VR فرقه القنبله", + "tokens": { + "getTokensText": "احصل على التوكنز", + "notEnoughTokensText": "!التوكنز غير كافية", + "numTokensText": "توكنز ${COUNT}", + "openNowDescriptionText": "انت تملك توكينز تكفي\nلفتح هذا الآن - انت لا\nتحتاج للإنتظار", + "shinyNewCurrencyText": "عملة فرقة القنبلة اللماعة الجديدة.", + "tokenPack1Text": "حزمة التوكن الصغيرة", + "tokenPack2Text": "حزمة التوكن المتوسطة", + "tokenPack3Text": "حزمة التوكن الكبيرة", + "tokenPack4Text": "حزمة التوكن جامبو", + "tokensDescriptionText": "التوكنز يمكن استخدامها في عدة أغراض ، وهي تسريع وقت فتح الكنوز و لأغراض و ميزات اخرى في اللعبة و الحساب الشخصي أيضاً.\n\nيمكنك أن تفوز التوكنز في اللعبة أو تشتريهم في حزم. أو تقوم بشراء (البطاقة الذهبية) للحصول على عدد لا نهائي منها.", + "youHaveGoldPassText": ".Gold Pass أنت لديك\n.جميع عمليات شراء التوكن مجانية\n!استمتع" + }, "topFriendsText": "أفضل الأصدقاء", "tournamentCheckingStateText": "التحقق من حالة البطولة. أرجو الإنتظار...", "tournamentEndedText": "انتهت هذه البطولة. وسوف تبدأ واحدة جديدة قريبا.", "tournamentEntryText": "دخول البطولة", + "tournamentFinalStandingsText": "الترتيب النهائي", "tournamentResultsRecentText": "نتائج البطولة الأخيرة", "tournamentStandingsText": "ترتيب البطولة", "tournamentText": "المسابقة", @@ -1381,32 +1478,32 @@ "tournamentsText": "البطولات", "translations": { "characterNames": { - "Agent Johnson": "العميل جونسون", + "Agent Johnson": "جسّاس", "B-9000": "B-9000", "Bernard": "بيرنارد", - "Bones": "هيكل عظمي", + "Bones": "المُغضّرف", "Butch": "بوتش", "Easter Bunny": "أرنب عيد الفصح", "Flopsy": "فلوبسي", - "Frosty": "فروستي", + "Frosty": "ثُلجلج", "Gretel": "جريتل", "Grumbledorf": "الساحر", - "Jack Morgan": "جاك مورجان (قرصان)", - "Kronk": "كرونك", + "Jack Morgan": "القُبطان", + "Kronk": "صخر", "Lee": "لي", "Lucky": "سعيد الحظ", - "Mel": "ميل", + "Mel": "الطبّاخ", "Middle-Man": "الرجل المتوسط", "Minimus": "أدنى لا", - "Pascal": "پاسكال", - "Pixel": "بيكسل", + "Pascal": "بطريق", + "Pixel": "سكاكر", "Sammy Slam": "سامي سلام", "Santa Claus": "سانتا كلوس", "Snake Shadow": "نينجا", "Spaz": "سپاز", "Taobao Mascot": "ماسكوت تاوباو", "Todd McBurton": "تود بيرتون", - "Zoe": "زوي", + "Zoe": "فُستُق", "Zola": "زولا" }, "coopLevelNames": { @@ -1428,18 +1525,30 @@ "Uber Onslaught": "هجمة غزيرة", "Uber Runaround": "جولة جري غزيرة" }, + "displayItemNames": { + "${C} Tickets": "${C} تذاكر", + "${C} Tokens": "${C} توكنز", + "Chest": "كنز", + "L1 Chest": "كنز L1", + "L2 Chest": "كنز L2", + "L3 Chest": "كنز L3", + "L4 Chest": "كنز L4", + "L5 Chest": "كنز L5", + "L6 Chest": "كنز L6", + "Unknown Chest": "كنز غير معروف" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "يكون اختيار واحد لفترة من الوقت للفوز.\nقتل اختيار واحد لتصبح عليه.", - "Bomb as many targets as you can.": "فجر أكبر عدد من الأهداف على قدر استطاعتك.", + "Bomb as many targets as you can.": "ارمِ قنابلك نحو الأهداف.", "Carry the flag for ${ARG1} seconds.": "حمل العلم مقابل ${ARG1} ثانية.", "Carry the flag for a set length of time.": "احمل العلم لمدة محددة من الزمن", "Crush ${ARG1} of your enemies.": "سحق ${ARG1} من أعدائك.", "Defeat all enemies.": "هزيمة جميع الأعداء.", - "Dodge the falling bombs.": "تفادى القنابل.", + "Dodge the falling bombs.": "تفادى الشُهُب القنبلية من السماء.", "Final glorious epic slow motion battle to the death.": "آخر معركة ملحمية بطيئة حتى الموت.", "Gather eggs!": "جمع البيض!", "Get the flag to the enemy end zone.": "الحصول على العلم إلى المنطقة نهاية العدو.", - "How fast can you defeat the ninjas?": "كم من الوقت ستحتاج لهزيمة النينجا؟", + "How fast can you defeat the ninjas?": "اقض على المقاتلين والرماة بسرعة", "Kill a set number of enemies to win.": "قتل عدد معين من الأعداء للفوز.", "Last one standing wins.": "آخر واحد يبقى يفوز.", "Last remaining alive wins.": "آخر شخص يبقى حياً يفوز", @@ -1495,13 +1604,13 @@ "Hockey": "الهوكي", "Keep Away": "ابتعد", "King of the Hill": "ملك التل", - "Meteor Shower": "دش النيازك", + "Meteor Shower": "مزلج الشُهب", "Ninja Fight": "قتال النينجا", "Onslaught": "هجوم", - "Race": "السباق", - "Runaround": "يركض حول", - "Target Practice": "الممارسة المستهدفة", - "The Last Stand": "الموقف الأخير" + "Race": "سباق", + "Runaround": "السباق الدوراني", + "Target Practice": "مرحله تدريبيه: رمي القنابل", + "The Last Stand": "الوقفه الاخيره" }, "inputDeviceNames": { "Keyboard": "لوحة المفاتيح", @@ -1511,40 +1620,46 @@ "Arabic": "العربية", "Belarussian": "البيلاروسية", "Chinese": "الصينية المبسطة", - "ChineseTraditional": "التقليدية الصينية", + "ChineseSimplified": "الصين - مبسط", + "ChineseTraditional": "الصين - تقليدي", "Croatian": "الكرواتية", - "Czech": "تشيكي", - "Danish": "دانماركي", - "Dutch": "هولندي", + "Czech": "التشيكية", + "Danish": "الدنماركية", + "Dutch": "الهولندية", "English": "الإنجليزية", "Esperanto": "الاسبرانتو", "Filipino": "الفلبينية", "Finnish": "اللغة الفنلندية", "French": "الفرنسية", "German": "الألمانية", - "Gibberish": "رطانة", + "Gibberish": "الإنجليزية التجريبية", "Greek": "الإغريقية", "Hindi": "الهندية", "Hungarian": "الهنغارية", "Indonesian": "الأندونيسية", - "Italian": "الإيطالي", + "Italian": "الإيطالية", "Japanese": "اليابانية", "Korean": "الكورية", "Malay": "لغة الملايو", - "Persian": "اللغة الفارسية", - "Polish": "البولندي", + "Persian": "الفارسية", + "PirateSpeak": "لغة القراصنة", + "Polish": "البولندية", "Portuguese": "البرتغالية", - "Romanian": "روماني", + "PortugueseBrazil": "برتغالية - برازيلية", + "PortuguesePortugal": "البرتغاليه - البرتغال", + "Romanian": "الرومانية", "Russian": "الروسية", "Serbian": "الصربية", "Slovak": "السلوفاكية", "Spanish": "الإسبانية", - "Swedish": "اللغة السويدية", - "Tamil": "اللغةالتاميلية", - "Thai": "تايلاندي", - "Turkish": "اللغة التركية", - "Ukrainian": "الأوكراني", - "Venetian": "فينيسي", + "SpanishLatinAmerica": "اسبانيا - امريكا لاتينا", + "SpanishSpain": "الاسبانية - إسبانيا", + "Swedish": "السويدية", + "Tamil": "التاميلية", + "Thai": "التايلاندية", + "Turkish": "التركية", + "Ukrainian": "الأوكرانية", + "Venetian": "البندقية", "Vietnamese": "الفيتنامية" }, "leagueNames": { @@ -1603,6 +1718,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "الغش الكشف عنها. تم تعليق العشرات والجوائز لمدة ${COUNT} من الأيام.", "Could not establish a secure connection.": "تعذر إنشاء اتصال آمن.", "Daily maximum reached.": "الحد الأقصى اليومي الذي تم الوصول إليه.", + "Daily sign-in reward": "جائزة تسجيل الدخول اليومي", "Entering tournament...": "جار دخول البطولة ...", "Invalid code.": "الرمز غير صحيح.", "Invalid payment; purchase canceled.": "دفعة غير صالحة؛ تم إلغاء الشراء.", @@ -1612,11 +1728,14 @@ "Item unlocked!": "العنصر غير مقفلة!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ربط مرفوض. ${ACCOUNT} يحتوي علي\nبيانات كبيرة والتي سيتم فقدانها.\nتستطيع الربط بالامر المعاكس اذا احببت\n(و فقدان بيانات هذا الحساب بالمقابل)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "هل تريد ربط الحساب ${ACCOUNT} بهذا الحساب؟\nسيتم فقد جميع البيانات الموجودة في ${ACCOUNT}.\nهذا لا يمكن التراجع عنها. هل أنت واثق؟", + "Longer streaks lead to better rewards.": "الستريك الأطول يقود الى جائزة أفضل", "Max number of playlists reached.": "تم الوصول إلى أقصى عدد من قوائم التشغيل.", "Max number of profiles reached.": "تم الوصول إلى أقصى عدد من الملفات الشخصية.", "Maximum friend code rewards reached.": "تم الوصول إلى الحد الأقصى لمكافآت الرمز الصديق.", "Message is too long.": "الرسالة طويلة جدا", + "New tournament result!": "نتيجة بطولة جديدة!", "No servers are available. Please try again soon.": "لا توجد خوادم متاحة. من فضلك حاول لاحقا", + "No slots available. Free a slot and try again.": "لا يوجد اماكن فارغة متاحة. فرّغ فتحة وحاول مجدداً.", "Profile \"${NAME}\" upgraded successfully.": "تمت ترقية الملف الشخصي \"${NAME}\" بنجاح.", "Profile could not be upgraded.": "تعذر ترقية الملف الشخصي.", "Purchase successful!": "تم الشراء بنجاح!", @@ -1626,7 +1745,9 @@ "Sorry, this code has already been used.": "عذرا، تم استخدام هذه الشفرة من قبل.", "Sorry, this code has expired.": "عذرا، انتهت صلاحية هذا الرمز.", "Sorry, this code only works for new accounts.": "عذرا، لا تعمل هذه الشفرة إلا لحسابات جديدة.", + "Sorry, this has expired.": "عذراً، لقد تم انتهاء صلاحية هذا.", "Still searching for nearby servers; please try again soon.": "يزال البحث عن سيرفرات قريبة; من فضلك كرر المحاولة لاحقا", + "Streak: ${NUM} days": "الستريك: ${NUM} الأيام", "Temporarily unavailable; please try again later.": "غير متاح مؤقتا؛ الرجاء معاودة المحاولة في وقت لاحق.", "The tournament ended before you finished.": "انتهت البطولة قبل الانتهاء.", "This account cannot be unlinked for ${NUM} days.": "لا يمكن إلغاء ربط هذا الحساب بمبلغ ${NUM} من الأيام.", @@ -1637,19 +1758,28 @@ "Tournaments require ${VERSION} or newer": "تتطلب الدورات ${VERSION} أو أحدث", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "هل تريد إلغاء ربط ${ACCOUNT} من هذا الحساب؟\nسيتم إعادة تعيين جميع البيانات على ${ACCOUNT}.\n(باستثناء الإنجازات في بعض الحالات)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "تحذير: تم إصدار شكاوى تتعلق بالقرصنة ضد حسابك.\nسيتم حظر الحسابات التي تم العثور عليها عن طريق القرصنة. يرجى لعب عادل.", + "Wait reduced!": "قلل الانتظار!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "تحذير: هذه النسخة من اللعبة تقتصر على بيانات الحساب القديمة؛ قد تظهر بعض الأشياء مفقودة أو قديمة.\nيرجى الترقية إلى إصدار أحدث من اللعبة لرؤية بيانات حسابك الأخيرة.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "هل تريد ربط حساب الجهاز بهذا الحساب؟\n\nحساب الجهاز هو ${ACCOUNT1}\nهذا الحساب هو ${ACCOUNT2}\n\nهذا سيسمح لك للحفاظ على التقدم المحرز الخاص بك.\nتحذير: لا يمكن التراجع عن ذلك!", "You already own this!": "كنت تملك هذا بالفعل!", "You can join in ${COUNT} seconds.": "يمكنك الانضمام في ${COUNT} ثانية.", "You don't have enough tickets for this!": "ليس لديك ما يكفي من تذاكر لهذا!", "You don't own that.": "أنت لا تملك ذلك.", "You got ${COUNT} tickets!": "لقد حصلت على تذاكر ${COUNT}!", + "You got ${COUNT} tokens!": "لقد حصلت على ${COUNT}توكنز!", "You got a ${ITEM}!": "لقد حصلت على ${ITEM}!", + "You got a chest!": "حصلت على كنز!", + "You got an achievement reward!": "لقد حصلت على جائزة إنجاز!", "You have been promoted to a new league; congratulations!": "لقد تم ترقيتك إلى الدوري الجديد. تهانينا!", + "You lost a chest! (All your chest slots were full)": "خسرت كنز! (كل فتحات الكنوز كانت ممتلئة)", + "You must update the app to view this.": "يجب عليك تحديث التطبيق لمشاهدة هذا", "You must update to a newer version of the app to do this.": "يجب تحديث إلى إصدار أحدث من التطبيق للقيام بذلك.", "You must update to the newest version of the game to do this.": "يجب عليك التحديث إلى الإصدار الأحدث من اللعبة للقيام بذلك.", "You must wait a few seconds before entering a new code.": "يجب الانتظار بضع ثوان قبل إدخال رمز جديد.", + "You placed #${RANK} in a tournament!": "لقد وضعت #${RANK} في بطولة!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "لقد حصلت على الترتيب # ${RANK} في البطولة الأخيرة. شكرا للعب!", "Your account was rejected. Are you signed in?": "لقد حُذف حسابك.هل قمت بتسجيل دخولك?", + "Your ad views are not registering. Ad options will be limited for a while.": "لم يتم تسجيل مشاهداتك للإعلان. خيارات الإعلان سيكون محدود لفترة من الوقت", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "تم تعديل نسختك من اللعبة.\nيرجى إعادة أي تغييرات وإعادة المحاولة.", "Your friend code was used by ${ACCOUNT}": "تم استخدام رمز صديقك بواسطة ${ACCOUNT}" }, @@ -1701,9 +1831,9 @@ }, "teamNames": { "Bad Guys": "الأشرار", - "Blue": "ازرق", + "Blue": "الزُرق", "Good Guys": "الأخيار", - "Red": "أحمر" + "Red": "الحُمر" }, "tips": { "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "A توقيت تماما تشغيل القفز تدور لكمة يمكن أن تقتل في ضربة واحدة\nوكسب لك مدى الحياة الاحترام من أصدقائك.", @@ -1741,45 +1871,45 @@ "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "الرأس هو المنطقة الأكثر ضعفا، لذلك قنبلة لزجة\nإلى نوجين يعني عادة لعبة أكثر.", "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "هذا المستوى لا تنتهي أبدا، ولكن على درجة عالية هنا\nسوف كسب لك الاحترام الأبدية في جميع أنحاء العالم.", "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "وتستند قوة رمي على الاتجاه الذي عقد.\nلإرم شيء برفق أمامك، لا تحمل أي اتجاه.", - "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "تعبت من الموسيقى التصويرية؟ استبدالها بنفسك!\nانظر إعدادات-> الصوت-> الموسيقى التصويرية", - "Try 'Cooking off' bombs for a second or two before throwing them.": "محاولة 'الطبخ قبالة' القنابل لمدة ثانية أو اثنين قبل رمي لهم.", - "Try tricking enemies into killing eachother or running off cliffs.": "محاولة خداع الأعداء في قتل بعضهم البعض أو الجري المنحدرات.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "تعبت من الموسيقى اللعبه؟ استبدالها بنفسك!\n ادخل إعدادات-> الصوت-> مسار الصوت", + "Try 'Cooking off' bombs for a second or two before throwing them.": "جرّب تأخير رمي القنبله لثانية أو ثانيتين قبل رميها.", + "Try tricking enemies into killing eachother or running off cliffs.": "حاول خداع الأعداء لجعلهم يقتلون بعضهم البعض أو يسقطون من المنحدرات", "Use the pick-up button to grab the flag < ${PICKUP} >": "استخدم زر البيك اب للاستيلاء على العلم <${PICKUP}", - "Whip back and forth to get more distance on your throws..": "سوط ذهابا وإيابا للحصول على مزيد من المسافة على رميات الخاص بك", - "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "يمكنك 'تهدف' اللكمات الخاصة بك عن طريق الغزل اليسار أو اليمين.\nوهذا مفيد لضرب الأشرار من حواف أو التهديف في الهوكي.", + "Whip back and forth to get more distance on your throws..": "تحرّك ذهابًا وإيابًا للرمي لمسافات ابعد", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "يمكنك توجيه ضرباتك عن طريق الدوران إلى اليسار أو اليمين.\nوهذا مفيد لإسقاط الأشرار من الحواف أو لتسجيل الأهداف في رياضة الهوكي.\"", "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "يمكنك تحديد وقت إنفجار القنبلة بناءً على لون الشرارة المنبعثة من فتيلها:\nأصفر..برتقالي..أحمر ثم بووم.", - "You can throw bombs higher if you jump just before throwing.": "يمكنك رمي القنابل أعلى إذا كنت القفز قبل رمي.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "كنت تأخذ الضرر عندما كنت اجتز رأسك على الأشياء،\nوذلك في محاولة لا اجتز رأسك على الأشياء.", + "You can throw bombs higher if you jump just before throwing.": "يمكنك رمي القنابل أعلى إذا كنت تقفز قبل ان ترمي القنابل.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "سوف تتلقي اضرار عندما تضرب راسك بالاشياء،\nفحاول انك تتجنب ضرب راسك في اي شي.", "Your punches do much more damage if you are running or spinning.": "لكماتك تؤثر بضرر اكبر اذا كنت تجري او تدور" } }, - "trophiesRequiredText": "جوائز ${NUMBER} هذا يحتاج على الاقل", + "trophiesRequiredText": "من الجوائز ${NUMBER} هذا يحتاج على الاقل", "trophiesText": "الجوائز", "trophiesThisSeasonText": "جوائز هذا الموسم", "tutorial": { "cpuBenchmarkText": "(CPU تشغيل البرنامج التعليمي بالسرعة المثيرة للسخرية (رئيسيا لتجريب سرعة", - "phrase01Text": "!مرحبا", - "phrase02Text": "!${APP_NAME} أهلا بك في", - "phrase03Text": "إليك بعض النصائح للتحكم بشخصيتك", - "phrase04Text": "درست فرقة القنبلة كثيرا من الاشياء فيزيائيا ${APP_NAME}**", - "phrase05Text": "...,على سبيل المثال, عندما تلكم", - "phrase06Text": "الضرر مبني على سرعة لكماتك", - "phrase07Text": "${NAME} كما ترى, نحن لا نتحرك لهذا بالكاد نصيب", - "phrase08Text": "الآن قم بالقفز والدوران لكسب زخم اكثر", + "phrase01Text": "!مرحبا صديقي", + "phrase02Text": "!${APP_NAME} أهلا و سهلا بك في لعبه", + "phrase03Text": "انا هنا لاقدم لك بعض النصائح علشان تتحكم بشخصيتك", + "phrase04Text": "في كثير حاجات في لعبه ${APP_NAME} تعتمد ميكانيكيات الفيزياء.", + "phrase05Text": "...,و كمثال على كلامي, عندما تلكم", + "phrase06Text": "الضرر يكون اقوي على حسب سرعة لكماتك", + "phrase07Text": "${NAME} زي ماتشوف ماتحركنا من مكاننا لهذا السبب ضربتنا لم توثر في", + "phrase08Text": "الآن قم بالقفز والدوران علشان تكتسب سرعة اكبر", "phrase09Text": "!آه هذا أفضل", "phrase10Text": "الجري يساعد ايضا", - "phrase11Text": "استمر في الضغط على اي زر للجري", + "phrase11Text": "استمر في الضغط على اي زر علشان تجري", "phrase12Text": "للحصول على لكمة رائعة اضافية, جرب الجري و الدوران", - "phrase13Text": "${NAME} أوبس؛ اعتذر بشأن هذا يا يا صاح", - "phrase14Text": "${NAME} يمكنك امساك ورمي الاشياء مثل الاعلام .. أو", - "phrase15Text": "أخيرا, هناك القنابل", + "phrase13Text": "${NAME} أوبس؛ اعتذر بشأن هذا يا", + "phrase14Text": "${NAME} يمكنك ان تمسك وترمي الاشياء مثل الاعلام .. أو", + "phrase15Text": "و الان, بنتحدث عن القنابل", "phrase16Text": "رمي القنابل يحتاج للتدريب", - "phrase17Text": "اوو! لم تكن رمية جيدة", + "phrase17Text": "اوتش! لم تكن رمية جيدة", "phrase18Text": "التحرك يساعدك على الرمي ابعد", "phrase19Text": "القفز يساعدك على الرمي اعلى", - "phrase20Text": "فجر\"قنابلك لمدى حتى أبعد من ذلك\"", + "phrase20Text": "أصب قنابلك لمدى ابعد.", "phrase21Text": "توقيت القنبلة يمكن أن يكون مخادعا", - "phrase22Text": "!بووم", + "phrase22Text": "دانغ", "phrase23Text": "جرب امساك القنبلة ليذوب الفتيل لثانية او اثنتين", "phrase24Text": "مرحى! لقد تم شواؤه بشكل رائع", "phrase25Text": "حسنا, هذا كل ما في الامر", @@ -1787,65 +1917,72 @@ "phrase27Text": "إن تذكرت تدريبك.. فستعود حيا", "phrase28Text": "...حسنا, ربما...", "phrase29Text": "!حظا سعيدا", - "randomName1Text": "فريد", - "randomName2Text": "هاني", - "randomName3Text": "باسل", - "randomName4Text": "كيفن", - "randomName5Text": "جوني", - "skipConfirmText": "حقا تريد تخطي البرنامج التعليمي؟ إلمس أو اضغط بإستمرار", - "skipVoteCountText": "تخطي اصوات ${COUNT}/${TOTAL}", + "randomName1Text": "بوت1", + "randomName2Text": "بوت2", + "randomName3Text": "بوت3", + "randomName4Text": "بوت4", + "randomName5Text": "بوت5", + "skipConfirmText": "هل انت متاكد من رغبتك في تخطي البرنامج التعليمي؟ إلمس أو اضغط بإستمرار", + "skipVoteCountText": "تصويتات ${COUNT}/${TOTAL}", "skippingText": "جاري تخطي البرنامج التعليمي....", "toSkipPressAnythingText": "(إلمس او إضغظ اي شئ لتخطي البرنامج التعليمي)" }, "twoKillText": "!قتل مزدوج", - "unavailableText": "غير متوفر", + "uiScaleText": "حجم الواجهة", + "unavailableText": "غير متاح", + "unclaimedPrizesText": "!انت تملك جوائز غير مستلمة", "unconfiguredControllerDetectedText": ":تم الكشف على يد تحكم غير مهيئة", "unlockThisInTheStoreText": "هذا يجب ان يفتح في المتجر", "unlockThisProfilesText": "لإنشاء أكثر من ${NUM} من الملفات الشخصية، تحتاج إلى:", "unlockThisText": ":لفتح هذا, تحتاج إلى", + "unsupportedControllerText": "عذرًا، وحدة التحكم \"${NAME}\" غير مدعومة.", "unsupportedHardwareText": "عفوا, هذه المعدات غير مدعومة في هذه النسخة من اللعبة", "upFirstText": ":يصل اولا", "upNextText": ":${COUNT}التالي في اللعبة", "updatingAccountText": "تحديث الحساب الخاص بك....", - "upgradeText": "احصل على ترقية", + "upgradeText": "ترقية", "upgradeToPlayText": "في متجر اللعبة لتلعب هذا \"${PRO}\" اشتري", "useDefaultText": "استخدام الإفتراضي", + "userSystemScriptsCreateText": "User System Scripts انشئ", + "userSystemScriptsDeleteText": "User System Scripts احذف", "usesExternalControllerText": "هذه اللعبة تستخدم يد تحكم خارجية للإدخال", "usingItunesText": "...استخدام تطبيق الموسيقى للموسيقى التصويرية", "v2AccountLinkingInfoText": "اذا اردت ربط حسابات V2، قم بالتوجه الى 'ادارة الحساب'.", - "validatingTestBuildText": "التحقق من صحة البناء", + "v2AccountRequiredText": ".طور حسابك و حاول مره ثانيه .V2 هذا يحتاج حساب", + "validatingTestBuildText": "التحقق من صحة التحديث...", + "viaText": "عبر", "victoryText": "!النصر", - "voteDelayText": "ثانية ${NUMBER} لا يمكنك التصويت ثانية حتى", + "voteDelayText": "لا يمكنك التصويت مره ثانيه حتي تعبر ${NUMBER} ثانيه", "voteInProgressText": "التصويت بالفعل في التقدم", - "votedAlreadyText": "لقد صوت بالفعل", - "votesNeededText": "صوت مطلوب ${NUMBER}", + "votedAlreadyText": "لقد صوتت بالفعل", + "votesNeededText": "عدد الاصوات المطلوبه ${NUMBER}", "vsText": "ضد", - "waitingForHostText": "(للإستمرار ${HOST} انتظار)", - "waitingForPlayersText": "...انتظار اللاعيبين للإنضمام", - "waitingInLineText": "الانتظار في السطر (الطرف ممتلئ) ...", + "waitingForHostText": "(للمتابعه ${HOST} منتظرين)", + "waitingForPlayersText": "...بانتظار الاعبين للانضمام", + "waitingInLineText": "الانتظار في الدور (الغرفه مليانه) ...", "watchAVideoText": "شاهد فيديو", "watchAnAdText": "شاهد اعلان", "watchWindow": { - "deleteConfirmText": "\"${REPLAY}\"? حذف", - "deleteReplayButtonText": "حذف\nالإعادة", - "myReplaysText": "إعاداتي", - "noReplaySelectedErrorText": "لايوجد إعادة تم اختيارها", - "playbackSpeedText": "سرعة الاعادة: ${SPEED}", - "renameReplayButtonText": "إعادة تسمبة \n الإعادة", + "deleteConfirmText": "\"${REPLAY}\"? هل انت متاكد من رغبتك بالحذف", + "deleteReplayButtonText": "حذف\nالتسجيل", + "myReplaysText": "تسجيلاتي", + "noReplaySelectedErrorText": "لايوجد تسجيل تم اختيارها", + "playbackSpeedText": "سرعة التسجيل: ${SPEED}", + "renameReplayButtonText": "إعادة تسمبة \n التسجيل", "renameReplayText": ":الى \"${REPLAY}\" اعادة تسمية", - "renameText": "إعادة تسمية", - "replayDeleteErrorText": "خطا في حذف الإعادة", - "replayNameText": "اسم الإعادة", - "replayRenameErrorAlreadyExistsText": "اسم الإعادة موجود بالفعل", - "replayRenameErrorInvalidName": "لايمكن اعادة تسمية الإعادة; الاسم غير صالح", - "replayRenameErrorText": "خطا في اعادة تسمية الإعادة", - "sharedReplaysText": "الإعادة المشاركة", - "titleText": "شاهد", - "watchReplayButtonText": "شاهد\nالإعادة" + "renameText": "اعاده تسميه", + "replayDeleteErrorText": "حصل خطأ اثناء حذف التسجيل", + "replayNameText": "اسم التسجيل", + "replayRenameErrorAlreadyExistsText": "اسم التسجيل موجود رجاء اكتب اسم اخر", + "replayRenameErrorInvalidName": "ماتقدر تسمي التسجيل بسبب; الاسم مش صالح للاستخدام", + "replayRenameErrorText": "حصل خطا اثناء تسميه التسجيل", + "sharedReplaysText": "مشاركه التسجيل", + "titleText": "التسجيلات", + "watchReplayButtonText": "شاهد\nالتسجيلات" }, - "waveText": "موجة", - "wellSureText": "!حسنا طبعا", - "whatIsThisText": "ما هذا؟", + "waveText": "جوله", + "wellSureText": "!حسنا بالطبع", + "whatIsThisText": "ايش ذا؟", "wiimoteLicenseWindow": { "titleText": "DarwinRemoteحقوق التأليف والنشر ل" }, @@ -1861,14 +1998,14 @@ "thanksText": "DarwiinRemote شكرا لفريق\nلجعل هذا ممكنا", "titleText": "wiimote تثبيت" }, - "winsPlayerText": "${NAME} !يفوز", - "winsTeamText": "${NAME} !يفوز فريق", - "winsText": "${NAME} !يفوز", - "workspaceSyncErrorText": "فشل في مزامنة ${WORKSPACE}. القي نظرة على السجل للتفاصيل.", - "workspaceSyncReuseText": "لا يمكن مزامنة ${WORKSPACE}. اعادة استخدام النسخة المتزامنة السابقة.", - "worldScoresUnavailableText": "(النتيجة العالمية غير متوفرة (اتصل بالانترنت", - "worldsBestScoresText": "افضل نتيجة للعالم", - "worldsBestTimesText": "افضل اوقات العالم", + "winsPlayerText": "${NAME} !انتصر", + "winsTeamText": "${NAME} انتصر فريق", + "winsText": "${NAME} !انتصر", + "workspaceSyncErrorText": "فشل في مزامنة ${WORKSPACE}. القي نظرة على السجل لمزيد من التفاصيل.", + "workspaceSyncReuseText": "تعذّر مزامنة ${WORKSPACE}. يتم حالياً استخدام النسخة السابقة التي تم مزامنتها.", + "worldScoresUnavailableText": ".النتائج العالمية ليست متاحه", + "worldsBestScoresText": "افضل النتائج العالميه", + "worldsBestTimesText": "افضل اوقاتك على مستوى عالمي", "xbox360ControllersWindow": { "getDriverText": "احصل على تعريف", "macInstructions2Text": "لاستخدام وحدات تحكم لاسلكيا، سوف تحتاج أيضا المتلقي ذلك\nيأتي مع \"تحكم اكس بوكس 360 اللاسلكية ويندوز\".\nواحد المتلقي يسمح لك لربط ما يصل إلى 4 وحدات تحكم.\n\nهام: لن تعمل أجهزة الاستقبال التابعة لجهة خارجية مع برنامج التشغيل هذا؛\nتأكد من جهاز الاستقبال يقول 'مايكروسوفت' على ذلك، وليس 'الاكس بوكس 360'.\nمايكروسوفت لم تعد تبيع هذه بشكل منفصل، لذلك سوف تحتاج إلى الحصول عليها\nواحد المجمعة مع وحدة تحكم أو البحث إيباي آخر.\n\nإذا وجدت هذا مفيد، يرجى النظر في التبرع ل\nمطور برامج في موقعه.", @@ -1877,6 +2014,7 @@ "titleText": "استخدام يد تحكم Xbox 360 مع ${APP_NAME}:" }, "yesAllowText": "!نعم,اسمح", - "yourBestScoresText": "أفضل نقاطك", - "yourBestTimesText": "أفضل أوقاتك" + "yourBestScoresText": "أفضل نتائجك", + "yourBestTimesText": "أفضل أوقاتك", + "yourPrizeText": "جائزتك:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/belarussian.json b/dist/ba_data/data/languages/belarussian.json index ce89a78e..4b4d5c70 100644 --- a/dist/ba_data/data/languages/belarussian.json +++ b/dist/ba_data/data/languages/belarussian.json @@ -1,12 +1,15 @@ { "accountSettingsWindow": { "accountNameRules": "Імя акаўнта не можа ўтрымліваць эмоджы і іншыя спецыяльныя сымбалі", - "accountsText": "Акаўнты", + "accountsText": "el idioma", "achievementProgressText": "Дасягненні: ${COUNT} з ${TOTAL}", "campaignProgressText": "Прагрэс кампаніі (Цяжка): ${PROGRESS}", "changeOncePerSeason": "Вы можаце змяніць толькі адзін раз за сезон.", "changeOncePerSeasonError": "Трэба пачакаць наступнага сезона, каб зноў змяніць гэта (${NUM} days)", + "createAnAccountText": "Стварыць акаўнт", "customName": "Зрабіць імя", + "deleteAccountText": "Выдаліць уліковы запіс", + "googlePlayGamesAccountSwitchText": "Калі вы жадаеце выкарыстоўваць іншы ўліковы запіс Google,\nвыберыце яго ў Google Play Games.", "linkAccountsEnterCodeText": "Увесцi Код", "linkAccountsGenerateCodeText": "Стварыць Код", "linkAccountsInfoText": "(сінхранізацыя гульні паміж рознымі платформамі)", @@ -14,6 +17,7 @@ "linkAccountsInstructionsText": "Каб звязаць 2 акаўнта, стварыце код на першым\nз іх і увядзіце яго ў другім.\nПрагрэс і пакупкі будуць сінранізаваны.\nВы можаце звязаць да ${COUNT} акаўнтаў.\n\nАсцярожна! Гэта нельга адмяніць!", "linkAccountsText": "Звязаць Акаўнты", "linkedAccountsText": "Злучаныя Акаўнты:", + "manageAccountText": "Кiраваць акаўнтам", "nameChangeConfirm": "Змяніць імя акаўнта на ${NAME} ?", "resetProgressConfirmNoAchievementsText": "Гэта скіне ўвесь ваш кааператыўны прагрэс\nды лакальныя лепшыя вынікі (акрамя білетаў).\nГэты працэс незваротны. Вы ўпэўнены?", "resetProgressConfirmText": "Гэта скіне ўвесь ваш кааператыўны\nпрагрэс, дасягненні ды лакальныя вынікі\n(акрамя білетаў). Гэты працэс незваротны.\nВы ўпэўнены?", @@ -22,14 +26,16 @@ "setAccountNameDesc": "Выберыце імя для адлюстравання для вашага ўліковага запісу.\nВы можаце выкарыстоўваць імя ў адным з звязаных\nуліковых запісаў альбо стварыць унікальнае прыстасаванае імя.", "signInInfoText": "Увайдзіце, каб збіраць квіткі, удзельнічаць у спаборніцтвах \nі сінхранізіраваць прагрэс паміж рознымі прыладамі.", "signInText": "Увайсці", + "signInWithAnEmailAddressText": "Увайсці з дапамогай адраса электроннай пошты", "signInWithDeviceInfoText": "(толькі аўтаматычны акаўнт даступны для гэтай прылады)", "signInWithDeviceText": "Увайсці з акаўнта прылады", "signInWithGameCircleText": "Увайсці з дапамогаю Game Circle", "signInWithGooglePlayText": "Увайсці з дапамогаю Google Play", "signInWithTestAccountInfoText": "(акаўнт, які ўжо існуе; спачатку увайдзіце з прылады)", "signInWithTestAccountText": "Увайсці з тэст-акаўнта", + "signInWithText": "Увайдзіце з дапамогай ${SERVICE}", "signInWithV2InfoText": "(уліковы запіс, які працуе на ўсіх платформах)", - "signInWithV2Text": "Увайдзіце з уліковым запісам BombSquad", + "signInWithV2Text": "Увайдзіце з дапамогай уліковага запісу ${APP_NAME}", "signOutText": "Выйсці", "signingInText": "Уваход...", "signingOutText": "Выхад...", @@ -40,6 +46,7 @@ "titleText": "Акаўнт", "unlinkAccountsInstructionsText": "Выберыце ўліковы запіс, каб спыніць сувязь", "unlinkAccountsText": "Адлучэнне акаунтау", + "unlinkLegacyV1AccountsText": "Адключэнне устарэлых уліковых запісаў (V1)", "v2LinkInstructionsText": "Выкарыстоўвайце гэтую спасылку, каб стварыць уліковы запіс або ўвайсці.", "viaAccount": "(праз акаунт ${NAME})", "youAreSignedInAsText": "Вы ўвайшлі як:" @@ -328,13 +335,19 @@ "achievementsRemainingText": "Дасягенні, Якія Засталіся", "achievementsText": "Дасягненні", "achievementsUnavailableForOldSeasonsText": "Прабачце, спецыфіка дасягненняў недаступна для старога сезона.", + "activatedText": "${THING} Актыўны", "addGameWindow": { "getMoreGamesText": "Атрымаць больш гульняў...", "titleText": "Дадаць гульню" }, + "addToFavoritesText": "Дадаць у абранае", + "addedToFavoritesText": "'${NAME}' дададзены ў абранае.", + "allText": "Усё", "allowText": "Дазволіць", "alreadySignedInText": "Ваш уліковы запіс увайшоў з іншай прылады;\nкалі ласка, пераключыце ўліковыя запісы альбо зачыніце гульню на вашым\nіншыя прылады і паспрабуйце яшчэ раз", "apiVersionErrorText": "Нельга загрузіць модуль ${NAME}; ён прапануецца для api-версіі ${VERSION_USED}; мы карыстаемся ${VERSION_REQUIRED}.", + "applyText": "Ужыць", + "areYouSureText": "Вы ўпэўнены", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Аўтаматычна\" працуе толькі калі ўстаўлены навушнікі)", "headRelativeVRAudioText": "H-R VR Аўдыя", @@ -356,14 +369,24 @@ "boostText": "Павышэнне", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} наладзіцца сам.", "buttonText": "Кнопка", - "canWeDebugText": "Ці жадаеце вы аўтаматычна паведамляць аб багах\nі аварыях распрацоўніку?\n\nГэтыя паведамленні не ўтрымліваюць асабістую інфармацыю\nі дапамагаюць палепшыць гульню.", + "canWeDebugText": "Хочаце, каб ${APP_NAME} аўтаматычна паведамляла\nпамылкі, збоі і асноўныя звесткі аб выкарыстанні для распрацоўшчыка?", "cancelText": "Зачыніць", "cantConfigureDeviceText": "Прабачце, ${DEVICE} не падтрымліваецца.", "challengeEndedText": "Спаборніцтва скончылася.", "chatMuteText": "Адключэнне гуку ў чаце", "chatMutedText": "Чат адключон", "chatUnMuteText": "Уключыць гук у чаце", + "chests": { + "prizeOddsText": "Прызавыя шанцы", + "reduceWaitText": "Паменшыць Час", + "slotDescriptionText": "Гэтая ячэйка можна храніць куфар.\n\nЗарабляй куфары гуляючы ў узроўні кампаніі, зарабляючы месцы ў турнірах, і робячы дасягнення.", + "slotText": "Ячэйка куфара ${NUM}", + "slotsFullWarningText": "УВАГА: Усё ячэйкі куфараў поўныя.\nДругія куфары якія вы заробіце будуць страчаны.", + "unlocksInText": "Адмыкае ў" + }, "choosingPlayerText": "<выбар гульца>", + "claimText": "Атрымаць", + "codesExplainText": "Коды прадастаўляюцца распрацоўшчыкам\nдыягностыка і выпраўленне праблем з уліковым запісам.", "completeThisLevelToProceedText": "Вы павінны прайсці гэты\nўзровень, каб працягнуць!", "completionBonusText": "Бонус за праходжанне", "configControllersWindow": { @@ -444,6 +467,7 @@ "swipeText": "змахванне", "titleText": "Налады Экрана" }, + "configureDeviceInSystemSettingsText": "${DEVICE} можна наладзіць у праграме \"Сістэмныя налады\".", "configureItNowText": "Наладзіць гэта зараз?", "configureText": "Налады", "connectMobileDevicesWindow": { @@ -498,6 +522,7 @@ "welcome2Text": "Вы таксама можаце зарабляць білеты многімі з такіх жа\nзаняткаў. Білеты дазваляюць адкрываць новых персанажаў, \nмапы, міні-гульні, удзельнічаць у турнірах і іншае.", "yourPowerRankingText": "Ваш Узровень:" }, + "copyConfirmText": "Капіравана ў буфэр", "copyOfText": "Копія ${NAME}", "copyText": "Копія", "createEditPlayerText": "<Стварыць/Змяніць Гульца>", @@ -544,7 +569,10 @@ "deleteText": "Выдаліць", "demoText": "Дэманстрацыя", "denyText": "Адхіліць", + "deprecatedText": "Састарэў", + "descriptionText": "Апісанне", "desktopResText": "Дазвол Экрана", + "deviceAccountUpgradeText": "Увага:\nВы ўзайшлі ў акаўнт дэвайса\n(${NAME}).\nАкаўнты дэвайса будуць Выдалены ў будучай абнове.", "difficultyEasyText": "Лёгка", "difficultyHardOnlyText": "Толькі на Складаным Узроўні", "difficultyHardText": "Цяжка", @@ -553,6 +581,10 @@ "disableRemoteAppConnectionsText": "Адключыць злучэнні з аддаленым дадаткам", "disableXInputDescriptionText": "Дазваляе больш за 4 кантролераў, але можа таксама не працаваць.", "disableXInputText": "Адключыць XInput", + "disabledText": "Выключана", + "discardText": "Адмовіться", + "discordFriendsText": "Хочаце шукаць новых людзей для гульні?\nДалучайцеся да нашага Discord і знайдзіце новых сяброў!", + "discordJoinText": "Далучайцеся да Discord", "doneText": "Зроблена", "drawText": "Нічыя", "duplicateText": "Дублікат", @@ -586,6 +618,7 @@ "localProfileText": "(лакальны профіль)", "nameDescriptionText": "Імя Гульца", "nameText": "Імя", + "profileAlreadyExistsText": "Профіль з такім імем ужо існуе.", "randomText": "выпадкова", "titleEditText": "Рэдагаваць Профіль", "titleNewText": "Новы Профіль", @@ -621,15 +654,20 @@ "useMusicFolderText": "Тэчка з Музыкай" }, "editText": "Рэдагаваць", + "enabledText": "Уключана", "endText": "Канец", "enjoyText": "Поспехаў!", "epicDescriptionFilterText": "${DESCRIPTION} у эпічным рэжыме.", "epicNameFilterText": "${NAME} у Эпічным Рэжыме", "errorAccessDeniedText": "доступ забаронены", + "errorDeviceTimeIncorrectText": "Час вашага дэвайса Няверны на ${HOURS} Гадзін.\nГэта можа прывесці да праблем.\nКалі ласка праверце ваш час і зону часа ў устаноўках", "errorOutOfDiskSpaceText": "не хапае месца на дыске", + "errorSecureConnectionFailText": "Нельга Наладзіць бяспечнае падключэнне да інтэрнету. Функцыі інтэренту могуць не працаваць.", "errorText": "Памылка", "errorUnknownText": "Невядомая памылка", "exitGameText": "Зачыніць ${APP_NAME}?", + "expiredAgoText": "Сапсаваўся ${T} таму", + "expiresInText": "Сапсуецца праз ${T}", "exportSuccessText": "'${NAME}' экспартуецца.", "externalStorageText": "Знешняя памяць", "failText": "Правал", @@ -664,6 +702,8 @@ "duplicateText": "Прадубляваць\nПлэйліст", "editText": "Рэдагаваць\nПлэйліст", "newText": "Новы\nПлэйліст", + "pointsToWinText": "Ачкоў Для Перамогі", + "seriesLengthText": "Даўжыня Чарады", "showTutorialText": "Паказаць Туторыял", "shuffleGameOrderText": "Выпадковы Парадак Гульняў", "titleText": "Наладзіць ${TYPE} Плэйлісты" @@ -690,23 +730,24 @@ "copyCodeConfirmText": "Код скапіяваны ў буфер абмену", "copyCodeText": "Скапіяваць код", "dedicatedServerInfoText": "Для дасягнення найлепшых вынікаў наладзьце спецыяльны сервер. Гл. Bombsquadgame.com/server, каб даведацца, як.", + "descriptionShortText": "Выкарыстайце акно збору каб сабраць групу.", "disconnectClientsText": "Гэта адлучыць ${COUNT} гульцоў з вашага\nлоббі. Вы ўпэўнены?", "earnTicketsForRecommendingAmountText": "Сябры атрымаюць ${COUNT} квіткоў, калі яны паспрабуюць гульню\n(вы таксама атрымаеце ${YOU_COUNT} квіткоў за кожнага сябра)", "earnTicketsForRecommendingText": "Падзяліцеся гульнёй, \nкаб атрымаць квіткі.", "emailItText": "Паслаць", "favoritesSaveText": "Захаваць як абранае", "favoritesText": "Абранае", - "freeCloudServerAvailableMinutesText": "Наступны бясплатны воблачны сервер будзе абноўлены праз ${MINUTES} мінут", + "freeCloudServerAvailableMinutesText": "Наступны дармовы воблачны сервер даступны праз ${MINUTES} хвілін.", "freeCloudServerAvailableNowText": "Бясплатны воблачны сервер абнавіўся!", "freeCloudServerNotAvailableText": "Бясплатных воблачных сервераў няма.", "friendHasSentPromoCodeText": "${COUNT} квіткоў ${APP_NAME} ад ${NAME}", "friendPromoCodeAwardText": "Вы атрымаеце ${COUNT} квіткоў кожны раз, калі ён будзе выкарыстаны.", "friendPromoCodeExpireText": "Код дзейнічае ${EXPIRE_HOURS} гадзін(ы) і працуе толькі для новых гульцоў.", "friendPromoCodeInfoText": "Ён можа быць абменены на ${COUNT} квіткоў.\n\nЗайдзіце ў \"Налады->Дадатковыя->Увесці прома-код\", каб скарыстацца ім.\nНаведайце bombsquadgame.com, каб зладаваць гульню на любую платформу, якая падтрымліваецца.\nГэты код мінае праз ${EXPIRE_HOURS} гадзін(ы)(а) і ён дзейнічае толькі для новых гульцоў.", - "friendPromoCodeInstructionsText": "Каб выкарыстоўваць яго, адкрыйце ${APP_NAME} і перайдзіце ў раздзел \"Налады-> Дадатковыя-> Увесці код\".\nГлядзіце bombsquadgame.com для спасылкі на загрузку ўсіх падтрымліваемых платформаў.", + "friendPromoCodeInstructionsText": "Каб выкарыстаць яго, адкрыйце ${APP_NAME} і перайдзіце ў раздзел \"Налады-> Дадатковыя->Даслаць інфармацыю\".\nГлядзіце bombsquadgame.com каб знайсці спасылкі на спампоўку для ўсіх платформаў, што падтрымліваюцца.", "friendPromoCodeRedeemLongText": "Ён можа быць абменены на ${COUNT} квіткоў максімум ${MAX_USES} гульцамі.", "friendPromoCodeRedeemShortText": "Ён можа быць абменены на ${COUNT} квіткоў у гульні.", - "friendPromoCodeWhereToEnterText": "(у раздзеле \"Налады->Дадатковыя->Увядзіце код\")", + "friendPromoCodeWhereToEnterText": "(у раздзеле \"Налады->Дадатковыя->Даслаць інфармацыю\")", "getFriendInviteCodeText": "Атрымаць Код для Сяброў", "googlePlayDescriptionText": "Запрасіце гульцоў з Google Play у вашае лоббі.", "googlePlayInviteText": "Запрасіць", @@ -738,6 +779,7 @@ "manualYourLocalAddressText": "Ваш лакальны адрас:", "nearbyText": "Побач", "noConnectionText": "<няма злучэння>", + "noPartiesAddedText": "Партыі не дададзены", "otherVersionsText": "(іншыя версіі)", "partyCodeText": "Код вечарыны", "partyInviteAcceptText": "Згадзіцца", @@ -768,7 +810,7 @@ "showMyAddressText": "Паказаць мой адрас", "startHostingPaidText": "Арганізаваць зараз за ${COST}", "startHostingText": "Арганізаваць", - "startStopHostingMinutesText": "Вы можаце пачаць і спыніць хостынг бясплатна на працягу наступных ${MINUTES} мінут.", + "startStopHostingMinutesText": "Вы можаце запускаць і спыняць хостынг задарма цягам наступных ${MINUTES} хвілін.", "stopHostingText": "Спыніць хостынг", "titleText": "Сабраць", "wifiDirectDescriptionBottomText": "Калі ўсе прылады падтрымліваюць 'Wi-Fi Direct', яны могуць карыстацца ім, каб падключыцца\nадзін да другога. Калі ўсе прылады падключаны, вы можаце ствараць лоббі, карыстаючыся\nўкладкай \"Лакальная сетка\" так жа, як і з звычайнай WiFi сеткай.\n\nДля лепшых вынікаў хост Wi-Fi Direct павінен таксама быць хостам гульні ${APP_NAME}.", @@ -793,7 +835,7 @@ "ticketPack4Text": "Вельмі Вялікі Пакет Квіткоў", "ticketPack5Text": "Гіганцкі Пакет Квіткоў", "ticketPack6Text": "Максімальны Пакет Квіткоў", - "ticketsFromASponsorText": "Атрымаць ${COUNT} квіткоў\nад спонсара", + "ticketsFromASponsorText": "Пагледзце Рэкламу і \nатрымайце ${COUNT} Квіткоў", "ticketsText": "${COUNT} Квіткоў", "titleText": "Атрымаць Квіткі", "unavailableLinkAccountText": "Прабачце, пакупкі недаступныя на гэтай платформе.\nВы можаце злучыць гэты акаўнт з іншым акаўнтам на\nіншайплатформе і рабіць пакупкі на ім.", @@ -803,16 +845,26 @@ "youHaveShortText": "вы маеце ${COUNT}", "youHaveText": "вы маеце ${COUNT} квіткоў" }, + "goldPass": { + "desc1InfTokensText": "Бясконцыя жэтоны.", + "desc2NoAdsText": "Без рэкламы.", + "desc3ForeverText": "Назаўсёды.", + "goldPassText": "Залатой пропуск" + }, "googleMultiplayerDiscontinuedText": "Прабачце, мультігульны сервіс Гугл не даступны у гэты час.\nЯ клапачуся над гэтым з усёй скорасцю.\n\nДа таго часу, калі ласка паспрабуйце другое падключэнне", + "googlePlayPurchasesNotAvailableText": "Пакупкі ў Google Play недаступныя.\nМагчыма, вам патрэбна абнавіць прыкладанне крамы.", + "googlePlayServicesNotAvailableText": "Сэрвісы Google Play недаступныя.\nНекаторыя функцыі прыкладання могуць быць адключаныя.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Заўсёды", "fullScreenCmdText": "Поўнаэкранны (Сmd-F)", "fullScreenCtrlText": "Поўнаэкранны (Ctrl-F)", + "fullScreenText": "На ўвесь экран", "gammaText": "Гама", "highText": "Высокае", "higherText": "Найвышэйшае", "lowText": "Нізкае", + "maxFPSText": "Самы высокі FPS", "mediumText": "Сярэдняе", "neverText": "Ніколі", "resolutionText": "Дазвол", @@ -873,6 +925,7 @@ "importText": "імпарт", "importingText": "Імпартырую...", "inGameClippedNameText": "У гульне будзе\n\"${NAME}\"", + "inboxText": "Уваходныя", "installDiskSpaceErrorText": "ПАМЫЛКА: Немагчыма закончыць усталёўку.\nХутчэй за ўсё, у вас на прыладзе закончылася \nмесца. Вызваліце нямнога і паспрабуйце яшчэ раз.", "internal": { "arrowsToExitListText": "націсніце ${LEFT} ці ${RIGHT}, каб закрыць спіс", @@ -927,12 +980,14 @@ "timeOutText": "(засталося ${TIME} секунд(ы))", "touchScreenJoinWarningText": "Вы зайшлі з сэнсарным экранам.\nКалі гэта была памылка, націсніце 'Меню -> Пакінуць Гульню'.", "touchScreenText": "Сэнсарны Экран", + "unableToCompleteTryAgainText": "Немагчыма гэта выпаўніць цяпер.\nПаспрабуйце яшчэ.", "unableToResolveHostText": "Памылка: немагчыма знайсцi хост.", "unavailableNoConnectionText": "Зараз гэта недаступна (няма інтэрнэт-злучэння?)", "vrOrientationResetCardboardText": "Скарыстайцеся гэтым, каб скінуць VR арыентацыю.\nКаб гуляць, вам спатрэбіцца знешні кантролер.", "vrOrientationResetText": "Скідванне арыентацыі VR.", "willTimeOutText": "(час скончыцца пры прастоі)" }, + "inventoryText": "Інвентар", "jumpBoldText": "ПРЫГАЙЦЕ!", "jumpText": "Прыгайце", "keepText": "Захаваць", @@ -976,11 +1031,14 @@ "seasonEndedDaysAgoText": "Сезон скончыўся ${NUMBER} дзён таму.", "seasonEndsDaysText": "Сезон скончыцца праз ${NUMBER} дзён.", "seasonEndsHoursText": "Сезон скончыцца праз ${NUMBER} гадзін.", - "seasonEndsMinutesText": "Сезон скончыцца праз ${NUMBER} мінут.", + "seasonEndsMinutesText": "Сезон скончыцца праз ${NUMBER} хвілін.", "seasonText": "Сезон ${NUMBER}", "tournamentLeagueText": "Вы павінны дасягнуць ${NAME} лігі, каб увайсці ў гэты турнір.", - "trophyCountsResetText": "Трафейныя ачкі знікнуць у наступным сезоне." + "trophyCountsResetText": "Трафейныя ачкі знікнуць у наступным сезоне.", + "upToDateBonusDescriptionText": "Гульцы з актуальнай версіяй гульні\n атрымліваюць ${PERCENT}% бонус тут.", + "upToDateBonusText": "Актуальны Бонус" }, + "learnMoreText": "Прачытайце больше", "levelBestScoresText": "Лепшыя вынікі на ўзроўні ${LEVEL}", "levelBestTimesText": "Лепшы час на ўзроўні ${LEVEL}", "levelFastestTimesText": "Самы хуткі на уроўні ${LEVEL}", @@ -1002,6 +1060,7 @@ "creditsText": "Падзякі", "demoMenuText": "Дэма-Меню", "endGameText": "Скончыць Гульню", + "endTestText": "Тэст пакончаны", "exitGameText": "Зачыніць Гульню", "exitToMenuText": "Выйсці ў меню?", "howToPlayText": "Як Гуляць", @@ -1021,9 +1080,12 @@ "maxConnectionsText": "Максімальная колькасць падключэнняў.", "maxPartySizeText": "Максімальны памер групы.", "maxPlayersText": "Максімальная колькасць гульцоў.", + "merchText": "Мэрч! (Кастам!)", "modeArcadeText": "Аркадны рэжым.", "modeClassicText": "Класічны рэжым.", "modeDemoText": "Дэмо рэжым", + "moreSoonText": "Скора будзе больш...", + "mostDestroyedPlayerText": "Самы Пабіты Гулец", "mostValuablePlayerText": "Самы Карысны Гулец", "mostViolatedPlayerText": "Самы Збіты Гулец", "mostViolentPlayerText": "Самы Жорсткі Гулец", @@ -1040,6 +1102,7 @@ "nameSuicideText": "${NAME} скончыў жыццё самагубствам.", "nameText": "Імя", "nativeText": "Родны", + "newExclaimText": "Новае!", "newPersonalBestText": "Новы асабісты рэкорд!", "newTestBuildAvailableText": "Новая тэставая зборка даступна! (${VERSION} build ${BUILD}).\nАтрымайце яе на ${ADDRESS}", "newText": "Новы", @@ -1050,24 +1113,32 @@ "noContinuesText": "(без працягу)", "noExternalStorageErrorText": "Знешняя памяць не знойдзена", "noGameCircleText": "Памылка: вы не ўвайшлі ў GameCircle", + "noMessagesText": "Няма паведамленняў.", + "noPluginsInstalledText": "Убудовы не ўстаноўлены", "noProfilesErrorText": "У вас няма ніводнага профіля, таму вас будуць называць '${NAME}'.\nЗайдзіце ў \"Налады -> Профілі\", каб стварыць уласны профіль.", "noScoresYetText": "Вынікаў пакуль няма.", + "noServersFoundText": "Серверы не знойдзены.", "noThanksText": "Не, дзякуй", "noTournamentsInTestBuildText": "УВАГА: Ацэнкі турніраў з гэтай тэставай зборкі будуць ігнаравацца.", "noValidMapsErrorText": "Не знойдзена мап для гэтага тыпу гульні.", "notEnoughPlayersRemainingText": "Засталося вельмі мала гульцоў; пачніце новую гульню.", "notEnoughPlayersText": "Вам патрэбна не менш за ${COUNT} гульцоў, каб пачаць!", + "notEnoughTicketsText": "Не дастаткова квіткоў!", "notNowText": "Не Зараз", "notSignedInErrorText": "Вы павінны ўвайсці, каб выканаць гэта.", "notSignedInGooglePlayErrorText": "Вы павінны ўвайсці з Google Play, каб выканаць гэта.", "notSignedInText": "не ўвайшлі", + "notUsingAccountText": "Заўвага: Ігнараванне улiковага запiсу ${SERVICE}.\nПерайдзіце ў «Уліковы запіс -> Увайсці з дапамогай ${SERVICE}», калі вы жадаеце яго выкарыстоўваць.", "nothingIsSelectedErrorText": "Нічога не выбрана!", "numberText": "№${NUMBER}", "offText": "Выключана", "okText": "Так", "onText": "Уключана", - "oneMomentText": "Адну мінуту...", + "oneMomentText": "Адзін момант...", "onslaughtRespawnText": "${PLAYER} з'явіцца ў ${WAVE} хвалі", + "openMeText": "Адчыні Мяне!", + "openNowText": "Адчыніць Зараз", + "openText": "Адчыніць", "orText": "${A} ці ${B}", "otherText": "Іншае...", "outOfText": "(#${RANK} з ${ALL})", @@ -1117,7 +1188,14 @@ "playlistsText": "Плэйлісты", "pleaseRateText": "Калі вам падабаецца ${APP_NAME}, калі ласка, знайдзіце\nчас, каб ацаніць яго ці напісаць водгук. Гэта забя-\nспечвае сувязь і дапамагае развіццю гульні.\n\nДзякуй!\n-Эрык", "pleaseWaitText": "Калі ласка пачакай...", - "pluginsDetectedText": "Выяўлены новыя ўбудовы. Уключыце / наладзьце іх у наладах.", + "pluginClassLoadErrorText": "Памылка пры загрузцы класа падключанага модулю \"${PLUGIN}\": ${ERROR}", + "pluginInitErrorText": "Памылка пры ініцыялізацыі плагіна \"${PLUGIN}\": ${ERROR}", + "pluginSettingsText": "Устаноўкі Плагінаў", + "pluginsAutoEnableNewText": "Аўтаматычнае ўключэнне новых плагінаў", + "pluginsDetectedText": "Выяўлены новыя плагiны. Перазапусціце, каб выкарыстоўваць іх, або наладзьце іх у наладах", + "pluginsDisableAllText": "Адключыць усе плагіны", + "pluginsEnableAllText": "Выбраць усе плагіны", + "pluginsRemovedText": "${NUM} Плагін(аў) Няма.", "pluginsText": "Убудовы", "practiceText": "Практыка", "pressAnyButtonPlayAgainText": "Націсніце любую кнопку, каб перазапусціць...", @@ -1147,6 +1225,8 @@ "punchText": "Ударыць", "purchaseForText": "Набыць за ${PRICE}", "purchaseGameText": "Набыць Гульню", + "purchaseNeverAvailableText": "На жаль, пакупкі недаступныя для гэтай зборкі.\nПаспрабуйце ўвайсці ў свой уліковы запіс на іншай платформе і рабіць пакупкі адтуль.", + "purchaseNotAvailableText": "Гэта купля не даступная.", "purchasingText": "Набыццё...", "quitGameText": "Зачыніць ${APP_NAME}?", "quittingIn5SecondsText": "Выхад праз 5 секунд...", @@ -1188,6 +1268,7 @@ "version_mismatch": "Старая версія.\nПераканайцеся, што вы маеце апошнія версіі\nBombSquad і BombSquad Remote." }, "removeInGameAdsText": "Купіце \"${PRO}\" у магазіне, каб выдаліць рэкламу.", + "removeInGameAdsTokenPurchaseText": "ЧАСОВАЯ ПРАПАНОВА: Купіце ЛЮБЫ пакет токенаў, каб выдаліць рэкламу ў гульні.", "renameText": "Перайменаваць", "replayEndText": "Закончыць Запіс", "replayNameDefaultText": "Запіс Апошняй Гульні", @@ -1208,7 +1289,9 @@ "revertText": "Аднавіць", "runText": "Бяжаць", "saveText": "Захаваць", - "scanScriptsErrorText": "Памылкі пры сканаванні сцэнарыяў; падрабязнасці глядзіце ў логах.", + "scanScriptsErrorText": "Памылкі пры сканаванні плагiнаў. Падрабязнасці глядзіце ў логах.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} і ${NUM} іншых модуляў патрэбна абнавіць для API ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} патрэбна абнавіць для API ${API}.", "scoreChallengesText": "Іншыя Вынікі", "scoreListUnavailableText": "Вынікі недаступны.", "scoreText": "Ачкі", @@ -1219,6 +1302,7 @@ }, "scoreWasText": "(быў ${COUNT})", "selectText": "Выбраць", + "sendInfoDescriptionText": "Адпраўляе інфармацыю пра стан акаўнта і дадатку распрацоўшчыку.\nКалі ласка, пакіньце сваё імя ці прычыну адпраўкі.", "seriesWinLine1PlayerText": "ПЕРАМАГАЕ Ў", "seriesWinLine1TeamText": "ПЕРАМАГАЮЦЬ У", "seriesWinLine1Text": "ПЕРАМАГАЕ Ў", @@ -1237,6 +1321,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(простая, зручная для кантролера клавіятура для рэдагавання тэксту)", "alwaysUseInternalKeyboardText": "Заўсёды карыстацца ўбудаванай клавіятурай", "benchmarksText": "Тэст Прадукцыйнасці і Тэст-Нагрузка", + "devToolsText": "Інструменты распрацоўшчыка", "disableCameraGyroscopeMotionText": "Адключыць рух гіраскопа камеры", "disableCameraShakeText": "Адключыць устрэсванне камеры", "disableThisNotice": "(вы можаце адключыць гэта апавяшчэнне ў дадатковых наладах)", @@ -1245,14 +1330,22 @@ "enterPromoCodeText": "Увесці код", "forTestingText": "Гэтыя значэнні выкарыстоўваюцца толькі для тэстаў і будуць згублены пры закрыцці гульні.", "helpTranslateText": "Пераклад ${APP_NAME} з англійскай мовы - намаганне супольнасці\nпадтрымкі. Калі вы жадаеце выправіць пераклад,\nпрайдзіце па спасылцы ніжэй. Дзякуй!", + "insecureConnectionsDescriptionText": "не рэкамендуецца, але можа дазволіць онлайн гульню\nз абмежаваных краін або сетак", + "insecureConnectionsText": "Выкарыстоўвайце небяспечныя злучэнні", "kickIdlePlayersText": "Выкідваць гульцоў, якія не дзейнічаюць", "kidFriendlyModeText": "Дзіцячы Рэжым (менш гвалту і г.д.)", "languageText": "Мова", "moddingGuideText": "Кіраўніцтва па Модынгу", + "moddingToolsText": "Прылады Для Модынгу", "mustRestartText": "Вы павінны перазагрузіць гульню, каб прымяніць новыя налады.", "netTestingText": "Тэсціраванне Сеткі", "resetText": "Скінуць", + "sendInfoText": "Даслаць інфармацыю", "showBombTrajectoriesText": "Паказваць Траекторыi Бомб", + "showDemosWhenIdleText": "Паказваць дэма ў рэжыме чакання", + "showDeprecatedLoginTypesText": "Паказаць састарэлыя тыпы ўваходу", + "showDevConsoleButtonText": "Паказаць кнопку кансолі распрацоўшчыка", + "showInGamePingText": "Паказваць пінг гульні", "showPlayerNamesText": "Паказваць Імёны Гульцоў", "showUserModsText": "Паказаць Тэчку З Модамі", "titleText": "Дадаткова", @@ -1260,7 +1353,7 @@ "translationFetchErrorText": "статус перакладу недаступны", "translationFetchingStatusText": "праверка статуса перакладу...", "translationInformMe": "Паведаміце мне, калі мая мова мае патрэбу ў абнаўленнях", - "translationNoUpdateNeededText": "гэтая мова абноўлена; ура!", + "translationNoUpdateNeededText": "Бягучая мова актуальная; Ура!", "translationUpdateNeededText": "** гэтая мова патрабуе абнаўлення!! **", "vrTestingText": "VR Тэстіраванне" }, @@ -1271,6 +1364,9 @@ "signInWithGameCenterText": "Каб карыстацца акаўнтам Game Centerб\nувайдзіце з дапамогаю прыкладання Game Center.", "singleGamePlaylistNameText": "Толькі ${GAME}", "singlePlayerCountText": "1 гулец", + "sizeLargeText": "Вялікі", + "sizeMediumText": "Сярэдні", + "sizeSmallText": "Маленькі", "soloNameFilterText": "Сола ${NAME}", "soundtrackTypeNames": { "CharSelect": "Выбар Героя", @@ -1296,6 +1392,7 @@ }, "spaceKeyText": "прабел", "statsText": "Статыстыка", + "stopRemindingMeText": "Перастаньце нагадваць мне", "storagePermissionAccessText": "Для гэтага неабходны доступ да сховішча", "store": { "alreadyOwnText": "У вас ужо ёсць ${NAME}!", @@ -1346,6 +1443,8 @@ "storeText": "Крама", "submitText": "Адправіць", "submittingPromoCodeText": "Адпраўка кода...", + "successText": "Паспяхова!", + "supportEmailText": "Калі ў вас узніклі праблемы з\nпрыкладаннем, калі ласка, напішыце ${EMAIL}.", "teamNamesColorText": "Назвы / колеры каманд ...", "telnetAccessGrantedText": "Доступ Telnet уключаны.", "telnetAccessText": "Знойдзены доступ Telnet, дазволіць?", @@ -1355,24 +1454,40 @@ "testBuildValidatedText": "Тэставая Зборка Праверана; Поспехаў!", "thankYouText": "Дзякуй за вашу падтрымку! Прыемнай гульні!!", "threeKillText": "ТРЫ ЗАБОЙСТВЫ!!", + "ticketsDescriptionText": "Білеты выкарыстоўвацца каб адкрыць персанажаў, карты, міні-гульні, і больш у краме.\n\nБілеты можна знайсці у куфарах атрыманных праз кампанію, турніры, і дасягненні.", "timeBonusText": "Бонус Часу", "timeElapsedText": "Прайшло Часу", "timeExpiredText": "Час Скончыўся", "timeSuffixDaysText": "${COUNT} дзён", "timeSuffixHoursText": "${COUNT} гадзін", - "timeSuffixMinutesText": "${COUNT} мінут", + "timeSuffixMinutesText": "${COUNT} хвілін", "timeSuffixSecondsText": "${COUNT} секунд", "tipText": "Парада", "titleText": "BombSquad", "titleVRText": "${ARG1}", + "tokens": { + "getTokensText": "Атрымайце жэтоны", + "notEnoughTokensText": "Не дастаткова квіткоў!", + "numTokensText": "${COUNT} Жэтоны", + "openNowDescriptionText": "У вас дастаткова жэтонаў\nадкрыць гэта зараз - вы не робіце\nтрэба пачакаць.", + "shinyNewCurrencyText": "Бліскучая новая валюта BombSquad's.", + "tokenPack1Text": "Малы набор жэтонаў", + "tokenPack2Text": "Сярэдні пакет жэтонаў", + "tokenPack3Text": "Вялікі набор жэтонаў", + "tokenPack4Text": "Велізарны набор жэтонаў", + "tokensDescriptionText": "Токены выкарыстоўвацца\nкаб паскорыць адчыненне куфараў\nі для іншых асаблівасцей.\n\nВы можаце выйграць токены ў гульні\n або купіць іх у наборах. Або купіць залаты пропуск для бясконцых токенаў і больш не слыхаць аб іх.", + "youHaveGoldPassText": "У вас ёсць залаты пропуск.\nУсе пакупкі жэтонаў бясплатныя.\nАтрымлівайце асалоду!" + }, "topFriendsText": "Топ Сяброў", "tournamentCheckingStateText": "Праверка статусу турніра; калі ласка, пачакайце...", "tournamentEndedText": "Гэты турнір скончыўся. Хутка пачнецца новы.", "tournamentEntryText": "Уваход у Турнір", + "tournamentFinalStandingsText": "Канчатковыя Месцы", "tournamentResultsRecentText": "Вынікі Нядаўніх Турніраў", "tournamentStandingsText": "Месцы ў Турніры", "tournamentText": "Турнір", "tournamentTimeExpiredText": "Час Турніра Скончыўся", + "tournamentsDisabledWorkspaceText": "Турніры адключаныя, калі працоўныя вобласці актыўныя.\nКаб зноў уключыць турніры, адключыце працоўную вобласць і перазапусціце гульню.", "tournamentsText": "Турніры", "translations": { "characterNames": { @@ -1410,12 +1525,12 @@ "${GAME} Training": "Падрыхтоўка да гульні ${GAME}", "Infinite ${GAME}": "Бясконцая ${GAME}", "Infinite Onslaught": "Бясконцая Атака", - "Infinite Runaround": "Бясконцы Манеўр", + "Infinite Runaround": "Бясконцая бегатня", "Onslaught Training": "Атака: Трэніроўка", "Pro ${GAME}": "${GAME} Профі", "Pro Football": "Футбол Профі", "Pro Onslaught": "Атака Профі", - "Pro Runaround": "Манёўр Профі", + "Pro Runaround": "Бегатня Профі", "Rookie ${GAME}": "${GAME} Лёгкі", "Rookie Football": "Футбол Лёгкі", "Rookie Onslaught": "Атака Лёгкая", @@ -1423,7 +1538,19 @@ "Uber ${GAME}": "Убер ${GAME}", "Uber Football": "Убер Футбол", "Uber Onslaught": "Убер Атака", - "Uber Runaround": "Убер Манёўр" + "Uber Runaround": "Убер Бегатня" + }, + "displayItemNames": { + "${C} Tickets": "${C} Білетаў0", + "${C} Tokens": "${C} Токенаў", + "Chest": "Куфар", + "L1 Chest": "Куфар У1", + "L2 Chest": "Куфар У2", + "L3 Chest": "Куфар У3", + "L4 Chest": "Куфар У4", + "L5 Chest": "Куфар У5", + "L6 Chest": "Куфар У6", + "Unknown Chest": "Невядомы Куфар" }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Каб перамагчы, стань абраным на некаторы час.\nКаб стаць абраным, забей мінулага абранага.", @@ -1527,7 +1654,9 @@ "Italian": "Італьянская", "Japanese": "Японская", "Korean": "Карэйская", + "Malay": "Малаі", "Persian": "Фарсі", + "PirateSpeak": "Пірацкая мова", "Polish": "Польская", "Portuguese": "Партугальская", "Romanian": "Румынская", @@ -1599,6 +1728,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Заўважана махлярства; ачкі і прызы забаронены на ${COUNT} дзён.", "Could not establish a secure connection.": "Немагчыма стварыць бяспечнае злучэнне.", "Daily maximum reached.": "Штодзённы максімум дасягнуты.", + "Daily sign-in reward": "Штодзённая ўзнагарода за ўваход", "Entering tournament...": "Уваход у турнір...", "Invalid code.": "Няправільны код.", "Invalid payment; purchase canceled.": "Несапраўдная аплата; купля адменена.", @@ -1608,11 +1738,14 @@ "Item unlocked!": "Элемент разблакаваны!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ЗВЯЗАННЕ АДМЕНАВАНА. ${ACCOUNT} змяшчае\nважныя дадзеныя, якія ЎСЕ БУДУЦЬ СТРАЧЭНЫ.\nВы можаце зрабіць спасылку ў адваротным парадку, калі хочаце\n(і замест гэтага страціць дадзеныя ГЭТАГА ўліковага запісу)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Прывязаць уліковы запіс ${ACCOUNT} к гэтаму улiковаму запiсу?\nУсе існуючыя дадзеныя на ${ACCOUNT} будуць страчаны.\nГэта не можа быць адменена. Вы ўпэўнены?", + "Longer streaks lead to better rewards.": "Больш працяглыя серыі прыводзяць да лепшых узнагарод.", "Max number of playlists reached.": "Максімальная колькасць плэйлістаў дасягнута.", "Max number of profiles reached.": "Максімальная колькасць профіляў дасягнута.", "Maximum friend code rewards reached.": "Дасягнута максімальная ўзнагарода за код сябра.", "Message is too long.": "Паведамленне занадта доўгае.", + "New tournament result!": "Новы вынік турніру!", "No servers are available. Please try again soon.": "Няма даступных сервераў. Калі ласка, паспрабуйце яшчэ раз пазней.", + "No slots available. Free a slot and try again.": "Няма ячэек. Вызваліце слот і паспрабуйце яшчэ.", "Profile \"${NAME}\" upgraded successfully.": "Профіль \"${NAME}\" палепшаны паспяхова.", "Profile could not be upgraded.": "Профіль нельга палепшыць.", "Purchase successful!": "Аб'ект набыты паспяхова!", @@ -1622,7 +1755,9 @@ "Sorry, this code has already been used.": "Прабачце, гэты код ужо выкарыстоўваўся.", "Sorry, this code has expired.": "На жаль, срок дзеяння гэтага кода ўжо скончыўся.", "Sorry, this code only works for new accounts.": "Прабачце, гэты код працуе толькі на новых акаўнтах.", + "Sorry, this has expired.": "Прабачце, гэта сапсавалася.", "Still searching for nearby servers; please try again soon.": "Працягваецца пошук бліжэйшых сервераў; калі ласка, паспрабуйце яшчэ раз пазней.", + "Streak: ${NUM} days": "Серыя: ${NUM} дзён", "Temporarily unavailable; please try again later.": "Часова недаступны; калі ласка паспрабуйце зноў пазней.", "The tournament ended before you finished.": "Турнір скончыўся перад тым, як вы закончылі.", "This account cannot be unlinked for ${NUM} days.": "Немагчыма адлучыць гэты ўліковы запіс на працягу ${NUM} дзён.", @@ -1633,31 +1768,40 @@ "Tournaments require ${VERSION} or newer": "Для турніраў патрабуецца ${VERSION} або больш позняя версія", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Адключыць ${ACCOUNT} ад гэтага ўліковага запісу?\nУсе дадзеныя на ${ACCOUNT} будуць скіданы.\n(за выключэннем дасягненняў у некаторых выпадках)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "УВАГА: на ваш уліковы запіс паступілі скаргі на ўзлом.\nБудуць забаронены ўліковыя запісы, якія будуць прызнаныя хакерскімі. Калі ласка, гуляйце сумленна.", + "Wait reduced!": "Час паменшаны!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Папярэджанне: Гэтая версія гульні абмежаваная старымі дадзенымі ўліковага запісу; некаторыя рэчы могуць адсутнічаць або быць састарэлымі.\nКалі ласка, абнавіце гульню да новай версіі, каб убачыць апошнія дадзеныя вашага ўліковага запісу.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ці жадаеце вы аб'яднаць ваш акаўнт на прыладзе з гэтым?\n\nВаш акаўнт на прыладзе - ${ACCOUNT1}\nГэты акаўнт - ${ACCOUNT2}\n\nГэта дазволіць вам сінхранізіраваць прагрэс.\nАсцярожна - гэта нельга адмяніць!", "You already own this!": "Вы ўжо маеце гэта!", "You can join in ${COUNT} seconds.": "Вы можаце далучыцца праз ${COUNT} секунд.", "You don't have enough tickets for this!": "У вас не хапае квіткоў!", "You don't own that.": "Вы не валодаеце гэтым.", "You got ${COUNT} tickets!": "Вы атрымалі ${COUNT} квіткоў!", + "You got ${COUNT} tokens!": "Вы атрымалі ${COUNT} токенаў!", "You got a ${ITEM}!": "Вы атрымалі ${ITEM}!", + "You got a chest!": "Вы атрымалі куфар!", + "You got an achievement reward!": "Вы атрымалі узнагароду дасягнення!", "You have been promoted to a new league; congratulations!": "Вас павысілі і перавялі ў іншую лігу; віншуем!", + "You lost a chest! (All your chest slots were full)": "Вы страцілі куфар! (Усе ячэйкі куфараў былі поўныя)", + "You must update the app to view this.": "Вы павінны абнавіць праграму, каб праглядзець гэта.", "You must update to a newer version of the app to do this.": "Вы павінны абнавіць гульню, каб зрабіць гэта.", "You must update to the newest version of the game to do this.": "Для гэтага неабходна абнавіць да новай версіі гульні.", "You must wait a few seconds before entering a new code.": "Пачакайце некалькі секунд, перад тым, як уводзіць новы код.", + "You placed #${RANK} in a tournament!": "Вы атрымалі #${RANK} месца ў турніры!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ваш узровень у апошнім турніры: #${RANK}. Дзякуй за гульню!", "Your account was rejected. Are you signed in?": "Ваш уліковы запіс быў адхілены. Вы ўвайшлі ў сістэму?", + "Your ad views are not registering. Ad options will be limited for a while.": "Прагляды вашай рэкламы не рэгіструюцца. Некаторы час параметры рэкламы будуць абмежаваныя.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версія гульні была мадыфікавана.\nКалі ласка, адмяніце ўсе змены і паспрабуйце яшчэ раз.", "Your friend code was used by ${ACCOUNT}": "${ACCOUNT} выкарыстаў ваш сяброўскі код" }, "settingNames": { - "1 Minute": "1 Мінута", + "1 Minute": "1 Хвіліна", "1 Second": "1 Секунда", - "10 Minutes": "10 Мінут", - "2 Minutes": "2 мінуты", + "10 Minutes": "10 Хвілін", + "2 Minutes": "2 Хвіліны", "2 Seconds": "2 Секунды", - "20 Minutes": "20 Мінут", + "20 Minutes": "20 Хвілін", "4 Seconds": "4 Секунды", - "5 Minutes": "5 Мінут", + "5 Minutes": "5 Хвілін", "8 Seconds": "8 секунд", "Allow Negative Scores": "Дазволiць Адмоўныя Вынікі", "Balance Total Lives": "Размяркоўваць Здароўе, Якое Засталося", @@ -1795,11 +1939,14 @@ "toSkipPressAnythingText": "(націсніце, каб прапусціць туторыял)" }, "twoKillText": "ДВА ЗАБОЙСТВЫ!", + "uiScaleText": "Маштаб КІ", "unavailableText": "недаступна", + "unclaimedPrizesText": "У вас незапатрабаваныя прызы!", "unconfiguredControllerDetectedText": "Невядомы кантролер знойдзены:", "unlockThisInTheStoreText": "Гэта павінна быць адкрыта ў магазіне.", "unlockThisProfilesText": "Каб стварыць больш за ${NUM} профіляў, вам трэба:", "unlockThisText": "Каб адкрыць гэта, вам патрэбна:", + "unsupportedControllerText": "На жаль, кантролер \"${NAME}\" не падтрымліваецца.", "unsupportedHardwareText": "Прабачце, ваша прылада не падтрымлівае гэтую версію гульні.", "upFirstText": "Спачатку:", "upNextText": "Далей у гульні ${COUNT}:", @@ -1807,10 +1954,15 @@ "upgradeText": "Палепшыць", "upgradeToPlayText": "Адкрыйце \"${PRO}\" у магазіне, каб гуляць у гэта.", "useDefaultText": "Вярнуць Стандартныя", + "userSystemScriptsCreateText": "Стварыць Карыстацкі Сыстэмны Сцэнар", + "userSystemScriptsDeleteText": "Выдаліць Карыстацкі Сыстэмны Сцэнар", "usesExternalControllerText": "Гэта гульня можа выкарыстоўваць знешні кантролер для кіравання.", "usingItunesText": "Выкарыстанне музычнага прыкладання для саўндтрэка ...", "usingItunesTurnRepeatAndShuffleOnText": "Калі ласка, праверце, што ператасаванне і паўтор усяго ў iTunes ўключаны. ", + "v2AccountLinkingInfoText": "Да прывязкі акаўнту V2, Нажміце 'Кіраваць акаўнтамі'.", + "v2AccountRequiredText": "Для гэтага патрабуецца ўліковы запіс V2. Абнавіце свой уліковы запіс і паўтарыце спробу.", "validatingTestBuildText": "Праверка Тэставай Зборкі...", + "viaText": "праз", "victoryText": "Перамога!", "voteDelayText": "Вы не можаце пачаць яшчэ адно галасаванне на працягу ${NUMBER} секунд", "voteInProgressText": "Галасаванне ўжо ідзе.", @@ -1842,6 +1994,7 @@ }, "waveText": "Хваля", "wellSureText": "Выдатна!", + "whatIsThisText": "Гэта што?", "wiimoteLicenseWindow": { "titleText": "DarwiinRemote Copyright" }, @@ -1860,6 +2013,8 @@ "winsPlayerText": "${NAME} Перамагае!", "winsTeamText": "${NAME} Перамагаюць!", "winsText": "${NAME} Перамагае!", + "workspaceSyncErrorText": "Памылка сінхранізацыі ${WORKSPACE}. Падрабязнасці глядзіце ў часопісе памылак.", + "workspaceSyncReuseText": "Немагчыма сінхранізаваць ${WORKSPACE}. Паўторнае выкарыстанне папярэдняй сінхранізаванай версіі.", "worldScoresUnavailableText": "Сусветныя вынікі недаступны.", "worldsBestScoresText": "Лепшыя Сусветныя Вынікі", "worldsBestTimesText": "Лепшы Сусветны Час", @@ -1872,5 +2027,6 @@ }, "yesAllowText": "Так, Дазволіць!", "yourBestScoresText": "Вашыя Лепшыя Вынікі", - "yourBestTimesText": "Ваш Лепшы Час" + "yourBestTimesText": "Ваш Лепшы Час", + "yourPrizeText": "Ваш прыз:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/chinese.json b/dist/ba_data/data/languages/chinese.json index fba406bf..0090eccf 100644 --- a/dist/ba_data/data/languages/chinese.json +++ b/dist/ba_data/data/languages/chinese.json @@ -24,16 +24,17 @@ "resetProgressText": "重置游戏进程", "setAccountName": "设置账户名称", "setAccountNameDesc": "选择要为您的帐户显示的名称。\n您可以从链接的帐户选择\n或创建唯一的自定义名称。", - "signInInfoText": "登陆以获取点券, 在线竞赛,\n并在不同设备上同步游戏进程。", + "signInInfoText": "登录以获取点券, 在线竞赛,\n并在不同设备上同步游戏进程。", "signInText": "登陆", "signInWithDeviceInfoText": "(仅适用于此设备的一个自动账户)", - "signInWithDeviceText": "用设备账户来登陆", + "signInWithDeviceText": "用设备账户来登录", "signInWithGameCircleText": "使用 Game Circle 登入", - "signInWithGooglePlayText": "用 Google Play 来登陆", + "signInWithGooglePlayText": "用 Google Play 来登录", "signInWithTestAccountInfoText": "使用设备上的其他网络帐号登录;不建议选择该项", "signInWithTestAccountText": "用测试账户来登陆", + "signInWithText": "使用 ${SERVICE} 登录", "signInWithV2InfoText": "(账户在所有平台都通用)", - "signInWithV2Text": "使用炸弹小分队账号登录", + "signInWithV2Text": "使用炸队V2账号登录", "signOutText": "登出", "signingInText": "登录中...", "signingOutText": "登出中...", @@ -42,8 +43,8 @@ "ticketsText": "点券:${COUNT}", "titleText": "账号", "unlinkAccountsInstructionsText": "选择要取消关联的帐户", - "unlinkAccountsText": "取消连结帐户", - "unlinkLegacyV1AccountsText": "取消连接旧版(V1)账户", + "unlinkAccountsText": "取关帐户", + "unlinkLegacyV1AccountsText": "取消关联旧版(V1)账户", "v2LinkInstructionsText": "扫码或使用链接来登录或注册新账户", "viaAccount": "(不可用名称 ${NAME})", "youAreLoggedInAsText": "您已登录为", @@ -64,7 +65,7 @@ "descriptionComplete": "没有使用任何炸弹就获胜了", "descriptionFull": "在${LEVEL}中不用炸弹获胜", "descriptionFullComplete": "在${LEVEL}中没用炸弹就获胜了", - "name": "拳王" + "name": "拳皇" }, "Dual Wielding": { "descriptionFull": "连接两个控制手柄(硬件或应用)", @@ -95,7 +96,7 @@ "descriptionComplete": "没有用炸弹或拳头攻击就获胜了", "descriptionFull": "在${LEVEL}中不用炸弹或拳头攻击就获胜", "descriptionFullComplete": "在${LEVEL}中没有用炸弹或拳头攻击就获胜了", - "name": "跑位是关键" + "name": "走位是关键" }, "In Control": { "descriptionFull": "连接一个控制手柄(硬件或应用)", @@ -338,6 +339,9 @@ "getMoreGamesText": "获取更多游戏模式…", "titleText": "添加比赛" }, + "addToFavoritesText": "添加到收藏", + "addedToFavoritesText": "将'${NAME}'添加到收藏", + "allText": "全部", "allowText": "允许", "alreadySignedInText": "您的账号已在其他设备登录;\n请切换账号或者退出已登录的设备,\n然后再试一次", "apiVersionErrorText": "无法加载模组${NAME};它的API版本为 ${VERSION_USED},我们需要 ${VERSION_REQUIRED}.", @@ -370,6 +374,7 @@ "chatMutedText": "聊天静音", "chatUnMuteText": "取消屏蔽消息", "choosingPlayerText": "<选择玩家>", + "codesExplainText": "开发者会提供代码来\n诊断和修复账户问题", "completeThisLevelToProceedText": "你需要先完成这一关", "completionBonusText": "完成奖励", "configControllersWindow": { @@ -450,6 +455,7 @@ "swipeText": "滑动", "titleText": "触摸屏配置" }, + "configureDeviceInSystemSettingsText": "${DEVICE} 可以在系统设置中配置捏", "configureItNowText": "立即配置?", "configureText": "配置", "connectMobileDevicesWindow": { @@ -506,14 +512,14 @@ }, "copyConfirmText": "复制到剪贴板", "copyOfText": "${NAME} 复制", - "copyText": "copy", + "copyText": "复制", "createEditPlayerText": "<创建/编辑玩家>", "createText": "创建", "creditsWindow": { "additionalAudioArtIdeasText": "添补音频、初期原图和创意:${NAME}", "additionalMusicFromText": "添补背景音乐:${NAME}", "allMyFamilyText": "帮助进行游戏测试的我的所有好友和家人", - "codingGraphicsAudioText": "编码、图像和音频:${NAME}", + "codingGraphicsAudioText": "编程、图形引擎和音频引擎:${NAME}", "languageTranslationsText": "语言翻译:", "legalText": "法律:", "publicDomainMusicViaText": "版权公有音乐:${NAME}", @@ -552,6 +558,7 @@ "demoText": "演示", "denyText": "拒绝", "deprecatedText": "已弃用", + "descriptionText": "描述", "desktopResText": "桌面分辨率", "deviceAccountUpgradeText": "紧急警告:\n你正在使用本地账户登录! (${NAME})\n此账户会在未来升级中被删除!!\n~如果想保持账号,请升级到v2账户~", "difficultyEasyText": "简单", @@ -562,6 +569,9 @@ "disableRemoteAppConnectionsText": "解除手柄应用链接", "disableXInputDescriptionText": "允许使用4个以上的控制器但可能不会正常工作", "disableXInputText": "禁用XInput", + "disabledText": "禁用", + "discordFriendsText": "这是官方Discord群的按钮,但是很可惜中国不许你用Discord\n所以来加鲨鱼QQ群902867245吧(译者注,有问题可改)", + "discordJoinText": "我就要加Discord", "doneText": "完成", "drawText": "平局", "duplicateText": "复制", @@ -579,7 +589,7 @@ "titleText": "列表编辑器" }, "editProfileWindow": { - "accountProfileInfoText": "此特殊玩家档案,\n可能含有其中一个图标:\n\n${ICONS}\n\n基于您的登录平台以显示\n相关图标。", + "accountProfileInfoText": "此特殊玩家档案,\n可能含有其中一个图标:\n\n${ICONS}\n\n基于您的登录平台以显示\n相关图标。(其中一部分可能已经绝版)", "accountProfileText": "(账户资料)", "availableText": "\"${NAME}\"可用。", "changesNotAffectText": "注意:更改不会影响已经存在的比赛角色", @@ -596,6 +606,7 @@ "localProfileText": "(本地档案)", "nameDescriptionText": "角色名称", "nameText": "名称", + "profileAlreadyExistsText": "具有该名称的配置文件已存在", "randomText": "随机", "titleEditText": "编辑档案", "titleNewText": "新建档案", @@ -631,6 +642,7 @@ "useMusicFolderText": "音乐文件夹" }, "editText": "修改", + "enabledText": "启用", "endText": "结束", "enjoyText": "尽情享用吧!", "epicDescriptionFilterText": "史诗级慢动作 ${DESCRIPTION}。", @@ -639,20 +651,20 @@ "errorDeviceTimeIncorrectText": "您设备的时间有 ${HOURS} 小时的误差。\n这会导致游戏出现问题。\n请检查您设备的时间和时区设置。", "errorOutOfDiskSpaceText": "磁盘空间不足", "errorSecureConnectionFailText": "无法建立安全的云链接,网络可能会连接失败", - "errorText": "错误", + "errorText": "啊呜,好像出错了喵...", "errorUnknownText": "未知错误", "exitGameText": "退出${APP_NAME}?", "exportSuccessText": "退出'${NAME}'", "externalStorageText": "外部存储器", "failText": "失败", - "fatalErrorText": "哎呀,有些档案遗失或损坏了。\n请尝试重新安装游戏,或者\n联系 ${EMAIL} 寻求帮助", + "fatalErrorText": "哎呀,有些文件丢失或损坏了喵~\n请尝试重新安装游戏,或者\n联系 ${EMAIL} 寻求帮助", "fileSelectorWindow": { "titleFileFolderText": "选择一个文件或文件夹", "titleFileText": "选择一个文件", "titleFolderText": "选择一个文件夹", "useThisFolderButtonText": "使用此文件夹" }, - "filterText": "过滤器", + "filterText": "搜索", "finalScoreText": "最后得分", "finalScoresText": "最后得分", "finalTimeText": "最终时间", @@ -677,7 +689,9 @@ "editText": "编辑比\n赛列表", "gameListText": "比赛列表", "newText": "新建比\n赛列表", - "showTutorialText": "显示教程", + "pointsToWinText": "获胜点数", + "seriesLengthText": "列表长度", + "showTutorialText": "播放教程", "shuffleGameOrderText": "随机比赛模式", "titleText": "自定义${TYPE}列表" }, @@ -686,8 +700,8 @@ }, "gamesToText": "${WINCOUNT}比${LOSECOUNT}", "gatherWindow": { - "aboutDescriptionLocalMultiplayerExtraText": "请记住:如果你有足够多的游戏手柄,\n派对中的任意设备可允许多个玩家同时游戏。", - "aboutDescriptionText": "使用这些选项卡来组织一场派对。\n\n通过派对,你可以和好友在不同的设备上\n一起玩游戏和比赛。\n\n使用手柄右上角的${PARTY}按钮\n来发起派对聊天和互动。\n(在菜单中时按${BUTTON})", + "aboutDescriptionLocalMultiplayerExtraText": "请记住:如果你有足够多的游戏手柄,\n那你就可以让多个玩家用手柄同时游戏。", + "aboutDescriptionText": "这个选项卡是用来联机(开派对/房间)的喵~\n\n在派对中,你可以和朋友在不同的设备上\n一起玩游戏和比赛。\n\n点击右上角的${PARTY}按钮\n来发起派对聊天和互动。\n(手柄请在菜单中时按${BUTTON})", "aboutText": "关于", "addressFetchErrorText": "<获取地址出错>", "appInviteInfoText": "邀请好友一起玩BombSquad,新玩家可获得 ${COUNT}免费点券。\n每成功邀请到一位好友,您可获得${YOU_COUNT}点券。", @@ -715,10 +729,10 @@ "friendHasSentPromoCodeText": "从 ${NAME} 中获取 ${COUNT} 张 ${APP_NAME} 点券", "friendPromoCodeAwardText": "每使用一次,你可收到${COUNT}张点券。", "friendPromoCodeExpireText": "代码将在 ${EXPIRE_HOURS} 小时后失效,代码仅适用于新玩家。", - "friendPromoCodeInstructionsText": "要使用代码,可打开 ${APP_NAME},按\"设置->高级->输入促销代码\"操作。\n所有支持平台的下载链接见 bombsquadgame.com。", + "friendPromoCodeInstructionsText": "要使用代码,可打开 ${APP_NAME},按\"设置->高级->输入兑换代码\"操作。\n要下载最新版,请访问www.bombsquad.cn", "friendPromoCodeRedeemLongText": "达到${MAX_USES}人后,就不可获得${COUNT}免费点券。(防止玩家用来作弊)", "friendPromoCodeRedeemShortText": "可在游戏中兑换${COUNT}免费点券。", - "friendPromoCodeWhereToEnterText": "(在\"设置->高级->输入促销代码\"中)", + "friendPromoCodeWhereToEnterText": "(在\"设置->高级->输入兑换代码\"中)", "getFriendInviteCodeText": "获取好友邀请码", "googlePlayDescriptionText": "邀请Google Play玩家来加入你的派对", "googlePlayInviteText": "邀请", @@ -730,10 +744,10 @@ "hostingUnavailableText": "主机不可用", "inDevelopmentWarningText": "注意:\n\n联网模式是一项新的并且还在开发特性,\n目前强烈建议所有玩家在同一个\n无线局域网下游戏。", "internetText": "在线游戏", - "inviteAFriendText": "好友还未加入该游戏?邀请他们\n一起玩,新玩家可获得${COUNT}张免费点券。", + "inviteAFriendText": "你的朋友还没下载?邀请他们\n一起玩,新玩家可获得${COUNT}张免费点券。", "inviteFriendsText": "邀请朋友", "joinPublicPartyDescriptionText": "加入一个公开派对", - "localNetworkDescriptionText": "加入一个局域网派对(通过wifi,蓝牙,etc等)", + "localNetworkDescriptionText": "加入一个局域网派对(通过wifi,蓝牙等各种方式)", "localNetworkText": "本地网络", "makePartyPrivateText": "将我的派对变成私人派对", "makePartyPublicText": "将我的派对变成公开派对", @@ -744,12 +758,13 @@ "manualJoinableFromInternetText": "是否可从互联网连接?:", "manualJoinableNoWithAsteriskText": "否*", "manualJoinableYesText": "是", - "manualRouterForwardingText": "* 若要解决此问题,请尝试将您的路由器设置为将UDP端口${PORT}转发到你的本地地址(地址一般是192.168.*.1)", + "manualRouterForwardingText": "* 若要解决此问题,请尝试将您的路由器设置为将UDP端口${PORT}转发到你的本地地址(地址一般是192.168.*.*)", "manualText": "手动", "manualYourAddressFromInternetText": "互联网地址:", "manualYourLocalAddressText": "本地地址:", "nearbyText": "附近", "noConnectionText": "<无连接>", + "noPartiesAddedText": "没有加入派对", "otherVersionsText": "(其他版本)", "partyCodeText": "派对代码", "partyInviteAcceptText": "接受", @@ -767,7 +782,7 @@ "partyStatusNotPublicText": "你的派对是私人的", "pingText": "延迟", "portText": "端口", - "privatePartyCloudDescriptionText": "私有方在专用的云服务器上运行;无需路由器配置", + "privatePartyCloudDescriptionText": "私人服务器在官方的云服务器上运行;无需路由器配置", "privatePartyHostText": "创建一个私人派对", "privatePartyJoinText": "加入一个公开派对", "privateText": "私人", @@ -781,14 +796,14 @@ "startHostingText": "创建", "startStopHostingMinutesText": "你还可以使用${MINUTES}分钟的免费服务器", "stopHostingText": "停止主机", - "titleText": "多人游戏", + "titleText": "在线游戏", "wifiDirectDescriptionBottomText": "如果所有设备都设有 Wi-Fi Direct 面板,那他们应该可以使用通过它来找到彼此,\n然后相互连接。一旦所有设备都相互连接上了,你就可以通过“本地网络”选项卡\n在此组织派对,常规的无线局域网也是一样。\n\n如要取得最佳效果,Wi-Fi Direct 创建者也应是${APP_NAME} 派对的创建者", "wifiDirectDescriptionTopText": "无需无线网络即可直接\n通过Wi-Fi Direct连接安卓设备。对于安装了Android 4.2或更高版本操作系统的设备效果更好。\n\n要使用该功能,可打开无线网络连接设置,然后在菜单中寻找'Wi-Fi Direct'。", "wifiDirectOpenWiFiSettingsText": "打开无线网络连接设置", "wifiDirectText": "Wi-Fi Direct", "worksBetweenAllPlatformsText": "(所有平台之间运作)", "worksWithGooglePlayDevicesText": "(适用于运行Google Play(安卓)版游戏的设备)", - "youHaveBeenSentAPromoCodeText": "您已送出一个 ${APP_NAME} 促销代码:" + "youHaveBeenSentAPromoCodeText": "您已送出一个 ${APP_NAME} 兑换代码:" }, "getTicketsWindow": { "freeText": "免费!", @@ -822,38 +837,40 @@ "alwaysText": "总是", "fullScreenCmdText": "全屏显示(Cmd+F)", "fullScreenCtrlText": "全屏(Ctrl-F)", + "fullScreenText": "全屏", "gammaText": "Gamma", "highText": "高", "higherText": "极高", "lowText": "低", + "maxFPSText": "最高帧数", "mediumText": "中", "neverText": "关", "resolutionText": "分辨率", - "showFPSText": "显示FPS", + "showFPSText": "显示FPS帧数", "texturesText": "材质质量", "titleText": "图像质量", - "tvBorderText": "电视边缘", + "tvBorderText": "大广角", "verticalSyncText": "垂直同步", "visualsText": "视觉" }, "helpWindow": { "bombInfoText": "炸弹\n比拳头伤害高,但也能把自己送上西天。\n给你个建议:等引线快烧完的时候\n再把炸弹扔向敌人。", - "canHelpText": "${APP_NAME}可以帮助。", + "canHelpText": "${APP_NAME}小帮助可以帮你快速入门!", "controllersInfoText": "你可以和好友在同一网络下玩${APP_NAME},或者\n如果你有足够多的手柄,那也可以在同一个设备上游戏。\n${APP_NAME}支持各种选择;你甚至可以通过免费的'${REMOTE_APP_NAME}'\n用手机作为游戏手柄。\n更多信息,请参见设置->手柄。", - "controllersInfoTextRemoteOnly": "你可以通过网络与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩", + "controllersInfoTextRemoteOnly": "你可以通过局域网与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩", "controllersText": "手柄", - "controlsSubtitleText": "你的友好的${APP_NAME}角色具有几个基本动作:", + "controlsSubtitleText": "${APP_NAME}的角色基本操作如下:", "controlsText": "控制键", "devicesInfoText": "VR版${APP_NAME}可与\n普通版本联网游戏,所以掏出你所有的手机、平板电脑\n和电脑,大玩一场吧。你甚至还可以将\n普通版本的游戏连接至VR版,\n让游戏外的人也能看你玩。", "devicesText": "设备", - "friendsGoodText": "这对你而言都是好事。和三五好友一起玩${APP_NAME}最有趣了,\n最多可以支持8个玩家一起玩,进入", + "friendsGoodText": "哎,一个人玩?那咋行!${APP_NAME}就是要人多才好玩嘛~\n最多支持8人同时游戏,如果你有魔法可以改掉限制喵~快拉你的小伙伴一起玩吧", "friendsText": "好友", - "jumpInfoText": "跳跃\n跳跃可以跳过较窄的缝隙,\n或是把炸弹扔的更远,\n或是表达你难以掩盖的喜悦之情。", - "orPunchingSomethingText": "或用拳猛击敌人,将它砸下悬崖,然后在它下落的途中用粘性炸弹炸掉它。", - "pickUpInfoText": "拾起\n你可以拾起旗子,敌人,\n还有所有没固定在地上的东西,\n然后,再扔出去吧。", + "jumpInfoText": "跳跃\n跳跃可以跳过小沟,\n或是把炸弹扔得更远,\n或是表达你难以掩盖的喜悦之情。", + "orPunchingSomethingText": "还可以用拳头攻击,或者把敌人举起来然后丢下去,或者更多好玩的...", + "pickUpInfoText": "拾起\n你可以拾起旗子,敌人,\n还有所有没固定在地上的东西,\n然后,再扔出去吧~", "powerupBombDescriptionText": "将炸弹最大投掷数量\n由一个提升为三个", "powerupBombNameText": "三连炸弹", - "powerupCurseDescriptionText": "你可能想要避开这些。\n…或者你想试试看?", + "powerupCurseDescriptionText": "最好不要接触它。\n...或者你想试试?", "powerupCurseNameText": "诅咒", "powerupHealthDescriptionText": "完全回血!\n想不到吧!", "powerupHealthNameText": "医疗包", @@ -872,8 +889,8 @@ "powerupsSubtitleText": "当然,没有道具的游戏很难通关:", "powerupsText": "道具", "punchInfoText": "拳击\n跑得越快,拳击的伤害\n越高。所以像疯子一样\n旋转跳跃吧!", - "runInfoText": "冲刺\n按任意键冲刺,如果你用手柄操作将会容易许多。\n冲刺跑的虽快,但会造成转向困难。且冲且珍惜。", - "someDaysText": "有些时候你只是想挥拳猛击某些东西,或把什么东西给炸飞。", + "runInfoText": "冲刺\n按住四个键中的一个即可冲刺,如果你用手柄可以将扳机设置为跑\n冲刺跑的虽快,但会造成转向困难。且冲且珍惜()", + "someDaysText": "当你想攻击别人时,你可以用各种炸弹", "titleText": "${APP_NAME}帮助", "toGetTheMostText": "要想最痛快地玩这个游戏,你需要:", "welcomeText": "欢迎来到${APP_NAME}!" @@ -891,7 +908,7 @@ "arrowsToExitListText": "按${LEFT}或${RIGHT}退出列表", "buttonText": "按钮", "cantKickHostError": "你不能踢房主啊喂!", - "chatBlockedText": "玩家 ${NAME} 被禁言 ${TIME} 秒.", + "chatBlockedText": "玩家 ${NAME} 被禁言 ${TIME} 秒,有话慢点说", "connectedToGameText": "加入 '${NAME}'", "connectedToPartyText": "加入${NAME}的房间!", "connectingToPartyText": "正在连接...", @@ -899,7 +916,7 @@ "connectionFailedPartyFullText": "连接出错:房间满员了…", "connectionFailedText": "连接失败。", "connectionFailedVersionMismatchText": "连接失败;创建者正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", - "connectionRejectedText": "连接被拒绝。", + "connectionRejectedText": "连接被拒绝,你有可能被踢了", "controllerConnectedText": "${CONTROLLER}已连接。", "controllerDetectedText": "检测到1个手柄。", "controllerDisconnectedText": "${CONTROLLER}断开连接。", @@ -934,14 +951,14 @@ "rejectingInviteAlreadyInPartyText": "拒绝邀请(已经在派对中)。", "serverRestartingText": "服务器自动重启中,请重新加入..", "serverShuttingDownText": "服务器正在关机…", - "signInErrorText": "登陆出错啦~", + "signInErrorText": "登录出错啦~", "signInNoConnectionText": "哎呀,无法登陆。(网络连接有故障?)", "telnetAccessDeniedText": "错误:用户未得到telnet访问授权。", "timeOutText": "(将在${TIME}秒内超出时限)", "touchScreenJoinWarningText": "您已以触摸屏方式加入。\n如果这是一个错误,点击“菜单->离开游戏菜单”。", "touchScreenText": "触摸屏", - "unableToResolveHostText": "错误:房主有问题", - "unavailableNoConnectionText": "哎呀,这个用不了呢(网络连接故障?)", + "unableToResolveHostText": "错误:请输入正确的地址", + "unavailableNoConnectionText": "哎呀,这个用不了呢(请等待连接主服务器)", "vrOrientationResetCardboardText": "重置VR定位。\n您需使用外部手柄来玩该游戏。", "vrOrientationResetText": "VR定位重置。", "willTimeOutText": "(若空闲则会超出时限)" @@ -963,7 +980,7 @@ "kickVoteStartedText": "踢出${NAME}的投票已被发起", "kickVoteText": "投票踢出玩家", "kickVotingDisabledText": "投票踢出已被禁用.", - "kickWithChatText": "在聊天框中输入 ${YES} 来同意,输入 ${NO} 来拒绝(输入2来弃权)", + "kickWithChatText": "在聊天框中输入 ${YES} 来同意,输入 ${NO} 来拒绝", "killsTallyText": "${COUNT}次击杀", "killsText": "击杀数", "kioskWindow": { @@ -1018,10 +1035,10 @@ "endTestText": "结束测试", "exitGameText": "退出", "exitToMenuText": "退出到菜单", - "howToPlayText": "帮助", + "howToPlayText": "小帮助", "justPlayerText": "(仅${NAME})", "leaveGameText": "离开游戏", - "leavePartyConfirmText": "确实要离开吗?", + "leavePartyConfirmText": "你确定要离开?", "leavePartyText": "离开派对", "quitText": "离开游戏", "resumeText": "回到游戏", @@ -1033,7 +1050,7 @@ "mapSelectTitleText": "${GAME}地图", "mapText": "地图", "maxConnectionsText": "最大连接数", - "maxPartySizeText": "最大派对规模", + "maxPartySizeText": "最大派对人数", "maxPlayersText": "最多人数", "merchText": "来买周边吧~", "modeArcadeText": "街机模式", @@ -1047,7 +1064,7 @@ "multiPlayerCountText": "${COUNT}名玩家", "mustInviteFriendsText": "注意:你必须在“${GATHER}”面板中邀请好友,\n或连接多个\n手柄,和好友一起游戏。", "nameBetrayedText": "${NAME}背叛了${VICTIM}", - "nameDiedText": "${NAME}挂了。", + "nameDiedText": "${NAME}寄了", "nameKilledText": "${NAME}把${VICTIM}杀了", "nameNotEmptyText": "名字不能为空", "nameScoresText": "${NAME}得分咯!", @@ -1056,7 +1073,7 @@ "nameText": "名称", "nativeText": "本机", "newPersonalBestText": "新个人记录!", - "newTestBuildAvailableText": "更新的测试版可供下载了!(${VERSION}生成${BUILD})。\n到${ADDRESS}获取", + "newTestBuildAvailableText": "更新的测试版可供下载了!(${VERSION} build${BUILD})。\n到${ADDRESS}获取吧!", "newText": "新建", "newVersionAvailableText": "更新版本的 ${APP_NAME} 可供下载了! 版本号(${VERSION})", "nextAchievementsText": "下一个成就:", @@ -1065,8 +1082,10 @@ "noContinuesText": "(无可继续)", "noExternalStorageErrorText": "该设备上未发现外部存储器", "noGameCircleText": "错误:未登入GameCircle", + "noPluginsInstalledText": "没有安装插件", "noProfilesErrorText": "您没有玩家档案,所以还得忍受“${NAME}”这个名字。\n进入设置->玩家档案,为自己创建档案。", "noScoresYetText": "还未有得分记录。", + "noServersFoundText": "未找到服务器", "noThanksText": "不,谢谢", "noTournamentsInTestBuildText": "温馨提示:测试版的锦标赛分数不能计入锦标赛哦!", "noValidMapsErrorText": "该比赛类型中未发现有效地图。", @@ -1137,8 +1156,8 @@ "pleaseRateText": "如果你喜欢 ${APP_NAME},请考虑花一点时间\n来评价一下它或为它写一篇评论。这将为我们提供\n有用的反馈建议,为游戏的未来开发给予支持。\n\n感谢您!\n-eric", "pleaseWaitText": "请稍等...", "pluginClassLoadErrorText": "加载'${PLUGIN}'插件时出错了耶: ${ERROR}", - "pluginInitErrorText": "初始化'${PLUGIN}'插件失败了啦: ${ERROR}", - "pluginSettingsText": "插件设置喵", + "pluginInitErrorText": "初始化'${PLUGIN}'插件失败了: ${ERROR}", + "pluginSettingsText": "插件设置", "pluginsAutoEnableNewText": "自动启用新插件", "pluginsDetectedText": "新插件安装成功,请重启游戏或在设置中设置它们~", "pluginsDisableAllText": "禁用所有插件", @@ -1176,7 +1195,7 @@ "purchasingText": "正在购买…", "quitGameText": "退出${APP_NAME}?", "quittingIn5SecondsText": "在5秒后退出...", - "randomPlayerNamesText": "企鹅王,企鹅骑士团成员,王♂の传人,挨揍使我快乐,ChineseBomber,一拳超人,二营长の意大利炮,野渡无人舟自横,马克斯,雪糕,炸鸡翅,手柄玩家18子,寻找宝藏的海盗,炸弹投手,炸弹不是糖果,我是对面的,万有引力,鸟语花香,狗年大吉,小狗狗,大狗子,二狗子,三狗子,四狗子,五狗子,高质量人类,吴签,菜虚困,劈我瓜是吧,是我dio哒,亚达哟,王雷卖鱼,蕉♂个朋友,小猪配齐,摇摆羊,可莉,胡桃,钟离,七七,刻晴,甘雨,巴巴托斯,温迪,旅行者,绿坝娘,哔哩哔哩,别闹我有药", + "randomPlayerNamesText": "企鹅王,企鹅骑士团成员,王♂の传人,挨揍使我快乐,ChineseBomber,一拳超人,二营长の意大利炮,野渡无人舟自横,马克斯,雪糕,炸鸡翅,手柄玩家18子,寻找宝藏的海盗,炸弹投手,炸弹不是糖果,我是对面的,万有引力,鸟语花香,兔年大吉,小狗狗,大狗子,二狗子,三狗子,四狗子,五狗子,高质量人类,吴签,菜虚困,劈我瓜是吧,是我dio哒,亚达哟,王雷卖鱼,蕉♂个朋友,小猪配齐,陈星宇批发商,蒙飞批发商,蒙腾批发商,渴望被怜爱的弱受杰瑞,汤姆猫,小灰机,炸弹大队队长,炸弹教主", "randomText": "随机", "rankText": "排行", "ratingText": "排名", @@ -1234,7 +1253,9 @@ "revertText": "还原", "runText": "运行", "saveText": "保存", - "scanScriptsErrorText": "扫描脚本存在一个或多个错误;查看错误日志来了解详情。", + "scanScriptsErrorText": "检查Mod文件时发现错误,报错见炸队日志文件喵", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 和 ${NUM} 个模组需要升级到API${API}才能使用喵~", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} 需要升级到API${API}才能使用喵~", "scoreChallengesText": "得分挑战", "scoreListUnavailableText": "得分列表不可用。", "scoreText": "得分", @@ -1245,10 +1266,11 @@ }, "scoreWasText": "(是${COUNT})", "selectText": "选择", - "seriesWinLine1PlayerText": "赢得", - "seriesWinLine1TeamText": "赢得", - "seriesWinLine1Text": "赢得", - "seriesWinLine2Text": "系列!", + "sendInfoDescriptionText": "向开发者发送账户和应用状态信息\n清附上您的姓名和寄送原因", + "seriesWinLine1PlayerText": "获得", + "seriesWinLine1TeamText": "获得", + "seriesWinLine1Text": "获得", + "seriesWinLine2Text": "冠军!", "settingsWindow": { "accountText": "账户", "advancedText": "高级", @@ -1268,27 +1290,31 @@ "disableThisNotice": "(可在高级设置中关闭此通知)", "enablePackageModsDescriptionText": "(启用额外的模组功能,但是禁用多人模式)", "enablePackageModsText": "启用本地程序包修改", - "enterPromoCodeText": "输入促销代码", + "enterPromoCodeText": "输入兑换代码喵~", "forTestingText": "注意:这些数值仅用于测试,并会在应用程序退出时丢失。", - "helpTranslateText": "${APP_NAME}的非英语翻译是社区\n共同努力的成果。如果您希望参与翻译或对其提出更正,\n请点击以下链接。先行感谢!", + "helpTranslateText": "${APP_NAME}有中文汉化是咱们社区\n共同努力的成果。如果您希望参与翻译或对其提出更正,\n请点击这个按钮。十分感谢!", "kickIdlePlayersText": "踢掉空闲玩家", "kidFriendlyModeText": "儿童友好模式(低暴力等)", "languageText": "语言", - "moddingGuideText": "修改指南", + "moddingGuideText": "Mod文档", + "moddingToolsText": "Mod工具", "mustRestartText": "您必须重启游戏来使之生效", "netTestingText": "网络测试", "resetText": "恢复默认值", + "sendInfoText": "发送消息", "showBombTrajectoriesText": "显示炸弹轨迹", + "showDemosWhenIdleText": "当游戏空闲时播放演示画面", + "showDevConsoleButtonText": "显示开发者控制台按钮", "showInGamePingText": "显示游戏延迟", "showPlayerNamesText": "显示玩家名字", - "showUserModsText": "显示修改文件夹", + "showUserModsText": "显示Mod文件夹", "titleText": "高级", "translationEditorButtonText": "${APP_NAME}翻译编辑器", "translationFetchErrorText": "翻译状态不可用", - "translationFetchingStatusText": "检查翻译进度…", - "translationInformMe": "所选语言可更新时请通知我!", - "translationNoUpdateNeededText": "当前语言是最新的;呜呼!", - "translationUpdateNeededText": "**当前语言需要更新!! **", + "translationFetchingStatusText": "正在检查翻译进度喵…", + "translationInformMe": "中文需要更新翻译时请通知我!", + "translationNoUpdateNeededText": "当前语言是最新的;喵呜!", + "translationUpdateNeededText": "**当前语言需要更新!!**", "vrTestingText": "VR测试" }, "shareText": "分享", @@ -1298,6 +1324,9 @@ "signInWithGameCenterText": "使用游戏中心\n应用程序登录。", "singleGamePlaylistNameText": "仅${GAME}", "singlePlayerCountText": "一个玩家", + "sizeLargeText": "大", + "sizeMediumText": "中", + "sizeSmallText": "小", "soloNameFilterText": "单挑模式 ${NAME}", "soundtrackTypeNames": { "CharSelect": "角色选择", @@ -1334,7 +1363,7 @@ "charactersText": "人物", "comingSoonText": "敬请期待……", "extrasText": "额外部分", - "freeBombSquadProText": "BombSquad现在是免费的,由于最初您是通过购买所得,您将获得\nBombSquad专业版升级和${COUNT}点券,以表感谢。\n尽享全新功能,同时感谢您的支持!\n-Eric", + "freeBombSquadProText": "炸弹小分队现在是免费的,由于最初您是通过购买所得,您将获得\n炸弹小分队专业版升级和${COUNT}点券,以表感谢。\n尽享全新功能,同时感谢您的支持!\n-Eric", "gameUpgradesText": "游戏升级", "holidaySpecialText": "假期特献", "howToSwitchCharactersText": "(进入\"${SETTINGS} -> ${PLAYER_PROFILES}\"指定和自定义人物)", @@ -1361,18 +1390,20 @@ "winterSpecialText": "冬季特献", "youOwnThisText": "- 您已拥有 -" }, - "storeDescriptionText": "8人派对游戏尽显疯狂!\n\n在爆炸类迷你游戏中炸飞您的好友(或电脑),如夺旗战、冰球战及史诗级慢动作死亡竞赛!\n\n简单的控制和广泛的手柄支持可轻松允许多达8人参与游戏;您甚至可以通过免费的“BombSquad Remote”应用将您的移动设备作为手柄使用!\n\n投射炸弹!\n\n更多信息,请登录www.froemling.net/bombsquad。", + "storeDescriptionText": "8人派对游戏疯狂乱炸!\n\n在迷你型爆炸游戏炸飞你的基友(或机器人),如夺旗战、冰球战及史诗级慢动作死亡竞赛!\n\n控制简单,操作便捷,可轻松支持多达8人同时游戏;您甚至可以通过免费的“炸弹小分队手柄”应用将您的手机作为手柄使用!\n\n炸死他们吧hiahiahia!\n\n更多信息,请打开www.froemling.net/bombsquad。", "storeDescriptions": { - "blowUpYourFriendsText": "炸飞你的好友。", - "competeInMiniGamesText": "在从竞速到飞行的迷你游戏中一较高下。", - "customize2Text": "自定义角色、迷你游戏,甚至是背景音乐。", - "customizeText": "自定义角色并创建自己的迷你游戏播放列表。", - "sportsMoreFunText": "加入炸药后运动变得更加有趣。", - "teamUpAgainstComputerText": "组队对抗电脑程序。" + "blowUpYourFriendsText": "炸飞你的朋友们", + "competeInMiniGamesText": "在竞速游戏、飞行游戏中一决高下吧", + "customize2Text": "支持自定义角色、游戏玩法,甚至背景音乐", + "customizeText": "选择角色并创建自己的游戏关卡吧", + "sportsMoreFunText": "加入炸药后游戏会变得更嗨皮。", + "teamUpAgainstComputerText": "或者和机器人PK" }, "storeText": "商店", "submitText": "提交", "submittingPromoCodeText": "正在提交代码...", + "successText": "成功", + "supportEmailText": "如果你在APP遇到任何问题\n请发邮件到${EMAIL}", "teamNamesColorText": "团队名称/颜色。。。", "telnetAccessGrantedText": "Telnet访问已启用。", "telnetAccessText": "检测到Telnet访问;是否允许?", @@ -1629,26 +1660,26 @@ "Entering tournament...": "进入锦标赛……", "Invalid code.": "代码无效。", "Invalid payment; purchase canceled.": "不可用的付款方式:交易取消", - "Invalid promo code.": "促销代码无效。", + "Invalid promo code.": "诶呀,代码好像无效了捏~", "Invalid purchase.": "购买无效。", - "Invalid tournament entry; score will be ignored.": "错误的联赛资料,分数会被忽略。", + "Invalid tournament entry; score will be ignored.": "由于你的联赛资料错误,分数会被忽略...", "Item unlocked!": "项目已解除锁定!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "连接账号行为取消。${ACCOUNT} 含有\n重要数据可能会丢失。\n如果你想要的话,你可以反向链接账号。\n(那样就会丢失这个账号的数据)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "将帐户${ACCOUNT}关联到此帐户吗?\n${ACCOUNT}将共享数据。\n此操作不能撤销。", "Max number of playlists reached.": "已达到最大列表数目。", "Max number of profiles reached.": "已达到最大档案数目。", "Maximum friend code rewards reached.": "邀请码奖励达到上限", - "Message is too long.": "消息太长.", + "Message is too long.": "诶呀,消息有点长捏~有话慢慢说", "No servers are available. Please try again soon.": "当前没有空余的服务器,请稍后再试", "Profile \"${NAME}\" upgraded successfully.": "${NAME}档案升级成功。", "Profile could not be upgraded.": "档案不可升级。", "Purchase successful!": "购买成功!", - "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "登录领取${COUNT}点券。\n明日再来领取${TOMORROW_COUNT}。", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "今日登录获得${COUNT}点券\n明日再来领取${TOMORROW_COUNT}点券", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本的游戏不再支持服务器功能;\n请更新到较新版本。", "Sorry, there are no uses remaining on this code.": "对不起,此代码已经无法继续使用了。", "Sorry, this code has already been used.": "对不起,此代码已被使用。", "Sorry, this code has expired.": "对不起,此代码已失效。", - "Sorry, this code only works for new accounts.": "对不起,此代码仅适用于新账户。", + "Sorry, this code only works for new accounts.": "此代码只能新用户使用啊喂!你是新用户嘛", "Still searching for nearby servers; please try again soon.": "正在搜索附近的服务器,请稍后再试", "Temporarily unavailable; please try again later.": "目前暂不可用;请稍候再试!", "The tournament ended before you finished.": "本次锦标赛在你完成之前结束。", @@ -1658,23 +1689,23 @@ "This requires version ${VERSION} or newer.": "这需要版本${VERSION}或更高版本。", "Tournaments disabled due to rooted device.": "该设备已禁用比赛。", "Tournaments require ${VERSION} or newer": "比赛需要${VERSION}或更高版本", - "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "从此帐户取消 ${ACCOUNT} 的连结?\n${ACCOUNT}上的所有数据将被重置。\n(在某些情况下除成就外)", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "从此帐户取消 ${ACCOUNT} 的关联?\n${ACCOUNT}上的所有数据将被重置。\n(在某些情况下除成就外)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:针对您的帐户发出黑客投诉。\n被盗用的帐户将被禁止。请公平竞技。", - "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否将您的设备帐户链接到此?\n\n您的设备账户为${ACCOUNT1}\n此帐户为${ACCOUNT2}\n\n您可保存现有进度。\n警告: 此操作不可撤消!", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否将您的设备帐户关联到此?\n\n您的设备账户为${ACCOUNT1}\n此帐户为${ACCOUNT2}\n\n您可保存现有进度。\n警告: 此操作不可撤消!", "You already own this!": "你已拥有了!", "You can join in ${COUNT} seconds.": "你在${COUNT} 秒后可以加入", "You don't have enough tickets for this!": "你的点券不足!", - "You don't own that.": "你尚未拥有", + "You don't own that.": "你没有真正购买它呢..(也许你正在用破解版)", "You got ${COUNT} tickets!": "你获得了${COUNT}点券!", "You got a ${ITEM}!": "你获得了一个${ITEM}!", - "You have been promoted to a new league; congratulations!": "你已被升级至一个全新联赛;恭喜!", + "You have been promoted to a new league; congratulations!": "你已被升级至一个新联赛等级;恭喜!", "You must update to a newer version of the app to do this.": "你必须升级到最新版本才可以", "You must update to the newest version of the game to do this.": "你必须更新到最新版来做到这一点。", "You must wait a few seconds before entering a new code.": "你必须在输入新代码前稍等几秒。", "You ranked #${RANK} in the last tournament. Thanks for playing!": "你在上一场锦标赛中排名#${RANK}。多谢玩赏本游戏!", "Your account was rejected. Are you signed in?": "您的账号被拒绝。您是否已登录?", - "Your copy of the game has been modified.\nPlease revert any changes and try again.": "你的游戏副本已被更改。\n请恢复任何更改并重试。", - "Your friend code was used by ${ACCOUNT}": "${ACCOUNT}已使用您的好友代码" + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "你的游戏似乎不是原版。\n请删除Mod并使用官方最新版再重试。", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT}使用了你的分享代码了哦~" }, "settingNames": { "1 Minute": "1分钟", @@ -1709,7 +1740,7 @@ "None": "无", "Normal": "正常", "Pro Mode": "专业模式", - "Respawn Times": "重生時長", + "Respawn Times": "复活时间", "Score to Win": "得分取胜", "Short": "短", "Shorter": "更短", @@ -1731,21 +1762,21 @@ "tips": { "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "一记完美、及时的“跑跳旋转拳”可一次性击杀敌人,并\n助你一生享有好友的尊重。", "Always remember to floss.": "地面上的辅助线可能会有用。", - "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "使用首选名称和外观,而非采用随机形式\n来为自己和好友创建玩家档案。", - "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢占一个生命值包。", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "请不要总是使用系统提供的随机档案,\n你可以在账户-玩家档案里创建自己的档案喵~", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢到医疗包。", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "尽管长相不同,所有人物的技能是相同的,\n所以只需随意挑选一个与你最相似的。", "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因为拥有能量盾牌而狂妄自大;你仍然可能使自己坠入悬崖。", - "Don't run all the time. Really. You will fall off cliffs.": "不要总是奔跑。真的。你可能会坠入悬崖。", - "Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会眩晕并摔倒。", + "Don't run all the time. Really. You will fall off cliffs.": "不要一直奔跑,真的,你可能会坠入悬崖。", + "Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会傻乎乎地眩晕并摔倒。", "Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按钮来奔跑。(如果你有的话,扳机按钮将会很有用)", - "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑。你将会更快地抵达一些地方,\n但是转弯效果并不好,所以当心悬崖。", - "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "寒冰炸弹并非很厉害,但它们能够冻结\n任何被击中者,使他们极易粉碎。", - "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人将你提起,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑,比普通行走的速度会快得多。\n但是奔跑时不太好转弯,所以当心摔下悬崖。", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "冰冻炸弹伤害并不高,但它们能够冻结\n被伤到的人,然后他们身体会变得脆弱(一碰就碎)", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人把你抓起来了,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "如果您缺控制器,可以在手机安装「${REMOTE_APP_NAME}」\n然后手机就可以当作控制器啦~", "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "如果你没有手柄,请在你的iOS或Android设备上安装\n“BombSquad Remote”应用程序,并将它们作为手柄使用。", - "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。你可能\n将炸弹抖落,或如果没有其他办法,你最后的时刻将是有趣的。", - "If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍积分。", - "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个加血包。", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。炸弹\n可能被抖落,或如果没有其他办法,你最后的时刻将是有趣的。", + "If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍分数。", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个医疗包。", "If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一个地方,你就完了。为了生存而奔跑和躲避……", "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果众多玩家进进出出,在设置下打开“自动踢出闲置玩家”,以防\n任何玩家忘记离开游戏。", "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的设备过热,或者你想要节省电池电量,\n则在设置->图形中调低“视觉效果”或“分辨率”", @@ -1756,13 +1787,13 @@ "Jump just as you're throwing to get bombs up to the highest levels.": "就像你试图将炸弹扔到最高点那样跳起来。", "Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敌人的一个很好的方式。", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多东西都可以捡起来并投掷,包括其他玩家。将你的\n敌人抛下悬崖可能是一个有效的且情感上可获得满足的策略。", - "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能在岩脊上起身。你必须要投掷炸弹。", + "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能跳上塔台去。你必须要用炸弹炸死塔台上的人。", "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多数游戏中途加入或离开,\n同时,你也可以在百忙中插上或拔出手柄。", - "Practice using your momentum to throw bombs more accurately.": "练习借助你的力量更准确地投掷炸弹。", + "Practice using your momentum to throw bombs more accurately.": "多加练习,你的炸弹技能会变得更精准", "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳头跑得越快,拳击的伤害越高,\n所以请成为飞奔的拳击手吧。", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投掷炸弹之前来回跑动,\n以“鞭打”炸弹,并将其投掷更远。", "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸药箱附近引爆\n一个炸弹来消灭一群敌人。", - "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着游戏结束。", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着一个生命的结束。", "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "这一关卡永远不会结束,但是更高的得分将\n助你赢得全世界永恒的尊重。", "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投掷力量取决于你所保持的方向。\n如要向前方轻轻投掷某物,不要保持在任何方向。", "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "更换背景音乐?更换成你自己音乐吧!\n参见设置->音频->背景音乐", @@ -1822,11 +1853,13 @@ "toSkipPressAnythingText": "(点击或按下任何按钮以跳过教程)" }, "twoKillText": "双杀!", + "uiScaleText": "UI缩放", "unavailableText": "不可用", "unconfiguredControllerDetectedText": "检测到未配置的手柄:", "unlockThisInTheStoreText": "这必须在商店中解锁。", "unlockThisProfilesText": "如需创建超过 ${NUM} 个玩家档案,你需要", "unlockThisText": "你需要这些来解锁", + "unsupportedControllerText": "抱歉,游戏不兼容你的控制器\"${NAME}\"", "unsupportedHardwareText": "抱歉,此版本的游戏不支持该硬件。", "upFirstText": "进入第一局:", "upNextText": "进入比赛${COUNT}第二局:", @@ -1834,11 +1867,14 @@ "upgradeText": "升级", "upgradeToPlayText": "在游戏商店中解锁\"${PRO}\",以体验该游戏。", "useDefaultText": "使用默认值", + "userSystemScriptsCreateText": "创建用户系统脚本", + "userSystemScriptsDeleteText": "删除用户系统脚本", "usesExternalControllerText": "该游戏使用外部手柄进行输入。", "usingItunesText": "使用音乐应用设置背景音乐……", "usingItunesTurnRepeatAndShuffleOnText": "请确认iTunes中随机播放已开启且重复全部歌曲。", - "v2AccountLinkingInfoText": "要连接V2账户,请点击“管理账户”~", + "v2AccountLinkingInfoText": "要关联V2账户,请点击“管理账户”喵~", "validatingTestBuildText": "测试版验证中……", + "viaText": "渠道账户:", "victoryText": "胜利!", "voteDelayText": "${NUMBER} 秒内你不能发起另一个投票", "voteInProgressText": "已经有一个投票在进行中了", diff --git a/dist/ba_data/data/languages/chinesesimplified.json b/dist/ba_data/data/languages/chinesesimplified.json new file mode 100644 index 00000000..ac9781f0 --- /dev/null +++ b/dist/ba_data/data/languages/chinesesimplified.json @@ -0,0 +1,1980 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "账户名称不能包含Emoji表情符号或其他特殊符号!", + "accountsText": "账户", + "achievementProgressText": "完成了${TOTAL}个成就中的${COUNT}个", + "campaignProgressText": "战役进程 [困难] :${PROGRESS}", + "changeOncePerSeason": "在每个赛季中你只能更改它一次。", + "changeOncePerSeasonError": "你需要等到下个赛季才能对它再次更改 (还有${NUM}天)", + "createAnAccountText": "创建一个帐户", + "customName": "玩家姓名", + "deleteAccountText": "删除账户", + "googlePlayGamesAccountSwitchText": "如果你想登录另一个不同的谷歌账户,\n请使用 \"Play 游戏\" 来操作~", + "linkAccountsEnterCodeText": "输入代码", + "linkAccountsGenerateCodeText": "生成代码", + "linkAccountsInfoText": "(在不同的平台上同步游戏进程)", + "linkAccountsInstructionsNewText": "要关联两个帐户,首先,你需要在你第一个设备点“生成代码”\n,然后,你需要在第二个设备点“输入代码”输入第一个设备生成的代码。\n两个帐户数据将被两者共享。\n\n您最多可以关联${COUNT}个帐户。\n(包括自己的账户)\n\n重要提示:最好只关联自己的账户;\n如果你与朋友的账户关联了,那么\n你们将不能同时游玩线上模式。", + "linkAccountsText": "关联账户", + "linkedAccountsText": "已关联的账户:", + "manageAccountText": "管理账户", + "nameChangeConfirm": "是否更改账户名称为${NAME}?", + "resetProgressConfirmNoAchievementsText": "如果这样做,会重置你的单机模式的进程和\n本地的高分记录(不包括你的点券),\n还不能恢复,你确定吗?", + "resetProgressConfirmText": "如果这样做,会重置你的单机模式的进程,\n成就和本地的高分记录\n(不包括你的点券),还不能\n恢复,你确定吗?", + "resetProgressText": "重置游戏进程", + "setAccountName": "设置账户名称", + "setAccountNameDesc": "选择要为您的帐户显示的名称。\n您可以从链接的帐户选择\n或创建唯一的自定义名称。", + "signInInfoText": "登录以获取点券, 在线竞赛,\n并在不同设备上同步游戏进程。", + "signInText": "登录", + "signInWithAnEmailAddressText": "用邮箱注册", + "signInWithDeviceInfoText": "(仅适用于此设备的一个自动账户)", + "signInWithDeviceText": "用设备账户来登录", + "signInWithText": "使用 ${SERVICE} 登录", + "signInWithV2InfoText": "(账户在所有平台都通用)", + "signInWithV2Text": "使用${APP_NAME}渠道账号登录", + "signOutText": "登出", + "signingInText": "登录中...", + "signingOutText": "登出中...", + "ticketsText": "点券:${COUNT}", + "titleText": "账户", + "unlinkAccountsInstructionsText": "选择要取消关联的帐户", + "unlinkAccountsText": "取消关联账户", + "unlinkLegacyV1AccountsText": "取消关联旧版(V1)账户", + "v2LinkInstructionsText": "扫码或使用链接来登录或注册新账户", + "viaAccount": "(不可用名称 ${NAME})", + "youAreSignedInAsText": "你已登录为:" + }, + "achievementChallengesText": "成就挑战", + "achievementText": "成就", + "achievements": { + "Boom Goes the Dynamite": { + "description": "用 TNT 炸死三个坏蛋", + "descriptionComplete": "用 TNT 炸死了三个坏蛋", + "descriptionFull": "在${LEVEL}中用TNT炸死三个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用 TNT 炸死了三个坏蛋", + "name": "发威吧!TNT!" + }, + "Boxer": { + "description": "不使用任何炸弹获得胜利", + "descriptionComplete": "没有使用任何炸弹就获胜了", + "descriptionFull": "在${LEVEL}中不用炸弹获胜", + "descriptionFullComplete": "在${LEVEL}中没用炸弹就获胜了", + "name": "拳皇" + }, + "Dual Wielding": { + "descriptionFull": "连接两个控制手柄(硬件或应用)", + "descriptionFullComplete": "已经连接两个控制手柄(硬件或应用)", + "name": "成双成对" + }, + "Flawless Victory": { + "description": "毫发无损地获胜", + "descriptionComplete": "毫发无损地获胜了", + "descriptionFull": "在${LEVEL}中毫发无损地获胜", + "descriptionFullComplete": "在${LEVEL}中毫发无损地获胜了", + "name": "完美获胜" + }, + "Free Loader": { + "descriptionFull": "开始一个“混战模式”游戏(2+玩家)", + "descriptionFullComplete": "已经开始一个“混战模式”游戏(2+玩家)", + "name": "揩油的人" + }, + "Gold Miner": { + "description": "用地雷杀死6个坏蛋", + "descriptionComplete": "用地雷杀死了6个坏蛋", + "descriptionFull": "在${LEVEL}中用地雷杀死6个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用地雷杀死了6个坏蛋", + "name": "地雷专家" + }, + "Got the Moves": { + "description": "不用炸弹或拳头攻击就获胜", + "descriptionComplete": "没有用炸弹或拳头攻击就获胜了", + "descriptionFull": "在${LEVEL}中不用炸弹或拳头攻击就获胜", + "descriptionFullComplete": "在${LEVEL}中没有用炸弹或拳头攻击就获胜了", + "name": "走位是关键" + }, + "In Control": { + "descriptionFull": "连接一个控制手柄(硬件或应用)", + "descriptionFullComplete": "已经连接一个控制手柄(硬件或应用)", + "name": "掌控之中" + }, + "Last Stand God": { + "description": "得1000分", + "descriptionComplete": "得了1000分", + "descriptionFull": "在${LEVEL}中获得1000分", + "descriptionFullComplete": "在${LEVEL}中获得了1000分", + "name": "${LEVEL}之神" + }, + "Last Stand Master": { + "description": "得250分", + "descriptionComplete": "得了250分", + "descriptionFull": "在${LEVEL}中获得250分", + "descriptionFullComplete": "在${LEVEL}中获得了250分", + "name": "${LEVEL}的大师" + }, + "Last Stand Wizard": { + "description": "得了500分", + "descriptionComplete": "得了500分", + "descriptionFull": "在${LEVEL}中获得500分", + "descriptionFullComplete": "在${LEVEL}中获得了500分", + "name": "${LEVEL}的行家" + }, + "Mine Games": { + "description": "用地雷炸死3个坏蛋", + "descriptionComplete": "用地雷炸死了3个坏蛋", + "descriptionFull": "在${LEVEL}中用地雷炸死3个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用地雷炸死了3个坏蛋", + "name": "地雷战" + }, + "Off You Go Then": { + "description": "把3个坏蛋扔出地图", + "descriptionComplete": "把3个坏蛋扔出地图", + "descriptionFull": "在${LEVEL}中把3个坏蛋扔出地图", + "descriptionFullComplete": "在${LEVEL}中把3个坏蛋扔出地图", + "name": "现在到你了" + }, + "Onslaught God": { + "description": "得5000分", + "descriptionComplete": "得了5000分", + "descriptionFull": "在${LEVEL}中获得5000分", + "descriptionFullComplete": "在${LEVEL}中获得了5000分", + "name": "${LEVEL}之神" + }, + "Onslaught Master": { + "description": "得500分", + "descriptionComplete": "得了500分", + "descriptionFull": "在${LEVEL}中得500分", + "descriptionFullComplete": "在${LEVEL} 中得到500分", + "name": "${LEVEL} 专家" + }, + "Onslaught Training Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 上打败所有敌人", + "descriptionFullComplete": "在${LEVEL} 上打败了所有敌人", + "name": "${LEVEL} 胜利" + }, + "Onslaught Wizard": { + "description": "得1000分", + "descriptionComplete": "得了1000分", + "descriptionFull": "在${LEVEL} 中得1000分", + "descriptionFullComplete": "在${LEVEL} 中得到了1000分", + "name": "${LEVEL} 之圣" + }, + "Precision Bombing": { + "description": "无道具获胜", + "descriptionComplete": "无道具获胜了", + "descriptionFull": "在${LEVEL} 中无道具获胜", + "descriptionFullComplete": "在${LEVEL} 中无道具获胜了", + "name": "精确爆炸" + }, + "Pro Boxer": { + "description": "不用任何炸弹就取胜", + "descriptionComplete": "不用任何炸弹就取胜了", + "descriptionFull": "在${LEVEL} 中不用炸弹就取胜", + "descriptionFullComplete": "在${LEVEL} 中不用炸弹就取胜了", + "name": "专业拳击手" + }, + "Pro Football Shutout": { + "description": "完爆坏人队(不让坏人队得分)", + "descriptionComplete": "完爆了坏人队(不让坏人队得分)", + "descriptionFull": "在${LEVEL} 中完爆坏人队(不让坏人队得分)", + "descriptionFullComplete": "在${LEVEL} 中完爆了坏人队(不让坏人队得分)", + "name": "无懈可击的${LEVEL}" + }, + "Pro Football Victory": { + "description": "赢得比赛", + "descriptionComplete": "赢得了比赛", + "descriptionFull": "赢得${LEVEL}", + "descriptionFullComplete": "赢得了${LEVEL}", + "name": "${LEVEL} 获胜" + }, + "Pro Onslaught Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 中打败所有坏蛋", + "descriptionFullComplete": "在${LEVEL} 中打败了所有坏蛋", + "name": "${LEVEL} 获胜" + }, + "Pro Runaround Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 中打败所有坏蛋", + "descriptionFullComplete": "在${LEVEL} 中打败了所有坏蛋", + "name": "${LEVEL} 取胜" + }, + "Rookie Football Shutout": { + "description": "完爆坏人队(不让坏人队得分)", + "descriptionComplete": "完爆了坏人队", + "descriptionFull": "在${LEVEL} 中完爆坏人队", + "descriptionFullComplete": "在${LEVEL} 中完爆了坏人队", + "name": "${LEVEL} 完胜" + }, + "Rookie Football Victory": { + "description": "赢得比赛", + "descriptionComplete": "赢得了比赛", + "descriptionFull": "赢得${LEVEL}", + "descriptionFullComplete": "赢得了${LEVEL}", + "name": "${LEVEL} 获胜" + }, + "Rookie Onslaught Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 中打败所有坏蛋", + "descriptionFullComplete": "在${LEVEL} 中打败了所有坏蛋", + "name": "${LEVEL} 获胜" + }, + "Runaround God": { + "description": "得2000分", + "descriptionComplete": "得了2000分", + "descriptionFull": "在${LEVEL} 中得到2000分", + "descriptionFullComplete": "在${LEVEL} 中得到了2000分", + "name": "${LEVEL} 之神" + }, + "Runaround Master": { + "description": "得500分", + "descriptionComplete": "得了500分", + "descriptionFull": "在${LEVEL} 中得到500分", + "descriptionFullComplete": "在${LEVEL} 中得到了500分", + "name": "${LEVEL} 大师" + }, + "Runaround Wizard": { + "description": "得1000分", + "descriptionComplete": "得了1000分", + "descriptionFull": "在${LEVEL} 得到1000分", + "descriptionFullComplete": "在${LEVEL} 中得到了1000分", + "name": "${LEVEL} 之圣" + }, + "Sharing is Caring": { + "descriptionFull": "成功和一个朋友分享游戏", + "descriptionFullComplete": "已经成功和一个朋友分享游戏", + "name": "独享不如分享" + }, + "Stayin' Alive": { + "description": "一直活着赢得比赛", + "descriptionComplete": "一直活着赢得了比赛", + "descriptionFull": "在${LEVEL} 中不死赢得比赛", + "descriptionFullComplete": "在${LEVEL} 中不死赢得了比赛", + "name": "不死之身" + }, + "Super Mega Punch": { + "description": "一拳造成100%的伤害", + "descriptionComplete": "一拳造成了100%的伤害", + "descriptionFull": "一拳造成了100%的伤害", + "descriptionFullComplete": "在${LEVEL}中一拳造成了100%的伤害", + "name": "无敌大拳头" + }, + "Super Punch": { + "description": "一拳造成50%的伤害", + "descriptionComplete": "一拳造成了50%的伤害", + "descriptionFull": "在${LEVEL}中一拳造成了50%的伤害", + "descriptionFullComplete": "在${LEVEL}中一拳造成50%的伤害", + "name": "大拳头" + }, + "TNT Terror": { + "description": "用TNT炸死6个坏蛋", + "descriptionComplete": "用TNT炸死了6个坏蛋", + "descriptionFull": "在${LEVEL}中用TNT炸死6个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用TNT炸死了6个坏蛋", + "name": "恐怖TNT" + }, + "Team Player": { + "descriptionFull": "开始一个“团队”游戏(4+玩家)", + "descriptionFullComplete": "已经开始一个“团队”游戏(4+玩家)", + "name": "团队玩家" + }, + "The Great Wall": { + "description": "阻止所有坏蛋通过", + "descriptionComplete": "阻止了所有坏蛋", + "descriptionFull": "在${LEVEL}中阻止所有坏蛋通过", + "descriptionFullComplete": "在${LEVEL}中阻止了所有坏蛋", + "name": "铜墙铁壁" + }, + "The Wall": { + "description": "阻止所有坏蛋通过", + "descriptionComplete": "阻止了所有的坏蛋", + "descriptionFull": "在${LEVEL}中阻止所有坏蛋通过", + "descriptionFullComplete": "在${LEVEL}中阻止了所有的坏蛋", + "name": "铜墙铁壁" + }, + "Uber Football Shutout": { + "description": "不失分赢得比赛", + "descriptionComplete": "不失分赢得了比赛", + "descriptionFull": "在${LEVEL} 中不失分赢得比赛", + "descriptionFullComplete": "在${LEVEL} 中不失分赢得了比赛", + "name": "${LEVEL} 完胜" + }, + "Uber Football Victory": { + "description": "赢得比赛", + "descriptionComplete": "赢得比赛", + "descriptionFull": "在${LEVEL}中获胜", + "descriptionFullComplete": "在${LEVEL}中获胜", + "name": "${LEVEL} 获胜" + }, + "Uber Onslaught Victory": { + "description": "防御所有坏蛋", + "descriptionComplete": "防御了所有坏蛋", + "descriptionFull": "在 ${LEVEL} 中防御所有坏蛋", + "descriptionFullComplete": "在 ${LEVEL} 中防御了所有坏蛋", + "name": "${LEVEL} 获胜" + }, + "Uber Runaround Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在 ${LEVEL} 中打败所有敌人", + "descriptionFullComplete": "在 ${LEVEL} 中打败了所有敌人", + "name": "${LEVEL} 获胜" + } + }, + "achievementsRemainingText": "未完成成就:", + "achievementsText": "成就", + "achievementsUnavailableForOldSeasonsText": "抱歉,往届的成就细节不可用。", + "activatedText": "${THING} 已激活", + "addGameWindow": { + "getMoreGamesText": "获取更多游戏模式…", + "titleText": "添加比赛" + }, + "addToFavoritesText": "添加到收藏", + "addedToFavoritesText": "将'${NAME}'添加到收藏", + "allText": "全部", + "allowText": "允许", + "alreadySignedInText": "您的账号已在其他设备登录;\n请切换账号或者退出已登录的设备,\n然后再试一次", + "apiVersionErrorText": "无法加载模组${NAME};它的API版本为 ${VERSION_USED},我们需要 ${VERSION_REQUIRED}.", + "applyText": "应用", + "areYouSureText": "你确定吗?", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(“自动”仅在插入耳机时有效)", + "headRelativeVRAudioText": "头部相对VR音频", + "musicVolumeText": "音乐音量", + "soundVolumeText": "音效音量", + "soundtrackButtonText": "自定义背景音乐", + "soundtrackDescriptionText": "导入自定义背景音乐", + "titleText": "声音" + }, + "autoText": "自动", + "backText": "返回", + "banThisPlayerText": "禁掉该玩家", + "bestOfFinalText": "${COUNT}局决胜制最后得分", + "bestOfSeriesText": "${COUNT}决胜制:", + "bestRankText": "您的最佳是 #${RANK}", + "bestRatingText": "您的最高评价是 ${RATING}", + "bombBoldText": "炸弹", + "bombText": "炸弹", + "boostText": "加速", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME}在该应用程序自身中设置。", + "buttonText": "按钮", + "canWeDebugText": "当${APP_NAME}出现错误或崩溃时\n我们能否收集错误信息并上报给件开发者?\n\n这样有助于开发者修复bug并完善功能\n同时我们承诺,上报的信息不会包含你的个人信息", + "cancelText": "取消", + "cantConfigureDeviceText": "抱歉,${DEVICE}不可配置。", + "challengeEndedText": "此挑战已经结束。", + "chatMuteText": "屏蔽消息", + "chatMutedText": "聊天静音", + "chatUnMuteText": "取消屏蔽消息", + "chests": { + "prizeOddsText": "奖品概率", + "reduceWaitText": "减少开箱时间", + "slotDescriptionText": "这个空位可用于存放宝箱。\n\n通过完成战役关卡、\n在锦标赛中获得名次以及达成成就,\n即可获得宝箱。", + "slotText": "宝箱槽位 ${NUM}", + "slotsFullWarningText": "警告:宝箱槽位已满!\n本局游戏内获得的所有宝箱将无法保存。", + "unlocksInText": "解锁" + }, + "choosingPlayerText": "<选择玩家>", + "claimText": "领取", + "codesExplainText": "开发者会提供代码来\n诊断和修复账户问题", + "completeThisLevelToProceedText": "你需要先完成这一关", + "completionBonusText": "完成奖励", + "configControllersWindow": { + "configureControllersText": "手柄配置", + "configureKeyboard2Text": "键盘设置 P2", + "configureKeyboardText": "键盘配置", + "configureMobileText": "用移动设备作为控制器", + "configureTouchText": "触摸屏配置", + "ps3Text": "PS3手柄", + "titleText": "手柄", + "wiimotesText": "Wii手柄", + "xbox360Text": "Xbox360手柄" + }, + "configGamepadSelectWindow": { + "androidNoteText": "注意:是否支持手柄取决于您的设备和系统版本。", + "pressAnyButtonText": "按手柄上的任意按钮\n 您想要配置...", + "titleText": "手柄配置" + }, + "configGamepadWindow": { + "advancedText": "高级", + "advancedTitleText": "高级控制器设置", + "analogStickDeadZoneDescriptionText": "(释放摇杆角色出现“漂移”情况时调高)", + "analogStickDeadZoneText": "模拟摇杆盲区", + "appliesToAllText": "(适用于所有该类型手柄)", + "autoRecalibrateDescriptionText": "(角色未全速移动时有效)", + "autoRecalibrateText": "自动校准模拟摇杆", + "axisText": "轴", + "clearText": "清除", + "dpadText": "方向键", + "extraStartButtonText": "额外启动按钮", + "ifNothingHappensTryAnalogText": "如无反应,请尝试分配至模拟摇杆。", + "ifNothingHappensTryDpadText": "如无反应,请尝试分配至方向键。", + "ignoreCompletelyDescriptionText": "(避免这个控制器影响游戏或菜单)", + "ignoreCompletelyText": "已完全忽略", + "ignoredButton1Text": "已忽略 按键1", + "ignoredButton2Text": "已忽略 按键2", + "ignoredButton3Text": "已忽略 按键3", + "ignoredButton4Text": "已忽略 按键4", + "ignoredButtonDescriptionText": "(用于防止“主页”或“同步”按钮影响用户界面)", + "pressAnyAnalogTriggerText": "按任意模拟扳机...", + "pressAnyButtonOrDpadText": "按任意键或方向键...", + "pressAnyButtonText": "按任意键", + "pressLeftRightText": "按左或右", + "pressUpDownText": "按上或下", + "runButton1Text": "跑 按键1", + "runButton2Text": "跑 按键2", + "runTrigger1Text": "跑 扳机1", + "runTrigger2Text": "跑 扳机2", + "runTriggerDescriptionText": "(模拟扳机可实现变速奔跑)", + "secondHalfText": "用于设置显示为单一手柄的\n二合一手柄设备的\n第二部分。", + "secondaryEnableText": "启用", + "secondaryText": "从属手柄", + "startButtonActivatesDefaultDescriptionText": "(如果启动按钮更倾向为“菜单”按钮,则关闭此功能)", + "startButtonActivatesDefaultText": "启动按钮激活默认部件", + "titleText": "手柄设置", + "twoInOneSetupText": "二合一手柄设置", + "uiOnlyDescriptionText": "(阻止这个控制器加入游戏)", + "uiOnlyText": "限制菜单应用", + "unassignedButtonsRunText": "全部未分配按钮 跑", + "unsetText": "<未设置>", + "vrReorientButtonText": "虚拟按钮调整" + }, + "configKeyboardWindow": { + "configuringText": "配置${DEVICE}", + "keyboard2NoteText": "注:大多数键盘一次只能同时按几个按键,\n所以如果玩家另接一个单独的键盘,\n则两个键盘可帮助他们更好地玩游戏。\n请注意,即使在这种情况下,您也仍需\n为两个玩家分配独特的按键。" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "动作键大小", + "actionsText": "动作", + "buttonsText": "按钮", + "dragControlsText": "<拖动手柄重新定位他们>", + "joystickText": "游戏摇杆", + "movementControlScaleText": "移动键大小", + "movementText": "移动", + "resetText": "重置", + "swipeControlsHiddenText": "隐藏滑动图标", + "swipeInfoText": "“滑动”式手柄是需要花点时间来适应的,但\n能不看手柄上的控制键玩游戏会更轻松。", + "swipeText": "滑动", + "titleText": "触摸屏配置" + }, + "configureDeviceInSystemSettingsText": "${DEVICE} 可以在系统设置中配置捏", + "configureItNowText": "现在立即配置吗?", + "configureText": "配置", + "connectMobileDevicesWindow": { + "amazonText": "亚马逊应用商店", + "appStoreText": "App Store", + "bestResultsText": "低延迟无线网可助你取得最佳成绩。要想降低无线网延迟,\n你可以关闭其他无线设备,\n或者在无线路由器附近玩,\n再或者将游戏主机连接以太网。", + "explanationText": "如果想把智能手机或平板设备作为控制器,请安装\n“${REMOTE_APP_NAME}”。通过无线网络,最多可\n以支持8个设备同时连接。最酷的是,这完全免费!", + "forAndroidText": "安卓", + "forIOSText": "iOS", + "getItForText": "iOS 用户可从App Store 获取 ${REMOTE_APP_NAME}\nAndroid 用户可以通过Google Play(中国无法正常获取)或者亚马逊应用商店(中国用户推荐使用)获取", + "googlePlayText": "Google Play", + "titleText": "把移动设备用作为游戏手柄" + }, + "continuePurchaseText": "花 ${PRICE}继续?", + "continueText": "继续", + "controlsText": "控制键", + "coopSelectWindow": { + "activenessAllTimeInfoText": "不提供所有时间的排名。", + "activenessInfoText": "倍数随玩游戏天数增加,\n随未玩游戏天数减少。", + "activityText": "活动", + "campaignText": "比赛", + "challengesInfoText": "获取完成迷你游戏的奖励。\n\n每完成一项挑战\n奖励和难度都会增加,\n每挑战失败或放弃挑战一次,奖励和难度都会降低。", + "challengesText": "挑战", + "currentBestText": "当前最高分", + "customText": "自定义", + "entryFeeText": "参赛", + "forfeitConfirmText": "要放弃挑战吗?", + "forfeitNotAllowedYetText": "尚不能放弃此挑战。", + "forfeitText": "放弃", + "multipliersText": "倍数", + "nextChallengeText": "下一挑战", + "nextPlayText": "下一次游戏", + "ofTotalTimeText": "${TOTAL}", + "playNowText": "立即开玩", + "pointsText": "分", + "powerRankingFinishedSeasonUnrankedText": "(已结束赛季,未排名)", + "powerRankingNotInTopText": "(${NUMBER}名以外)", + "powerRankingPointsEqualsText": "${NUMBER}分", + "powerRankingPointsMultText": "(x ${NUMBER} 分)", + "powerRankingPointsText": "${NUMBER} 分", + "powerRankingPointsToRankedText": "(${CURRENT}分 已获得 共${REMAINING}分)", + "powerRankingText": "能力排位", + "prizesText": "奖励", + "proMultInfoText": "${PRO}升级的玩家\n获得${PERCENT}%的得分提速。", + "seeMoreText": "更多……", + "skipWaitText": "跳过等待", + "timeRemainingText": "剩余时间", + "toRankedText": "排名", + "totalText": "总计", + "tournamentInfoText": "与联赛中的其他玩家\n争夺高分。\n\n锦标赛时间结束时\n高分玩家将赢得奖励。", + "welcome1Text": "欢迎来到${LEAGUE}。你可以通过\n在锦标赛中赚取星级、达成成就及\n赢得冠军来提升你的联赛排名。", + "welcome2Text": "你还可参加很多相同活动来赢取点券。\n点券可用于解锁新的角色、地图和\n迷你游戏,或进入锦标赛,或更多用途", + "yourPowerRankingText": "你的能力排位:" + }, + "copyConfirmText": "复制到剪贴板", + "copyOfText": "${NAME} 复制", + "copyText": "复制", + "createEditPlayerText": "<创建/编辑玩家>", + "createText": "创建", + "creditsWindow": { + "additionalAudioArtIdeasText": "添补音频、初期原图和创意:${NAME}", + "additionalMusicFromText": "添补背景音乐:${NAME}", + "allMyFamilyText": "帮助进行游戏测试的我的所有好友和家人", + "codingGraphicsAudioText": "编程、图形引擎和音频引擎:${NAME}", + "languageTranslationsText": "语言翻译:", + "legalText": "法律:", + "publicDomainMusicViaText": "版权公有音乐:${NAME}", + "softwareBasedOnText": "该软件部分基于${NAME}的工作", + "songCreditText": "${TITLE}演唱:${PERFORMER}\n作曲:${COMPOSER},改编:${ARRANGER},发行:${PUBLISHER},\n由${SOURCE}提供", + "soundAndMusicText": "音乐和音效", + "soundsText": "音乐(${SOURCE}):", + "specialThanksText": "特别感谢", + "thanksEspeciallyToText": "尤其感谢 ${NAME}", + "titleText": "${APP_NAME}制作团队", + "whoeverInventedCoffeeText": "发明咖啡的人" + }, + "currentStandingText": "您目前的排名是#${RANK}", + "customizeText": "自定义...", + "deathsTallyText": "${COUNT}次死亡", + "deathsText": "死亡", + "debugText": "调试", + "debugWindow": { + "reloadBenchmarkBestResultsText": "注意:建议您在调试阶段将设置->画面->纹理设置为“高”。", + "runCPUBenchmarkText": "运行CPU基准程序", + "runGPUBenchmarkText": "运行GPU基准程序", + "runMediaReloadBenchmarkText": "运行媒体重载基准程序", + "runStressTestText": "运行压力测试", + "stressTestPlayerCountText": "玩家计数", + "stressTestPlaylistDescriptionText": "压力测试列表", + "stressTestPlaylistNameText": "列表名称", + "stressTestPlaylistTypeText": "列表类型", + "stressTestRoundDurationText": "回合时长", + "stressTestTitleText": "压力测试", + "titleText": "基准程序和压力测试", + "totalReloadTimeText": "总计重载时间:${TIME}(详见日志)" + }, + "defaultGameListNameText": "默认${PLAYMODE}列表", + "defaultNewGameListNameText": "我的${PLAYMODE}列表", + "deleteText": "删除", + "demoText": "演示", + "denyText": "拒绝", + "deprecatedText": "已弃用", + "descriptionText": "内容", + "desktopResText": "桌面分辨率", + "deviceAccountUpgradeText": "紧急警告:\n你正在使用本地账户登录! (${NAME})\n此账户会在未来升级中被删除!!\n~如果想保持账号,请升级到v2账户~", + "difficultyEasyText": "简单", + "difficultyHardOnlyText": "仅限困难模式", + "difficultyHardText": "困难", + "difficultyHardUnlockOnlyText": "该关卡只可解锁在困难模式下解锁。\n你认为自己拥有夺冠的实力吗!?!?", + "directBrowserToURLText": "请打开网页浏览器访问以下链接:", + "disableRemoteAppConnectionsText": "禁止炸队手柄应用连接", + "disableXInputDescriptionText": "允许使用4个以上的控制器但可能不会正常工作", + "disableXInputText": "禁用XInput", + "disabledText": "禁用", + "discardText": "Discard", + "discordFriendsText": "想要结交新朋友一起玩吗?\n来加入我们的Discord吧!", + "discordJoinText": "加入Discord", + "doneText": "完成", + "drawText": "平局", + "duplicateText": "复制", + "editGameListWindow": { + "addGameText": "添加\n比赛", + "cantOverwriteDefaultText": "不可以覆盖默认的比赛列表!", + "cantSaveAlreadyExistsText": "已存在与此名字相同的比赛列表!", + "cantSaveEmptyListText": "不可以保存空白的比赛列表!", + "editGameText": "编辑\n比赛", + "listNameText": "比赛列表名称", + "nameText": "名称", + "removeGameText": "删除\n比赛", + "saveText": "保存", + "titleText": "列表编辑器" + }, + "editProfileWindow": { + "accountProfileInfoText": "此特殊玩家档案,\n可能含有其中一个图标:\n\n${ICONS}\n\n基于您的登录平台以显示\n相关图标。(其中一部分可能已经绝版)", + "accountProfileText": "(账户资料)", + "availableText": "\"${NAME}\"可用。", + "characterText": "角色", + "checkingAvailabilityText": "正在检查\"${NAME}\"是否可用…", + "colorText": "颜色", + "getMoreCharactersText": "获取更多角色...", + "getMoreIconsText": "获取更多图标...", + "globalProfileInfoText": "全球玩家档案可使玩家拥有全世界唯一的名称。\n档案也包括自定义图标。", + "globalProfileText": "(全球档案)", + "highlightText": "副颜色", + "iconText": "图标", + "localProfileInfoText": "本地玩家档案不含图标,且玩家名称不具唯一性。\n升级至全球档案,以拥有唯一的游戏名称,并添加自定义图标。\n#警告:切勿使用随机到的名称,被使用的可能性极大。", + "localProfileText": "(本地档案)", + "nameDescriptionText": "角色名称", + "nameText": "名称", + "profileAlreadyExistsText": "具有该名称的配置文件已存在", + "randomText": "随机", + "titleEditText": "编辑档案", + "titleNewText": "新建档案", + "unavailableText": "\"${NAME}\"不可用;请尝试另一名称。", + "upgradeProfileInfoText": "这可在全球范围内保存您的玩家名称,\n并可让您为自己的名称分配一个自定义图标。", + "upgradeToGlobalProfileText": "升级至全球档案" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "不能删除默认的背景音乐。", + "cantEditDefaultText": "不能编辑默认的背景音乐。请备份或是新建一个背景音乐列表。", + "cantOverwriteDefaultText": "不可以覆盖默认的背景音乐", + "cantSaveAlreadyExistsText": "这个名字的背景音乐已经存在!", + "defaultGameMusicText": "<默认游戏音乐>", + "defaultSoundtrackNameText": "默认自定义背景音乐", + "deleteConfirmText": "删除自定义背景音乐:\n\n'${NAME}'?", + "deleteText": "删除自定义\n背景音乐", + "duplicateText": "备份自定义\n背景音乐", + "editSoundtrackText": "自定义背景音乐编辑器", + "editText": "编辑自定义\n背景音乐", + "fetchingITunesText": "正在获得音乐应用播放列表", + "musicVolumeZeroWarning": "注意:现在音量为0", + "nameText": "名称", + "newSoundtrackNameText": "我的背景音乐${COUNT}", + "newSoundtrackText": "新的背景音乐:", + "newText": "创建背\n景音乐", + "selectAPlaylistText": "选择一个列表", + "selectASourceText": "音乐来源", + "testText": "测试", + "titleText": "自定义背景音乐", + "useDefaultGameMusicText": "默认游戏音乐", + "useITunesPlaylistText": "音乐应用播放列表", + "useMusicFileText": "音乐文件(mp3文件等)", + "useMusicFolderText": "音乐文件夹" + }, + "editText": "修改", + "enabledText": "启用", + "endText": "结束", + "enjoyText": "尽情享用吧!", + "epicDescriptionFilterText": "史诗级慢动作的 ${DESCRIPTION}。", + "epicNameFilterText": "史诗级 ${NAME}", + "errorAccessDeniedText": "访问被拒绝", + "errorDeviceTimeIncorrectText": "您设备的时间有 ${HOURS} 小时的误差。\n这会导致游戏出现问题。\n请检查您设备的时间和时区设置。", + "errorOutOfDiskSpaceText": "存储空间不足,无法保存游戏进度", + "errorSecureConnectionFailText": "无法建立安全的云链接,网络可能会连接失败", + "errorText": "啊呜,好像出错了喵...", + "errorUnknownText": "未知错误", + "exitGameText": "退出${APP_NAME}?", + "expiredAgoText": "${T} 前已过期", + "expiresInText": "${T} 后过期", + "exportSuccessText": "退出'${NAME}'", + "externalStorageText": "外部存储器", + "failText": "失败", + "fatalErrorText": "哎呀,有些文件丢失或损坏了喵~\n请尝试重装游戏,或者\n联系 ${EMAIL} 寻求帮助喵~", + "fileSelectorWindow": { + "titleFileFolderText": "选择一个文件或文件夹", + "titleFileText": "选择一个文件", + "titleFolderText": "选择一个文件夹", + "useThisFolderButtonText": "使用此文件夹" + }, + "filterText": "搜索", + "finalScoreText": "最后得分", + "finalScoresText": "最后得分", + "finalTimeText": "最终时间", + "finishingInstallText": "安装即将完成...", + "fireTVRemoteWarningText": "* 为获得更好的游戏体验,请使用\n游戏手柄或在您的手机和\n平板电脑上安装\n'${REMOTE_APP_NAME}'。", + "firstToFinalText": "${COUNT}局自由混战赛最后得分", + "firstToSeriesText": "${COUNT}局自由混战赛", + "fiveKillText": "五连杀!!!", + "flawlessWaveText": "完美的一波!", + "fourKillText": "四连杀!!!", + "friendScoresUnavailableText": "无法查看好友的得分。", + "gameLeadersText": "最高得分玩家数:${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "您不能删除默认的比赛列表!", + "cantEditDefaultText": "不能编辑默认的比赛列表!复制或者新建一个。", + "cantShareDefaultText": "你不能分享默认列表", + "deleteConfirmText": "是否删除“${LIST}”?", + "deleteText": "删除\n比赛列表", + "duplicateText": "复制\n比赛列表", + "editText": "编辑\n比赛列表", + "newText": "新建\n比赛列表", + "pointsToWinText": "获胜点数", + "seriesLengthText": "列表长度", + "showTutorialText": "展示游戏基本教程", + "shuffleGameOrderText": "随机比赛模式", + "titleText": "自定义${TYPE}列表" + }, + "gameSettingsWindow": { + "addGameText": "添加比赛" + }, + "gamesToText": "${WINCOUNT}比${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "请记住:如果你有足够多的游戏手柄,\n那你就可以让多个玩家用手柄同时游戏。", + "aboutDescriptionText": "这个选项卡是用来联机(开派对/房间)的喵~\n\n在派对中,你可以和朋友在不同的设备上\n一起玩游戏和比赛的喵~\n\n点击右上角的${PARTY}按钮\n来发起派对聊天和互动喵~\n(手柄请在菜单中时按${BUTTON}喵~)", + "aboutText": "关于", + "addressFetchErrorText": "<获取地址出错>", + "appInviteMessageText": "${NAME} 在${APP_NAME}中送给了您${COUNT} 点券", + "appInviteSendACodeText": "向他们发送一个代码", + "appInviteTitleText": "${APP_NAME} App 邀请码", + "bluetoothAndroidSupportText": "(适用于任何支持蓝牙功能的安卓设备)", + "bluetoothDescriptionText": "通过蓝牙来创建或加入比赛", + "bluetoothHostText": "通过蓝牙来创建游戏", + "bluetoothJoinText": "通过蓝牙来加入游戏", + "bluetoothText": "蓝牙", + "checkingText": "检查中...", + "copyCodeConfirmText": "代码已复制到粘贴板。", + "copyCodeText": "复制代码", + "dedicatedServerInfoText": "建立一个专用服务器来获得最佳效果,详情见 bombsquadgame.com/server 哦!", + "descriptionShortText": "使用多人游戏窗口来组建派对。", + "disconnectClientsText": "这将使派对中的${COUNT}位玩家\n断开连接。是否确定?", + "earnTicketsForRecommendingAmountText": "如果您的朋友们玩了这款游戏,他们将会收到 ${COUNT} 点券\n(每个畅游的朋友将让你收到 ${YOU_COUNT}点券)", + "earnTicketsForRecommendingText": "分享游戏来\n获取免费点券...", + "emailItText": "通过电子邮件发送", + "favoritesSaveText": "另存为收藏", + "favoritesText": "收藏", + "freeCloudServerAvailableMinutesText": "下一次免费云服务器将在 ${MINUTES} 分钟后可用。", + "freeCloudServerAvailableNowText": "当前免费云服务器可用!", + "freeCloudServerNotAvailableText": "无免费云服务器可用。", + "friendHasSentPromoCodeText": "从 ${NAME} 中获取 ${COUNT} 张 ${APP_NAME} 点券", + "friendPromoCodeAwardText": "每使用一次,你可收到${COUNT}张点券。", + "friendPromoCodeExpireText": "代码将在 ${EXPIRE_HOURS} 小时后失效,代码仅适用于新玩家。", + "friendPromoCodeInstructionsText": "请前往${APP_NAME}的“设置->高级->兑换礼包码”来兑换;\n要下载最新版,请访问www.bombsquad.cn(仅限中国大陆)", + "friendPromoCodeRedeemLongText": "达到${MAX_USES}人后,就不可获得${COUNT}免费点券。(防止玩家用来作弊)", + "friendPromoCodeRedeemShortText": "可在游戏中兑换${COUNT}免费点券。", + "friendPromoCodeWhereToEnterText": "(新用户可前往\"设置->高级->兑换礼包码\"中兑换)", + "getFriendInviteCodeText": "获取好友邀请码", + "googlePlayDescriptionText": "邀请Google Play玩家来加入你的派对", + "googlePlayInviteText": "邀请", + "googlePlayReInviteText": "如果你发出一个新邀请,\n则你的派对中的${COUNT}位Google Play玩家将断开连接。\n在发出的新邀请中再次邀请他们,让他们重回派对。", + "googlePlaySeeInvitesText": "查看邀请", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(仅针对 Google Play 设备)", + "hostPublicPartyDescriptionText": "创建一个公开派对", + "hostingUnavailableText": "主机不可用", + "inDevelopmentWarningText": "注意:\n\n联网模式是一项新的并且还在开发特性,\n目前强烈建议所有玩家在同一个\n无线局域网下游戏。", + "internetText": "在线游戏", + "inviteAFriendText": "你的朋友还没下载?邀请他们\n一起玩,新玩家可获得${COUNT}张免费点券。", + "inviteFriendsText": "邀请朋友", + "joinPublicPartyDescriptionText": "加入一个公开派对", + "localNetworkDescriptionText": "加入一个局域网派对(通过wifi,蓝牙等各种方式)", + "localNetworkText": "本地网络", + "makePartyPrivateText": "将我的派对变成私人派对", + "makePartyPublicText": "将我的派对变成公开派对", + "manualAddressText": "地址", + "manualConnectText": "连接", + "manualDescriptionText": "加入派对,地址:", + "manualJoinSectionText": "使用地址加入", + "manualJoinableFromInternetText": "是否可从互联网连接?:", + "manualJoinableNoWithAsteriskText": "否*", + "manualJoinableYesText": "是", + "manualRouterForwardingText": "* 若要解决此问题,请尝试将您的路由器设置为将UDP端口${PORT}转发到你的本地地址(地址一般是192.168.*.*)", + "manualText": "手动", + "manualYourAddressFromInternetText": "互联网地址:", + "manualYourLocalAddressText": "本地地址:", + "nearbyText": "附近", + "noConnectionText": "<无连接>", + "noPartiesAddedText": "没有加入派对", + "otherVersionsText": "(其他版本)", + "partyCodeText": "派对代码", + "partyInviteAcceptText": "接受", + "partyInviteDeclineText": "拒绝", + "partyInviteIgnoreText": "忽略", + "partyInviteText": "${NAME}已邀请\n你加入他们的派对!", + "partyNameText": "派对名称", + "partyServerRunningText": "您的派对服务器正在运行。", + "partySizeText": "派对规模大小", + "partyStatusCheckingText": "检查中", + "partyStatusJoinableText": "你的派对现在可以从互联网上加入了", + "partyStatusNoConnectionText": "无法连接到服务器", + "partyStatusNotJoinableText": "你的派对不能从互联网上加入", + "partyStatusNotPublicText": "你的派对是私人的", + "pingText": "延迟", + "portText": "端口", + "privatePartyCloudDescriptionText": "私人服务器在官方的云服务器上运行;无需路由器配置", + "privatePartyHostText": "创建一个私人派对", + "privatePartyJoinText": "加入一个公开派对", + "privateText": "私人", + "publicHostRouterConfigText": "这可能需要配置路由器进行端口转发,为了更简单的选择,请使用私人派对", + "publicText": "公共", + "requestingAPromoCodeText": "正在请求代码…", + "sendDirectInvitesText": "直接邀请", + "shareThisCodeWithFriendsText": "与好友分享此代码:", + "showMyAddressText": "显示我的地址", + "startHostingPaidText": "创建需花费 ${COST}", + "startHostingText": "创建", + "startStopHostingMinutesText": "你还可以使用${MINUTES}分钟的免费服务器", + "stopHostingText": "停止主机", + "titleText": "多人游戏", + "wifiDirectDescriptionBottomText": "如果所有设备都设有 Wi-Fi Direct 面板,那他们应该可以使用通过它来找到彼此,\n然后相互连接。一旦所有设备都相互连接上了,你就可以通过“本地网络”选项卡\n在此组织派对,常规的无线局域网也是一样。\n\n如要取得最佳效果,Wi-Fi Direct 创建者也应是${APP_NAME} 派对的创建者", + "wifiDirectDescriptionTopText": "无需无线网络即可直接\n通过Wi-Fi Direct连接安卓设备。对于安装了Android 4.2或更高版本操作系统的设备效果更好。\n\n要使用该功能,可打开无线网络连接设置,然后在菜单中寻找'Wi-Fi Direct'。", + "wifiDirectOpenWiFiSettingsText": "打开无线网络连接设置", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(所有平台之间运作)", + "youHaveBeenSentAPromoCodeText": "您已送出一个 ${APP_NAME} 兑换代码:" + }, + "getTicketsWindow": { + "freeText": "免费!", + "freeTicketsText": "免费点券", + "inProgressText": "一个交易正在进行;请稍后再试。", + "purchasesRestoredText": "购买恢复。", + "receivedTicketsText": "获得${COUNT}点券!", + "restorePurchasesText": "恢复购买", + "ticketPack1Text": "小型点券包", + "ticketPack2Text": "中等点券包", + "ticketPack3Text": "大型点券包", + "ticketPack4Text": "巨型点券包", + "ticketPack5Text": "猛犸象点券包", + "ticketPack6Text": "终极点券包", + "ticketsFromASponsorText": "观看广告\n白嫖${COUNT}个点券", + "ticketsText": "${COUNT}点券", + "titleText": "获得点券", + "unavailableLinkAccountText": "对不起,该平台上不可进行购买。\n您可将此帐户链接到另一个\n平台,以进行购买。", + "unavailableTemporarilyText": "该选项当前不可用;请稍后再试。", + "unavailableText": "对不起,该选项不可用。", + "versionTooOldText": "对不起,这个版本的游戏太旧了;请更新到新版本。", + "youHaveShortText": "您拥有${COUNT}", + "youHaveText": "你拥有${COUNT}点券" + }, + "goldPass": { + "desc1InfTokensText": "✨取之不尽的炸弹币", + "desc2NoAdsText": "❌移除广告", + "desc3ForeverText": "✅一次购买终身使用", + "goldPassText": "超级通行证" + }, + "googlePlayPurchasesNotAvailableText": "Google商店购买不可用!\n请安装谷歌框架或更新Google服务。", + "googlePlayServicesNotAvailableText": "Google Play服务不可用\n某些功能可能会被禁用", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "总是", + "fullScreenCmdText": "全屏显示(Cmd+F)", + "fullScreenCtrlText": "全屏(Ctrl-F)", + "fullScreenText": "全屏", + "gammaText": "Gamma", + "highText": "高", + "higherText": "极高", + "lowText": "低", + "maxFPSText": "最大帧数限制", + "mediumText": "中", + "neverText": "关", + "resolutionText": "分辨率", + "showFPSText": "显示帧数", + "texturesText": "材质质量", + "titleText": "图像质量", + "tvBorderText": "UI缩进", + "verticalSyncText": "垂直同步", + "visualsText": "视觉" + }, + "helpWindow": { + "bombInfoText": "炸弹\n比拳头伤害高,但也能把自己送上西天。\n给你个建议:等引线快烧完的时候\n再把炸弹扔向敌人。", + "canHelpText": "${APP_NAME}小帮助可以帮你快速入门!", + "controllersInfoText": "你可以和好友在同一网络下玩${APP_NAME},或者\n如果你有足够多的手柄,那也可以在同一个设备上游戏。\n${APP_NAME}支持各种选择;你甚至可以通过免费的'${REMOTE_APP_NAME}'\n用手机作为游戏手柄。\n更多信息,请参见设置->手柄。", + "controllersInfoTextRemoteOnly": "你可以通过局域网与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩", + "controllersText": "手柄", + "controlsSubtitleText": "${APP_NAME}的角色基本操作如下:", + "controlsText": "控制键", + "devicesInfoText": "VR版${APP_NAME}可与\n普通版本联网游戏,所以掏出你所有的手机、平板电脑\n和电脑,大玩一场吧。你甚至还可以将\n普通版本的游戏连接至VR版,\n让游戏外的人也能看你玩。", + "devicesText": "设备", + "friendsGoodText": "哎,一个人玩?那咋行!${APP_NAME}就是要人多才好玩嘛~\n最多支持8人同时游戏,如果你有魔法可以改掉限制喵~快拉你的小伙伴一起玩吧", + "friendsText": "好友", + "jumpInfoText": "跳跃\n跳跃可以跳过鸿沟,\n或是把炸弹扔得更远,\n或是表达你难以掩盖的喜悦之情。", + "orPunchingSomethingText": "还可以用拳头攻击,或者把敌人举起来然后丢下去,或者更多好玩的...", + "pickUpInfoText": "拾起\n你可以拾起旗子,敌人,\n还有所有没固定在地上的东西,\n然后,再扔出去吧~", + "powerupBombDescriptionText": "将炸弹最大投掷数量\n三个愿望,一次满足", + "powerupBombNameText": "三连炸弹", + "powerupCurseDescriptionText": "最好不要接触它。\n...或者你想试试?", + "powerupCurseNameText": "诅咒", + "powerupHealthDescriptionText": "完全回血!\n想不到吧!", + "powerupHealthNameText": "医疗包", + "powerupIceBombsDescriptionText": "威力比普通炸弹小,但\n能将你的敌人冻住,\n让它们变成妙脆角!(或者你也可以", + "powerupIceBombsNameText": "冰冻弹", + "powerupImpactBombsDescriptionText": "威力比普通炸弹稍弱,但碰到外物后\n就会爆炸。(你扔出去后,再多碰一下就会...", + "powerupImpactBombsNameText": "触感弹", + "powerupLandMinesDescriptionText": "大特价,一包3个。居家旅行,防守阵地的不二选择,\n还可以阻止那些跑的飞快的敌人。\n或者你可以扔出去再打一下??", + "powerupLandMinesNameText": "地雷", + "powerupPunchDescriptionText": "让您变成专业拳击手\n更高!更快!更强!200%!", + "powerupPunchNameText": "拳击手套", + "powerupShieldDescriptionText": "能吸收一些伤害,关键时刻\n可能会有用。(记住,时间是敌人)", + "powerupShieldNameText": "能量护盾", + "powerupStickyBombsDescriptionText": "黏在任何碰到的东西上,然后\n就等着看烟花吧。(其实用力能甩飞...", + "powerupStickyBombsNameText": "黏黏炸弹", + "powerupsSubtitleText": "当然,没有道具的游戏很难通关:", + "powerupsText": "道具", + "punchInfoText": "拳击\n跑得越快,拳击的伤害\n越高。所以像疯子一样\n旋转跳跃吧!", + "runInfoText": "冲刺\n按住四个键中的一个即可冲刺,如果你用手柄可以将扳机设置为跑\n冲刺跑的虽快,但会造成转向困难。且冲且珍惜()", + "someDaysText": "当你想攻击别人时,你可以用各种炸弹", + "titleText": "${APP_NAME}帮助", + "toGetTheMostText": "要想最痛快地玩这个游戏,你需要:", + "welcomeText": "欢迎来到${APP_NAME}!" + }, + "holdAnyButtonText": "<按住任意按钮>", + "holdAnyKeyText": "<按住任何键>", + "hostIsNavigatingMenusText": "- ${HOST}像皇帝一样控制主菜单 -", + "importPlaylistCodeInstructionsText": "用代码来导入列表", + "importPlaylistSuccessText": "成功导入${TYPE}列表 '${NAME}'", + "importText": "导入", + "importingText": "导入中", + "inGameClippedNameText": "名字会是\n\"${NAME}\"", + "inboxText": "收件箱", + "installDiskSpaceErrorText": "错误:无法完成安装。\n您的设备可能是空间不足。\n腾出一些空间,然后重试。", + "internal": { + "arrowsToExitListText": "按${LEFT}或${RIGHT}退出列表", + "buttonText": "按钮", + "cantKickHostError": "你不能踢房主啊喂!", + "chatBlockedText": "玩家 ${NAME} 被禁言 ${TIME} 秒,有话慢点说", + "connectedToGameText": "加入 '${NAME}'", + "connectedToPartyText": "加入${NAME}的房间!", + "connectingToPartyText": "正在连接...", + "connectionFailedHostAlreadyInPartyText": "连接失败;创建者正在另一派对中。", + "connectionFailedPartyFullText": "连接出错:房间满员了…", + "connectionFailedText": "连接失败。", + "connectionFailedVersionMismatchText": "连接失败;创建者正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", + "connectionRejectedText": "连接被拒绝。", + "controllerConnectedText": "${CONTROLLER}已连接。", + "controllerDetectedText": "检测到1个手柄。", + "controllerDisconnectedText": "${CONTROLLER}断开连接。", + "controllerDisconnectedTryAgainText": "${CONTROLLER}断开连接。请尝试重新连接。", + "controllerForMenusOnlyText": "此控制器无法在游戏中使用", + "controllerReconnectedText": "${CONTROLLER}重新连接。", + "controllersConnectedText": "已连接${COUNT}个手柄。", + "controllersDetectedText": "检测到${COUNT}个手柄。", + "controllersDisconnectedText": "${COUNT}个手柄断开连接。", + "corruptFileText": "检测到已损坏的文件。请尝试重新安装,或发送电子邮件至${EMAIL}", + "errorPlayingMusicText": "播放音乐错误:${MUSIC}", + "errorResettingAchievementsText": "无法重置在线成就;请稍后再试。", + "hasMenuControlText": "${NAME}目前拥有菜单的控制权限。", + "incompatibleNewerVersionHostText": "房主运行着最新版本游戏。\n请更新您的游戏版本然后重试。", + "incompatibleVersionHostText": "创建者正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", + "incompatibleVersionPlayerText": "${NAME}正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", + "invalidAddressErrorText": "错误:无效的地址。", + "invalidNameErrorText": "错误:无效的名字", + "invalidPortErrorText": "错误:无效端口", + "invitationSentText": "已发出邀请。", + "invitationsSentText": "已发出${COUNT}个邀请。", + "joinedPartyInstructionsText": "有人加入了你的派对\n去“开始战斗”中开始一场游戏吧", + "keyboardText": "键盘", + "kickIdlePlayersKickedText": "${NAME}空闲,将其踢出。", + "kickIdlePlayersWarning1Text": "如果${NAME}仍然空闲,则将在${COUNT}秒后被踢出。", + "kickIdlePlayersWarning2Text": "(您可以在设置 ->高级中将其关闭)", + "leftGameText": "离开 '${NAME}'.", + "leftPartyText": "离开${NAME}的游戏", + "noMusicFilesInFolderText": "文件夹内没有音乐文件。", + "playerJoinedPartyText": "${NAME}加入了游戏!", + "playerLeftPartyText": "${NAME}离开了游戏。", + "rejectingInviteAlreadyInPartyText": "拒绝邀请(已经在派对中)。", + "serverRestartingText": "服务器自动重启中,请重新加入..", + "serverShuttingDownText": "服务器正在关机…", + "signInErrorText": "登录出错啦~", + "signInNoConnectionText": "哎呀,无法登录。(网络连接有故障?)", + "telnetAccessDeniedText": "错误:用户未得到telnet访问授权。", + "timeOutText": "(将在${TIME}秒内超出时限)", + "touchScreenJoinWarningText": "您已以触摸屏方式加入。\n如果这是一个错误,点击“菜单->离开游戏菜单”。", + "touchScreenText": "触摸屏", + "unableToCompleteTryAgainText": "现在无法完成。\n请重试。", + "unableToResolveHostText": "错误:请输入正确的地址", + "unavailableNoConnectionText": "哎呀,这个用不了呢(请等待连接主服务器)", + "vrOrientationResetCardboardText": "点击手机屏幕,重置VR定位。\n您需使用外部手柄来玩VR版炸弹小分队。", + "vrOrientationResetText": "VR定位重置。", + "willTimeOutText": "(若空闲则会超出时限)" + }, + "inventoryText": "库存", + "jumpBoldText": "跳", + "jumpText": "跳", + "keepText": "举起", + "keepTheseSettingsText": "要保留您的新设置吗?", + "keyboardChangeInstructionsText": "双击空格以更改控制器", + "keyboardNoOthersAvailableText": "无其他可用的控制器", + "keyboardSwitchText": "切换控制器为\"${NAME}\"", + "kickOccurredText": "踢出 ${NAME}", + "kickQuestionText": "你们说要不要踢 ${NAME}? 呢…", + "kickText": "踢出", + "kickVoteCantKickAdminsText": "无法踢出管理员.", + "kickVoteCantKickSelfText": "您不能踢出您自己.", + "kickVoteFailedNotEnoughVotersText": "没有足够玩家投票", + "kickVoteFailedText": "踢出玩家投票未成功", + "kickVoteStartedText": "踢出${NAME}的投票已被发起", + "kickVoteText": "投票踢出玩家", + "kickVotingDisabledText": "投票踢出已被禁用.", + "kickWithChatText": "在聊天框中输入 ${YES} 来同意,输入 ${NO} 来拒绝", + "killsTallyText": "${COUNT}次击杀", + "killsText": "击杀数", + "kioskWindow": { + "easyText": "简单", + "epicModeText": "史诗模式", + "fullMenuText": "完整菜单", + "hardText": "困难", + "mediumText": "中等", + "singlePlayerExamplesText": "单人游戏/合作模式样例", + "versusExamplesText": "对战模式样例" + }, + "languageSetText": "现在的语言是 \"${LANGUAGE}\"。", + "lapNumberText": "圈数:${CURRENT}/${TOTAL}", + "lastGamesText": "(最后${COUNT}局比赛)", + "leaderboardsText": "排行榜", + "league": { + "allTimeText": "所有时间", + "currentSeasonText": "当前赛季(${NUMBER})", + "leagueFullText": "${NAME}联赛", + "leagueRankText": "联赛排名", + "leagueText": "联赛", + "rankInLeagueText": "#${RANK}、${NAME}联赛${SUFFIX}", + "seasonEndedDaysAgoText": "赛季已于${NUMBER}天前结束。", + "seasonEndsDaysText": "赛季将于${NUMBER}天后结束。", + "seasonEndsHoursText": "赛季将于${NUMBER}小时后结束。", + "seasonEndsMinutesText": "赛季将于${NUMBER}分钟后结束。", + "seasonText": "第${NUMBER}赛季", + "tournamentLeagueText": "你一定要到${NAME}联赛参加这项赛事。", + "trophyCountsResetText": "奖杯计数将在下个赛季重置。", + "upToDateBonusDescriptionText": "运行最新版本的\n游戏在此处获得 ${PERCENT}% 奖金。", + "upToDateBonusText": "最新奖金" + }, + "learnMoreText": "更多信息", + "levelBestScoresText": "在 ${LEVEL}中的最佳成绩", + "levelBestTimesText": "在 ${LEVEL}中的最佳时间", + "levelIsLockedText": "${LEVEL}处于锁定状态。", + "levelMustBeCompletedFirstText": "必须先完成${LEVEL}。", + "levelText": "${NUMBER}关卡", + "levelUnlockedText": "关卡解锁!", + "livesBonusText": "生命奖励", + "loadingText": "载入中", + "loadingTryAgainText": "加载中请稍后再试", + "macControllerSubsystemBothText": "均可(不推荐)", + "macControllerSubsystemClassicText": "经典", + "macControllerSubsystemDescriptionText": "(如果你的手柄无法工作,请尝试更改此项)", + "macControllerSubsystemMFiNoteText": "已检测到 Made-for-iOS/Mac 手柄;\n你需要在 设置->手柄 中启用该设备", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "手柄支持", + "mainMenu": { + "creditsText": "制作团队", + "demoMenuText": "演示菜单", + "endGameText": "结束", + "endTestText": "结束测试", + "exitGameText": "退出", + "exitToMenuText": "退出到菜单", + "howToPlayText": "小帮助", + "justPlayerText": "(仅${NAME})", + "leaveGameText": "离开游戏", + "leavePartyConfirmText": "你确定要离开?", + "leavePartyText": "离开派对", + "quitText": "离开游戏", + "resumeText": "回到游戏", + "settingsText": "设置" + }, + "makeItSoText": "应用", + "mapSelectGetMoreMapsText": "获取更多地图…", + "mapSelectText": "选择…", + "mapSelectTitleText": "${GAME}地图", + "mapText": "地图", + "maxConnectionsText": "最大连接数", + "maxPartySizeText": "最大派对人数", + "maxPlayersText": "最多人数", + "merchText": "来买周边吧~", + "modeArcadeText": "街机模式", + "modeClassicText": "经典模式", + "modeDemoText": "演示模式", + "moreSoonText": "更多内容即将推出...", + "mostDestroyedPlayerText": "被摧毁次数最多的球员", + "mostValuablePlayerText": "最具价值玩家", + "mostViolatedPlayerText": "最遭暴力玩家", + "mostViolentPlayerText": "最暴力玩家", + "moveText": "移动", + "multiKillText": "${COUNT}连杀!!", + "multiPlayerCountText": "${COUNT}名玩家", + "mustInviteFriendsText": "注意:你必须在“${GATHER}”面板中邀请好友,\n或连接多个\n手柄,和好友一起游戏。", + "nameBetrayedText": "${NAME}背叛了${VICTIM}", + "nameDiedText": "${NAME}寄了", + "nameKilledText": "${NAME}把${VICTIM}杀了", + "nameNotEmptyText": "名字不能为空", + "nameScoresText": "${NAME}得分咯!", + "nameSuicideKidFriendlyText": "${NAME}意外挂了。", + "nameSuicideText": "${NAME}自杀了。", + "nameText": "名称", + "nativeText": "本机", + "newExclaimText": "新品上新!", + "newPersonalBestText": "新个人记录!", + "newTestBuildAvailableText": "更新的测试版可供下载了!(${VERSION} build${BUILD})。\n到${ADDRESS}获取吧!", + "newText": "新建", + "newVersionAvailableText": "更新版本的 ${APP_NAME} 可供下载了! 版本号(${VERSION})", + "nextAchievementsText": "下一个成就:", + "nextLevelText": "下一关", + "noAchievementsRemainingText": "- '无'", + "noContinuesText": "(无可继续)", + "noExternalStorageErrorText": "该设备上未发现外部存储器", + "noGameCircleText": "错误:未登入GameCircle", + "noMessagesText": "无信息", + "noPluginsInstalledText": "没有安装插件", + "noScoresYetText": "还未有得分记录。", + "noServersFoundText": "未找到服务器", + "noThanksText": "不,谢谢", + "noTournamentsInTestBuildText": "温馨提示:测试版的锦标赛分数不能计入锦标赛哦!", + "noValidMapsErrorText": "该比赛类型中未发现有效地图。", + "notEnoughPlayersRemainingText": "剩余玩家不足,退出并开始新游戏。", + "notEnoughPlayersText": "你需要至少${COUNT}名玩家来开始这场比赛!", + "notEnoughTicketsText": "门票不够!", + "notNowText": "不是现在", + "notSignedInErrorText": "您必须登录到您的帐户。", + "notSignedInGooglePlayErrorText": "您必须通过Google Play登录。", + "notSignedInText": "(未登录)", + "notUsingAccountText": "注意:已忽略${SERVICE}账户的自动登录\n如果你想用它登录,前往“账户->使用${SERVICE}登录”~", + "nothingIsSelectedErrorText": "未选择任何内容!", + "numberText": "#${NUMBER}", + "offText": "关", + "okText": "好的", + "onText": "开", + "oneMomentText": "请稍候...", + "onslaughtRespawnText": "${PLAYER}将于第${WAVE}波后复活", + "openMeText": "打开我!", + "openNowText": "立即打开", + "openText": "打开", + "orText": "${A}或${B}", + "otherText": "其他。。。", + "outOfText": "(在${ALL}名玩家中位列#${RANK})", + "ownFlagAtYourBaseWarning": "你的旗帜必须在\n你自己的基地上才能得分!", + "partyWindow": { + "chatMessageText": "聊天消息", + "emptyText": "你的派对为空", + "hostText": "(创建者)", + "sendText": "发送", + "titleText": "你的派对" + }, + "pausedByHostText": "(创建者已暂停)", + "perfectWaveText": "完美的一波!", + "pickUpText": "捡起", + "playModes": { + "coopText": "合作", + "freeForAllText": "混战模式", + "multiTeamText": "多团队", + "singlePlayerCoopText": "单人游戏/合作模式", + "teamsText": "团队对抗" + }, + "playText": "开始战斗", + "playWindow": { + "oneToFourPlayersText": "适合1~4名玩家", + "titleText": "开始战斗", + "twoToEightPlayersText": "适合2~8名玩家" + }, + "playerCountAbbreviatedText": "${COUNT}名玩家", + "playerDelayedJoinText": "${PLAYER}将在下一回合开始时进入。", + "playerInfoText": "玩家资料", + "playerLeftText": "${PLAYER}离开了游戏。", + "playerLimitReachedText": "已达到${COUNT}名玩家上限;其他玩家不允许加入。", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "您无法删除您的帐户资料。", + "deleteButtonText": "删除\n档案", + "deleteConfirmText": "删除'${PROFILE}'?", + "editButtonText": "编辑\n档案", + "explanationText": "(为这个账号定制玩家名称和外观)", + "newButtonText": "创建\n档案", + "titleText": "玩家档案" + }, + "playerText": "玩家", + "playlistNoValidGamesErrorText": "此列表未包含有效的已解锁游戏。", + "playlistNotFoundText": "找不到列表", + "playlistText": "列表", + "playlistsText": "列表", + "pleaseRateText": "如果你喜欢 ${APP_NAME},请考虑花一点时间\n来评价一下它或为它写一篇评论。这将为我们提供\n有用的反馈建议,为游戏的未来开发给予支持。\n\n感谢您!\n-eric", + "pleaseWaitText": "请稍等...", + "pluginClassLoadErrorText": "加载'${PLUGIN}'插件时出错了耶: ${ERROR}", + "pluginInitErrorText": "初始化'${PLUGIN}'插件失败了: ${ERROR}", + "pluginSettingsText": "插件设置", + "pluginsAutoEnableNewText": "自动启用新插件", + "pluginsDetectedText": "新插件安装成功,请重启游戏或在设置中设置它们~", + "pluginsDisableAllText": "禁用所有插件", + "pluginsEnableAllText": "启用所有插件", + "pluginsRemovedText": "有${NUM}个插件被删除了...", + "pluginsText": "插件", + "practiceText": "练习", + "pressAnyButtonPlayAgainText": "按任意按钮再玩一次...", + "pressAnyButtonText": "按任意按钮继续...", + "pressAnyButtonToJoinText": "按任意按钮加入...", + "pressAnyKeyButtonPlayAgainText": "按任意键/按钮再玩一次...", + "pressAnyKeyButtonText": "按任意键/按钮继续......", + "pressAnyKeyText": "按任意键...", + "pressJumpToFlyText": "** 按连续跳跃以腾空 **", + "pressPunchToJoinText": "按下“出拳”来加入", + "pressToOverrideCharacterText": "按${BUTTONS}更换您的角色", + "pressToSelectProfileText": "按${BUTTONS}选择一个玩家", + "pressToSelectTeamText": "按下${BUTTONS}来选择一支队伍", + "promoCodeWindow": { + "codeText": "代码", + "enterText": "输入" + }, + "promoSubmitErrorText": "提交代码时出错; 检查您的互联网连接", + "ps3ControllersWindow": { + "macInstructionsText": "关闭PS3背面的电源开关,确保\n您的 Mac 上启用了蓝牙,然后通过USB连接线将您的手柄连接到\n您的 Mac 上使其配对。之后,您\n就可以使用该手柄上的主页按钮以有线(USB)或无线(蓝牙)模式\n将其连接到您的 Mac 上。\n\n在一些 Mac 上配对时可能会提示您输入蓝牙设备的密码。\n在此情况下,请参阅一下教程或搜索百度或Bing寻求帮助。\n\n\n\n\n无线连接的PS3手柄应该出现在\n Mac 上的“系统偏好设置”>“蓝牙”(MacOS Ventura以前适用)或“系统设置”>“蓝牙”(MacOS Ventura及以上适用)\n中的设备列表中。当您想要再次用你的PS3使用它们时,\n您可能需要关闭蓝牙或从该列表中移除它们。\n\n另外,请确保它们在未使用状态下时与蓝牙断开连接,以免其电池持续消耗。\n\nApple 宣称一台 Mac 最多可连接7个蓝牙设备,\n但通常情况下只能连接3至4个蓝牙设备,请视实际情况而定。", + "ouyaInstructionsText": "若要通过OUYA使用PS3手柄,仅需使用USB连接线\n将其连接配对。这样做可能会使您的其他手柄断开连接,因此\n您应该重新启动您的OUYA,然后拔下USB连接线。\n\n然后,你应该能够使用手柄的主页按钮\n以无线模式将其连接。结束游戏后,按住主页按钮\n10秒钟,以关闭手柄;否则,手柄将持续处于启动状态\n并消耗电池。", + "pairingTutorialText": "配对教程视频", + "titleText": "使用 PS3 手柄玩 ${APP_NAME}:" + }, + "punchBoldText": "拳击", + "punchText": "拳击", + "purchaseForText": "购买花费${PRICE}", + "purchaseGameText": "购买游戏", + "purchaseNeverAvailableText": "抱歉,此账户无法进行购买\n请使用其他平台的账户进行购买", + "purchaseNotAvailableText": "此交易不可用", + "purchasingText": "正在购买…", + "quitGameText": "退出${APP_NAME}?", + "quittingIn5SecondsText": "在5秒后退出...", + "randomPlayerNamesText": "企鹅王,企鹅骑士团成员,王♂の传人,挨揍使我快乐,一拳超人,二营长の意大利炮,雪糕,炸鸡翅,手柄玩家18子,寻找宝藏的海盗,炸弹投手,炸弹不是糖果,我是对面的,万有引力,鸟语花香,兔年大吉,小狗狗,大狗子,二狗子,三狗子,四狗子,五狗子,亚达哟,小猪配齐,汤姆猫,小灰机,炸弹大队队长,炸弹教主", + "randomText": "随机", + "rankText": "排行", + "ratingText": "排名", + "reachWave2Text": "进入第2波才可排名。", + "readyText": "准备", + "recentText": "最近", + "remoteAppInfoShortText": "与家人或者朋友们一起玩${APP_NAME}是非常有趣的!\n您可以连接一个或多个硬件控制器\n或者在手机、平板上安装${REMOTE_APP_NAME}APP程序\n把他们当做控制器使用。", + "remote_app": { + "app_name": "炸弹小分队手柄", + "app_name_short": "炸弹小分队手柄", + "button_position": "按钮位置", + "button_size": "按钮尺寸", + "cant_resolve_host": "无法解析主机。", + "capturing": "捕捉中…", + "connected": "已连接。", + "description": "使用手机或平板电脑作为炸弹小分队游戏手柄。\n一台电视或平板电脑上可同时连接8台设备,体验史诗级多人模式的疯狂游戏。", + "disconnected": "服务器断开连接", + "dpad_fixed": "固定", + "dpad_floating": "浮动", + "dpad_position": "方向键位置", + "dpad_size": "方向键尺寸", + "dpad_type": "方向键类型", + "enter_an_address": "输入地址", + "game_full": "游戏连接已满或不接受更多连接。", + "game_shut_down": "游戏关闭。", + "hardware_buttons": "硬件按钮", + "join_by_address": "通过地址…加入", + "lag": "延迟:${SECONDS}秒", + "reset": "恢复默认值", + "run1": "运行 1", + "run2": "运行 2", + "searching": "正在搜索炸弹小分队游戏…", + "searching_caption": "点击游戏名,进入游戏。\n确保和游戏处于相同的wifi网络下。", + "start": "开始", + "version_mismatch": "版本不匹配。\n确定 炸弹小分队 和 BombSquad Remote\n 为最新版本后,重新尝试。" + }, + "removeInGameAdsText": "在商店中解锁\"${PRO}\",以删除游戏中的广告。", + "removeInGameAdsTokenPurchaseText": "限时优惠:购买任何代币包以删除游戏内广告。", + "renameText": "重命名", + "replayEndText": "结束回放", + "replayNameDefaultText": "终场游戏回放", + "replayReadErrorText": "读取回放文件时出错。", + "replayRenameWarningText": "如果想保存回放文件,则以游戏来命名\"${REPLAY}\";否则文件将被覆盖。", + "replayVersionErrorText": "抱歉,该回放由不同版本的游戏制成,\n不能使用。", + "replayWatchText": "观看回放", + "replayWriteErrorText": "写入回放文件时出错。", + "replaysText": "回放", + "reportPlayerExplanationText": "利用此电子邮箱举报作弊、 不当言语或其他不良行为。\n请描述如下信息:", + "reportThisPlayerCheatingText": "作弊", + "reportThisPlayerLanguageText": "不当言语", + "reportThisPlayerReasonText": "举报内容是?", + "reportThisPlayerText": "举报该玩家", + "requestingText": "正在请求...", + "restartText": "重新启动", + "retryText": "请重试", + "revertText": "还原", + "runText": "运行", + "saveText": "保存", + "scanScriptsErrorText": "检查Mod文件时发现错误,报错见炸队日志文件喵", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 和 ${NUM} 个模组需要升级到API${API}才能使用喵~", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} 需要升级到API${API}才能使用喵~", + "scoreChallengesText": "得分挑战", + "scoreListUnavailableText": "得分列表不可用。", + "scoreText": "得分", + "scoreUnits": { + "millisecondsText": "毫秒", + "pointsText": "分", + "secondsText": "秒" + }, + "scoreWasText": "(是${COUNT})", + "selectText": "选择", + "sendInfoDescriptionText": "在这里输入你想反馈给开发者的话...(记得附上姓名和原因)\n也可以输入礼包码来兑换礼包(专业版或者点券啥的)", + "seriesWinLine1PlayerText": "获得", + "seriesWinLine1TeamText": "获得", + "seriesWinLine1Text": "获得", + "seriesWinLine2Text": "冠军!", + "settingsWindow": { + "accountText": "账户", + "advancedText": "高级", + "audioText": "音效", + "controllersText": "控制器", + "graphicsText": "图像", + "playerProfilesMovedText": "注意:玩家档案已移至主菜单的「账号」窗口下", + "titleText": "设置" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(一款简单、控制方便的用于英文文本编辑的屏幕键盘(打中文想都不要想))", + "alwaysUseInternalKeyboardText": "始终使用内置键盘", + "benchmarksText": "基准与压力测试", + "devToolsText": "开发工具", + "disableCameraGyroscopeMotionText": "禁用相机陀螺仪运动", + "disableCameraShakeText": "禁用相机抖动", + "disableThisNotice": "(可在高级设置中关闭此通知)", + "enterPromoCodeText": "输入兑换代码", + "forTestingText": "注意:这些数值仅用于测试,并会在应用程序退出时丢失。", + "helpTranslateText": "${APP_NAME}有中文汉化是咱们社区\n共同努力的成果。如果您希望参与翻译或对其提出更正,\n请点击这个按钮。十分感谢!", + "insecureConnectionsDescriptionText": "不推荐,但(也许会)允许\n受限国家/网络的线上游玩", + "insecureConnectionsText": "使用非私密链接", + "kickIdlePlayersText": "踢掉空闲玩家", + "kidFriendlyModeText": "低龄段友好模式(低暴力等)", + "languageText": "语言", + "moddingGuideText": "Mod文档", + "moddingToolsText": "Mod工具", + "mustRestartText": "必须重启游戏后生效喵", + "netTestingText": "网络测试", + "resetText": "恢复默认值", + "sendInfoText": "功能反馈/兑换礼包码", + "showBombTrajectoriesText": "显示炸弹轨迹", + "showDemosWhenIdleText": "当游戏空闲时播放演示画面", + "showDeprecatedLoginTypesText": "显示不推荐的登录类型", + "showDevConsoleButtonText": "显示开发者控制台按钮", + "showInGamePingText": "显示游戏延迟", + "showPlayerNamesText": "显示玩家名字", + "showUserModsText": "显示Mod文件夹", + "titleText": "高级", + "translationEditorButtonText": "${APP_NAME}翻译编辑器", + "translationFetchErrorText": "翻译状态不可用", + "translationFetchingStatusText": "正在检查翻译进度…", + "translationInformMe": "中文需要更新翻译时请通知我!", + "translationNoUpdateNeededText": "当前语言是最新的;喵呜!", + "translationUpdateNeededText": "**当前语言需要更新!!**", + "vrTestingText": "VR测试" + }, + "shareText": "分享", + "sharingText": "分享", + "showText": "显示", + "signInForPromoCodeText": "您必须登录到一个帐户, 代码才能生效", + "singleGamePlaylistNameText": "仅${GAME}", + "singlePlayerCountText": "一个玩家", + "sizeLargeText": "大", + "sizeMediumText": "中", + "sizeSmallText": "小", + "soloNameFilterText": "单挑模式 ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "角色选择", + "Chosen One": "选定模式", + "Epic": "史诗模式游戏", + "Epic Race": "史诗级竞赛", + "FlagCatcher": "夺旗战", + "Flying": "快乐山区", + "Football": "运旗战", + "ForwardMarch": "突袭战", + "GrandRomp": "征服战", + "Hockey": "冰球战", + "Keep Away": "抓旗战", + "Marching": "塔防战", + "Menu": "主菜单", + "Onslaught": "冲锋战", + "Race": "竞赛", + "Scary": "山丘之王", + "Scores": "得分屏幕", + "Survival": "消除战", + "ToTheDeath": "死亡竞赛", + "Victory": "最终得分屏幕" + }, + "spaceKeyText": "空格", + "statsText": "详情", + "stopRemindingMeText": "别再提醒我", + "storagePermissionAccessText": "需要存储权限", + "store": { + "alreadyOwnText": "您已拥有${NAME}!", + "bombSquadProNameText": "${APP_NAME}专业版", + "bombSquadProNewDescriptionText": "• 移除游戏内广告和烦人页面\n• 解锁更多的游戏设置\n• 另外还包括:", + "buyText": "购买", + "charactersText": "人物", + "comingSoonText": "敬请期待……", + "extrasText": "额外部分", + "holidaySpecialText": "假期特献", + "howToSwitchCharactersText": "(进入\"${SETTINGS} -> ${PLAYER_PROFILES}\"指定和自定义人物)", + "howToUseIconsText": "(升级全球档案以使用图标)", + "howToUseMapsText": "(在团队/混战游戏中使用这些地图)", + "iconsText": "图标", + "loadErrorText": "无法加载页面。\n请检查您的网络连接。", + "loadingText": "加载中", + "mapsText": "地图", + "miniGamesText": "迷你游戏", + "oneTimeOnlyText": "(仅一次)", + "purchaseAlreadyInProgressText": "该物品的购买已在进行中。", + "purchaseConfirmText": "购买${ITEM}?", + "purchaseNotValidError": "购买无效。\n如果这是一个错误,请联系${EMAIL}。", + "purchaseText": "购买", + "saleBundleText": "捆绑销售!", + "saleExclaimText": "出售!", + "salePercentText": "(${PERCENT}%折扣)", + "saleText": "特卖", + "searchText": "搜索", + "teamsFreeForAllGamesText": "团队/混战游戏", + "totalWorthText": "*** 价值${TOTAL_WORTH}! ***", + "upgradeQuestionText": "升级专业版吗?", + "winterSpecialText": "冬季特献", + "youOwnThisText": "- 您已拥有 -" + }, + "storeDescriptionText": "8人派对游戏疯狂乱炸!\n\n在迷你型爆炸游戏炸飞你的基友(或机器人),如夺旗战、冰球战及史诗级慢动作死亡竞赛!\n\n控制简单,操作便捷,可轻松支持多达8人同时游戏;您甚至可以通过免费的“炸弹小分队手柄”应用将您的手机作为手柄使用!\n\n炸死他们吧。\n\n更多信息,请打开www.froemling.net/bombsquad。", + "storeDescriptions": { + "blowUpYourFriendsText": "炸飞你的朋友们", + "competeInMiniGamesText": "在竞速游戏、飞行游戏中一决高下吧", + "customize2Text": "支持自定义角色、游戏玩法,甚至背景音乐", + "customizeText": "选择角色并创建自己的游戏关卡吧", + "sportsMoreFunText": "加入炸药后游戏会变得更嗨皮。", + "teamUpAgainstComputerText": "或者和机器人PK" + }, + "storeText": "商店", + "submitText": "提交", + "submittingPromoCodeText": "正在提交代码...", + "successText": "成功", + "supportEmailText": "如果你在APP遇到任何问题\n请发邮件到${EMAIL}", + "teamNamesColorText": "团队名称/颜色。。。", + "telnetAccessGrantedText": "Telnet访问已启用。", + "telnetAccessText": "检测到Telnet访问;是否允许?", + "testBuildErrorText": "该测试版已失效;请检查是否存在新版本。", + "testBuildText": "测试版", + "testBuildValidateErrorText": "无法验证测试版。(无网络连接?)", + "testBuildValidatedText": "测试版已通过验证;尽请享用!", + "thankYouText": "感谢您的支持!尽情享受游戏!!", + "threeKillText": "三杀!!", + "ticketsDescriptionText": "门票可用于解锁商店中的角色、\n地图、迷你游戏等。\n\n门票可以在通过活动、\n锦标赛和成就赢得的箱子里找到。", + "timeBonusText": "时间奖励", + "timeElapsedText": "时间耗尽", + "timeExpiredText": "时间结束", + "timeSuffixDaysText": "${COUNT}天", + "timeSuffixHoursText": "${COUNT}时", + "timeSuffixMinutesText": "${COUNT}分", + "timeSuffixSecondsText": "${COUNT}秒", + "tipText": "提示", + "titleText": "炸弹小分队", + "titleVRText": "炸弹小分队 VR", + "tokens": { + "getTokensText": "购买炸弹币", + "notEnoughTokensText": "炸弹币不足哦", + "numTokensText": "${COUNT}个炸弹币", + "openNowDescriptionText": "您现在有足够的代币来\n打开它 - 您不需要\n等待。", + "shinyNewCurrencyText": "炸队的新型货币喵喵喵", + "tokenPack1Text": "小型炸币包", + "tokenPack2Text": "中型炸币包", + "tokenPack3Text": "大型炸币包", + "tokenPack4Text": "超大炸币包", + "tokensDescriptionText": "代币用于加速胸部解锁以及其他游戏和帐户功能。\n您可以在游戏中赢得代币,\n\n也可以打包购买。\n或者购买无限代币的Gold Pass,\n再也不会听说它们了。", + "youHaveGoldPassText": "你获得了黄金通行证\n所有花销全部免费啦!\n感谢你游玩本游戏!" + }, + "topFriendsText": "最佳好友", + "tournamentCheckingStateText": "检查锦标赛状态;请稍候……", + "tournamentEndedText": "本次锦标赛已经结束。一场新的锦标赛即将开始。", + "tournamentEntryText": "锦标赛入口", + "tournamentFinalStandingsText": "最终排名", + "tournamentResultsRecentText": "最近锦标赛结果", + "tournamentStandingsText": "锦标赛积分榜", + "tournamentText": "锦标赛", + "tournamentTimeExpiredText": "锦标赛时间结束", + "tournamentsDisabledWorkspaceText": "工作区启用时无法参加锦标赛!\n关闭工作区,才能进入锦标赛。", + "tournamentsText": "锦标赛", + "translations": { + "characterNames": { + "Agent Johnson": "约翰逊特工", + "B-9000": "B-9000", + "Bernard": "伯纳德", + "Bones": "骷髅", + "Butch": "牛仔邦奇", + "Easter Bunny": "复活兔", + "Flopsy": "萌兔耷拉", + "Frosty": "冰冰", + "Gretel": "格蕾特", + "Grumbledorf": "男巫", + "Jack Morgan": "杰克摩根", + "Kronk": "克罗克", + "Lee": "李", + "Lucky": "幸运儿", + "Mel": "梅尔", + "Middle-Man": "平衡之尊", + "Minimus": "迷你姆斯", + "Pascal": "巴斯卡", + "Pixel": "精灵", + "Sammy Slam": "萨米斯拉姆", + "Santa Claus": "圣诞老人", + "Snake Shadow": "蛇影", + "Spaz": "斯巴子", + "Taobao Mascot": "淘公仔", + "Todd McBurton": "托德马克波顿", + "Zoe": "佐伊", + "Zola": "佐拉" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME}训练", + "Infinite ${GAME}": "无限${GAME}", + "Infinite Onslaught": "无限冲锋战", + "Infinite Runaround": "无限塔防战", + "Onslaught Training": "冲锋训练", + "Pro ${GAME}": "专业${GAME}", + "Pro Football": "专业橄榄球赛", + "Pro Onslaught": "专业冲锋战", + "Pro Runaround": "专业塔防战", + "Rookie ${GAME}": "新手${GAME}", + "Rookie Football": "新手橄榄球赛", + "Rookie Onslaught": "新手冲锋战", + "The Last Stand": "最终杀敌战", + "Uber ${GAME}": "高级${GAME}", + "Uber Football": "高级橄榄球赛", + "Uber Onslaught": "高级冲锋战", + "Uber Runaround": "高级塔防战" + }, + "displayItemNames": { + "${C} Tickets": "${C} 门票", + "${C} Tokens": "${C} 门票", + "Chest": "宝箱", + "L1 Chest": "一级宝箱", + "L2 Chest": "二级宝箱", + "L3 Chest": "三级宝箱", + "L4 Chest": "四级宝箱", + "L5 Chest": "五级宝箱", + "L6 Chest": "六级宝箱", + "Unknown Chest": "???宝箱" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "在一定时间内取代选定目标进而获得胜利。\n杀死选定目标并取而代之。", + "Bomb as many targets as you can.": "尽可能多地炸毁目标。", + "Carry the flag for ${ARG1} seconds.": "扛旗${ARG1}秒。", + "Carry the flag for a set length of time.": "在设定时长内扛旗。", + "Crush ${ARG1} of your enemies.": "粉碎${ARG1}敌人。", + "Defeat all enemies.": "打败所有的敌人。", + "Dodge the falling bombs.": "躲避下落的炸弹。", + "Final glorious epic slow motion battle to the death.": "在最后的荣耀史诗级慢动作大战中战斗至死。", + "Gather eggs!": "收集蛋吧!", + "Get the flag to the enemy end zone.": "扛旗进入敌人达阵区。", + "How fast can you defeat the ninjas?": "你能多快地打败忍者?", + "Kill a set number of enemies to win.": "杀死一定数量的敌人来获得胜利。", + "Last one standing wins.": "最终杀敌者获胜。", + "Last remaining alive wins.": "最终幸存者获胜。", + "Last team standing wins.": "最终杀敌团队获胜。", + "Prevent enemies from reaching the exit.": "阻止敌人到达出口。", + "Reach the enemy flag to score.": "触碰敌人的旗帜来得分。", + "Return the enemy flag to score.": "交回敌人的旗帜来得分。", + "Run ${ARG1} laps.": "跑${ARG1}圈。", + "Run ${ARG1} laps. Your entire team has to finish.": "跑${ARG1}圈。你的整个团队都得完成。", + "Run 1 lap.": "跑1圈。", + "Run 1 lap. Your entire team has to finish.": "跑1圈。你的整个团队都得完成。", + "Run real fast!": "快速奔跑!", + "Score ${ARG1} goals.": "${ARG1}进球得分。", + "Score ${ARG1} touchdowns.": "${ARG1}触地得分。", + "Score a goal.": "一次进球得分。", + "Score a touchdown.": "一次触地得分。", + "Score some goals.": "多次进球得分。", + "Secure all ${ARG1} flags.": "固定所有的${ARG1}旗帜。", + "Secure all flags on the map to win.": "固定地图上的所有旗帜来获得胜利。", + "Secure the flag for ${ARG1} seconds.": "固定旗帜${ARG1}秒。", + "Secure the flag for a set length of time.": "在设定时长内固定旗帜。", + "Steal the enemy flag ${ARG1} times.": "窃取敌人的旗帜${ARG1}次。", + "Steal the enemy flag.": "窃取敌人的旗帜。", + "There can be only one.": "仅单玩家可被选定。", + "Touch the enemy flag ${ARG1} times.": "触碰敌人的旗帜${ARG1}次。", + "Touch the enemy flag.": "触碰敌人的旗帜。", + "carry the flag for ${ARG1} seconds": "扛旗${ARG1}秒", + "kill ${ARG1} enemies": "杀死${ARG1}敌人", + "last one standing wins": "最终杀敌者获胜", + "last team standing wins": "最终杀敌团队获胜", + "return ${ARG1} flags": "交回${ARG1}旗帜", + "return 1 flag": "交回1面旗帜", + "run ${ARG1} laps": "跑${ARG1}圈", + "run 1 lap": "跑1圈", + "score ${ARG1} goals": "${ARG1}进球得分", + "score ${ARG1} touchdowns": "${ARG1}触地得分", + "score a goal": "一次进球得分", + "score a touchdown": "一次触地得分", + "secure all ${ARG1} flags": "固定所有的${ARG1}旗帜", + "secure the flag for ${ARG1} seconds": "固定旗帜${ARG1}秒", + "touch ${ARG1} flags": "触碰${ARG1}旗帜", + "touch 1 flag": "触碰1面旗帜" + }, + "gameNames": { + "Assault": "突袭战", + "Capture the Flag": "夺旗战", + "Chosen One": "选定模式", + "Conquest": "征服战", + "Death Match": "死亡竞赛", + "Easter Egg Hunt": "彩蛋猎人", + "Elimination": "消除战", + "Football": "运旗战", + "Hockey": "冰球战", + "Keep Away": "抓旗战", + "King of the Hill": "山丘之王", + "Meteor Shower": "流星战", + "Ninja Fight": "忍者大战", + "Onslaught": "冲锋战", + "Race": "竞速赛", + "Runaround": "塔防战", + "Target Practice": "目标训练", + "The Last Stand": "最终杀敌战" + }, + "inputDeviceNames": { + "Keyboard": "键盘", + "Keyboard P2": "键盘P2" + }, + "languages": { + "Arabic": "阿拉伯语", + "Belarussian": "白俄罗斯语", + "Chinese": "简体中文", + "ChineseSimplified": "简体中文", + "ChineseTraditional": "繁体中文", + "Croatian": "克罗地亚语", + "Czech": "捷克语", + "Danish": "丹麦语", + "Dutch": "荷兰语", + "English": "英语", + "Esperanto": "世界语", + "Filipino": "菲律宾语", + "Finnish": "芬兰语", + "French": "法语", + "German": "德语", + "Gibberish": "胡言乱语 - 用于测试", + "Greek": "希腊语", + "Hindi": "印度语", + "Hungarian": "匈牙利语", + "Indonesian": "印尼语", + "Italian": "意大利语", + "Japanese": "日本语", + "Korean": "朝鲜语", + "Malay": "马来语", + "Persian": "波斯文", + "PirateSpeak": "海盗语", + "Polish": "波兰语", + "Portuguese": "葡萄牙语", + "PortugueseBrazil": "葡萄牙语 - 巴西", + "PortuguesePortugal": "葡萄牙语 - 葡萄牙", + "Romanian": "罗马尼亚语", + "Russian": "俄语", + "Serbian": "塞尔维亚语", + "Slovak": "斯洛伐克语", + "Spanish": "西班牙语", + "SpanishLatinAmerica": "西班牙语 - 拉丁美洲", + "SpanishSpain": "西班牙语 - 西班牙", + "Swedish": "瑞典语", + "Tamil": "泰米尔语", + "Thai": "泰语", + "Turkish": "土耳其语", + "Ukrainian": "乌克兰语", + "Venetian": "威尼斯语", + "Vietnamese": "越南语" + }, + "leagueNames": { + "Bronze": "铜牌联赛", + "Diamond": "钻石联赛", + "Gold": "金牌联赛", + "Silver": "银牌联赛" + }, + "mapsNames": { + "Big G": "大G地图", + "Bridgit": "小桥地图", + "Courtyard": "庭院地图", + "Crag Castle": "岩城地图", + "Doom Shroom": "末日蘑菇地图", + "Football Stadium": "橄榄球场", + "Happy Thoughts": "快乐想法", + "Hockey Stadium": "曲棍球场地图", + "Lake Frigid": "寒湖地图", + "Monkey Face": "猴面地图", + "Rampage": "狂暴地图", + "Roundabout": "塔防地图", + "Step Right Up": "攻击地图", + "The Pad": "平板地图", + "Tip Top": "顶点地图", + "Tower D": "塔防地图", + "Zigzag": "蜿蜒地图" + }, + "playlistNames": { + "Just Epic": "仅限史诗级", + "Just Sports": "仅限运动类" + }, + "scoreNames": { + "Flags": "旗帜", + "Goals": "进球", + "Score": "得分", + "Survived": "幸存", + "Time": "时间", + "Time Held": "保持时间" + }, + "serverResponses": { + "A code has already been used on this account.": "该账户已使用代码。", + "A reward has already been given for that address.": "您已经领取过该奖励了", + "Account linking successful!": "账号连接成功!", + "Account unlinking successful!": "取消关联账户成功!", + "Accounts are already linked.": "账号已经连接。", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "广告加载失败。\n请验证你的游戏版本为官方最新版。", + "An error has occurred; (${ERROR})": "出现了一个错误; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "出现了一个错误,请联系官方获取支持.(${ERROR})", + "An error has occurred; please contact support@froemling.net.": "发生了一个错误,请联系 support@froemling.net。", + "An error has occurred; please try again later.": "发生了一个错误, 请稍候再试", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "确定要链接这些账户?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n此操作不可撤销!", + "BombSquad Pro unlocked!": "炸弹小分队专业版已解锁!", + "Can't link 2 accounts of this type.": "无法连接2个这种账号。", + "Can't link 2 diamond league accounts.": "无法连接两个钻石联赛账号。", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "无法连接,会超过上限 ${COUNT} 个账号。", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "发现作弊行为;得分及奖励在${COUNT}天内暂停。", + "Could not establish a secure connection.": "无法建立安全连接。", + "Daily maximum reached.": "已达今日上限。", + "Daily sign-in reward": "每日登录奖励", + "Entering tournament...": "进入锦标赛……", + "Invalid code.": "代码无效。", + "Invalid payment; purchase canceled.": "不可用的付款方式:交易取消", + "Invalid promo code.": "诶呀,代码好像无效了捏~", + "Invalid purchase.": "购买无效。", + "Invalid tournament entry; score will be ignored.": "由于你的联赛资料错误,分数会被忽略...", + "Item unlocked!": "项目已解除锁定!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "连接账号行为取消。${ACCOUNT} 含有\n重要数据可能会丢失。\n如果你想要的话,你可以反向链接账号。\n(那样就会丢失这个账号的数据)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "将帐户${ACCOUNT}关联到此帐户吗?\n${ACCOUNT}将共享数据。\n此操作不能撤销。", + "Longer streaks lead to better rewards.": "连续每日登录会获得更好的奖励", + "Max number of playlists reached.": "已达到最大列表数目。", + "Max number of profiles reached.": "已达到最大档案数目。", + "Maximum friend code rewards reached.": "邀请码奖励达到上限", + "Message is too long.": "诶呀,消息有点长捏~有话慢慢说", + "New tournament result!": "新的比赛结果!", + "No servers are available. Please try again soon.": "当前没有空余的服务器,请稍后再试", + "No slots available. Free a slot and try again.": "没有可用插槽。释放一个插槽并重试。", + "Profile \"${NAME}\" upgraded successfully.": "${NAME}档案升级成功。", + "Profile could not be upgraded.": "档案不可升级。", + "Purchase successful!": "购买成功!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "今日登录获得${COUNT}点券\n明日再来领取${TOMORROW_COUNT}点券", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本的游戏不再支持服务器功能;\n请更新到较新版本。", + "Sorry, there are no uses remaining on this code.": "对不起,此代码已经无法继续使用了。", + "Sorry, this code has already been used.": "对不起,此代码已被使用。", + "Sorry, this code has expired.": "对不起,此代码已失效。", + "Sorry, this code only works for new accounts.": "此代码只能新用户使用啊喂!你是新用户嘛", + "Sorry, this has expired.": "抱歉,已过期。", + "Still searching for nearby servers; please try again soon.": "正在搜索附近的服务器,请稍后再试", + "Streak: ${NUM} days": "已连续登录${NUM}天", + "Temporarily unavailable; please try again later.": "目前暂不可用;请稍候再试!", + "The tournament ended before you finished.": "本次锦标赛在你完成之前结束。", + "This account cannot be unlinked for ${NUM} days.": "此帐户无法在${NUM}天内取消关联。", + "This code cannot be used on the account that created it.": "此代码不可在创建其的账户上使用。", + "This is currently unavailable; please try again later.": "当前不可用:请稍后再试", + "This requires version ${VERSION} or newer.": "这需要版本${VERSION}或更高版本。", + "Tournaments disabled due to rooted device.": "此设备已Root或遭到未经授权的修改,已禁用锦标赛。", + "Tournaments require ${VERSION} or newer": "比赛需要${VERSION}或更高版本", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "从此帐户取消 ${ACCOUNT} 的关联?\n${ACCOUNT}上的所有数据将被重置。\n(在某些情况下除成就外)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:针对您的帐户发出黑客投诉。\n被盗用的帐户将被禁止。请公平竞技。", + "Wait reduced!": "等待减少!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "警告:此版本的游戏仅限于旧帐户数据;内容可能缺失或过时。\n请升级到较新版本的游戏以查看您的最新帐户数据。", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否将您的设备帐户关联到此?\n\n您的设备账户为${ACCOUNT1}\n此帐户为${ACCOUNT2}\n\n您可保存现有进度。\n警告: 此操作不可撤消!", + "You already own this!": "你已拥有了!", + "You can join in ${COUNT} seconds.": "你在${COUNT} 秒后可以加入", + "You don't have enough tickets for this!": "你的点券不足!", + "You don't own that.": "你没有真正购买它呢..", + "You got ${COUNT} tickets!": "你获得了${COUNT}点券!", + "You got ${COUNT} tokens!": "您获得了${COUNT}代币!", + "You got a ${ITEM}!": "你获得了一个${ITEM}!", + "You got a chest!": "你有获得了一个宝箱!", + "You got an achievement reward!": "你获得了成就奖励!", + "You have been promoted to a new league; congratulations!": "你已被升级至一个新联赛等级;恭喜!", + "You lost a chest! (All your chest slots were full)": "你丢了一个宝箱!(你所有的宝箱槽都已满)", + "You must update the app to view this.": "您必须更新应用程序才能查看此内容", + "You must update to a newer version of the app to do this.": "你必须升级到最新版本才可以", + "You must update to the newest version of the game to do this.": "你必须更新到最新版来做到这一点。", + "You must wait a few seconds before entering a new code.": "你必须在输入新代码前稍等几秒。", + "You placed #${RANK} in a tournament!": "您在锦标赛中排名 #${RANK}!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "你在上一场锦标赛中排名#${RANK}。多谢玩赏本游戏!", + "Your account was rejected. Are you signed in?": "您的账号被拒绝。您是否已登录?", + "Your ad views are not registering. Ad options will be limited for a while.": "广告观看数据有误,暂时无法继续观看广告", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "你的游戏已被修改。\n请撤销修改并使用官方最新版再重试。", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT}使用了你的分享代码了哦~" + }, + "settingNames": { + "1 Minute": "1分钟", + "1 Second": "1秒钟", + "10 Minutes": "10分钟", + "2 Minutes": "2分钟", + "2 Seconds": "2秒钟", + "20 Minutes": "20分钟", + "4 Seconds": "4秒钟", + "5 Minutes": "5分钟", + "8 Seconds": "8秒钟", + "Allow Negative Scores": "允许负分", + "Balance Total Lives": "平衡总生命", + "Bomb Spawning": "生成炸弹", + "Chosen One Gets Gloves": "选定目标获取手套", + "Chosen One Gets Shield": "选定目标获取盾牌", + "Chosen One Time": "选定模式时间", + "Enable Impact Bombs": "启用冲击炸弹", + "Enable Triple Bombs": "启用三连炸弹", + "Entire Team Must Finish": "整个队伍必须一起通过(一人跑路全队遭殃)", + "Epic Mode": "史诗模式", + "Flag Idle Return Time": "旗帜闲置返回时间", + "Flag Touch Return Time": "旗帜触碰返回时间", + "Hold Time": "保持时间", + "Kills to Win Per Player": "每一玩家取胜击杀数", + "Laps": "圈数", + "Lives Per Player": "每一玩家生命", + "Long": "长", + "Longer": "更长", + "Mine Spawning": "地雷增生", + "No Mines": "无地雷", + "None": "无", + "Normal": "正常", + "Pro Mode": "专业模式", + "Respawn Times": "复活时间", + "Score to Win": "得分取胜", + "Short": "短", + "Shorter": "更短", + "Solo Mode": "单人模式", + "Target Count": "目标计数", + "Time Limit": "时限" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM}被踢,因为 ${PLAYER}离开了(补药开全队通过)", + "Killing ${NAME} for skipping part of the track!": "杀死跳过部分赛道的${NAME}!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "警告 ${NAME}: 超幅 / 散播按钮 将使你被踢出。补药用连点啊!" + }, + "teamNames": { + "Bad Guys": "坏人队", + "Blue": "蓝队", + "Good Guys": "好人队", + "Red": "红队" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "一记完美、及时的“跑跳旋转拳”可一次性击杀敌人,并\n助你一生享有好友的尊重。", + "Always remember to floss.": "地面上的辅助线可能会有用。", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "请不要总是使用系统提供的随机档案,\n你可以在账户-玩家档案里创建自己的档案喵~", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢到医疗包。", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "尽管长相不同,所有人物的技能是相同的,\n所以只需随意挑选一个与你最相似的。", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因为拥有能量盾牌而狂妄自大;你仍然可能使自己坠入悬崖。", + "Don't run all the time. Really. You will fall off cliffs.": "不要一直奔跑,真的,你可能会坠入悬崖。", + "Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会傻乎乎地眩晕并摔倒。", + "Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按钮来奔跑。(如果你有的话,扳机按钮将会很有用)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑,比普通行走的速度会快得多。\n但是奔跑时不太好转弯,所以当心摔下悬崖。", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "冰冻炸弹伤害并不高,但它们能够冻结\n被伤到的人,然后他们身体会变得脆弱(一碰就碎)", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人把你抓起来了,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "如果您缺控制器,可以在手机安装「${REMOTE_APP_NAME}」\n然后手机就可以当作控制器啦~", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。炸弹\n可能被抖落,或如果没有其他办法,你最后的时刻将是有趣的。", + "If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍分数。", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个医疗包。", + "If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一个地方,你就完了。为了生存而奔跑和躲避……", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果众多玩家进进出出,在设置下打开“自动踢出闲置玩家”,以防\n任何玩家忘记离开游戏。", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的设备过热,或者你想要节省电池电量,\n则在设置->图形中调低“视觉效果”或“分辨率”", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "如果你的帧速率不稳定,请尝试在游戏的\n图形设置中调低分辨率或视觉效果。", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "在夺旗战中,你的旗帜必须位于你的基地才能得分,如果对方\n团队即将得分,窃取他们的旗帜是一个不错的阻止方法。", + "In hockey, you'll maintain more speed if you turn gradually.": "在冰球战中,逐渐转向将使你保持更快的速度。", + "It's easier to win with a friend or two helping.": "在拥有一名好友或两个帮扶的情况下更易获胜。", + "Jump just as you're throwing to get bombs up to the highest levels.": "就像你试图将炸弹扔到最高点那样跳起来。", + "Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敌人的一个很好的方式。", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多东西都可以捡起来并投掷,包括其他玩家。将你的\n敌人抛下悬崖可能是一个有效的且情感上可获得满足的策略。", + "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能跳上塔台去。你必须要用炸弹炸死塔台上的人。", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多数游戏中途加入或离开,\n同时,你也可以在百忙中插上或拔出手柄。", + "Practice using your momentum to throw bombs more accurately.": "多加练习,你的炸弹技能会变得更精准", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳头跑得越快,拳击的伤害越高,\n所以请成为飞奔的拳击手吧。", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投掷炸弹之前来回跑动,\n以“鞭打”炸弹,并将其投掷更远。", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸药箱附近引爆\n一个炸弹来消灭一群敌人。", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着一个生命的结束。", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "这一关卡永远不会结束,但是更高的得分将\n助你赢得全世界永恒的尊重。", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投掷力量取决于你所保持的方向。\n如要向前方轻轻投掷某物,不要保持在任何方向。", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "更换背景音乐?更换成你自己音乐吧!\n参见设置->音频->背景音乐", + "Try 'Cooking off' bombs for a second or two before throwing them.": "尝试在投掷之前将炸弹“爆燃”一秒或两秒。", + "Try tricking enemies into killing eachother or running off cliffs.": "试图诱使敌人互相厮杀或坠入悬崖。", + "Use the pick-up button to grab the flag < ${PICKUP} >": "使用拾取按钮来抢夺旗帜< ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "来回鞭打以投掷更远距离……", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "你可以通过左转或右转“瞄准”出拳。\n这有利于将坏人击倒出边界或在冰球战中得分。", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "你可以根据导火线火花的颜色判断炸弹什么时候爆炸:\n黄色……橙色……红色……嘭。", + "You can throw bombs higher if you jump just before throwing.": "如果投弹前跳起,你将投掷更远。", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "当你用头部重击物体时将受到伤害,\n所以尽量不要用头部重击物体。", + "Your punches do much more damage if you are running or spinning.": "如果你奔跑或旋转,拳击的伤害将更高。" + } + }, + "trophiesRequiredText": "你必须要有至少 ${NUMBER} 个奖杯", + "trophiesText": "奖杯", + "trophiesThisSeasonText": "本赛季奖杯", + "tutorial": { + "cpuBenchmarkText": "以惊人的速度运行教程(主要用于测试CPU速度)", + "phrase01Text": "嗨,您好!", + "phrase02Text": "欢迎来到${APP_NAME}!", + "phrase03Text": "以下是用于控制你的角色的一些技巧:", + "phrase04Text": "${APP_NAME}的很多方面是以物理为基础的。", + "phrase05Text": "例如,当你出拳时,", + "phrase06Text": "伤害程度取决于你拳头的速度。", + "phrase07Text": "看到没?如果我们不动,这样几乎不会伤害${NAME}。", + "phrase08Text": "现在,让我们跳跃并旋转起来,以获得更快的速度。", + "phrase09Text": "啊,这样好多了。", + "phrase10Text": "奔跑也会发挥作用。", + "phrase11Text": "按住任意按钮来奔跑。", + "phrase12Text": "想成为一拳超人,可以尝试边跑边旋转。", + "phrase13Text": "啊;真抱歉啊,${NAME}。(狗头)", + "phrase14Text": "你可以捡起并投掷物体,如旗帜或${NAME}。", + "phrase15Text": "最后,还有炸弹。", + "phrase16Text": "投掷炸弹需要练习。", + "phrase17Text": "大家不要学我这样丢...", + "phrase18Text": "跑起来有助你投掷得更远。", + "phrase19Text": "跳跃有助你投掷得更高。", + "phrase20Text": "“鞭打”你的炸弹以抛出更远的距离。", + "phrase21Text": "你还要卡准时机丢出炸弹。", + "phrase22Text": "我靠。", + "phrase23Text": "可以让火线先燃烧一秒或两秒。", + "phrase24Text": "好耶!差点秒杀~", + "phrase25Text": "好了,教程先到这里吧。", + "phrase26Text": "先尝试一波吧,老铁!", + "phrase27Text": "记住刚刚的教程,你会活着回来的!", + "phrase28Text": "......好吧,也许...", + "phrase29Text": "祝好运!", + "randomName1Text": "弗雷德", + "randomName2Text": "哈里", + "randomName3Text": "比尔", + "randomName4Text": "查克", + "randomName5Text": "菲尔", + "skipConfirmText": "确定跳过教程?点击或按下按钮以确认。(注意你不用跟着点!)", + "skipVoteCountText": "${COUNT}/${TOTAL}跳过投票", + "skippingText": "跳过教程……", + "toSkipPressAnythingText": "(点击或按下任何按钮以跳过教程)" + }, + "twoKillText": "双杀!", + "uiScaleText": "UI缩放", + "unavailableText": "不可用", + "unclaimedPrizesText": "您还有未领取的奖品!", + "unconfiguredControllerDetectedText": "检测到未配置的手柄:", + "unlockThisInTheStoreText": "这必须在商店中解锁。", + "unlockThisProfilesText": "如需创建超过 ${NUM} 个玩家档案,你需要", + "unlockThisText": "你需要这些来解锁", + "unsupportedControllerText": "抱歉,游戏不兼容你的控制器\"${NAME}\"", + "unsupportedHardwareText": "抱歉,此版本的游戏不支持该硬件。", + "upFirstText": "进入第一局:", + "upNextText": "进入比赛${COUNT}第二局:", + "updatingAccountText": "更新您的帐户……", + "upgradeText": "升级", + "upgradeToPlayText": "在游戏商店中解锁\"${PRO}\",以体验该游戏。", + "useDefaultText": "使用默认值", + "userSystemScriptsCreateText": "创建并启用外挂载内核代码(会禁用锦标赛)", + "userSystemScriptsDeleteText": "停用并删除外挂载内核代码(对内核的更改将被删除!)", + "usesExternalControllerText": "该游戏使用外部手柄进行输入。", + "usingItunesText": "使用音乐应用设置背景音乐……", + "v2AccountLinkingInfoText": "要关联V2账户,请点击“管理账户”喵~", + "v2AccountRequiredText": "仅V2账户支持此功能,请先升级账户", + "validatingTestBuildText": "测试版验证中……", + "viaText": "渠道账户:", + "victoryText": "胜利!", + "voteDelayText": "${NUMBER} 秒内你不能发起另一个投票", + "voteInProgressText": "已经有一个投票在进行中了", + "votedAlreadyText": "你已经投过票啦!", + "votesNeededText": "通过需要 ${NUMBER} 个投票", + "vsText": "vs.", + "waitingForHostText": "(请等待${HOST}继续游戏)", + "waitingForPlayersText": "等待玩家的加入……", + "waitingInLineText": "正在排队等候(人满为患)...", + "watchAVideoText": "看一个小广告视频", + "watchAnAdText": "观看广告", + "watchWindow": { + "deleteConfirmText": "删除\"${REPLAY}\"?", + "deleteReplayButtonText": "删除\n回放", + "myReplaysText": "我的回放", + "noReplaySelectedErrorText": "未选择回放", + "playbackSpeedText": "回放速度: ${SPEED}", + "renameReplayButtonText": "重命名\n录像", + "renameReplayText": "重命名\"${REPLAY}\"至:", + "renameText": "重命名", + "replayDeleteErrorText": "删除回放错误。", + "replayNameText": "回放名称", + "replayRenameErrorAlreadyExistsText": "该名称的回放已经存在。", + "replayRenameErrorInvalidName": "无法重命名回放;名称无效。", + "replayRenameErrorText": "重命名回放错误。", + "sharedReplaysText": "共享回放", + "titleText": "观看回放", + "watchReplayButtonText": "观看\n回放" + }, + "waveText": "波", + "wellSureText": "确定!", + "whatIsThisText": "这啥玩意??", + "winsPlayerText": "${NAME}获胜!", + "winsTeamText": "${NAME}获胜!", + "winsText": "${NAME}获胜!", + "workspaceSyncErrorText": "同步${WORKSPACE}出错了啦,详情见日志文件", + "workspaceSyncReuseText": "同步${WORKSPACE}时出错,正在使用以前同步的数据....", + "worldScoresUnavailableText": "全球得分不可用。", + "worldsBestScoresText": "全球最高得分", + "worldsBestTimesText": "全球最佳时间", + "yesAllowText": "是的,允许!", + "yourBestScoresText": "你的最高得分", + "yourBestTimesText": "你的最佳时刻", + "yourPrizeText": "您的奖品:" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/chinesetraditional.json b/dist/ba_data/data/languages/chinesetraditional.json index 5c26f30b..3393f3a7 100644 --- a/dist/ba_data/data/languages/chinesetraditional.json +++ b/dist/ba_data/data/languages/chinesetraditional.json @@ -6,7 +6,9 @@ "campaignProgressText": "戰役進度[困難]: ${PROGRESS}", "changeOncePerSeason": "每一賽季只有一次更改機會", "changeOncePerSeasonError": "您必須等${NUM}天到下個賽季改變此選項", + "createAnAccountText": "建立一個帳戶", "customName": "自定義名稱", + "deleteAccountText": "刪除帳戶", "googlePlayGamesAccountSwitchText": "如果您想使用其他 Google 帳戶,\n使用 Google Play 遊戲應用程序進行切換。", "linkAccountsEnterCodeText": "輸入代碼", "linkAccountsGenerateCodeText": "生成代碼", @@ -23,14 +25,16 @@ "setAccountNameDesc": "選擇你要為你帳號使用的遊戲內名稱。\n你直接使用你其中一個已連結的賬戶的名稱或\n創造一個獨特的自定義名稱。", "signInInfoText": "登入得以收集票卷,完成線上\n和與其他裝置共享進度", "signInText": "登入", + "signInWithAnEmailAddressText": "以電郵登入", "signInWithDeviceInfoText": "一個這裝置現有的自動帳號", "signInWithDeviceText": "使用設備賬戶登入", "signInWithGameCircleText": "使用Game Circle登入", "signInWithGooglePlayText": "用play商店登入", "signInWithTestAccountInfoText": "(舊有的帳號登入方式;使用後來的創設的帳號)", "signInWithTestAccountText": "用測試帳號登入", + "signInWithText": "通過${SERVICE}登錄", "signInWithV2InfoText": "(可用於所有平臺的賬戶)", - "signInWithV2Text": "使用Bombsquad賬戶登入", + "signInWithV2Text": "以${APP_NAME}登入", "signOutText": "登出", "signingInText": "登入中…", "signingOutText": "登出中…", @@ -332,9 +336,14 @@ "getMoreGamesText": "獲取更多比賽模式", "titleText": "新增比賽" }, + "addToFavoritesText": "添加到收藏", + "addedToFavoritesText": "已將'${NAME}'添加到收藏", + "allText": "全部", "allowText": "允許", "alreadySignedInText": "你的賬號已在其他設備上登錄\n請退出其他設備的登錄\n然後重試", "apiVersionErrorText": "無法加載模塊${NAME},它的API版本為${VERSION_USED},我們需要${VERSION_REQUIRED}。", + "applyText": "套用", + "areYouSureText": "確定?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(“自動”僅在插入耳機時有效)", "headRelativeVRAudioText": "頭戴式VR音頻", @@ -356,14 +365,24 @@ "boostText": "加速", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME}是在应用本身中配置的。", "buttonText": "按鈕", - "canWeDebugText": "你想要炸彈小分隊自動報告\n錯誤信息給開發人員嗎?\n\n信息中不包含個人信息\n可用於遊戲更加穩定", + "canWeDebugText": "你想要${APP_NAME}自動報告\n錯誤信息給開發人員嗎?\n\n信息中不包含個人信息\n可用於遊戲更加穩定", "cancelText": "取消", "cantConfigureDeviceText": "抱歉,${DEVICE}不可配置", "challengeEndedText": "此比賽挑戰已結束", "chatMuteText": "屏蔽消息", "chatMutedText": "屏蔽聊天信息", "chatUnMuteText": "取消屏蔽消息", + "chests": { + "prizeOddsText": "中獎機率", + "reduceWaitText": "減少等待", + "slotDescriptionText": "這個插槽可以容納一個箱子。\n\n透過玩戰役關卡贏取寶箱,\n參加比賽,並完成\n成就。", + "slotText": "寶箱槽 ${NUM}", + "slotsFullWarningText": "警告:您的所有寶箱槽都已滿。\n您在本遊戲中獲得的所有寶箱都將遺失。", + "unlocksInText": "解鎖" + }, "choosingPlayerText": "<選擇玩家>", + "claimText": "宣稱", + "codesExplainText": "代碼由開發者提供\n以診斷及改正帳戶問題。", "completeThisLevelToProceedText": "你需要先完成\n這一關", "completionBonusText": "完成獎勵", "configControllersWindow": { @@ -444,6 +463,7 @@ "swipeText": "滑動", "titleText": "觸屏操作設置" }, + "configureDeviceInSystemSettingsText": "${DEVICE}可以於系統設定中配置", "configureItNowText": "立即配置?", "configureText": "配置", "connectMobileDevicesWindow": { @@ -464,7 +484,7 @@ "activenessAllTimeInfoText": "不提供所有時間的排名", "activenessInfoText": "倍數隨著遊戲天數增加\n隨著離線天數減少", "activityText": "活動", - "campaignText": "比賽", + "campaignText": "徵戰", "challengesInfoText": "獲得完成迷你遊戲的獎勵\n\n每完成一項挑戰\n獎勵和難度就會隨之增加\n每挑戰失敗或放棄一次,獎勵和難度就會隨之下降", "challengesText": "挑戰", "currentBestText": "當前最高分", @@ -546,6 +566,7 @@ "demoText": "演示", "denyText": "拒絕", "deprecatedText": "棄用", + "descriptionText": "簡介", "desktopResText": "桌面分辨率", "deviceAccountUpgradeText": "警告:\n您已使用設備帳戶(${NAME})登錄。\n設備帳戶將在未來的更新中刪除。\n如果您想保留賬戶,請升級到 V2 帳戶。", "difficultyEasyText": "簡單", @@ -556,6 +577,10 @@ "disableRemoteAppConnectionsText": "取消Remote應用連接", "disableXInputDescriptionText": "允許使用四個以上的控制器,但可能不會正常工作", "disableXInputText": "禁用XInput", + "disabledText": "禁用", + "discardText": "丟棄", + "discordFriendsText": "想要尋找新的朋友一起遊玩嗎?\n快來加入我們的Discord社區發現新夥伴!", + "discordJoinText": "加入Discord社區", "doneText": "完成", "drawText": "平局", "duplicateText": "複製", @@ -588,6 +613,7 @@ "localProfileText": "(本地檔案)", "nameDescriptionText": "玩家名稱", "nameText": "名稱", + "profileAlreadyExistsText": "同樣名稱的使用者已存在!", "randomText": "隨機", "titleEditText": "編輯檔案", "titleNewText": "新建檔案", @@ -623,6 +649,7 @@ "useMusicFolderText": "音樂文件夾" }, "editText": "修改", + "enabledText": "啓用", "endText": "結束", "enjoyText": "盡情享用吧", "epicDescriptionFilterText": "史詩級慢動作${DESCRIPTION}", @@ -634,6 +661,8 @@ "errorText": "錯誤", "errorUnknownText": "未知錯誤", "exitGameText": "退出${APP_NAME}?", + "expiredAgoText": "${T} 前已過期", + "expiresInText": "${T} 後過期", "exportSuccessText": "退出'${NAME}'", "externalStorageText": "外部存儲器", "failText": "失敗", @@ -668,6 +697,8 @@ "duplicateText": "複製\n比賽列表", "editText": "編輯\n比賽列表", "newText": "新建\n比賽列表", + "pointsToWinText": "勝利分數", + "seriesLengthText": "遊戲長度", "showTutorialText": "顯示新手教程", "shuffleGameOrderText": "隨機比賽模式", "titleText": "自定義${TYPE}列表" @@ -693,6 +724,7 @@ "copyCodeConfirmText": "代碼已複製進剪切板", "copyCodeText": "複製此代碼", "dedicatedServerInfoText": "建立一個伺服器來獲取最佳效果,詳情見bombsquadgame.com/server", + "descriptionShortText": "使用「多人遊戲」視窗來創造多人遊戲。", "disconnectClientsText": "這將使派對中的${COUNT}位玩家斷開連接\n確定這麼做嗎?", "earnTicketsForRecommendingAmountText": "如果您的朋友們玩了這款遊戲,它們將會受到${COUNT}點券\n(每個遊玩的朋友會使你獲取${YOU_COUNT}點券)", "earnTicketsForRecommendingText": "分享遊戲來\n獲取免費點券...", @@ -705,10 +737,10 @@ "friendHasSentPromoCodeText": "從${NAME}中獲取到${COUNT}個${APP_NAME}點券", "friendPromoCodeAwardText": "每使用一次,你就會收到${COUNT}張點券", "friendPromoCodeExpireText": "此代碼將在${EXPIRE_HOURS}小時後失效,該代碼只對新玩家有效", - "friendPromoCodeInstructionsText": "要使用此代碼,可打開${APP_NAME}。通過“設置->高級設置->輸入促銷代碼”操作\n所有支持平台的下載鏈接可見bombsquadgame.com", + "friendPromoCodeInstructionsText": "要使用此代碼,可打開${APP_NAME}。通過“設置->高級設置->傳送資料”操作\n所有支持平台的下載鏈接可見bombsquadgame.com", "friendPromoCodeRedeemLongText": "達到${MAX_USES}人後就不能獲得${COUNT}免費點券(防止玩家作弊)", "friendPromoCodeRedeemShortText": "可在遊戲中兌換${COUNT}免費點券", - "friendPromoCodeWhereToEnterText": "(在“設置->高級設置->輸入促銷代碼”中)", + "friendPromoCodeWhereToEnterText": "(在 設置->高級設置->傳送資料 中)", "getFriendInviteCodeText": "獲取好友邀請碼", "googlePlayDescriptionText": "通過Google Play邀請玩家進入你的派對", "googlePlayInviteText": "邀請", @@ -740,6 +772,7 @@ "manualYourLocalAddressText": "本地地址:", "nearbyText": "附近", "noConnectionText": "<無連接>", + "noPartiesAddedText": "未添加派對", "otherVersionsText": "(其他版本)", "partyCodeText": "派對代碼", "partyInviteAcceptText": "接受", @@ -803,6 +836,12 @@ "youHaveShortText": "你擁有 ${COUNT}", "youHaveText": "你擁有 ${COUNT}點券" }, + "goldPass": { + "desc1InfTokensText": "無限代幣", + "desc2NoAdsText": "零廣告", + "desc3ForeverText": "直到永遠。", + "goldPassText": "黃金通行證" + }, "googleMultiplayerDiscontinuedText": "抱歉,Google的多人遊戲服務不再可用。\n我將盡快更換新的替代服務。\n在此之前,請嘗試其他連接方法。\n-Eric", "googlePlayPurchasesNotAvailableText": "Google Play購買不可用\n你可能需要更新你的Google Play商店組件", "googlePlayServicesNotAvailableText": "Google play當前不可用\n一些功能將會被禁用", @@ -811,10 +850,12 @@ "alwaysText": "總是", "fullScreenCmdText": "全屏顯示Cmd-F", "fullScreenCtrlText": "全屏顯示(Ctrl-F)", + "fullScreenText": "全屏", "gammaText": "Gamma", "highText": "高", "higherText": "最高", "lowText": "低", + "maxFPSText": "幀速上限", "mediumText": "中", "neverText": "關", "resolutionText": "分辨率", @@ -875,6 +916,7 @@ "importText": "導入", "importingText": "導入中...", "inGameClippedNameText": "名字會是\n\"${NAME}\"", + "inboxText": "收件匣", "installDiskSpaceErrorText": "錯誤:無法完成安裝\n你的設備磁盤空間不足\n請釋放一些空間後重試", "internal": { "arrowsToExitListText": "按${LEFT} 或 ${RIGHT} 退出列表", @@ -929,12 +971,14 @@ "timeOutText": "(將在${TIME} 秒後超出時限)", "touchScreenJoinWarningText": "你已以觸摸屏的方式加入\n如果這是一個錯誤,請手動退出遊戲", "touchScreenText": "觸摸屏", + "unableToCompleteTryAgainText": "現在無法完成此操作\n請稍後再試", "unableToResolveHostText": "錯誤:創建者網絡環境有問題", "unavailableNoConnectionText": "網絡連接故障", "vrOrientationResetCardboardText": "重置VR定位\n您需要用外部手柄來進行遊戲", "vrOrientationResetText": "VR定位重置", "willTimeOutText": "(若掛機則會超出時限)" }, + "inventoryText": "庫存", "jumpBoldText": "跳", "jumpText": "跳", "keepText": "舉起", @@ -981,8 +1025,11 @@ "seasonEndsMinutesText": "賽季將於${NUMBER}分鐘後結束", "seasonText": "第${NUMBER}賽季", "tournamentLeagueText": "你一定要到${NAME}聯賽後才能參加此賽事", - "trophyCountsResetText": "獎杯計數將於下個賽季重置" + "trophyCountsResetText": "獎杯計數將於下個賽季重置", + "upToDateBonusDescriptionText": "請使用最新遊戲版本\n來獲得${PERCENT}%額外賠率", + "upToDateBonusText": "最新版賠率" }, + "learnMoreText": "更多資訊...", "levelBestScoresText": "在${LEVEL}中的最高成績", "levelBestTimesText": "在${LEVEL}中的最佳時間", "levelIsLockedText": "${LEVEL}正在鎖定狀態", @@ -1026,6 +1073,8 @@ "modeArcadeText": "街機模式", "modeClassicText": "經典模式", "modeDemoText": "演示模式", + "moreSoonText": "更多內容即將推出...", + "mostDestroyedPlayerText": "被摧毀次數最多的球員", "mostValuablePlayerText": "最有價值的玩家", "mostViolatedPlayerText": "最遭受暴力的玩家", "mostViolentPlayerText": "最暴力的玩家", @@ -1042,6 +1091,7 @@ "nameSuicideText": "${NAME}自殺了.", "nameText": "名稱", "nativeText": "本機", + "newExclaimText": "全新!", "newPersonalBestText": "新個人最佳!", "newTestBuildAvailableText": "更新的測試版可供下載了! (${VERSION} 升級至 ${BUILD}).\n到${ADDRESS}獲取測試版", "newText": "新建", @@ -1052,12 +1102,16 @@ "noContinuesText": "(無可繼續)", "noExternalStorageErrorText": "該設備未發現外部存儲器", "noGameCircleText": "錯誤:未登錄GameCircle", + "noMessagesText": "沒有消息.", + "noPluginsInstalledText": "未安裝插件", "noScoresYetText": "沒有得分記錄", + "noServersFoundText": "未找到服務器", "noThanksText": "不,謝謝", "noTournamentsInTestBuildText": "注意:此測試版本的比賽分數將會被作廢", "noValidMapsErrorText": "沒有發現該比賽類型的有效地圖", "notEnoughPlayersRemainingText": "剩餘玩家不足,退出並開始新遊戲", "notEnoughPlayersText": "至少需要${COUNT}名玩家來開始遊戲", + "notEnoughTicketsText": "票不夠了!", "notNowText": "不是現在", "notSignedInErrorText": "你必須登入來進行該操作.", "notSignedInGooglePlayErrorText": "您必須通過Google Play登錄", @@ -1070,6 +1124,9 @@ "onText": "開", "oneMomentText": "請等待", "onslaughtRespawnText": "${PLAYER}將於${WAVE}波復活", + "openMeText": "打開我!", + "openNowText": "即時打開", + "openText": "打開", "orText": "${A} 或 ${B}", "otherText": "其他", "outOfText": "(在${ALL}名玩家中位列#${RANK})", @@ -1121,7 +1178,11 @@ "pleaseWaitText": "請稍等....", "pluginClassLoadErrorText": "加載插件類'${PLUGIN}'時出錯:${ERROR}", "pluginInitErrorText": "初始化插件'${PLUGIN}'時出錯:${ERROR}", + "pluginSettingsText": "插件設置", + "pluginsAutoEnableNewText": "自動啟用新插件", "pluginsDetectedText": "檢測到新插件。重新啓動以激活,或在設置中配置這些插件", + "pluginsDisableAllText": "禁用所有插件", + "pluginsEnableAllText": "啟用所有插件", "pluginsRemovedText": "${NUM}個插件已丟失", "pluginsText": "外掛程式", "practiceText": "練習", @@ -1151,10 +1212,12 @@ "punchText": "拳擊", "purchaseForText": "購買花費 ${PRICE}", "purchaseGameText": "購買遊戲", + "purchaseNeverAvailableText": "抱歉, 此版本並不支援遊戲購物。\n請於另一個平台上登入你的帳號,並於該處進行購買。", + "purchaseNotAvailableText": "此產品目前缺貨。。。", "purchasingText": "正在購買...", "quitGameText": "退出 ${APP_NAME}?", "quittingIn5SecondsText": "將於5秒後退出...", - "randomPlayerNamesText": "Reol,爆破鬼才,ZACK,炸蛋小分隊,隊友摧毀者,炸彈吞噬者,TNT的朋友,冰凍使者,田所浩二,拳擊高手,創世神,炸彈人,機械狂人,大發明家,吹噓海盜,末日預言者", + "randomPlayerNamesText": "爆破鬼才,ZACK,炸蛋小分隊,隊友摧毀者,炸彈吞噬者,TNT的朋友,冰凍使者,拳擊高手,創世神,炸彈人,機械狂人,大發明家,吹噓海盜,末日預言者", "randomText": "隨機", "rankText": "排行", "ratingText": "排名", @@ -1192,6 +1255,7 @@ "version_mismatch": "版本不匹配\n確保Bombsquad與Bombsquad手柄都是\n最新版本後重試" }, "removeInGameAdsText": "在商店中解鎖\"${PRO}\",以刪除遊戲中的廣告", + "removeInGameAdsTokenPurchaseText": "!!限時優惠!! 購買任何代幣包以移除廣告", "renameText": "重命名", "replayEndText": "結束回放", "replayNameDefaultText": "終場遊戲回放", @@ -1212,7 +1276,9 @@ "revertText": "還原", "runText": "運行", "saveText": "保存", - "scanScriptsErrorText": "掃描腳本時存在錯誤,查看錯誤日誌來了解詳情", + "scanScriptsErrorText": "錯誤掃描腳本。 有關詳細信息,請參閱日誌。", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 和 ${NUM} 個其他模塊需要針對 api ${API} 進行更新。", + "scanScriptsSingleModuleNeedsUpdatesText": "需要為 api ${API} 更新 ${PATH}。", "scoreChallengesText": "得分挑戰", "scoreListUnavailableText": "得分列表不可用", "scoreText": "得分", @@ -1223,6 +1289,7 @@ }, "scoreWasText": "(是 ${COUNT})", "selectText": "選擇", + "sendInfoDescriptionText": "把帳戶狀態以及遊戲狀態資料給予開發者。\n必須包括你的名稱,以及傳送資料理由。", "seriesWinLine1PlayerText": "贏得", "seriesWinLine1TeamText": "贏得", "seriesWinLine1Text": "贏得", @@ -1240,6 +1307,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(注意:遊戲內置輸入法只能讓輸入英文字符和部分符號)", "alwaysUseInternalKeyboardText": "使用遊戲內置輸入法", "benchmarksText": "基準/壓力測試", + "devToolsText": "開發工具", "disableCameraGyroscopeMotionText": "禁用陀螺儀畫面抖動", "disableCameraShakeText": "禁止畫面抖動", "disableThisNotice": "(可在高級設置中關閉此通知)", @@ -1248,14 +1316,22 @@ "enterPromoCodeText": "輸入促銷代碼", "forTestingText": "注意:這些數值僅用於測試,並會在退出遊戲後重置", "helpTranslateText": "${APP_NAME}的非英語翻譯是其他玩家\n共同努力的成果,如果你希望參與遊戲文本翻譯或修正\n請點擊以下連接。感謝大家對遊戲翻譯提出的貢獻", + "insecureConnectionsDescriptionText": "可以開放來自受限制國家或互聯網的網上遊玩\n因安全隱憂並不建議使用", + "insecureConnectionsText": "使用公開網絡連接", "kickIdlePlayersText": "自動踢出掛機玩家", "kidFriendlyModeText": "兒童模式(低暴力等)", "languageText": "語言", "moddingGuideText": "修改指南", + "moddingToolsText": "改裝工具", "mustRestartText": "你必須重啟遊戲才能生效", "netTestingText": "網絡連接測試", "resetText": "恢復默認", + "sendInfoText": "傳送資料", "showBombTrajectoriesText": "顯示炸彈軌跡", + "showDemosWhenIdleText": "掛機時展示遊戲示範", + "showDeprecatedLoginTypesText": "展示廢舊的登入選項", + "showDevConsoleButtonText": "顯示開發控制臺按鈕", + "showInGamePingText": "顯示遊戲內延遲", "showPlayerNamesText": "顯示玩家名稱", "showUserModsText": "顯示MOD安裝文件夾", "titleText": "高級設置", @@ -1263,7 +1339,7 @@ "translationFetchErrorText": "翻譯狀態不可用", "translationFetchingStatusText": "檢查翻譯進度...", "translationInformMe": "我的語言翻譯可更新時通知我", - "translationNoUpdateNeededText": "當前語言翻譯文本是最新的", + "translationNoUpdateNeededText": "當前語言翻譯文本是最新的!帥呀!", "translationUpdateNeededText": "**當前語言翻譯文本需要更新**", "vrTestingText": "VR 調試" }, @@ -1274,6 +1350,9 @@ "signInWithGameCenterText": "使用Game Center\n來登錄", "singleGamePlaylistNameText": "僅 ${GAME}", "singlePlayerCountText": "1 玩家", + "sizeLargeText": "大", + "sizeMediumText": "中", + "sizeSmallText": "小", "soloNameFilterText": "單挑模式 ${NAME}", "soundtrackTypeNames": { "CharSelect": "角色選擇", @@ -1299,6 +1378,7 @@ }, "spaceKeyText": "空格", "statsText": "統計", + "stopRemindingMeText": "別再提醒我了", "storagePermissionAccessText": "需要存儲權限", "store": { "alreadyOwnText": "您已擁有${NAME}!", @@ -1334,7 +1414,7 @@ "winterSpecialText": "冬季特售", "youOwnThisText": "-您已擁有-" }, - "storeDescriptionText": "8人派对游戏尽显疯狂!\n\n在爆炸类迷你游戏中炸飞您的好友(或电脑),如夺旗战、冰球战及史诗级慢动作死亡竞赛!\n\n简单的控制和广泛的手柄支持可轻松允许多达8人参与游戏;您甚至可以通过免费的“BombSquad Remote”应用将您的移动设备作为手柄使用!\n\n投射炸弹!\n\n更多信息,请登录www.froemling.net/bombsquad。", + "storeDescriptionText": "瘋狂的8人派對遊戲!!!\n\n在錦標賽或大小遊戲中(包括但不限於奪旗,冰球,慢動作的死亡競賽)用炸彈炸毁你的朋友(或人機)吧!\n\n簡易的控制模式以及廣泛的控制器支援令召集8個人變得相當容易;甚至可以用 BombSquad Remote 手機程式來用手機作為控制器!\n\n爆炸就是藝術!!\n\n更多資訊請查看www.froemling.net/bombsquad", "storeDescriptions": { "blowUpYourFriendsText": "炸飛你的朋友", "competeInMiniGamesText": "在從競速到飛行的迷你遊戲中一決高下", @@ -1346,6 +1426,8 @@ "storeText": "商店", "submitText": "提交", "submittingPromoCodeText": "正在提交代碼...", + "successText": "大功告成!", + "supportEmailText": "如果您在使用應用中遇到任何問題,\n請發送郵件至${EMAIL}.", "teamNamesColorText": "團隊名稱/顏色...", "telnetAccessGrantedText": "Telnet訪問以啟用", "telnetAccessText": "檢測到Telnet訪問,是否允許?", @@ -1355,6 +1437,7 @@ "testBuildValidatedText": "測試版已通過驗證,盡情享用", "thankYouText": "感謝你的支持!盡情享受遊戲!", "threeKillText": "三殺!!", + "ticketsDescriptionText": "點券可以解鎖新角色,新遊戲,新地圖\n以及更多在商店找到的東西\n\n你可以透過贏取寶箱來獲得更多點券\n( 方法包括:徵戰、錦標賽、成就)", "timeBonusText": "時間獎勵", "timeElapsedText": "時間耗盡", "timeExpiredText": "時間結束", @@ -1363,12 +1446,26 @@ "timeSuffixMinutesText": "${COUNT}分", "timeSuffixSecondsText": "${COUNT}秒", "tipText": "提示", - "titleText": "BombSquad", + "titleText": "炸彈小分隊", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "獲得代幣...", + "notEnoughTokensText": "代幣不足!", + "numTokensText": "${COUNT}代幣", + "openNowDescriptionText": "您有足夠的代幣\n現在打開這個 - 你不\n需要等待。", + "shinyNewCurrencyText": "炸彈小分隊 閃亮亮 的全新遊戲幣!!", + "tokenPack1Text": "50代幣", + "tokenPack2Text": "500代幣", + "tokenPack3Text": "1200代幣", + "tokenPack4Text": "2600代幣", + "tokensDescriptionText": "代幣能夠加速寶箱解鎖\n或其他遊戲及帳戶有關功能\n\n你可以於遊戲中贏取代幣或\n購買代幣包\n另外亦可以購買黃金通行證以得到無限代幣", + "youHaveGoldPassText": "你有黃金通行證\n所有費用已豁免\n盡情享用!!" + }, "topFriendsText": "最佳好友", "tournamentCheckingStateText": "檢查錦標賽狀態中,請稍後...", "tournamentEndedText": "此錦標賽已結束。新的錦標賽已開始", "tournamentEntryText": "錦標賽入口", + "tournamentFinalStandingsText": "最終排名", "tournamentResultsRecentText": "最近錦標賽結果", "tournamentStandingsText": "錦標賽積分榜", "tournamentText": "錦標賽", @@ -1424,6 +1521,18 @@ "Uber Onslaught": "高級衝鋒戰", "Uber Runaround": "高級塔防戰" }, + "displayItemNames": { + "${C} Tickets": "${C}點券", + "${C} Tokens": "${C}代幣", + "Chest": "寶箱", + "L1 Chest": "壹等寶箱", + "L2 Chest": "貳等寶箱", + "L3 Chest": "參等寶箱", + "L4 Chest": "肆等寶箱", + "L5 Chest": "伍等寶箱", + "L6 Chest": "陸等寶箱", + "Unknown Chest": "寶箱等級: 不明!" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "在一定時間內取代選定目標進而取得勝利\n殺死選定目標並取而代之", "Bomb as many targets as you can.": "盡可能多的摧毀炸毀", @@ -1528,6 +1637,7 @@ "Korean": "朝鮮語", "Malay": "馬來語", "Persian": "波斯文", + "PirateSpeak": "海盜口語", "Polish": "波蘭語", "Portuguese": "葡萄牙語", "Romanian": "羅馬尼亞語", @@ -1550,23 +1660,23 @@ "Silver": "銀牌" }, "mapsNames": { - "Big G": "大G", - "Bridgit": "小橋", + "Big G": "大G賽道", + "Bridgit": "布里吉特橋", "Courtyard": "庭院", - "Crag Castle": "岩城", - "Doom Shroom": "蘑菇雲", + "Crag Castle": "雙子岩城", + "Doom Shroom": "末日蘑菇谷", "Football Stadium": "橄欖球場", - "Happy Thoughts": "飛行地帶", + "Happy Thoughts": "快樂仙境", "Hockey Stadium": "冰球場", - "Lake Frigid": "寒湖", + "Lake Frigid": "冰湖賽道", "Monkey Face": "猴面", - "Rampage": "狂暴", - "Roundabout": "塔防", - "Step Right Up": "攻擊", - "The Pad": "平板", - "Tip Top": "頂點", - "Tower D": "塔防", - "Zigzag": "蜿蜒" + "Rampage": "狂暴擂台", + "Roundabout": "馬蹄木塔", + "Step Right Up": "對立戰地", + "The Pad": "平板高塔", + "Tip Top": "頂峰據點", + "Tower D": "D氏城堡", + "Zigzag": "蜿蜒地帶" }, "playlistNames": { "Just Epic": "僅限史詩級", @@ -1599,6 +1709,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "發現賬號作弊行為;得分及獎勵在${COUNT}天內暫停", "Could not establish a secure connection.": "無法建立安全連接", "Daily maximum reached.": "已達今日上限", + "Daily sign-in reward": "每天登入獎勵", "Entering tournament...": "進入錦標賽...", "Invalid code.": "代碼無效", "Invalid payment; purchase canceled.": "不可用的付款方式:交易取消", @@ -1608,11 +1719,14 @@ "Item unlocked!": "項目已解除綁定", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "連接賬號行為取消,${ACCOUNT}含有\n的重要數據可能會丟失\n如果想要關聯的話,你可以反向鏈接賬號\n(最好用自己的賬號進行關聯)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "確定將${ACCOUNT}關聯到此賬戶嗎\n${ACCOUNT}將共享數據\n可在30天后取消", + "Longer streaks lead to better rewards.": "連勝越長,獎勵越好", "Max number of playlists reached.": "已達到最大列表數", "Max number of profiles reached.": "已達到最大檔案數", "Maximum friend code rewards reached.": "邀請碼獎勵達到上限", "Message is too long.": "消息過長", + "New tournament result!": "新的比賽結果!", "No servers are available. Please try again soon.": "當前沒有空餘的伺服器,請稍後再試", + "No slots available. Free a slot and try again.": "沒有可用空位。釋放一個插槽並重試。", "Profile \"${NAME}\" upgraded successfully.": "\"${NAME}\"檔案升級成功", "Profile could not be upgraded.": "檔案不可升級", "Purchase successful!": "購買成功", @@ -1622,7 +1736,9 @@ "Sorry, this code has already been used.": "對不起,此代碼已被使用", "Sorry, this code has expired.": "對不起,此代碼已失效", "Sorry, this code only works for new accounts.": "對不起,此代碼僅適用於新用戶", + "Sorry, this has expired.": "抱歉,此物品已經過期。", "Still searching for nearby servers; please try again soon.": "正在查詢附近的伺服器,請稍後再試", + "Streak: ${NUM} days": "連勝: ${NUM}天", "Temporarily unavailable; please try again later.": "目前暫不可用,請稍後再試", "The tournament ended before you finished.": "本次錦標賽將於在你完成之前結束了", "This account cannot be unlinked for ${NUM} days.": "此賬戶在${NUM}天內無法取消關聯", @@ -1633,19 +1749,28 @@ "Tournaments require ${VERSION} or newer": "比賽需要${VERSION}或更高的版本", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "從此賬戶上取消${ACCOUNT}的關聯?\n${ACCOUNT}上的數據將會被重置\n(在某些情況下成就除外)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:針對你的賬戶發出黑客控訴\n被盜用的賬戶將被禁止。請公平競技", + "Wait reduced!": "等待減少!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "警告:本版本遊戲僅限舊帳號資料;東西可能會遺失或過時。\n請升級到較新版本的遊戲才能查看您最新的帳戶資料。", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否經你的賬戶連接到此?\n\n你的賬戶為${ACCOUNT1}\n此賬戶為${ACCOUNT2}\n\n你可以保存現有進度\n警告:此操作可在30天后取消", "You already own this!": "你已擁有這個", "You can join in ${COUNT} seconds.": "你可以在${COUNT}秒後加入", "You don't have enough tickets for this!": "你的點券不足", "You don't own that.": "你尚未擁有", "You got ${COUNT} tickets!": "你獲得了${COUNT}點券", + "You got ${COUNT} tokens!": "你獲得了${COUNT}代幣", "You got a ${ITEM}!": "你獲得了一個${ITEM}!", + "You got a chest!": "你獲得了一個寶箱!", + "You got an achievement reward!": "你獲得了一個成就獎項!", "You have been promoted to a new league; congratulations!": "你已經被升級至一個全新的聯賽:恭喜", + "You lost a chest! (All your chest slots were full)": "你失去了一個箱子! (您的所有寶箱槽都已滿)", + "You must update the app to view this.": "您必須更新應用程式才能查看此內容", "You must update to a newer version of the app to do this.": "你必須先更新遊戲才能這麼做", "You must update to the newest version of the game to do this.": "你必須更新到最新版本才可以執行此操作", "You must wait a few seconds before entering a new code.": "你必須要在輸入新代碼前等待一會", + "You placed #${RANK} in a tournament!": "你於錦標賽中得到第${RANK}名!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "你在上一場錦標賽中排名#${RANK},繼續加油", "Your account was rejected. Are you signed in?": "你的髒號被拒絕,您是否已登陸?", + "Your ad views are not registering. Ad options will be limited for a while.": "您的廣告瀏覽量未記錄。 廣告選項將在一段時間內受到限制。", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "您的遊戲副本已更改\n請恢復任何更改並重試", "Your friend code was used by ${ACCOUNT}": "${ACCOUNT}已使用您的促銷代碼" }, @@ -1702,51 +1827,51 @@ "Red": "紅隊" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "一记完美、及时的“跑跳旋转拳”可一次性击杀敌人,并\n助你一生享有好友的尊重。", - "Always remember to floss.": "地面上的辅助线可能会有用。", - "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "使用首选名称和外观,而非采用随机形式\n来为自己和好友创建玩家档案。", - "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢占一个生命值包。", - "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "尽管长相不同,所有人物的技能是相同的,\n所以只需随意挑选一个与你最相似的。", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因为拥有能量盾牌而狂妄自大;你仍然可能使自己坠入悬崖。", - "Don't run all the time. Really. You will fall off cliffs.": "不要总是奔跑。真的。你可能会坠入悬崖。", - "Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会眩晕并摔倒。", - "Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按钮来奔跑。(如果你有的话,扳机按钮将会很有用)", - "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑。你将会更快地抵达一些地方,\n但是转弯效果并不好,所以当心悬崖。", - "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "寒冰炸弹并非很厉害,但它们能够冻结\n任何被击中者,使他们极易粉碎。", - "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人将你提起,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "及時進行跑跳旋轉會打出完美的必殺拳,\n效率高, 而且會令你的朋友尊重你一世。", + "Always remember to floss.": "好孩子早晚刷牙,並且要善用牙線。", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "為自己與朋友製作玩家檔案並使用自己的愛稱及外貌,\n相對於隨機名稱更為易辨認。", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "詛咒之盒把你變成了一個定時炸彈。\n唯一的解決方法是迅速搶佔一個急救包。", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "儘管長相不同,所有人物的技能是相同的\n所以只需隨意挑選一個與你最相似的。", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因為擁有能量盾牌而狂妄自大;你仍然可能使自己墜入懸崖。", + "Don't run all the time. Really. You will fall off cliffs.": "不要總是奔跑。真的。你可能會墜入懸崖。", + "Don't spin for too long; you'll become dizzy and fall.": "不要旋轉得太久,不然你會眩暈並摔倒。", + "Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按鈕來奔跑。(如果你有的話,扳機按鈕將會很有用)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按鈕來奔跑。你將會更快地抵達一些地方,\n但是轉彎效果並不好,所以當心懸崖。", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "冰彈傷害力較低,但具有凍結效果\n被擊中者會無法動彈並變得極易粉碎。", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人將你捉住,出拳攻擊他們,他們便會放手。\n這在現實生活中同樣奏效。", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "如果您缺控制器,在手機上安裝「${REMOTE_APP_NAME}」\n並用手機當控制器。", - "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。你可能\n将炸弹抖落,或如果没有其他办法,你最后的时刻将是有趣的。", - "If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍积分。", - "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个生命值提升器。", - "If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一个地方,你就完了。为了生存而奔跑和躲避……", - "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果众多玩家进进出出,在设置下打开“自动踢出闲置玩家”,以防\n任何玩家忘记离开游戏。", - "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的设备过热,或者你想要节省电池电量,\n则在设置->图形中调低“视觉效果”或“分辨率”", - "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "如果你的帧速率不稳定,请尝试在游戏的\n图形设置中调低分辨率或视觉效果。", - "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "在夺旗战中,你的旗帜必须位于你的基地才能得分,如果对方\n团队即将得分,窃取他们的旗帜是一个不错的阻止方法。", - "In hockey, you'll maintain more speed if you turn gradually.": "在冰球战中,逐渐转向将使你保持更快的速度。", - "It's easier to win with a friend or two helping.": "在拥有一名好友或两个帮扶的情况下更易获胜", - "Jump just as you're throwing to get bombs up to the highest levels.": "就像你试图将炸弹扔到最高点那样跳起来。", - "Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敌人的一个很好的方式。", - "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多东西都可以捡起来并投掷,包括其他玩家。将你的\n敌人抛下悬崖可能是一个有效的且情感上可获得满足的策略。", - "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能在岩脊上起身。你必须要投掷炸弹", - "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多数游戏中途加入或离开,\n同时,你也可以在百忙中插上或拔出手柄。", - "Practice using your momentum to throw bombs more accurately.": "练习借助你的力量更准确地投掷炸弹。", - "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳头跑得越快,拳击的伤害越高,\n所以请成为飞奔的拳击手吧。", - "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投掷炸弹之前来回跑动,\n以“鞭打”炸弹,并将其投掷更远。", - "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸药箱附近引爆\n一个炸弹来消灭一群敌人。", - "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着游戏结束。", - "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "这一关卡永远不会结束,但是更高的得分将\n助你赢得全世界永恒的尊重。", - "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投掷力量取决于你所保持的方向。\n如要向前方轻轻投掷某物,不要保持在任何方向。", - "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "更换背景音乐?更换成你自己音乐吧!\n参见设置->音频->背景音乐", - "Try 'Cooking off' bombs for a second or two before throwing them.": "尝试在投掷之前将炸弹“爆燃”一秒或两秒。", - "Try tricking enemies into killing eachother or running off cliffs.": "试图诱使敌人互相厮杀或坠入悬崖。", - "Use the pick-up button to grab the flag < ${PICKUP} >": "使用拾取按钮来抢夺旗帜< ${PICKUP} >", - "Whip back and forth to get more distance on your throws..": "来回鞭打以投掷更远距离……", - "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "你可以通过左转或右转“瞄准”出拳。\n这有利于将坏人击倒出边界或在冰球战中得分。", - "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "你可以根据导火线火花的颜色判断炸弹什么时候爆炸:\n黄色……橙色……红色……嘭。", - "You can throw bombs higher if you jump just before throwing.": "如果投弹前跳起,你将投掷更远。", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "当你用头部重击物体时将受到伤害,\n所以尽量不要用头部重击物体。", - "Your punches do much more damage if you are running or spinning.": "如果你奔跑或旋转,拳击的伤害将更高。" + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一個黏黏彈將你困住,你應該四處跳動並轉圈。你\n有機會將炸彈抖落,或如果沒有其他辦法,你最後的時刻將是有趣的。", + "If you kill an enemy in one hit you get double points for it.": "如果你一擊秒殺一個敵人,你將獲得雙倍積分。", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你撿到一個詛咒之盒,你唯一的生存希望是\n在接下來的幾秒內找到一個生命值提升器。", + "If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一個地方,你就完了。為了生存而奔跑和躲避……", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果眾多玩家進進出出,在設置下打開“自動踢出閒置玩家”,\n以防任何玩家忘記離開遊戲。", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的設備過熱,或者你想要節省電池電量,\n則在設置->圖形中調低“視覺效果”或“分辨率”", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "如果你的幀速率不穩定,請嘗試在遊戲的\n圖形設置中調低分辨率或視覺效果。", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "在奪旗戰中,你的旗幟必須位於你的基地才能得分,\n如果敵隊即將得分,竊取他們的旗幟是一個不錯的阻止方法。", + "In hockey, you'll maintain more speed if you turn gradually.": "在冰球戰中,逐漸轉向將使你保持更快的速度。", + "It's easier to win with a friend or two helping.": "在擁有一名好友或兩個幫扶的情況下更易獲勝", + "Jump just as you're throwing to get bombs up to the highest levels.": "就像你試圖將炸彈扔到最高點那樣跳起來。", + "Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敵人的一個很好的方式。", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多東西都可以撿起來並投擲,包括其他玩家。將你的\n敵人拋下懸崖可能是一個有效的且情感上可獲得滿足的策略。", + "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能在攀上岩脊。你必須要投擲炸彈", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多數遊戲中途加入或離開,\n同時,你也可以在百忙中插上或拔出手柄。", + "Practice using your momentum to throw bombs more accurately.": "練習借助你的力量更準確地投擲炸彈。", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳頭跑得越快,拳擊的傷害越高,\n所以請成為飛奔的拳擊手吧。", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投擲炸彈之前來回跑動,\n以“鞭打”炸彈,並將其投擲更遠。", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸藥箱附近引爆\n一個炸彈來消滅一群敵人。", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "頭部是最脆弱的區域,所以一個黏黏彈\n接觸頭部通常便意味著遊戲結束。", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "這一關卡永遠不會結束,但是更高的\n得分將助你贏得永世之敬畏。", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投擲力量取決於你所保持的方向。\n如要向前方輕輕投擲某物,不要保持在任何方向。", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "不喜歡預設的音樂? 換成自己的音樂吧! \n參見 設置->音頻->背景音樂", + "Try 'Cooking off' bombs for a second or two before throwing them.": "嘗試在投擲之前將炸彈“爆燃”一秒或兩秒。", + "Try tricking enemies into killing eachother or running off cliffs.": "試圖誘使敵人互相殘殺或墜入懸崖。", + "Use the pick-up button to grab the flag < ${PICKUP} >": "使用拾取按鈕來搶奪旗幟< ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "來回鞭打以投擲更遠距離……", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "你可以通過左轉或右轉“瞄准”出拳。\n這有利於將壞人擊倒出邊界或在冰球戰中得分。", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "你可你可以根據導火線火花的顏色判斷炸彈什麼時候爆炸:\n黃色……橙色……紅色……嘭。", + "You can throw bombs higher if you jump just before throwing.": "如果投彈前跳起,你將投擲更遠。", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "當你用頭部重擊物體時將受到傷害,\n所以盡量不要用頭部重擊物體。", + "Your punches do much more damage if you are running or spinning.": "如果你奔跑或旋轉,拳擊的傷害將更高。" } }, "trophiesRequiredText": "你至少要擁有${NUMBER}個獎杯", @@ -1755,50 +1880,53 @@ "tutorial": { "cpuBenchmarkText": "以驚人的速度來運行遊戲教程(用於測試CPU上限)", "phrase01Text": "嘿,夥計", - "phrase02Text": "歡迎來到${APP_NAME}!", - "phrase03Text": "以下適用於此遊戲的一些技巧", - "phrase04Text": "${APP_NAME}在很多情況下還是很物理的", + "phrase02Text": "歡迎遊玩${APP_NAME}!", + "phrase03Text": "以下有一些適用於此遊戲的技巧:", + "phrase04Text": "${APP_NAME}在很多情況下是相當講求物理學的。", "phrase05Text": "比如,當你出拳時", "phrase06Text": "拳頭的傷害取決於你它的速度", - "phrase07Text": "看到了嗎,如果我們不動,這樣幾乎不會造成傷害${NAME}", + "phrase07Text": "看到了嗎?如果我們動也不動,我們幾乎無法傷害${NAME}。", "phrase08Text": "現在,讓我們跳躍並旋轉起來,以獲得更快的速度", - "phrase09Text": "啊,這樣就好多了", + "phrase09Text": "啊,這樣就好多了。", "phrase10Text": "奔跑也會發揮作用", "phrase11Text": "按住任意按鈕來奔跑", "phrase12Text": "如果要完成一個很棒的出拳,請持續奔跑和旋轉", - "phrase13Text": "humm 關於${NAME}我很抱歉", + "phrase13Text": "抱歉囉${NAME}, 犧牲是需要的。", "phrase14Text": "你可以撿起投擲物品,如炸彈、旗幟或${NAME}", - "phrase15Text": "最後還有炸彈", + "phrase15Text": "最後,當然有炸彈", "phrase16Text": "投擲炸彈需要練習", - "phrase17Text": "ahh這一次貌似並不漂亮", + "phrase17Text": "哎呀,這一次貌似並不漂亮", "phrase18Text": "移動有助於你投擲的更遠", "phrase19Text": "跳躍有助於你投擲的更高", "phrase20Text": "甩炸彈會讓你把炸彈投擲到更遠的位置", "phrase21Text": "把握好時間可能會十分困難", - "phrase22Text": "¿", + "phrase22Text": "我呸。", "phrase23Text": "嘗試將導火線控制的更加精準", - "phrase24Text": "OHHHHH爆炸就是藝術", - "phrase25Text": "OK已經很不錯了", - "phrase26Text": "現在去完成你的任務吧,兄弟", - "phrase27Text": "記住你的訓練,你會活著回來的", - "phrase28Text": "也許...是吧", - "phrase29Text": "祝你好運", - "randomName1Text": "Fred", - "randomName2Text": "Harry", - "randomName3Text": "Bill", - "randomName4Text": "Chuck", - "randomName5Text": "Phil", + "phrase24Text": "OHHHHH爆炸就是藝術!!!", + "phrase25Text": "OK, 教程來到這裏差不多了。", + "phrase26Text": "現在去完成你的任務吧,兄弟!", + "phrase27Text": "記住你的訓練,你會活著回來的!", + "phrase28Text": "應該會...吧", + "phrase29Text": "祝你好運 :)", + "randomName1Text": "弗雷迪", + "randomName2Text": "哈利", + "randomName3Text": "比爾", + "randomName4Text": "查克", + "randomName5Text": "菲利浦", "skipConfirmText": "確定要跳過教程?再次按下按鈕來確定", "skipVoteCountText": "${COUNT}/${TOTAL} 跳過投票", "skippingText": "跳過教程...", "toSkipPressAnythingText": "(按下任意鍵來跳過教程)" }, "twoKillText": "雙殺!", + "uiScaleText": "介面大小", "unavailableText": "不可用", + "unclaimedPrizesText": "您有無人領會的獎品!", "unconfiguredControllerDetectedText": "檢測到未配置的手柄", "unlockThisInTheStoreText": "這必須從商店解鎖", "unlockThisProfilesText": "如需創建超過${NUM}個檔案,你需要", "unlockThisText": "你需要這些來解鎖", + "unsupportedControllerText": "抱歉,不支持控制器\"${NAME}\"", "unsupportedHardwareText": "抱歉,此版本的遊戲不支持該硬件", "upFirstText": "進入第一局", "upNextText": "進入比賽${COUNT}第二局", @@ -1806,10 +1934,14 @@ "upgradeText": "升級", "upgradeToPlayText": "你必須在商店裡解鎖${PRO}以體驗此內容", "useDefaultText": "使用默認值", + "userSystemScriptsCreateText": "創建用家自訂程式碼", + "userSystemScriptsDeleteText": "拆除用家自訂程式碼", "usesExternalControllerText": "該遊戲使用外部手柄進行接入", "usingItunesText": "使用音樂軟件設置背景音樂...", "v2AccountLinkingInfoText": "要鏈接 V2 帳戶,請使用“管理帳戶”按鈕。", + "v2AccountRequiredText": "此需要V2帳戶。請更新帳戶後再試。", "validatingTestBuildText": "測試版驗證中", + "viaText": "其他賬戶", "victoryText": "勝利!", "voteDelayText": "你不能在${NUMBER}內發起一個新的投票", "voteInProgressText": "已經有一個投票正在進行中了", @@ -1874,5 +2006,6 @@ }, "yesAllowText": "是的,允許!", "yourBestScoresText": "最佳分數", - "yourBestTimesText": "最佳時間" + "yourBestTimesText": "最佳時間", + "yourPrizeText": "獎勵:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/croatian.json b/dist/ba_data/data/languages/croatian.json index e88c2e14..287e5129 100644 --- a/dist/ba_data/data/languages/croatian.json +++ b/dist/ba_data/data/languages/croatian.json @@ -7,7 +7,10 @@ "campaignProgressText": "Napredak kampanje[Teško]: ${PROGRESS}", "changeOncePerSeason": "Ovo možeš promjeniti samo jednom po sezoni.", "changeOncePerSeasonError": "Moraš pričekati sljedeču sezonu da promjeniš ovo(${NUM} days)", + "createAnAccountText": "Napravi racun", "customName": "Prilagođeno ime", + "deleteAccountText": "Izbriši račun", + "googlePlayGamesAccountSwitchText": "Ako želite koristiti drugi Google račun,\nidite u aplikaciju Google Play Igre za promijeniti račun.", "linkAccountsEnterCodeText": "Unesi kod", "linkAccountsGenerateCodeText": "Stvori kod", "linkAccountsInfoText": "(podijeli napredak na svim platformama)", @@ -15,6 +18,7 @@ "linkAccountsInstructionsText": "Da povežeš dva profila, stvori kod na \njednomod njih i unesi ga na drugom.\nNapredak i sve kupljeno bit će kombinirano.\nMožeš povezati najviše ${COUNT} profila.", "linkAccountsText": "Poveži profile", "linkedAccountsText": "Povezani računi:", + "manageAccountText": "Kontroliraj Račun", "nameChangeConfirm": "Promjeni svoje ime u ${NAME}?", "resetProgressConfirmNoAchievementsText": "Ovo će poništiti tvoj napredak u timskom modu i\ntvoje najbolje rezultate (ali ne i tvoje kupone).\nNemaš mogućnost povratka. Jesi li siguran?", "resetProgressConfirmText": "Ovo će poništiti tvoj napredak u timskom modu,\npostignuća, i vaše najbolje rezultate\n(ali ne i tvoje kupone). Nemaš mogućnost\npovratka. Jesi li siguran?", @@ -23,6 +27,7 @@ "setAccountNameDesc": "Odaberi koje ime da se prikaže za tvoj račun.\nMožeš koristiti ime jednog od tvojih povezanih računa\nili kreirati vlastito prilagođeno ime.", "signInInfoText": "Prijavi se da možeš dobivati kupone, natjecati\nse online, i dijeliti napredak između uređaja.", "signInText": "Prijavi se", + "signInWithAnEmailAddressText": "Uloguj se sa email adresom", "signInWithDeviceInfoText": "(automatski profil dostupan samo na ovom uređaju)", "signInWithDeviceText": "Prijavi se sa profilom uređaja", "signInWithGameCircleText": "Prijavi se sa Game Circle", @@ -41,6 +46,7 @@ "titleText": "Račun", "unlinkAccountsInstructionsText": "Odaberi račun za prekid veze.", "unlinkAccountsText": "Prekini vezu računa", + "unlinkLegacyV1AccountsText": "Odveži Stare (V1) Račune", "v2LinkInstructionsText": "Koristite ovu vezu za kreiranje računa ili prijavu.", "viaAccount": "(Preko ${NAME} računa)", "youAreSignedInAsText": "Prijavljeni ste kao:" @@ -334,9 +340,12 @@ "getMoreGamesText": "Još igara...", "titleText": "Dodaj igru" }, + "addToFavoritesText": "Dodaj u omiljene", + "allText": "Sve", "allowText": "Dopusti", "alreadySignedInText": "Tvoj akaunt je prijavljen sa drugog uredjaja;\nmolimo promenite akaunt ili zatvori igru na\ntvom drugom uredjaju i probaj opet.", "apiVersionErrorText": "Nemoguće je učitati modul ${NAME}; napravljen je za ${VERSION_USED} verziju aplikacije; potrebna je verzija ${VERSION_REQUIRED}.", + "areYouSureText": "Dali si siguran?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Automatski\" omogućuje ovo samo kad su slušalice priključene)", "headRelativeVRAudioText": "VR relativni zvuk", @@ -366,6 +375,9 @@ "chatMuteText": "Stišaj Chat", "chatMutedText": "Chat Stišan", "chatUnMuteText": "Upali Chat", + "chests": { + "reduceWaitText": "Skrati cekanje" + }, "choosingPlayerText": "", "completeThisLevelToProceedText": "Moraš završiti ovu\nrazinu da nastaviš!", "completionBonusText": "Završni bonus", @@ -501,6 +513,7 @@ "welcome2Text": "Možeš zarađivati kupone raznim aktivnostima.\nKupone možeš koristiti za otključavanje novih likova, mapa, i\nigara, ulaženje u turnire, i puno više.", "yourPowerRankingText": "Tvoja pozicija" }, + "copyConfirmText": "Kopirano na međuspremnik.", "copyOfText": "Kopija ${NAME}", "copyText": "Kopirati", "createEditPlayerText": "", @@ -547,7 +560,10 @@ "deleteText": "Izbriši", "demoText": "Demo", "denyText": "Odbij", + "deprecatedText": "Zastareno", + "descriptionText": "Diskripcija", "desktopResText": "Desktop rezolucija", + "deviceAccountUpgradeText": "Upozorenje:\nPrijavljeni ste s uređajnim računom\n(${NAME}).\nUređajni računi će biti izbrisani u budućem ažuriranju.", "difficultyEasyText": "Lagano", "difficultyHardOnlyText": "Samo u teškom modu", "difficultyHardText": "Teško", @@ -556,6 +572,8 @@ "disableRemoteAppConnectionsText": "Isključi konekciju Remote-aplikacije", "disableXInputDescriptionText": "Dozvoljava više od 4 kontrolera ali možda neće raditi dobro.", "disableXInputText": "Isključi XInput", + "disabledText": "Deaktiviraj", + "discordJoinText": "Pridruzi se diskordu", "doneText": "Gotovo", "drawText": "Neriješeno", "duplicateText": "Dupliciraj", @@ -589,6 +607,7 @@ "localProfileText": "(Lokalni profil)", "nameDescriptionText": "Ime Igrača", "nameText": "Ime", + "profileAlreadyExistsText": "Profil sa tim imenom već postoji", "randomText": "nasumično", "titleEditText": "Uredi Profil", "titleNewText": "Novi Profil", @@ -624,12 +643,15 @@ "useMusicFolderText": "Mapa s Glazbenim Datotekama" }, "editText": "Izmjeni", + "enabledText": "Aktiviraj", "endText": "Kraj", "enjoyText": "Uživaj", "epicDescriptionFilterText": "${DESCRIPTION} U epskom usporenom filmu.", "epicNameFilterText": "${NAME} (epski mod)", "errorAccessDeniedText": "pristup zabranjen", + "errorDeviceTimeIncorrectText": "Vrijeme vašeg uređaja je krivo za ${HOURS} sati.\nOvo će stvarati probleme.\nMolimo provjerite vaše postavke vremena i vremenske zone.", "errorOutOfDiskSpaceText": "nema prostora na disku", + "errorSecureConnectionFailText": "Nije moguće uspostaviti sigurnu vezu; internetska funkcionalnost može ne uspjeti.", "errorText": "Greška", "errorUnknownText": "nepoznata greška", "exitGameText": "Izlaz iz ${APP_NAME}?", @@ -739,6 +761,7 @@ "manualYourLocalAddressText": "Tvoja lokalna adresa:", "nearbyText": "Blizu", "noConnectionText": "", + "noPartiesAddedText": "Nema zurki dodanih", "otherVersionsText": "(druge verzije)", "partyCodeText": "Grupna šifra", "partyInviteAcceptText": "Prihvati", @@ -794,7 +817,7 @@ "ticketPack4Text": "Jumbo paket kupona", "ticketPack5Text": "Mamutski paket kupona", "ticketPack6Text": "Ultimativni paket kupona", - "ticketsFromASponsorText": "Dobij ${COUNT} kupona\nod sponzora", + "ticketsFromASponsorText": "Pogledaj reklamu\nza ${COUNT} kupona", "ticketsText": "${COUNT} kupona", "titleText": "Zaradi kupone", "unavailableLinkAccountText": "Nažalost, kupovina nije dostupna na ovoj platformi.\nKao zaobilazno rješenje, možete povezati račun s računom na \ndrugoj platformi i tamo nastaviti kupovinu.", @@ -804,12 +827,21 @@ "youHaveShortText": "imaš ${COUNT}", "youHaveText": "imaš ${COUNT} kupona" }, + "goldPass": { + "desc1InfTokensText": "Beskonacno tokena", + "desc2NoAdsText": "Nema reklama", + "desc3ForeverText": "Zauvjek.", + "goldPassText": "Zlatna propusnica" + }, "googleMultiplayerDiscontinuedText": "Oprostite, Google Play Games servis za partije u igrama više ne postoji.\nTrenutno radim na zamjeni što je brže moguće.\nTo tada, priključujte se u partije na druge načine.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google Play kupnje nisu dostupne.\nMožda ćete trebati ažurirati svoju trgovinu aplikacija.", + "googlePlayServicesNotAvailableText": "Google Play Services nije dostupan.\nNeke funkcionalnosti aplikacije mogu biti isključene.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Uvijek", "fullScreenCmdText": "Cijeli ekran (Cmd-F)", "fullScreenCtrlText": "Cijeli ekran (Ctrl-F)", + "fullScreenText": "Puni zaslon", "gammaText": "Svjetlina(Gamma)", "highText": "Visoko", "higherText": "Više", @@ -1003,6 +1035,7 @@ "creditsText": "Zasluge", "demoMenuText": "Demo izbornik", "endGameText": "Kraj igre", + "endTestText": "Završi Test", "exitGameText": "Izlaz iz igre", "exitToMenuText": "Povratak u izbornik?", "howToPlayText": "Kako igrati", @@ -1022,6 +1055,7 @@ "maxConnectionsText": "Maksimalna konekcija", "maxPartySizeText": "Maksimum veličine žurke", "maxPlayersText": "Maksimum igrača", + "merchText": "Roba!", "modeArcadeText": "Arkadni Mod", "modeClassicText": "Klasični Mod", "modeDemoText": "Demo Mod", @@ -1051,17 +1085,21 @@ "noContinuesText": "(bez nastavaka)", "noExternalStorageErrorText": "Vanjska pohrana nije pronađena", "noGameCircleText": "Greška: nisi prijavljen u GameCircle", + "noMessagesText": "Nema poruka.", "noProfilesErrorText": "Nemaš profila igrača, pa ti je samo ime '${NAME}' na raspolaganju. \nPođi pod Postavke->Profili igrača da sebi napraviš profil. ", "noScoresYetText": "Još nema rezultata.", + "noServersFoundText": "Nema nađenih servera.", "noThanksText": "Ne hvala", "noTournamentsInTestBuildText": "UPOZORENJE: Turnirski bodovi od ove test gradnje će biti ignorirani.", "noValidMapsErrorText": "Nijedna ispravna mapa nije pronađena za ovu igru.", "notEnoughPlayersRemainingText": "Nije ostalo dovoljno igrača; iziđi i započni novu igru.", "notEnoughPlayersText": "Trebaš najmanje ${COUNT} igrača da započneš ovu igru!", + "notEnoughTicketsText": "Nemaš dovoljno kupona!", "notNowText": "Ne sad", "notSignedInErrorText": "Moraš se prijaviti da uradiš ovo.", "notSignedInGooglePlayErrorText": "Moraš se ulogovati preko Google pleja da uradiš ovo.", "notSignedInText": "nisi prijavljen", + "notUsingAccountText": "Bilješka: ignoriranje ${SERVICE} račun.\nIdite u 'Račun -> Prijavite se s ${SERVICE} ako ga želite koristiti.", "nothingIsSelectedErrorText": "Ništa nije odabrano!", "numberText": "#${NUMBER}", "offText": "Isključeno", @@ -1069,6 +1107,9 @@ "onText": "Uključeno", "oneMomentText": "Jedan trenutak...", "onslaughtRespawnText": "${PLAYER} će se ponovno pojaviti u naletu ${WAVE}", + "openMeText": "Otvori me!", + "openNowText": "Otvori sada", + "openText": "Otvori", "orText": "${A} ili ${B}", "otherText": "Drugo...", "outOfText": "(#${RANK} od ${ALL})", @@ -1120,7 +1161,11 @@ "pleaseWaitText": "Molimo sačekajte...", "pluginClassLoadErrorText": "Pogreška učitavanja dodatka klase '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Pogreška iniciranja dodatka '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Postavke Dodataka", + "pluginsAutoEnableNewText": "Automatski Uključi Nove Dodatke", "pluginsDetectedText": "Novi dodatak(ci) detektiran(i) Resetiraj da ih ukljućiš ili ih konfiguriraj u postavkima", + "pluginsDisableAllText": "Isključi Sve Dodatke", + "pluginsEnableAllText": "Uključi Sve Dodatke", "pluginsRemovedText": "${NUM} dodatak/ci više nisu pronađeni.", "pluginsText": "Dodatci", "practiceText": "Vježba", @@ -1212,7 +1257,7 @@ "revertText": "Poništi", "runText": "Trk", "saveText": "Spremi", - "scanScriptsErrorText": "Greška(e) skeniranja skripra; provjerite dnevnik za detalje.", + "scanScriptsErrorText": "Greška(e) skeniranja skripta. Provjerite dnevnik za detalje", "scoreChallengesText": "Izazovi za rezultat", "scoreListUnavailableText": "Lista s rezultatima nedostupna.", "scoreText": "Rezultat", @@ -1257,6 +1302,7 @@ "netTestingText": "Testiranje mreže", "resetText": "Poništi", "showBombTrajectoriesText": "Pokaži putanju bombe", + "showInGamePingText": "Prikaži Ping", "showPlayerNamesText": "Pokaži imena igrača", "showUserModsText": "Pokaži mapu za modove", "titleText": "Napredno", @@ -1369,14 +1415,20 @@ "tipText": "Savjet", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Nabavi tokene", + "notEnoughTokensText": "Nemas dovoljno tokena!" + }, "topFriendsText": "Prijatelji s najboljim rezultatima", "tournamentCheckingStateText": "Provjeravam stanje turnira; molim pričekaj...", "tournamentEndedText": "Ovaj turnir je završio. Novi će započeti ubrzo.", "tournamentEntryText": "Kotizacija", + "tournamentFinalStandingsText": "Finalna rijesenja", "tournamentResultsRecentText": "Nedavni Rezultati turnira", "tournamentStandingsText": "Poredak", "tournamentText": "Turnir", "tournamentTimeExpiredText": "Vrijeme turnira je isteklo", + "tournamentsDisabledWorkspaceText": "Turnamenti su deaktivirani kad su radni prostori upaljeni.\nDa re-aktiviraš turnamente, ugasi svoj radni prostor i resetiraj.", "tournamentsText": "Turniri", "translations": { "characterNames": { @@ -1529,6 +1581,7 @@ "Italian": "Talijanski", "Japanese": "Japanski", "Korean": "Korejski", + "Malay": "Malajski", "Persian": "Perzijski", "Polish": "Poljski", "Portuguese": "Portugalski", @@ -1614,6 +1667,7 @@ "Max number of profiles reached.": "Max broj dosegao profila.", "Maximum friend code rewards reached.": "Maksimalne nagrade od prijateljskih kodova dostignute.", "Message is too long.": "Poruka je prevelika.", + "New tournament result!": "Novi rezultat turnira!", "No servers are available. Please try again soon.": "Nema dostupnih servera. Pokušajte opet kasnije.", "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" uspjesno upgrajdovan", "Profile could not be upgraded.": "Profil se ne može ažurirati.", @@ -1812,6 +1866,7 @@ "usesExternalControllerText": "Ova igra koristi vanjski kontroler za kretanje.", "usingItunesText": "Koristim glazbenu aplikaciju za glazbenu listu...", "usingItunesTurnRepeatAndShuffleOnText": "Molim provjeri da je opcija shuffle uključena, a opcija repeat postavljena na SVE na iTunes. ", + "v2AccountLinkingInfoText": "Za povezivanje V2 računa, korist 'Upravlaj računima' botun", "validatingTestBuildText": "Potvrđujem testnu verziju...", "victoryText": "Pobjeda!", "voteDelayText": "Nemožeš započeti još jedno glasanje ${NUMBER} sekundi", @@ -1844,19 +1899,20 @@ }, "waveText": "Nalet", "wellSureText": "Sigurno!", + "whatIsThisText": "Što je ovo?", "wiimoteLicenseWindow": { "titleText": "DarwiinRemote Copyright" }, "wiimoteListenWindow": { - "listeningText": "Tražim Wiimote-ove...", - "pressText": "Pritisni Wiimote tipke 1 i 2 istovremeno.", - "pressText2": "Na novijim Wiimote-ovima s ugrađenim Motion Plus-om, umjesto njih pritisni crvenu 'sync' tipku na poleđini." + "listeningText": "Tražim Wiimote-ove... ", + "pressText": "Pritisni Wiimote tipke 1 i 2 istovremeno. ", + "pressText2": "Na novijim Wiimote-ovima s ugrađenim Motion Plus-om, umjesto njih pritisni crvenu 'sync' tipku na poleđini. " }, "wiimoteSetupWindow": { "copyrightText": "DarwiinRemote Copyright", "listenText": "Traži", "macInstructionsText": "Provjeri da je tvoj Wii isključen, a Bluetooth uključen\nna tvome Macu, pa pritisni 'Traži'. Podrška za Wiimote-ove\nmože biti malo nestabilna, pa ćeš možda morati pokušati nekoliko puta\nprije nego što uspostaviš vezu.\n\nBluetooth bi trebao podržati do 7 povezanih uređaja,\nmada bi tvoja udaljenost mogla varirati.\n\nBombSquad podržava originalne Wiimote-ove, Nunchuk-ove,\ni Classic Controller.\nNoviji Wii Remote Plus sada radi,\nali ne s dodacima.", - "thanksText": "Hvala DarwiinRemote timu\nšto je ovo omogućio.", + "thanksText": "Hvala DarwiinRemote timu\nšto je ovo omogućio. ", "titleText": "Podešavanje Wiimote-ova" }, "winsPlayerText": "${NAME} pobjeđuje!", @@ -1870,7 +1926,7 @@ "xbox360ControllersWindow": { "getDriverText": "Nabavi driver", "macInstructions2Text": "Da možeš koristiti kontrolere bežično, trebat ćeš i reciever koji\ndolazi u 'Xbox 360 Wireless Controller for Windows' paketu.\nJedan reciever omogućuje ti da povežeš do 4 kontrolera.\n\nVažno: recieveri trećih strana neće raditi s ovim driverom; \nprovjeri da na tvom recieveru piše 'Microsoft', a ne 'XBOX 360'.\nMicrosoft ih više ne prodaje odvojeno, pa ćeš morati nabaviti\njednoga u paketu s kontrolerom ili potraži na ebayu.\n\nAko ti je ovo bilo korisno, molim te razmisli o donaciji\nprogrameru drivera na njegovoj stranici.", - "macInstructionsText": "Da možeš koristiti Xbox 360 kontrolere, morat ćeš instalirati\nMac driver dostupan na poveznici ispod. \nRadi i sa žičnim i s bežičnim kontrolerima.", + "macInstructionsText": "Da možeš koristiti Xbox 360 kontrolere, morat ćeš instalirati\nMac driver dostupan na poveznici ispod. \nRadi i sa žičnim i s bežičnim kontrolerima. ", "ouyaInstructionsText": "Za korištenje žičnih Xbox 360 kontrolera s BombSquadom, jednostavno\nih uključi u USB ulaz tvog uređaja. Možeš koristiti USB hub\nda priključiš više kontrolera.\n\nZa korištenje bežičnih kontrolera trebat ćeš bežični reciever, \nkoji je dostupan kao dio \"Xbox 360 wireless Controller for Windows\" \npaketa ili u slobodnoj prodaji. Svaki se reciever priključuje u USB ulaz i\nomogućuje ti da povežeš do 4 bežična kontrolera.", "titleText": "Korišćenje Xbox 360 kontrolera sa $(APP_NAME)" }, diff --git a/dist/ba_data/data/languages/czech.json b/dist/ba_data/data/languages/czech.json index f7cdb15d..0979ac5e 100644 --- a/dist/ba_data/data/languages/czech.json +++ b/dist/ba_data/data/languages/czech.json @@ -1,13 +1,15 @@ { "accountSettingsWindow": { - "accountNameRules": "Jména účtů nemůžou obsahovat smajlíky ani jiné speciální znaky", + "accountNameRules": "Jména účtů nemůžou obsahovat emoji ani jiné speciální znaky", "accountProfileText": "(Aktuální profil)", "accountsText": "Účty", - "achievementProgressText": "Achievementy: ${COUNT}/${TOTAL}", - "campaignProgressText": "Postup Kampaně [Těžká]: ${PROGRESS}", + "achievementProgressText": "Trofeje: ${COUNT}/${TOTAL}", + "campaignProgressText": "Postup kampaně [Těžká]: ${PROGRESS}", "changeOncePerSeason": "Lze změnit pouze jednou za sezónu.", "changeOncePerSeasonError": "Chcete-li toto změnit znovu, musíte počkat na další sezónu (${NUM} days)", - "customName": "Vlastní Jméno", + "createAnAccountText": "Založit účet", + "customName": "Vlastní jméno", + "deleteAccountText": "Smazat Účet", "googlePlayGamesAccountSwitchText": "Pokud chcete použít jiný Google účet,\npoužijte pro změnu aplikaci Google Play Hry.", "linkAccountsEnterCodeText": "Vložit kód", "linkAccountsGenerateCodeText": "Generovat kód", @@ -16,24 +18,26 @@ "linkAccountsInstructionsText": "Pokud chcete propojit účty, na jednom z nich generujte kód\na na druhém tento kód zadejte.\nPostup a inventář bude zkombinován.\nMůžete propojit až ${COUNT} účtů.\n\nDŮLEŽITÉ: PROPOJUJTE POUZE ÚČTY KTERÉ JSOU VAŠE!\nPOKUD PROPOJÍTE ÚČTY S KAMARÁDEM, NEBUDETE MOCI\nHRÁT OBA VE STEJNÝ ČAS!\n\nDobře si to rozmyslete; Tuto akci nelze vrátit zpět!", "linkAccountsText": "Propojit účty", "linkedAccountsText": "Propojené účty:", - "manageAccountText": "Spravovat Účet", + "manageAccountText": "Spravovat účet", "nameChangeConfirm": "Přejete si změnit jméno účtu na ${NAME}?", "notLoggedInText": "", - "resetProgressConfirmNoAchievementsText": "Jste si jistí, že to chcete udělat?\nTímto NENÁVRATNĚ resetujete veškerý postup Co-op\na lokální nejlepší výsledky (ale kupóny vám zůstanou).", - "resetProgressConfirmText": "Jste si jistí, že to chcete udělat?\nTímto NENÁVRATNĚ resetujete veškerý postup Co-Op,\nachievementy a lokální nejlepší výsledky.\n(ale kupóny vám zůstanou)", - "resetProgressText": "Resetovat Postup", + "resetProgressConfirmNoAchievementsText": "Toto resetuje váš postup v Co-op\na lokální rekordy (ale ne vaše kupóny).\nToto je nenávratné. Jste si jisti?", + "resetProgressConfirmText": "Toto resetuje váš postup v Co-op,\ntrofeje a lokální rekordy (ale ne vaše kupóny).\nToto je nenávratné. Jste si jisti?", + "resetProgressText": "Resetovat postup", "setAccountName": "Nastavit jméno účtu", "setAccountNameDesc": "Vyberte si jméno pro váš účet.\nMůžete použít jedno ze svých již\npoužitých nebo si vytvořit nové.", - "signInInfoText": "Přihlašte se, abyste mohli sbírat kupóny, soupeřit online,\na sdílet postup mezi zařízeními.", + "signInInfoText": "Přihlašte se, abyste mohli sbírat kupóny, soupeřit online\na sdílet postup mezi zařízeními.", "signInText": "Přihlásit", + "signInWithAnEmailAddressText": "Přihlášení s emailem", "signInWithDeviceInfoText": "(automaticky vytvořený účet dostupný pouze na tomto zařízení)", "signInWithDeviceText": "Přihlásit se s účtem zařízení", - "signInWithGameCircleText": "Přihlásit se s ,,Game circle\"", + "signInWithGameCircleText": "Přihlásit se s přes Game Circle", "signInWithGooglePlayText": "Přihlásit se přes Google Play", "signInWithTestAccountInfoText": "(zastaralý typ účtu; použije raději účet zařízení)", "signInWithTestAccountText": "Přihlásit se s testovacím účtem", + "signInWithText": "Přihlásit se s ${SERVICE}", "signInWithV2InfoText": "(účet který funguje na všech platformách)", - "signInWithV2Text": "Přihlášení s BombSquad účtem", + "signInWithV2Text": "Přihlášení s ${APP_NAME} účtem", "signOutText": "Odhlásit se", "signingInText": "Přihlašuji se...", "signingOutText": "Odhlašuji se...", @@ -44,14 +48,14 @@ "titleText": "Profil", "unlinkAccountsInstructionsText": "Zvolte účet k odpojení", "unlinkAccountsText": "Odpojit účty", - "unlinkLegacyV1AccountsText": "na rozdíl od starších účtů (V1).", + "unlinkLegacyV1AccountsText": "Odpojit zastaralé (V1) účty", "v2LinkInstructionsText": "Použijte tento odkaz pro vytvoření účtu nebo přihlášení.", "viaAccount": "(přes účet ${NAME})", "youAreLoggedInAsText": "Jste přihlášen jako:", - "youAreSignedInAsText": "Jste přihlášen jako:" + "youAreSignedInAsText": "Jste přihlášeni jako:" }, - "achievementChallengesText": "Ocenění Výzev", - "achievementText": "Úspěch", + "achievementChallengesText": "Trofeje Výzev", + "achievementText": "Trofej", "achievements": { "Boom Goes the Dynamite": { "description": "Zabijte 3 padouchy pomocí TNT", @@ -68,20 +72,20 @@ "name": "Boxer" }, "Dual Wielding": { - "descriptionFull": "Připojte alespoň 2 ovladače (Hardware nebo aplikaci)", - "descriptionFullComplete": "Připojeno alespoň 2 ovladače (hardware/aplikaci)", + "descriptionFull": "Připojte alespoň 2 ovladače (fyzické nebo aplikaci)", + "descriptionFullComplete": "Připojeny alespoň 2 ovladače (fyzické/aplikace)", "name": "Ovladačový maniak" }, "Flawless Victory": { - "description": "Vyhrajte aniž byste byly zasaženi", - "descriptionComplete": "Vyhráli jste aniž byste byly zasaženi", + "description": "Vyhrajte, aniž byste byli zasaženi", + "descriptionComplete": "Vyhráli jste, aniž byste byli zasaženi", "descriptionFull": "Vyhrajte ${LEVEL} aniž byste byli zasaženi", "descriptionFullComplete": "Vyhráli jste ${LEVEL} aniž byste byli zasaženi", "name": "Bezvadná Výhra" }, "Free Loader": { - "descriptionFull": "Začněte hru ,,všichni proti všem\" s alespoň 2 hráči", - "descriptionFullComplete": "Začali jste ,,všichni proti všem\" hru s více jak 2 hráči", + "descriptionFull": "Začněte hru Všichni Proti Všem s alespoň 2 hráči", + "descriptionFullComplete": "Začali jste hru Všichni Proti Všem s více jak 2 hráči", "name": "Všichni proti všem!!!" }, "Gold Miner": { @@ -99,8 +103,8 @@ "name": "Naučit se kroky" }, "In Control": { - "descriptionFull": "Připojte ovladač (hardware/aplikaci)", - "descriptionFullComplete": "Připojen ovladač (hardware/aplikaci)", + "descriptionFull": "Připojte ovladač (fyzický/aplikace)", + "descriptionFullComplete": "Připojen ovladač (fyzický/aplikace)", "name": "Ve spojení" }, "Last Stand God": { @@ -125,18 +129,18 @@ "name": "${LEVEL} Kouzelník" }, "Mine Games": { - "description": "Zabij 3 padouchy pomocí min", + "description": "Zabijte 3 padouchy pomocí min", "descriptionComplete": "Zabili jste 3 padouchy pomocí min", - "descriptionFull": "Zabij 3 padouchy pomocí min v ${LEVEL}", + "descriptionFull": "Zabijte 3 padouchy pomocí min v ${LEVEL}", "descriptionFullComplete": "Zabili jste 3 padouchy pomocí min v ${LEVEL}", "name": "Minové hry" }, "Off You Go Then": { - "description": "Vyhoď 3 padouchy pryč z mapy", + "description": "Vyhoďte 3 padouchy pryč z mapy", "descriptionComplete": "Vyhodili jste 3 padouchy pryč z mapy", "descriptionFull": "Vyhoďte 3 padouchy pryč z mapy v ${LEVEL}", "descriptionFullComplete": "Vyhodili jste 3 padouchy pryč z mapy v ${LEVEL}", - "name": "Je čas, aby jsi odešel" + "name": "Je na čase abys odešel" }, "Onslaught God": { "description": "Získejte 5000 bodů", @@ -181,10 +185,10 @@ "name": "Profi Boxer" }, "Pro Football Shutout": { - "description": "Vyhrajte aniž by padouši skórovali", - "descriptionComplete": "Vyhráli jste aniž by padouši skórovali", - "descriptionFull": "Vyhrajte ${LEVEL} aniž by padouši skórovali", - "descriptionFullComplete": "Vyhráli jste ${LEVEL} aniž by padouši skórovali", + "description": "Vyhrajte, aniž by padouši skórovali", + "descriptionComplete": "Vyhráli jste, aniž by padouši skórovali", + "descriptionFull": "Vyhrajte ${LEVEL}, aniž by padouši skórovali", + "descriptionFullComplete": "Vyhráli jste ${LEVEL}, aniž by padouši skórovali", "name": "${LEVEL} Bezchybná výhra" }, "Pro Football Victory": { @@ -209,10 +213,10 @@ "name": "${LEVEL} Výhra" }, "Rookie Football Shutout": { - "description": "Vyhrajte aniž by padouši skórovali", - "descriptionComplete": "Vyhráli jste aniž by padouši skórovali", - "descriptionFull": "Vyhrajte ${LEVEL} aniž by padouši skórovali", - "descriptionFullComplete": "Vyhráli jste ${LEVEL} aniž by padouši skórovali", + "description": "Vyhrajte, aniž by padouši skórovali", + "descriptionComplete": "Vyhráli jste, aniž by padouši skórovali", + "descriptionFull": "Vyhrajte ${LEVEL}, aniž by padouši skórovali", + "descriptionFullComplete": "Vyhráli jste ${LEVEL}, aniž by padouši skórovali", "name": "${LEVEL} Bezchybná výhra" }, "Rookie Football Victory": { @@ -251,7 +255,7 @@ "name": "${LEVEL} Kouzelník" }, "Sharing is Caring": { - "descriptionFull": "Úspěšně sdílet hru s přítelem", + "descriptionFull": "Úspěšně sdílejte hru s přítelem", "descriptionFullComplete": "Úspěšně sdílena hra s přítelem", "name": "Sdílení je laskavé" }, @@ -285,7 +289,7 @@ }, "Team Player": { "descriptionFull": "Začněte týmovou hru s 4+ hráči", - "descriptionFullComplete": "Začali jste Týmovou hru s 4+ hráči", + "descriptionFullComplete": "Začali jste týmovou hru s 4+ hráči", "name": "Týmový hráč" }, "The Great Wall": { @@ -303,10 +307,10 @@ "name": "Zeď" }, "Uber Football Shutout": { - "description": "Vyhrajte bez toho, aby padouši skórovali", - "descriptionComplete": "Vyhráli jste bez toho, aby padouši skórovali", - "descriptionFull": "Vyhrajte ${LEVEL} bez toho, aby padouši skórovali", - "descriptionFullComplete": "Vyhráli jste ${LEVEL} bez toho, aby padouchové skórovali", + "description": "Vyhrajte, aniž by padouši skórovali", + "descriptionComplete": "Vyhráli jste, aniž by padouši skórovali", + "descriptionFull": "Vyhrajte ${LEVEL}, aniž by padouši skórovali", + "descriptionFullComplete": "Vyhráli jste ${LEVEL}, aniž by padouši skórovali", "name": "${LEVEL} Bezchybná výhra" }, "Uber Football Victory": { @@ -331,21 +335,26 @@ "name": "${LEVEL} Vítězství" } }, - "achievementsRemainingText": "Achievementů Zbývá:", - "achievementsText": "Achievementy", - "achievementsUnavailableForOldSeasonsText": "Promiňte, ale detaily úspěchu nejsou pro starší sezóny zpřístupněny.", + "achievementsRemainingText": "Zbývající Trofeje:", + "achievementsText": "Trofeje", + "achievementsUnavailableForOldSeasonsText": "Omlouváme se, ale detaily trofeje nejsou pro starší sezóny dostupné.", "activatedText": "${THING} aktivováno.", "addGameWindow": { - "getMoreGamesText": "Získat Více Her...", - "titleText": "Přidat Hru" + "getMoreGamesText": "Získat více her...", + "titleText": "Přidat hru" }, + "addToFavoritesText": "Přidáno do Oblíbených", + "addedToFavoritesText": "Přidáno '${NAME}' do Oblíbených.", + "allText": "Vše", "allowText": "Povolit", - "alreadySignedInText": "Tento účet je používán v jiném zařízení;\npřepněte účet nebo v druhém zařízení hru zavřete, \npoté to zkuste znova.", - "apiVersionErrorText": "Nelze načíst modul ${NAME}; je vytvořen pro verzi api ${VERSION_USED}; je potřeba ${VERSION_REQUIRED}.", + "alreadySignedInText": "Tento účet je používán v jiném zařízení;\npřepněte prosím účet nebo v druhém\nzařízení hru zavřete, poté to zkuste znova.", + "apiVersionErrorText": "Nelze načíst modul ${NAME}; je vytvořen pro API verze ${VERSION_USED}; je potřeba ${VERSION_REQUIRED}.", + "applyText": "Použít", + "areYouSureText": "Jste si jistí?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" zapněte pouze když jsou připojeny sluchátka)", "headRelativeVRAudioText": "Head-Relative VR Audio", - "musicVolumeText": "Hlasitost Hudby", + "musicVolumeText": "Hlasitost hudby", "soundVolumeText": "Hlasitost Zvuků", "soundtrackButtonText": "Soundtracky", "soundtrackDescriptionText": "(přiřaďte vaši vlastní hudbu, která bude hrát při hraní)", @@ -353,9 +362,9 @@ }, "autoText": "Automaticky", "backText": "Zpět", - "banThisPlayerText": "Znemožnit hráči přístup do hry", - "bestOfFinalText": "Nejlepší z ${COUNT} Finální", - "bestOfSeriesText": "Nejlepší z ${COUNT} sérií", + "banThisPlayerText": "Zabanovat hráče", + "bestOfFinalText": "Nejlepší z ${COUNT} - výsledky", + "bestOfSeriesText": "Nejlepší z ${COUNT} her", "bestRankText": "Váš nejlepší je #${RANK}", "bestRatingText": "Vaše nejlepší hodnocení je ${RATING}", "betaErrorText": "Tato beta-verze již není aktivní; prosím podívejte se na novější verze", @@ -366,40 +375,50 @@ "boostText": "Zrychlit", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} je nastaven v aplikaci sám.", "buttonText": "tlačitko", - "canWeDebugText": "Chtěli byste, aby BombSquad automaticky hlásil \nchyby a základní info o používání, vývojáři?\n\nTato data neobsahují žádné osobní informace a napomáhají,\naby hra běžela hladce a bez chyb.", + "canWeDebugText": "Chtěli byste, aby ${APP_NAME} automaticky hlásil \nchyby, pády a základní info o používání vývojáři?\n\nTato data neobsahují žádné osobní informace a napomáhají,\naby hra běžela hladce a bez chyb.", "cancelText": "Zrušit", "cantConfigureDeviceText": "Omlouváme se, ale ${DEVICE} není nastavitelné", - "challengeEndedText": "Tato výzva již byla ukončena.", + "challengeEndedText": "Tato výzva již skončila.", "chatMuteText": "Ztlumit Chat", "chatMutedText": "Chat ztlumen", "chatUnMuteText": "Obnovit chat", + "chests": { + "prizeOddsText": "Šance na výhru", + "reduceWaitText": "Zkrať čekání", + "slotDescriptionText": "Toto je místo pro truhlu.\n\nTruhly lze získat hraním kampaně,\numístěním v turnajích a získáním\ntrofejí.", + "slotText": "Místo pro truhlu ${NUM}", + "slotsFullWarningText": "VAROVÁNÍ: Všechna místa pro truhly jsou obsazená.\nV této hře ztrácíte možnost získat další truhlu.", + "unlocksInText": "Otevře se Za" + }, "choosingPlayerText": "", - "completeThisLevelToProceedText": "Musíte dokončit\ntento level abyste mohli pokračovat!", + "claimText": "Získat", + "codesExplainText": "Kódy jsou zřizovány vývojářem za účelem\ndiagnózy a opravy problémů s účty.", + "completeThisLevelToProceedText": "Musíte dokončit\ntento level, abyste mohli pokračovat!", "completionBonusText": "Bonus za dokončení", "configControllersWindow": { - "configureControllersText": "Nastavit Ovladače", - "configureKeyboard2Text": "Nastavit Klávesnici P2", - "configureKeyboardText": "Nastavit Klávesnici", - "configureMobileText": "Mobilní Zařízení jako Ovladače", - "configureTouchText": "Nastavit Dotykovou obrazovku", + "configureControllersText": "Nastavit ovladače", + "configureKeyboard2Text": "Nastavit klávesnici P2", + "configureKeyboardText": "Nastavit klávesnici", + "configureMobileText": "Mobilní zařízení jako ovladače", + "configureTouchText": "Nastavit dotykovou obrazovku", "ps3Text": "PS3 Ovladače", "titleText": "Ovladače", "wiimotesText": "Wiimote ovladače", "xbox360Text": "Xbox 360 Ovladače" }, "configGamepadSelectWindow": { - "androidNoteText": "Poznámka: podpora ovladače závisí na zařízení a verzi Androidu", + "androidNoteText": "Poznámka: podpora ovladačů závisí na zařízení a verzi Androidu", "pressAnyButtonText": "Stiskněte libovolné tlačítko na ovladači,\n který chcete nastavovat...", - "titleText": "Nastavit Ovladače" + "titleText": "Nastavit ovladače" }, "configGamepadWindow": { "advancedText": "Pokročilé", - "advancedTitleText": "Pokročilé Nastavení Ovladače", - "analogStickDeadZoneDescriptionText": "(zapněte tohle, jestliže Vaše postava 'klouže' po uvolnění páčky)", - "analogStickDeadZoneText": "Mrtvá Zóna Analogové Páčky", + "advancedTitleText": "Pokročilé nastavení ovladače", + "analogStickDeadZoneDescriptionText": "(zvyšte, jestliže se Vaše postava pohybuje i po uvolnění páčky)", + "analogStickDeadZoneText": "Mrtvá zóna analogové páčky", "appliesToAllText": "(nastaví na všechny ovladače tohoto typu)", - "autoRecalibrateDescriptionText": "(zapněte to, jestliže se Vaše postava nepohybuje plnou rychlostí)", - "autoRecalibrateText": "Automaticky Rekalibrovat Analogovou Páčku", + "autoRecalibrateDescriptionText": "(zapněte, jestliže se Vaše postava nepohybuje plnou rychlostí)", + "autoRecalibrateText": "Automaticky rekalibrovat analogovou páčku", "axisText": "osa", "clearText": "smazat", "dpadText": "dpad", @@ -408,76 +427,77 @@ "ifNothingHappensTryDpadText": "Jestliže se nic neděje, zkuste místo toho přiřadit d-pad.", "ignoreCompletelyDescriptionText": "(zabránit tomuto ovladači ovlivnit buď hru nebo nabídku)", "ignoreCompletelyText": "Ignorovat úplně", - "ignoredButton1Text": "Ignorované Tlačítko 1", - "ignoredButton2Text": "Ignorované Tlačítko 2", - "ignoredButton3Text": "Ignorované Tlačítko 3", + "ignoredButton1Text": "Ignorované tlačítko 1", + "ignoredButton2Text": "Ignorované tlačítko 2", + "ignoredButton3Text": "Ignorované tlačítko 3", "ignoredButton4Text": "Ignorováno tlačítko 4", - "ignoredButtonDescriptionText": "(použijte tohle pro zabránění tlačítkům 'home' nebo 'synchronizace' ovlivnění UI)", + "ignoredButtonDescriptionText": "(použijte pro zabránění tlačítkům 'home' nebo 'synchronizace' ovlivňovat nabídky)", "pressAnyAnalogTriggerText": "Stiskněte libovolný analogový spínač...", "pressAnyButtonOrDpadText": "Stistkněte libovolné tlačítko nebo dpad...", "pressAnyButtonText": "Stiskněte libovolné tlačítko...", "pressLeftRightText": "Stistkněte doleva nebo doprava...", "pressUpDownText": "Stiskněte nahoru nebo dolů...", - "runButton1Text": "Tlačítko Běh 1", - "runButton2Text": "Tlačítko Běh 2", - "runTrigger1Text": "Přepnutí Běhu 1", - "runTrigger2Text": "Přepnutí Běhu 2", - "runTriggerDescriptionText": "(analogové spínače Vám dovolí běhat v různých rychlostech)", - "secondHalfText": "Použijte tohle k nastavení druhé poloviny\n2 ovladačů v 1 zařízení, které se zobrazuje\njako jedno zařízení", + "runButton1Text": "Přepnutí běhu 1", + "runButton2Text": "Přepnutí běhu 2", + "runTrigger1Text": "Spínač běhu 1", + "runTrigger2Text": "Spínač běhu 2", + "runTriggerDescriptionText": "(analogové spínače Vám dovolí běžet v různých rychlostech)", + "secondHalfText": "Použijte k nastavení druhé poloviny ovladačů,\nkteré používají dva samostatné ovladače jako\njedno zařízení.", "secondaryEnableText": "Zapnout", - "secondaryText": "Druhý Ovladač", - "startButtonActivatesDefaultDescriptionText": "(vypněte, jestliže Vaše start tlačítko je spíše 'menu' tlačítko)", - "startButtonActivatesDefaultText": "Start Tlačítko Aktivuje Základní Widget", - "titleText": "Nastavení Ovladače", - "twoInOneSetupText": "2-v-1 Ovladač Nastavení", + "secondaryText": "Druhý ovladač", + "startButtonActivatesDefaultDescriptionText": "(vypněte, jestliže Vaše start tlačítko je se chová spíš jako 'menu' tlačítko)", + "startButtonActivatesDefaultText": "Start tlačítko aktivuje základní widget", + "titleText": "Nastavení ovladače", + "twoInOneSetupText": "Nastavení ovladače 2-v-1", "uiOnlyDescriptionText": "(zabránit ovladači k připojení do hry)", - "uiOnlyText": "Omezeno k použití menu", - "unassignedButtonsRunText": "Všechna Nenastavená Tlačítka Běh", + "uiOnlyText": "Omezit k použití nabídek", + "unassignedButtonsRunText": "Všechna nenastavená tlačítka pro běh", "unsetText": "", - "vrReorientButtonText": "Reorientovat VR tlačítko" + "vrReorientButtonText": "Tlačítko pro VR reorientaci" }, "configKeyboardWindow": { "configuringText": "Nastavuji ${DEVICE}", - "keyboard2NoteText": "Poznámka: většina klávesnic může registrovat jen pár stisklých\nkláves najednou, takže pro druhého hráče na klávesnici může být\nvýhodnější, když má druhou, vlastní klávesnici, kterou bude používat.\nOvšem,i v tomto případě, je stejně potřeba nastavit \nkaždému jiné klávesy." + "keyboard2NoteText": "Poznámka: většina klávesnic může registrovat jen pár stisklých\nkláves najednou, takže pro druhého hráče na klávesnici může být\nvýhodnější, když má druhou, vlastní klávesnici, kterou bude používat.\nOvšem i v tomto případě je potřeba nastavit \nkaždému jiné klávesy." }, "configTouchscreenWindow": { - "actionControlScaleText": "Velikost Ovládacího Prvku", - "actionsText": "Ovládací Prvky", + "actionControlScaleText": "Velikost ovládacího prvku", + "actionsText": "Ovládací prvky", "buttonsText": "tlačítka", "dragControlsText": "< posouvejte ovládacími prvky pro změnu jejich pozice >", "joystickText": "joystick", - "movementControlScaleText": "Velikost Ovládacího Prvku pro Pohyb", + "movementControlScaleText": "Velikost ovládacího prvku pro pohyb", "movementText": "Pohyb", "resetText": "Resetovat", - "swipeControlsHiddenText": "Skrýt Přejížděcí Ikony", - "swipeInfoText": "Na 'Přejížděcí' styl ovládání se trochu déle zvyká, ale\nje s ním jednodužší hrát bez koukání se na tlačítka.", + "swipeControlsHiddenText": "Skrýt přejížděcí ikony", + "swipeInfoText": "Na „Přejížděcí“ styl ovládání se trochu déle zvyká, ale\nje s ním jednodužší hrát bez koukání se na tlačítka.", "swipeText": "přejíždění", - "titleText": "Nastavit Dotykovou Obrazovku" + "titleText": "Nastavit dotykovou obrazovku" }, + "configureDeviceInSystemSettingsText": "${DEVICE} může být nakonfigurováno v Nastavení Systému", "configureItNowText": "Nastavit teď?", "configureText": "Nastavit", "connectMobileDevicesWindow": { "amazonText": "Amazon Appstore", "appStoreText": "App Store", - "bestResultsText": "Pro nejlepší výsledky budete potřebovat wifi síť bez lagů.\nLagy na wifi můžete snížit vypnutím některých bezdrátových zařízení,\nhraním blízko Vašeho routeru, a připojením hostitele hry přímo\ndo sítě přes ethernet.", - "explanationText": "Pro použití chytrého telefonu nebo tabletu jako bezdrátový ovladač,nainstalujte si aplikaci ${REMOTE_APP_NAME}.\nLibovolný počet zařízení může by připojeno do hry ${APP_NAME}\npřipojeno přes síť Wi-Fi , a je to zdarma !!", + "bestResultsText": "Pro nejlepší výsledky budete potřebovat WiFi síť bez lagů.\nLagy na WiFi můžete snížit vypnutím některých bezdrátových zařízení,\nhraním blízko Vašeho routeru, a připojením hostitele hry přímo\ndo sítě přes Ethernet.", + "explanationText": "Pro použití chytrého telefonu nebo tabletu jako bezdrátový\novladač si nainstalujte aplikaci ${REMOTE_APP_NAME}.\nDo hry ${APP_NAME} se s ní může připojit neomezený počet zařízení, a je to zdarma!", "forAndroidText": "pro Android:", "forIOSText": "pro iOS:", - "getItForText": "Získejte ${REMOTE_APP_NAME} pro I OS v App Store,\nnebo pro Android v Google play nebo v Amazon appstore", + "getItForText": "Získejte ${REMOTE_APP_NAME} pro iOS v App Store,\nnebo pro Android v Google play nebo v Amazon Appstore", "googlePlayText": "Google Play", - "titleText": "Použití Mobilních Zařízení jako Ovladačů" + "titleText": "Použití mobilních zařízení jako ovladačů" }, "continuePurchaseText": "Pokračovat za ${PRICE}?", "continueText": "Pokračovat", "controlsText": "Ovládání", "coopSelectWindow": { "activenessAllTimeInfoText": "Nepočítá se do celkového žebříčku.", - "activenessInfoText": "Tento násobič se zvyšuje ve dnech kdy hrajete,\na snižuje ve dnech, kdy ne.", + "activenessInfoText": "Tento násobič se zvyšuje ve dnech, kdy hrajete,\na snižuje ve dnech, kdy ne.", "activityText": "Aktivita", "campaignText": "Kampaň", "challengesInfoText": "Vyhrajte ceny za dokončování mini-her.\n\nCeny a obtížnost úrovní se zvyšují vždy,\njakmile je výzva dokončena a snižují se vždy\njakmile výzva vyprší nebo je zahozena.", "challengesText": "Výzvy", - "currentBestText": "Aktuální Nejepší", + "currentBestText": "Aktuální nejepší", "customText": "Speciální mapy", "entryFeeText": "Vstupné", "forfeitConfirmText": "Chcete zahodit tuto výzvu?", @@ -491,179 +511,188 @@ "pointsText": "Body", "powerRankingFinishedSeasonUnrankedText": "(sezóna ukončena bez hodnocení)", "powerRankingNotInTopText": "(nejste v top ${NUMBER})", - "powerRankingPointsEqualsText": "= ${NUMBER}bodů", - "powerRankingPointsMultText": "(x ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} bodů", + "powerRankingPointsMultText": "(x ${NUMBER} bodů)", "powerRankingPointsText": "${NUMBER} bodů", "powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} bodů)", "powerRankingText": "Hodnocení", "prizesText": "Ceny", "proMultInfoText": "Hráči s upgradem ${PRO}\nobdrží ${PERCENT}% bonus k bodům.", - "seeMoreText": "Zobrazit více...", + "seeMoreText": "Více...", "skipWaitText": "Přeskočit čekání", - "timeRemainingText": "Zbývající Čas", + "timeRemainingText": "Zbývající čas", "toRankedText": "Pro hodnocení", - "totalText": "Celkem", + "totalText": "celkem", "tournamentInfoText": "Soutěžte s vysokým skóre\ns ostatními hráči ve Vaší lize.\n\nCeny jsou uělovány hráčům, kteří mají\nnejvíce bodů po ukončení turnaje.", - "welcome1Text": "Vítejte v ${LEAGUE}. Pozici v lize\nmůžete vylepšit pomocí hvězdných hodnocení,\nplněním achievementů a vyhráváním trofejí v turnajích.", + "welcome1Text": "Vítejte v ${LEAGUE}. Pozici v lize\nmůžete zvýšit získáním hvězdných hodnocení,\nzískávýním trofejí a vyhráváním pohárů v turnajích.", "welcome2Text": "Také můžete získávat kupóny z mnoha aktivit.\nMohou být použity pro odemykání nových postav, map,\nmini-her, pro vstup do turnajů, a dalších.", "yourPowerRankingText": "Vaše pozice:" }, "copyConfirmText": "Zkopírováno do schránky.", "copyOfText": "${NAME} Kopie", "copyText": "Kopírovat", - "createEditPlayerText": "", + "createEditPlayerText": "", "createText": "Vytvořit", "creditsWindow": { - "additionalAudioArtIdeasText": "Dodatečné Audio, První Artworky, a nápady od ${NAME}", + "additionalAudioArtIdeasText": "Dodatečné audio, první artworky a nápady od ${NAME}", "additionalMusicFromText": "Dodatečná hudba od ${NAME}", "allMyFamilyText": "Všem mým přátelům a rodině, kteří pomohli testovat hratelnost", - "codingGraphicsAudioText": "Kódování, Grafika, a Audio od ${NAME}", + "codingGraphicsAudioText": "Kódování, grafika, a audio od ${NAME}", "languageTranslationsText": "Překladatelé:", "legalText": "Práva:", - "publicDomainMusicViaText": "Public-domain hudba přes ${NAME}", + "publicDomainMusicViaText": "Hudba ve veřejné doméně od ${NAME}", "softwareBasedOnText": "Tento software je založen na části práce ${NAME}", "songCreditText": "${TITLE} od ${PERFORMER}\nSložil ${COMPOSER}, Aranžér ${ARRANGER}, Publikoval ${PUBLISHER},\nS laskavým svolením ${SOURCE}", - "soundAndMusicText": "Zvuky & Hudba", + "soundAndMusicText": "Zvuky & hudba", "soundsText": "Zvuky (${SOURCE}):", - "specialThanksText": "Zvláštní Poděkování:", + "specialThanksText": "Zvláštní poděkování:", "thanksEspeciallyToText": "Děkuji zejména ${NAME}", "titleText": "Tvůrci ${APP_NAME}", "whoeverInventedCoffeeText": "Tomu, kdo vynalezl kávu" }, "currentStandingText": "Vaše momentální umístění je #${RANK}", "customizeText": "Přizpůsobit...", - "deathsTallyText": "${COUNT} - počet smrtí", + "deathsTallyText": "${COUNT} smrtí", "deathsText": "Smrti", "debugText": "ladění", "debugWindow": { - "reloadBenchmarkBestResultsText": "Poznámka: je doporučené nastavit Nastavení->Grafika>Textury na \"Vysoká\" při tomto testování.", - "runCPUBenchmarkText": "Spustit CPU Benchmark", - "runGPUBenchmarkText": "Spustit GPU Benchmark", - "runMediaReloadBenchmarkText": "Spustit Media-Reload Benchmark", + "reloadBenchmarkBestResultsText": "Poznámka: je doporučené nastavit při tomto testování Nastavení->Grafika>Textury na „Vysoká“.", + "runCPUBenchmarkText": "Spustit CPU benchmark", + "runGPUBenchmarkText": "Spustit GPU benchmark", + "runMediaReloadBenchmarkText": "Spustit Media-Reload benchmark", "runStressTestText": "Spustit test výdrže", - "stressTestPlayerCountText": "Počet Hráčů", - "stressTestPlaylistDescriptionText": "Playlist Testu Výdrže", - "stressTestPlaylistNameText": "Název Playlistu", - "stressTestPlaylistTypeText": "Typ Playlistu", - "stressTestRoundDurationText": "Délka Trvání Kola", - "stressTestTitleText": "Test Výdrže", - "titleText": "Benchmarky & Testy Výdrže", - "totalReloadTimeText": "Celkový čas znovunačtení: ${TIME} (koukněte do logu pro detaily)" + "stressTestPlayerCountText": "Počet hráčů", + "stressTestPlaylistDescriptionText": "Playlist testu výdrže", + "stressTestPlaylistNameText": "Název playlistu", + "stressTestPlaylistTypeText": "Typ playlistu", + "stressTestRoundDurationText": "Délka trvání kola", + "stressTestTitleText": "Test výdrže", + "titleText": "Benchmarky & testy výdrže", + "totalReloadTimeText": "Celkový čas znovunačtení: ${TIME} (nahlédněte do logu pro detaily)" }, - "defaultGameListNameText": "Výchozí ${PLAYMODE} Playlist", - "defaultNewGameListNameText": "Můj ${PLAYMODE} Playlist", - "deleteText": "Vymaž", + "defaultGameListNameText": "Výchozí ${PLAYMODE} playlist", + "defaultNewGameListNameText": "Můj ${PLAYMODE} playlist", + "deleteText": "Smazat", "demoText": "Demo", "denyText": "Zakázat", "deprecatedText": "Zastaralé", - "desktopResText": "Rozlišení Plochy", - "deviceAccountUpgradeText": "Varování:\nJste přihlášeni na účet dostupný pouze na tomto zařízení\n(${NAME}).\nTyto účty budou v příští aktualizaci odstraněny.", + "descriptionText": "Popisek", + "desktopResText": "Rozlišení plochy", + "deviceAccountUpgradeText": "Varování:\nJste přihlášeni na účet dostupný pouze na tomto zařízení (${NAME}).\nTyto účty budou v nastávající aktualizaci odstraněny.\nPřejděte na účet V2, chcete-li si ponechat Váš postup.", "difficultyEasyText": "Lehká", - "difficultyHardOnlyText": "Pouze Těžký Mód", + "difficultyHardOnlyText": "Pouze těžký mód", "difficultyHardText": "Těžká", "difficultyHardUnlockOnlyText": "Tento level může být odemčen pouze v těžkém módu.\nMyslíte si snad, že na to máte?", "directBrowserToURLText": "Naveďte prosím svůj webový prohlížeč na následující adresu:", - "disableRemoteAppConnectionsText": "Zablokovat přístup Ovladačům-z-aplikace", - "disableXInputDescriptionText": "Povolí více než 4 ovladače ale nemusí fungovat dobře.", + "disableRemoteAppConnectionsText": "Zablokovat přístup ovladačům v aplikaci", + "disableXInputDescriptionText": "Povolí více než 4 ovladače, ale nemusí fungovat tak dobře.", "disableXInputText": "Vypnout XInput", + "disabledText": "Zakázáno", + "discardText": "Zbavit se", + "discordFriendsText": "Chcete najít nové lidi na hraní?\nPřipojte se k našemu Discordu a najděte nové přátele!", + "discordJoinText": "Připoj se k Discordu", "doneText": "Hotovo", "drawText": "Remíza", "duplicateText": "Duplikovat", "editGameListWindow": { "addGameText": "Přidat\nHru", - "cantOverwriteDefaultText": "Nemohu přepsat výchozí playlist!", - "cantSaveAlreadyExistsText": "Playlist s tímto jménem už existuje!", - "cantSaveEmptyListText": "Nemohu uložit prázdný playlist!", + "cantOverwriteDefaultText": "Nelze přepsat výchozí playlist!", + "cantSaveAlreadyExistsText": "Playlist s tímto jménem již existuje!", + "cantSaveEmptyListText": "Nelze uložit prázdný playlist!", "editGameText": "Upravit\nHru", - "listNameText": "Název Playlistu", + "listNameText": "Název playlistu", "nameText": "Jméno", "removeGameText": "Odstranit\nHru", "saveText": "Uložit seznam", - "titleText": "Editor Playlistů" + "titleText": "Editor playlistů" }, "editProfileWindow": { "accountProfileInfoText": "Toto je speciální profil se jménem\na ikonou založenou na Vašem účtě.\n\n${ICONS}\n\nVytvořte si vlastní profily pro použití\nrůzných jmen či vlastních ikon.", "accountProfileText": "(profil účtu)", - "availableText": "Jméno \"${NAME}\" je dostupné.", + "availableText": "Jméno „${NAME}“ je dostupné.", "changesNotAffectText": "Poznámka: změny neovlivní postavy, které jsou již ve hře", "characterText": "postava", - "checkingAvailabilityText": "Kontrola dostupnosti jména \"${NAME}\"...", + "checkingAvailabilityText": "Kontrola dostupnosti jména „${NAME}“...", "colorText": "barva", - "getMoreCharactersText": "Získat Více Postav...", - "getMoreIconsText": "Získat Více Ikon...", + "getMoreCharactersText": "Získat více postav...", + "getMoreIconsText": "Získat více ikon...", "globalProfileInfoText": "U globálních herních profilů je garantováno, že Vaše\njméno bude na celém světě unikátní. Včetně vlastních ikon.", "globalProfileText": "(globální profil)", "highlightText": "zvýraznění", "iconText": "ikona", - "localProfileInfoText": "Lokální herní profily nemají žádné ikony a u jejich jmen \nnelze garantovat jejich unikátnost. Přeměnou na globální profil\nsi zajistíte unikátní uživatelské jméno a možnost přidat vlatní ikonu.", - "localProfileText": "(local profile)", + "localProfileInfoText": "Lokální herní profily nemají žádné ikony a u jejich jmen\nnelze garantovat jejich unikátnost. Převedením na globální profil\nsi zajistíte unikátní uživatelské jméno a možnost přidat vlatní ikonu.", + "localProfileText": "(lokální profil)", "nameDescriptionText": "Přezdívka", "nameText": "Jméno", + "profileAlreadyExistsText": "Profil s tímto jménem již existuje.", "randomText": "náhodně", - "titleEditText": "Upravit Profil", - "titleNewText": "Nový Profil", - "unavailableText": "jméno \"${NAME}\" není dostupné; zkuste jiné.", + "titleEditText": "Upravit profil", + "titleNewText": "Nový profil", + "unavailableText": "Jméno „${NAME}“ není dostupné; zkuste jiné.", "upgradeProfileInfoText": "Toto rezervuje Vaše uživatelské jméno celosvětově,\na povolí Vám k němu přiřadit vlastní ikonu.", "upgradeToGlobalProfileText": "Přeměnit na Globální profil" }, "editSoundtrackWindow": { "cantDeleteDefaultText": "Nemůžete odstranit výchozí soundtrack.", - "cantEditDefaultText": "Nelze upravit výchozí soundtrack. Zduplikujte jej nebo vytvořte nový.", + "cantEditDefaultText": "Nelze upravit výchozí soundtrack. Duplikujte jej nebo vytvořte nový.", "cantEditWhileConnectedOrInReplayText": "Nelze upravovat soundtracky, když jste připojení k partě nebo při záznamu.", "cantOverwriteDefaultText": "Nelze přepsat výchozí soundtrack", - "cantSaveAlreadyExistsText": "Soundtrack s tímto jménem už existuje!", + "cantSaveAlreadyExistsText": "Soundtrack s tímto jménem již existuje!", "defaultGameMusicText": "", - "defaultSoundtrackNameText": "Výchozí Soundtrack", - "deleteConfirmText": "Odstranit Soundtrack:\n\n'${NAME}'?", - "deleteText": "Odstranit\nSoundtrack", - "duplicateText": "Duplikovat\nSoundtrack", - "editSoundtrackText": "Editor Soundtracků", - "editText": "Upravit\nSoundtrack", - "fetchingITunesText": "získávám Music App playlisty...", + "defaultSoundtrackNameText": "Výchozí soundtrack", + "deleteConfirmText": "Odstranit soundtrack:\n\n„${NAME}“?", + "deleteText": "Odstranit\nsoundtrack", + "duplicateText": "Duplikovat\nsoundtrack", + "editSoundtrackText": "Editor soundtracků", + "editText": "Upravit\nsoundtrack", + "fetchingITunesText": "získávám playlisty z aplikace hudby...", "musicVolumeZeroWarning": "Varování: hlasitost hudby je nastavena na 0", "nameText": "Název", - "newSoundtrackNameText": "Můj Soundtrack ${COUNT}", - "newSoundtrackText": "Nový Soundtrack:", - "newText": "Nový\nSoundtrack", - "selectAPlaylistText": "Vybrat Playlist", - "selectASourceText": "Zdroj Hudby", + "newSoundtrackNameText": "Můj soundtrack ${COUNT}", + "newSoundtrackText": "Nový soundtrack:", + "newText": "Nový\nsoundtrack", + "selectAPlaylistText": "Vybrat playlist", + "selectASourceText": "Zdroj hudby", "testText": "test", "titleText": "Soundtracky", - "useDefaultGameMusicText": "Výchozí Herní Hudba", - "useITunesPlaylistText": "Music App Playlist", - "useMusicFileText": "Hudební Soubor (mp3, atd.)", - "useMusicFolderText": "Složka s Hudebními Soubory" + "useDefaultGameMusicText": "Výchozí herní hudba", + "useITunesPlaylistText": "Playlist z apliace hudby", + "useMusicFileText": "Soubor hudby (mp3, atd.)", + "useMusicFolderText": "Složka se sooubory hudby" }, "editText": "Upravit", + "enabledText": "Povoleno", "endText": "Konec", - "enjoyText": "Užij si to!", - "epicDescriptionFilterText": "${DESCRIPTION} V epickém slow motionu", - "epicNameFilterText": "Epické ${NAME}", + "enjoyText": "Užívejte!", + "epicDescriptionFilterText": "${DESCRIPTION} V epickém zpomaleném záběru.", + "epicNameFilterText": "Epické: ${NAME}", "errorAccessDeniedText": "přístup zamítnut", - "errorDeviceTimeIncorrectText": "Čas vašeho zařízení je špatně o ${HOURS} h.\nTo pravděpodobně způsobí problémy.\nProsím zkontrolujte nastavení času a časového pásma.", + "errorDeviceTimeIncorrectText": "Čas vašeho zařízení je špatně o ${HOURS}h.\nTo Vám pravděpodobně způsobí problémy.\nProsím zkontrolujte nastavení času a časového pásma.", "errorOutOfDiskSpaceText": "není místo na disku", - "errorSecureConnectionFailText": "Unable to establish secure cloud connection; network functionality may fail.", + "errorSecureConnectionFailText": "Nelze vytvořit zabezpečené připojení ke cloudu, síťové služby nemusí fungovat.", "errorText": "Chyba", "errorUnknownText": "neznámá chyba", - "exitGameText": "Ukončit ${APP_NAME} ???", - "exportSuccessText": "'${NAME}' úspěšně exportován.", - "externalStorageText": "Externí Úložiště", - "failText": "Fail", - "fatalErrorText": "Ajaj, něco chybí nebo se něco rozbilo.\nZkuste reinstalovat BombSquad\nnebo kontaktujte ${EMAIL} pro pomoc.", + "exitGameText": "Ukončit ${APP_NAME}?", + "expiredAgoText": "Vypršel před ${T}", + "expiresInText": "Vyprší za ${T}", + "exportSuccessText": "„${NAME}“ úspěšně exportován.", + "externalStorageText": "Externí úložiště", + "failText": "Neúspěch", + "fatalErrorText": "Jejda; něco chybí nebo se rozbilo.\nZkuste aplikaci reinstalovat\nnebo kontaktujte ${EMAIL} pro pomoc.", "fileSelectorWindow": { - "titleFileFolderText": "Vyberte Soubor nebo Složku", - "titleFileText": "Vybrat Soubor", - "titleFolderText": "Vybrat Složku", - "useThisFolderButtonText": "Použít Tuto Složku" + "titleFileFolderText": "Vyberte soubor nebo složku", + "titleFileText": "Vybrat soubor", + "titleFolderText": "Vybrat složku", + "useThisFolderButtonText": "Použít tuto složku" }, "filterText": "Filtr", - "finalScoreText": "Konečné Skóre", - "finalScoresText": "Konečné Výsledky", - "finalTimeText": "Konečný Čas", + "finalScoreText": "Konečné skóre", + "finalScoresText": "Konečné výsledky", + "finalTimeText": "Konečný čas", "finishingInstallText": "Dokončuji instalaci; chvilí strpení...", "fireTVRemoteWarningText": "* Pro lepší zkušenosti použijte \novladač nebo nainstalujte aplikaci \n${REMOTE_APP_NAME} na Váš\ntelefon nebo tablet.", - "firstToFinalText": "První-do-${COUNT} Finále", - "firstToSeriesText": "První-do-${COUNT} Série", + "firstToFinalText": "První do ${COUNT} bodů - výsledky", + "firstToSeriesText": "První do ${COUNT} bodů", "fiveKillText": "PĚT ZABITÍ!!!", "flawlessWaveText": "Dokonalá vlna!", "fourKillText": "ČTYŘI ZABITÍ!!!", @@ -673,30 +702,32 @@ "gameLeadersText": "Nejlepší hráči - ${COUNT}. hra", "gameListWindow": { "cantDeleteDefaultText": "Nemůžete odstranit výchozí playlist.", - "cantEditDefaultText": "Nelze upravit výchozí playlist! Duplikujte ho nebo vytvořte nový.", + "cantEditDefaultText": "Nelze upravit výchozí playlist! Duplikujte jej nebo vytvořte nový.", "cantShareDefaultText": "Nemůžete sdílet výchozí playlist.", - "deleteConfirmText": "Odstranit \"${LIST}\" ?", - "deleteText": "Odstranit\nPlaylist", - "duplicateText": "Duplikovat\nPlaylist", - "editText": "Upravit\nPlaylist", - "newText": "Nový\nPlaylist", - "showTutorialText": "Zobrazit Tutorial", + "deleteConfirmText": "Odstranit „${LIST}“?", + "deleteText": "Odstranit\nplaylist", + "duplicateText": "Duplikovat\nplaylist", + "editText": "Upravit\nplaylist", + "newText": "Nový\nplaylist", + "pointsToWinText": "Bodů Do Výhry", + "seriesLengthText": "Délka Série", + "showTutorialText": "Zobrazit návod", "shuffleGameOrderText": "Náhodné seřazení her", - "titleText": "Přizpůsobit ${TYPE} Playlisty" + "titleText": "Přizpůsobit ${TYPE} playlisty" }, "gameSettingsWindow": { - "addGameText": "Přidat Hru" + "addGameText": "Přidat hru" }, - "gamesToText": "${WINCOUNT} Her k ${LOSECOUNT}", + "gamesToText": "${WINCOUNT} her k ${LOSECOUNT}", "gatherWindow": { "aboutDescriptionLocalMultiplayerExtraText": "Pamatujte: jakékoli zařízení v partě může mít více\nnež jednoho hráče, když máte dostatek ovladačů.", - "aboutDescriptionText": "Použijte tyto záložky pro vytvoření party.\n\nHra s partou vám umožní hrát turnaje\ns Vašimi přáteli mezi různými zařízeními.\n\nPoužijte ${PARTY} Tlačítko v pravo nahoře\npro chat a interakci s Vaší partou.\n(na ovladači stiskněte tlačítko ${BUTTON}, když jste v menu)", + "aboutDescriptionText": "Použijte tyto záložky pro vytvoření Party.\n\nHra v Partě Vám umožní hrát turnaje\ns Vašimi přáteli mezi různými zařízeními.\n\nPoužijte tlačítko ${PARTY} vpravo nahoře\npro chat a interakci s Vaší Partou.\n(na ovladači stiskněte tlačítko ${BUTTON}, když jste v menu)", "aboutText": "Použití", "addressFetchErrorText": "", "appInviteInfoText": "Pozvěte přátele ke hraní BombSquad a získají\n${COUNT} kupónů zdarma. Vy získáte ${YOU_COUNT} kupónů\nza každého kdo hru vyzkouší.", - "appInviteMessageText": "${NAME} Vám poslal ${COUNT} kupónů v ${APP_NAME}", + "appInviteMessageText": "${NAME} Vám posílá ${COUNT} kupónů v ${APP_NAME}", "appInviteSendACodeText": "Odeslat jim kód", - "appInviteTitleText": "Pozvat ke hraní ${APP_NAME}", + "appInviteTitleText": "Pozvat ke hraní ${APP_NAME}", "bluetoothAndroidSupportText": "(funguje s jakýmkoli Android zařízením podporujícím Bluetooth)", "bluetoothDescriptionText": "Hostovat/Připojit se k partě přes Bluetooth:", "bluetoothHostText": "Hostovat přes Bluetooth", @@ -705,8 +736,9 @@ "checkingText": "zjišťuji...", "copyCodeConfirmText": "Kód zkopírován do schránky", "copyCodeText": "Zkopírovat kód", - "dedicatedServerInfoText": "Pro dosažení nejlepších výsledků nastavte dedikovaný server. Viz bombsquadgame.com/server přečti si to.", - "disconnectClientsText": "Tímto se odpojí ${COUNT} hráč/ů\nve Vaší partě. Jste si jistí?", + "dedicatedServerInfoText": "Pro dosažení nejlepších výsledků nastavte dedikovaný server.\nZjistěte více na bombsquadgame.com/server", + "descriptionShortText": "K založení party použijte okno Klubovna.", + "disconnectClientsText": "Tímto se odpojí ${COUNT} hráč/ů\nve Vaší partě. Jste si jisti?", "earnTicketsForRecommendingAmountText": "Přátelé získají ${COUNT} tiketů když zkusí tuto hru\n(a ty získáš ${YOU_COUNT} za každého, kdo to udělá)", "earnTicketsForRecommendingText": "Sdílet hru\nza kupóny zdarma...", "emailItText": "Odeslat emailem", @@ -718,63 +750,64 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} kupónů od ${NAME}", "friendPromoCodeAwardText": "Získáte ${COUNT} kupónů pokaždé, jakmile je použit.", "friendPromoCodeExpireText": "Kód vyprší za ${EXPIRE_HOURS} hodin a je funkční pouze pro nové hráče.", - "friendPromoCodeInstructionsText": "Pro použití otevřete ${APP_NAME} a jděte do ,,Nastavení->Pokročilé->Vložit kód\"\nPodívejte se na bombsquadgame.com na odkazy k stažení na všechny podporované platformy.", - "friendPromoCodeRedeemLongText": "Může z něj být získáno ${COUNT} kupónů zdarma, až pro ${MAX_USES} lidí.", + "friendPromoCodeInstructionsText": "Pro použití otevřete ${APP_NAME} a jděte do „Nastavení->Pokročilé->Poslat info“\nNa bombsquadgame.com na odkazy k stažení na všechny podporované platformy.", + "friendPromoCodeRedeemLongText": "Může z něj být získáno ${COUNT} kupónů zdarma až ${MAX_USES} lidmi.", "friendPromoCodeRedeemShortText": "Může být použit pro získání ${COUNT} kupónů do hry.", - "friendPromoCodeWhereToEnterText": "(v \"Nastavení->Pokročilé->Vložit Kód\")", + "friendPromoCodeWhereToEnterText": "(v „Nastavení->Pokročilé->Poslat info“)", "getFriendInviteCodeText": "Získat kód pro pozvání přátel", "googlePlayDescriptionText": "Pozvěte Google Play hráče do vaší Party:", "googlePlayInviteText": "Pozvat", - "googlePlayReInviteText": "Máte v partě ${COUNT} Google Play hráčů.\nTi budou odpojeni, pokud odešlete novou pozvánku.\nPozvěte je také, aby se připojili zpět.", - "googlePlaySeeInvitesText": "Zobrazit Pozvánky", + "googlePlayReInviteText": "Máte v partě ${COUNT} Google Play hráčů.\nTi budou odpojeni, pokud odešlete novou pozvánku.\nPozvěte je také, aby se mohli připojit zpět.", + "googlePlaySeeInvitesText": "Zobrazit pozvánky", "googlePlayText": "Google Play", "googlePlayVersionOnlyText": "(Android / Google play verze)", - "hostPublicPartyDescriptionText": "Hostovat veřejnou party", + "hostPublicPartyDescriptionText": "Hostovat veřejnou Partu", "hostingUnavailableText": "Hostování není dostupné", "inDevelopmentWarningText": "Poznámka:\n\nSíťová hra je nová a stále se rozvíjející funkce.\nAktualně je vysoce doporučeno, aby všichni hráči\nbyli na stejné Wi-Fi síti.", "internetText": "Internet", - "inviteAFriendText": "Že vaši přátelé ještě tuto hru nehrají? Pozvěte je,\naby ji vyzkoušeli, a získají ${COUNT} kupónů zdarma.", + "inviteAFriendText": "Vaši přátelé tuto hru ještě nehrají? Pozvěte je,\naby ji vyzkoušeli, a získají ${COUNT} kupónů zdarma.", "inviteFriendsText": "Pozvat přátele", - "joinPublicPartyDescriptionText": "Připojit se k veřejné skupině", - "localNetworkDescriptionText": "Připojit se k partě (LAN, Bluetooth, atd.)", + "joinPublicPartyDescriptionText": "Připojit se k veřejné Partě", + "localNetworkDescriptionText": "Připojit se k Partě (LAN, Bluetooth, atd.)", "localNetworkText": "Lokální síť", - "makePartyPrivateText": "Publikovat mojí Party", - "makePartyPublicText": "Publikovat mojí Party", + "makePartyPrivateText": "Skrýt moji Partu", + "makePartyPublicText": "Publikovat moji Partu", "manualAddressText": "Adresa", "manualConnectText": "Připojit", - "manualDescriptionText": "Připojit se k partě pomocí adresy:", + "manualDescriptionText": "Připojit se k Partě pomocí adresy:", "manualJoinSectionText": "Připojit k adrese", "manualJoinableFromInternetText": "Jste připojitelní přes internet?:", "manualJoinableNoWithAsteriskText": "NE*", "manualJoinableYesText": "ANO", - "manualRouterForwardingText": "*aby to mohlo fungovat, zkuste nastavit forward UDP portu ${PORT} ve vašem routeru, na vaší lokální adresu", + "manualRouterForwardingText": "*aby to fungovalo, zkuste nastavit router tak, aby přesměrovával UDP port ${PORT} na Vaši lokální adresu", "manualText": "Ručně", "manualYourAddressFromInternetText": "Vaše adresa z internetu:", "manualYourLocalAddressText": "Vaše lokální adresa:", - "nearbyText": "Blízké", + "nearbyText": "Lokální", "noConnectionText": "<žádné připojení>", + "noPartiesAddedText": "Nebyly přidány žádné strany", "otherVersionsText": "(ostatní verze)", - "partyCodeText": "Kód party", + "partyCodeText": "Kód Party", "partyInviteAcceptText": "Potvrdit", "partyInviteDeclineText": "Zamítnout", - "partyInviteGooglePlayExtraText": "(koukněte se do 'Google Play' záložky v okně 'Klubovna')", + "partyInviteGooglePlayExtraText": "(koukněte se do „Google Play“ záložky v okně „Klubovna“)", "partyInviteIgnoreText": "Ignorovat", - "partyInviteText": "${NAME} Vás pozval\nk připojení se k jeho partě!", + "partyInviteText": "${NAME} Vás zve\nk připojení do jeho Pary!", "partyNameText": "Název Party", - "partyServerRunningText": "Server vaší party běží", - "partySizeText": "velikost party", - "partyStatusCheckingText": "Zjištiji stav...", - "partyStatusJoinableText": "Nyní se k vaší Party může kdokoli přidat", + "partyServerRunningText": "Server vaší Party běží", + "partySizeText": "velikost Party", + "partyStatusCheckingText": "zjištiji stav...", + "partyStatusJoinableText": "vaše Parta je nyní přístupná na internetu", "partyStatusNoConnectionText": "Připojení k serveru selhalo", - "partyStatusNotJoinableText": "K vaší Party se nikdo nemůže přidat z internetu", - "partyStatusNotPublicText": "Vaše párty není veřejná", + "partyStatusNotJoinableText": "vaše Parta není přístupná na internetu", + "partyStatusNotPublicText": "vaše Parta není veřejná", "pingText": "ping", "portText": "Port", - "privatePartyCloudDescriptionText": "Privátní parta běží na dedikovaných serverech; není potřeba nastavovat router.", - "privatePartyHostText": "Hostovat privátní partu", - "privatePartyJoinText": "Připojit se k privátní partě", - "privateText": "Privátní", - "publicHostRouterConfigText": "Může vyžadovat konfiguraci přesměrování portů na vašem routeru. Pro snadnější volbu, hostujte privátní partu.", + "privatePartyCloudDescriptionText": "Privátní Party běží na dedikovaných serverech; není potřeba nastavovat router.", + "privatePartyHostText": "Hostovat soukromou Partu", + "privatePartyJoinText": "Připojit se k soukromé Partě", + "privateText": "Soukromé", + "publicHostRouterConfigText": "Může vyžadovat nastavení přesměrování portů na vašem routeru. Pro snadnější volbu hostujte soukromou Partu.", "publicText": "Veřejné", "requestingAPromoCodeText": "Získávám kód...", "sendDirectInvitesText": "Odeslat přímou pozvánku", @@ -785,97 +818,105 @@ "startStopHostingMinutesText": "Můžete začít a ukončit bezplatné hostování na dalších ${MINUTES} minut.", "stopHostingText": "Ukončit hostování", "titleText": "Klubovna", - "wifiDirectDescriptionBottomText": "Jestližem mají všechna zařízení funkci 'Wi-Fi Direct', je možné ji použít k nalezení\na připojení k sobě navzájem. Jakmile jsou všichni jednou propojeni, můžou tvořit party\npomocí záložky 'Lokální síť', prostě tak, jako kdyby byli v normální Wi-Fi síti.\n\nPro nejlepší výsledky by měl být hostitel Wi-Fi Direct zároveň hostitel ${APP_NAME} party.", - "wifiDirectDescriptionTopText": "Wi-Fi Direct může být použit pro propojení zařízení Android přímo,\nbez potřeby Wi-Fi sítě. Nejlépe to funguje na Android 4.2 a novějších.\n\nPro použítí, otevřete Wi-Fi nastavení, a podívejte se v menu po 'Wi-Fi Direct'.", + "wifiDirectDescriptionBottomText": "Jestližem mají všechna zařízení funkci „Wi-Fi Direct“, je možné ji použít k nalezení\na připojení k sobě navzájem. Jakmile jsou všichni jednou propojeni, můžou vytvořit Partu pomocí záložky „Lokální síť“ tak, jako kdyby byli v normální Wi-Fi síti.\n\nPro nejlepší výsledky by měl být hostitel Wi-Fi Direct zároveň hostitel ${APP_NAME} Party.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct může být použit pro propojení zařízení Android přímo,\nbez potřeby Wi-Fi sítě. Nejlépe to funguje na Android 4.2 a novějších.\n\nPro použítí, otevřete Wi-Fi nastavení, a podívejte se v menu po „Wi-Fi Direct“.", "wifiDirectOpenWiFiSettingsText": "Otevřít nastavení Wi-Fi", "wifiDirectText": "Wi-Fi Direct", "worksBetweenAllPlatformsText": "(funguje mezi všemi platformami)", "worksWithGooglePlayDevicesText": "(funguje se zařízeními které mají Google Play (android) verzi hry)", - "youHaveBeenSentAPromoCodeText": "Byl vám odeslán ${APP_NAME} promo kód:" + "youHaveBeenSentAPromoCodeText": "Byl Vám odeslán ${APP_NAME} promo kód:" }, "getTicketsWindow": { "freeText": "ZDARMA!", - "freeTicketsText": "Kupóny Zdarma!", - "inProgressText": "Probíhá transakce; Prosím zkuste to za chvíli.", + "freeTicketsText": "Kupóny zdarma!", + "inProgressText": "Probíhá transakce; zkuste to prosím za chvíli.", "purchasesRestoredText": "Transakce obnoveny", "receivedTicketsText": "Obdrženo ${COUNT} kupónů!", "restorePurchasesText": "Obnovit nákupy", "ticketDoublerText": "Zdvojnásobovač Kupónů", - "ticketPack1Text": "Malý Balíček Kupónů", - "ticketPack2Text": "Střední Balíček Kupónů", - "ticketPack3Text": "Velký Balíček Kupónů", - "ticketPack4Text": "Sloní Balíček Kupónů", - "ticketPack5Text": "Mamutí Balíček Kupónů!", - "ticketPack6Text": "Ultimátní Balíček Kupónů", - "ticketsFromASponsorText": "Zhlédni reklamu \nza ${COUNT} tiketů", - "ticketsText": "${COUNT} Kupónů", - "titleText": "Získat Kupóny", - "unavailableLinkAccountText": "Omlouváme se, ale nákupy nejsou na této platformě možné.\nJako řešení je, že můžete si tento účet propojit s jiným\nna jiné platformě a uskutečnit nákup tam.", - "unavailableTemporarilyText": "Momentálně nedostupné; Zkuste to prosím později", - "unavailableText": "Omlouváme se, ale není dostupné", - "versionTooOldText": "Omlouváme se, ale tato verze hry je moc stará; aktualizujte prosím na novější", - "youHaveShortText": "Máš ${COUNT}", + "ticketPack1Text": "Malý balíček kupónů", + "ticketPack2Text": "Střední balíček kupónů", + "ticketPack3Text": "Velký balíček kupónů", + "ticketPack4Text": "Sloní balíček kupónů", + "ticketPack5Text": "Mamutí balíček kupónů", + "ticketPack6Text": "Ultimátní balíček kupónů", + "ticketsFromASponsorText": "Zhlédni reklamu \nza ${COUNT} kupónů", + "ticketsText": "${COUNT} kupónů", + "titleText": "Získat kupóny", + "unavailableLinkAccountText": "Omlouváme se, ale nákupy nejsou na této platformě možné.\nJako řešení si můžete tento účet propojit s jiným\nna jiné platformě a uskutečnit nákup tam.", + "unavailableTemporarilyText": "Momentálně nedostupné; zkuste to prosím později", + "unavailableText": "Omlouváme se, toto není dostupné", + "versionTooOldText": "Omlouváme se, ale tato verze hry je moc stará; aktualizujte prosím na novější.", + "youHaveShortText": "Máte ${COUNT}", "youHaveText": "Máte ${COUNT} kupónů" }, - "googleMultiplayerDiscontinuedText": "Litujeme, služba pro více hráčů Google již není k dispozici.\n Pracuji na výměně co nejrychleji.\n Do té doby zkuste jiný způsob připojení.\n -Eric", - "googlePlayPurchasesNotAvailableText": "Nákupy na Google Play nejsou k dispozici.\nMožná budete muset aktualizovat obchod play.", - "googlePlayServicesNotAvailableText": "Služby Google play nejsou dostupné.\nNěkteré funkce mohou být zakázány.", + "goldPass": { + "desc1InfTokensText": "Nekonečně tokenů.", + "desc2NoAdsText": "Žádné reklamy.", + "desc3ForeverText": "Navždy.", + "goldPassText": "Gold Pass" + }, + "googleMultiplayerDiscontinuedText": "Omlouvám se, služba pro více hráčů Google již není k dispozici.\nPracuji co nejrychleji na výměně.\nDo té doby zkuste jiný způsob připojení.\n- Eric", + "googlePlayPurchasesNotAvailableText": "Nákupy na Google Play nejsou k dispozici.\nMožná budete muset aktualizovat Obchod Play.", + "googlePlayServicesNotAvailableText": "Služby Google Play nejsou dostupné.\nNěkteré funkce mohou být zakázány.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Vždy", "fullScreenCmdText": "Celá obrazovka (Cmd-F)", "fullScreenCtrlText": "Celá obrazovka (Ctrl-F)", + "fullScreenText": "Na celou obrazovku", "gammaText": "Gamma", - "highText": "Velká", - "higherText": "Větší", - "lowText": "Malá", + "highText": "Vysoká", + "higherText": "Vyšší", + "lowText": "Nízká", + "maxFPSText": "Maximální FPS", "mediumText": "Střední", "neverText": "Nikdy", "resolutionText": "Rozlišení", "showFPSText": "Zobrazit FPS", "texturesText": "Textury", "titleText": "Grafika", - "tvBorderText": "TV Rámeček", - "verticalSyncText": "Vertikální Synchronizace", + "tvBorderText": "TV rámeček", + "verticalSyncText": "Vertikální synchronizace", "visualsText": "Kvalita zobrazení" }, "helpWindow": { - "bombInfoText": "- Bomba -\nSilnější než pěsti, ale\nmůže dojít k sebe-zraněním.\nNejlepší bude, když hodíte bombu\nna nepřítele dříve, než vyprší její čas.", + "bombInfoText": "- Bomba -\nSilnější než pěsti, ale\nmůžete si s nimi ublížit.\nNejlepší bude, když bombu hodíte\nna nepřítele dříve, než vyprší její odpočet.", "canHelpText": "${APP_NAME} může pomoci.", - "controllersInfoText": "Můžete hrát ${APP_NAME} s přáteli přes síť nebo můžete, pokud máte\ndostatek ovladačů, hrát všichni na stejném zařízení. ${APP_NAME}\njich podporuje nepřeberné množství. Navíc můžete použít svoje telefony\njako ovladače pomocí aplikace '${REMOTE_APP_NAME}', která\nje zdarma. Podívejte se do Nastavení->Ovladače pro více informací.", - "controllersInfoTextRemoteOnly": "Hrajte ${APP_NAME} s přáteli přes internet \nnebo všichni na jednom zařízení za pomoci \nGamepadů nebo mobilní aplikace '${REMOTE_APP_NAME}'", + "controllersInfoText": "${APP_NAME} můžete hrát s přáteli přes síť nebo, pokud máte\ndostatek ovladačů, můžete hrát všichni na stejném zařízení.\n${APP_NAME} jich podporuje nepřeberné množství, navíc můžete použít telefony\njako ovladače pomocí aplikace „${REMOTE_APP_NAME}“, která je zdarma. \nPodívejte se do Nastavení->Ovladače pro více informací.", + "controllersInfoTextRemoteOnly": "Hrajte ${APP_NAME} s přáteli přes internet \nnebo všichni na jednom zařízení za pomoci \novladačů nebo mobilní aplikace „${REMOTE_APP_NAME}“", "controllersText": "Ovladače", "controlsSubtitleText": "Vaše přátelská ${APP_NAME} postava má pár základních schopností:", "controlsText": "Ovládání", - "devicesInfoText": "VR verze ${APP_NAME} může být hrána přes síť s normální\nverzí. Tak vyndejte telefony, tablety a počítače co máte\nnavíc a zapněte svou hru. Propojení normální verze k VR\nverzi může být užitečné kvůli povolení pozorování akce\nlidem zvenčí.", + "devicesInfoText": "VR verze ${APP_NAME} může být hrána přes síť s normální\nverzí, tak vytáhněte telefony, tablety a počítače co máte\nnavíc a zapněte svou hru. Propojení normální verze k VR\nverzi může být užitečné kvůli povolení pozorování akce\nlidmi zvenčí.", "devicesText": "Zařízení", "friendsGoodText": "Je dobré je mít. ${APP_NAME} je největší zábava s více hráči\na podporuje jich až 8 najednou, což nás přivádí k:", "friendsText": "Přátelé", "jumpInfoText": "- Skok -\nSkákejte přes malé mezery,\nházejte věci výše nebo si skočte\njen tak z radosti.", - "orPunchingSomethingText": "Nebo do něčeho udeřit, hodit to z útesu nebo to odpálit lepivou bombou", - "pickUpInfoText": "- Zvedání -\nBrát vlajky, nepřátele, nebo cokoli\njiného nepřibitého k zemi.\nStiskněte znovu pro házení.", - "powerupBombDescriptionText": "Dovolí vám vyhodit tři bomby\nza sebou místo pouhé jedné.", - "powerupBombNameText": "Trojité-Bomby", - "powerupCurseDescriptionText": "Pravděpodobně se jim chcete vyhnout.\n ...nebo nechcete?", + "orPunchingSomethingText": "Nebo něco udeřit, shodit to z útesu a ještě tomu přištědřit lepící bombu, zatímco to padá.", + "pickUpInfoText": "- Zvedání -\nBerte vlajky, nepřátele, nebo cokoli\njiného nepřibitého k zemi.\nStiskněte znovu pro hození.", + "powerupBombDescriptionText": "Dovolí Vám vyhodit tři bomby\nza sebou místo pouhé jedné.", + "powerupBombNameText": "Trojité bomby", + "powerupCurseDescriptionText": "Pravděpodobně se jim chcete vyhnout.\n...nebo nechcete?", "powerupCurseNameText": "Prokletí", - "powerupHealthDescriptionText": "Obnoví veškeré zdraví\nO tom se Vám ani nesnilo.", + "powerupHealthDescriptionText": "Obnoví veškeré Vaše zdraví.\nTo by Vás v životě nenapadlo.", "powerupHealthNameText": "Lékárnička", - "powerupIceBombsDescriptionText": "Slabší než normální bomby,\ntvé nepřátele však zmrazí\na učiní je křehkými.", - "powerupIceBombsNameText": "Ledové-Bomby", + "powerupIceBombsDescriptionText": "Slabší než normální bomby,\nVaše nepřátele však zmrazí\na učiní je křehkými.", + "powerupIceBombsNameText": "Ledové bomby", "powerupImpactBombsDescriptionText": "Trochu slabší než normální bomby,\nale explodují při nárazu.", - "powerupImpactBombsNameText": "Nárazové-Bomby", + "powerupImpactBombsNameText": "Nárazové bomby", "powerupLandMinesDescriptionText": "Jsou v balíčku po 3;\nUžitečné pro základní obranu\nnebo zastavování rychlých nepřátel", - "powerupLandMinesNameText": "Pozemní-Miny", - "powerupPunchDescriptionText": "Udělá tvé pěsti tvrdšími,\nrychlejšími, lepšími, silnějšími.", - "powerupPunchNameText": "Boxovací-Rukavice", - "powerupShieldDescriptionText": "Absorbuje trochu zranění,\ntakže Vám se nic moc nestane.", - "powerupShieldNameText": "Energetický-Štít", - "powerupStickyBombsDescriptionText": "Přilepí se k čemukoli co trefí.\nZábava zaručena.", - "powerupStickyBombsNameText": "Lepící-Bomby", + "powerupLandMinesNameText": "Nášlapné miny", + "powerupPunchDescriptionText": "Udělá Vaše pěsti tvrdší,\nrychlejší, lepší, silnější.", + "powerupPunchNameText": "Boxovací rukavice", + "powerupShieldDescriptionText": "Absorbuje trochu zranění,\naby se Vám nic moc nestalo.", + "powerupShieldNameText": "Energetický štít", + "powerupStickyBombsDescriptionText": "Přilepí se k čemukoli, co trefí.\nZábava zaručena.", + "powerupStickyBombsNameText": "Lepící bomby", "powerupsSubtitleText": "Samozřejmě, žádná hra není hotová bez bonusů:", "powerupsText": "Bonusy", "punchInfoText": "- Pěsti -\nPěsti zraní více,\nkdyž se rychle pohybují.\nTakže běhejte a točte se jako šílenci.", - "runInfoText": "- Sprint -\nDržením libovolného tlačítka sprintujte. Pokud máte ovladač tak fungují i ostatní tlačítka.\nSprintování Vás značně zrychlí ale ztíží vám pohyb, takže si dávejte pozor na okraje mapy.", + "runInfoText": "- Sprint -\nDržením libovolného tlačítka sprintujte. Pokud máte ovladač, fungují i ostatní tlačítka.\nSprintování Vás značně zrychlí, ale ztíží Vám pohyb, takže si dávejte pozor na okraje mapy.", "someDaysText": "Některé dny prostě cítíte, že potřebujete něco praštit. Nebo něco vyhodit do vzduchu.", "titleText": "${APP_NAME} Nápověda", "toGetTheMostText": "Abyste si hru nejvíce užili, budete potřebovat:", @@ -883,110 +924,113 @@ }, "holdAnyButtonText": "", "holdAnyKeyText": "", - "hostIsNavigatingMenusText": "- ${HOST} obsluhuje menu like a boss -", - "importPlaylistCodeInstructionsText": "Použijte následující kó pro importování kdekoliv jinde:", - "importPlaylistSuccessText": "Úspěšně importován ${TYPE} playlist „'${NAME}'“", + "hostIsNavigatingMenusText": "- ${HOST} ovládá nabídky jako největší borec -", + "importPlaylistCodeInstructionsText": "Použijte následující kód pro importování kdekoliv jinde:", + "importPlaylistSuccessText": "Úspěšně importován ${TYPE} playlist „${NAME}“", "importText": "Importovat", "importingText": "Probíhá importování...", - "inGameClippedNameText": "Ve hře bude vidět jako\n\"${NAME}\"", - "installDiskSpaceErrorText": "CHYBA: Není možné dokončit instalaci.\nMožná nemáte dostatek volného místa na Vašem zařízení.\nUvolněte nějaké místo, a zkuste to znovu.", + "inGameClippedNameText": "Ve hře bude vidět jako\n„${NAME}“", + "inboxText": "Pošta", + "installDiskSpaceErrorText": "CHYBA: Není možné dokončit instalaci.\nMožná nemáte dostatek volného místa na Vašem zařízení.\nUvolněte nějaké místo a zkuste to znovu.", "internal": { "arrowsToExitListText": "stiskněte ${LEFT} nebo ${RIGHT} pro opuštění seznamu", "buttonText": "tlačítko", - "cantKickHostError": "Nemůžete kopat hostitele.", - "chatBlockedText": "${NAME} chat je blokován na ${TIME} sekund.", - "connectedToGameText": "Připojen '${NAME}'", - "connectedToPartyText": "Připojen k ${NAME} partě!", + "cantKickHostError": "Nelze vykopnout hostitele.", + "chatBlockedText": "${NAME} je umlčen na ${TIME} sekund.", + "connectedToGameText": "Připojen „${NAME}“", + "connectedToPartyText": "Připojen k Partě ${NAME}!", "connectingToPartyText": "Připojuji...", - "connectionFailedHostAlreadyInPartyText": "Připojení selhalo; Hostitel je v jiné partě.", - "connectionFailedPartyFullText": "Připojení se nezdařilo; parta je plná.", + "connectionFailedHostAlreadyInPartyText": "Připojení selhalo; hostitel je v jiné Partě.", + "connectionFailedPartyFullText": "Připojení selhalo; Parta je plná.", "connectionFailedText": "Připojení selhalo.", - "connectionFailedVersionMismatchText": "Připojení selhalo; Hostitel používá jinou verzi hry.\nUjistěte se, že máte oba aktualizovanou verzi, a zkuste to znovu.", + "connectionFailedVersionMismatchText": "Připojení selhalo; hostitel používá jinou verzi hry.\nUjistěte se, že máte oba aktualizovanou verzi a zkuste to znovu.", "connectionRejectedText": "Připojení odmítnuto.", "controllerConnectedText": "${CONTROLLER} připojen.", "controllerDetectedText": "1 nalezený ovladač.", "controllerDisconnectedText": "${CONTROLLER} odpojen.", - "controllerDisconnectedTryAgainText": "${CONTROLLER} odpojen. Prosím, zkuste ho připojit znovu.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} odpojen. Zkuste ho prosím připojit znovu.", "controllerForMenusOnlyText": "Tento ovladač nemůže být použit pro hraní; pouze k ovládání v nabídce", "controllerReconnectedText": "${CONTROLLER} znovu připojen.", - "controllersConnectedText": "${COUNT} - ovladačů připojeno.", - "controllersDetectedText": "${COUNT} - ovladačů nalezeno.", - "controllersDisconnectedText": "${COUNT} - ovladačů odpojeno.", - "corruptFileText": "Nalezen jeden nebo více poškozených souborů. Zkuste prosím reinstalaci, nebo napište email na ${EMAIL}", + "controllersConnectedText": "Připojeny ovladače: ${COUNT}.", + "controllersDetectedText": "Nalezeny ovladače: ${COUNT}.", + "controllersDisconnectedText": "Odpojeny ovladače: ${COUNT}.", + "corruptFileText": "Nalezen jeden nebo více poškozených souborů. Zkuste prosím reinstalovat nebo napište na ${EMAIL}", "errorPlayingMusicText": "Chyba při přehrávání hudby: ${MUSIC}", - "errorResettingAchievementsText": "Nebylo možné resetovat online achievementy; zkuste to prosím znovu později", + "errorResettingAchievementsText": "Nebylo možné resetovat online Trofeje; zkuste to prosím znovu později", "hasMenuControlText": "${NAME} ovládá menu.", - "incompatibleNewerVersionHostText": "Hostitel serveru má novější verzi než vy, \npro připojení hru aktualizujte.", - "incompatibleVersionHostText": "Hostitel používá jinou verzi hry.\nUjistěte se, že oba používáte aktualizovanou verzi, a zkuste to znovu", - "incompatibleVersionPlayerText": "${NAME} používá jinou verzi hry.\nUjistěte se, že oba použváte aktualizovanou verzi, a zkuste to znovu.", + "incompatibleNewerVersionHostText": "Hostitel má novější verzi hry.\nAktualizujte na nejnovější verzi a zkuste to znovu.", + "incompatibleVersionHostText": "Hostitel má jinou verzi hry.\nUjistěte se, že oba používáte aktualizovanou verzi, a zkuste to znovu.", + "incompatibleVersionPlayerText": "${NAME} má jinou verzi hry.\nUjistěte se, že oba používáte aktualizovanou verzi, a zkuste to znovu.", "invalidAddressErrorText": "Chyba: Neplatná adresa.", "invalidNameErrorText": "Chyba: Neplatné jméno.", "invalidPortErrorText": "Chyba: neplatný port.", "invitationSentText": "Pozvánka odeslána.", - "invitationsSentText": "${COUNT} - pozvánek odesláno.", - "joinedPartyInstructionsText": "Někdo se připojil do tvojí party. \nStiskni 'Hrát' pro start hry", + "invitationsSentText": "Odesláno pozvánek: ${COUNT}.", + "joinedPartyInstructionsText": "Někdo se připojil do Vaší Party. \nStiskněte „Hrát“ pro spuštění hry.", "keyboardText": "Klávesnice", - "kickIdlePlayersKickedText": "${NAME} vyhozen kvůli neaktivitě.", - "kickIdlePlayersWarning1Text": "${NAME} bude vyhozen do ${COUNT} sekund, pokud bude stále neaktivní.", + "kickIdlePlayersKickedText": "Vyhazuji ${NAME} kvůli neaktivitě.", + "kickIdlePlayersWarning1Text": "Vyhazuji ${NAME} za ${COUNT} sekund, bude-li stále neaktivní.", "kickIdlePlayersWarning2Text": "(můžete to vypnout v Nastavení -> Pokročilé)", - "leftGameText": "Odpojen '${NAME}'.", - "leftPartyText": "Opustili jste ${NAME} partu.", + "leftGameText": "Opouštíte „${NAME}“.", + "leftPartyText": "Opustili jste Partu ${NAME}.", "noMusicFilesInFolderText": "Složka neobsahuje žádnou hudbu.", - "playerJoinedPartyText": "${NAME} se připojil do party!", - "playerLeftPartyText": "${NAME} opustil partu.", - "rejectingInviteAlreadyInPartyText": "Odmítnutí pozvánky (už jste v partě).", + "playerJoinedPartyText": "${NAME} se připojuje do Party!", + "playerLeftPartyText": "${NAME} opouští partu.", + "rejectingInviteAlreadyInPartyText": "Odmítám pozvánku (již jste v Partě).", "serverRestartingText": "Server se restartuje. Vraťte se za chvíli...", "serverShuttingDownText": "Server se vypíná...", "signInErrorText": "Chyba přihlašování.", - "signInNoConnectionText": "Přihlášení selhalo. (žádné internetové připojení)", - "telnetAccessDeniedText": "CHYBA: uživatel nemá povolený přístup k telnetu.", + "signInNoConnectionText": "Přihlášení selhalo. (žádné internetové připojení?)", + "telnetAccessDeniedText": "CHYBA: uživatel nepřidělil přístup k telnetu.", "timeOutText": "(vyprší za ${TIME} sekund)", - "touchScreenJoinWarningText": "Připojili jste se s dotykovou obrazovkou.\nJestli je to chyba, klepněte na 'Menu->Opustit hru'.", - "touchScreenText": "Dotyková Obrazovka", - "unableToResolveHostText": "Chyba: Nezdařilo se spojit s hostitelem (IP adresa možná neexistuje)", - "unavailableNoConnectionText": "Toto je momentálně nedostupné (bez internetového připojení?)", - "vrOrientationResetCardboardText": "Použitjte toto pro reset orientace VR.\nPro hraní hry budete potřebovat externí ovladač.", - "vrOrientationResetText": "VR resetování orientace.", - "willTimeOutText": "(vyprší čas, když je neaktivní)" + "touchScreenJoinWarningText": "Připojili jste se s dotykovou obrazovkou.\nJestli je toto omylem, klepněte na Menu->Opustit hru.", + "touchScreenText": "Dotyková obrazovka", + "unableToCompleteTryAgainText": "Toto nebylo možné nyní dokončit.\nZkuste to prosím znovu.", + "unableToResolveHostText": "Chyba: Nezdařilo se spojit s hostitelem", + "unavailableNoConnectionText": "Toto je momentálně nedostupné (žádné internetové připojení?)", + "vrOrientationResetCardboardText": "Použitjte pro reset orientace ve VR.\nPro hraní hry budete potřebovat externí ovladač.", + "vrOrientationResetText": "VR orientace resetována.", + "willTimeOutText": "(vyprší, když je neaktivní)" }, + "inventoryText": "Inventář", "jumpBoldText": "SKOK", "jumpText": "Skok", "keepText": "Zachovat", "keepTheseSettingsText": "Zachovat tato nastavení?", - "keyboardChangeInstructionsText": "Dvakrát stiskni mezerník pro změnu klávesnice.", + "keyboardChangeInstructionsText": "Dvakrát stiskněte mezerník pro změnu klávesnice.", "keyboardNoOthersAvailableText": "Žádné další klávesnice nejsou dostupné.", - "keyboardSwitchText": "Změna klávesnice na \"${NAME}\".", + "keyboardSwitchText": "Změna klávesnice na „${NAME}“.", "kickOccurredText": "${NAME} byl vykopnut.", "kickQuestionText": "Kopnout ${NAME}?", - "kickText": "kop", - "kickVoteCantKickAdminsText": "Admin nemůže být vyhozen.", - "kickVoteCantKickSelfText": "Nemůžeš vyhodit sám sebe.", + "kickText": "Vykopnout", + "kickVoteCantKickAdminsText": "Admin nemůže být vykopnut.", + "kickVoteCantKickSelfText": "Nemůžeš vykopnout sám sebe.", "kickVoteFailedNotEnoughVotersText": "Není dostatek hráčů pro hlasování.", - "kickVoteFailedText": "Kopací-hlasování se nezdařilo.", + "kickVoteFailedText": "Kopací hlasování se nezdařilo.", "kickVoteStartedText": "Kopací hlasování bylo zahájeno pro ${NAME}.", - "kickVoteText": "Hlasovat pro Kopnutí", + "kickVoteText": "Hlasovat pro kopnutí", "kickVotingDisabledText": "Hlasování pro vyhození je vypnuto.", - "kickWithChatText": "Typ ${YES} v chatu pro ano a ${NO} pro ne.", + "kickWithChatText": "Napiš ${YES} v chatu pro ano nebo ${NO} pro ne.", "killsTallyText": "${COUNT} zabití", "killsText": "Zabití", "kioskWindow": { "easyText": "Lehké", - "epicModeText": "Epický Mód", - "fullMenuText": "Celé Menu", + "epicModeText": "Epický mód", + "fullMenuText": "Celé menu", "hardText": "Těžké", "mediumText": "Střední", - "singlePlayerExamplesText": "Sólo Hra / Co-op Ukázky", - "versusExamplesText": "Versus Ukázky" + "singlePlayerExamplesText": "Sólo hra / Co-op ukázky", + "versusExamplesText": "Versus ukázky" }, - "languageSetText": "Jazyk je nastaven na \"${LANGUAGE}\".", + "languageSetText": "Jazyk je nastaven na „${LANGUAGE}“.", "lapNumberText": "Kolo ${CURRENT}/${TOTAL}", "lastGamesText": "(posledních ${COUNT} her)", "leaderboardsText": "Žebříčky", "league": { "allTimeText": "Celkově", - "currentSeasonText": "Tato Sezóna (${NUMBER})", + "currentSeasonText": "Tato sezóna (${NUMBER})", "leagueFullText": "${NAME} Liga", - "leagueRankText": "Liga - Umístění", + "leagueRankText": "Liga - umístění", "leagueText": "Liga", "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", "seasonEndedDaysAgoText": "Sezóna ukončena před ${NUMBER} dny.", @@ -995,8 +1039,11 @@ "seasonEndsMinutesText": "Sezóna končí za ${NUMBER} minut.", "seasonText": "Sezóna ${NUMBER}", "tournamentLeagueText": "Musíte být v lize ${NAME}, abyste se mohli zúčastnit tohoto turnaje.", - "trophyCountsResetText": "Počet trofejí se vymaže příští sezónu." + "trophyCountsResetText": "Počet pohárů se resetuje příští sezónu.", + "upToDateBonusDescriptionText": "Hráči, kteří hrají aktuální verzi této\nhry získají ${PERCENT}% bonus.", + "upToDateBonusText": "Aktualizační bonus" }, + "learnMoreText": "Zjistit Více", "levelBestScoresText": "Nejlepší skóre na ${LEVEL}", "levelBestTimesText": "Nejlepší čas na ${LEVEL}", "levelFastestTimesText": "Nejrychleji v ${LEVEL}", @@ -1008,24 +1055,24 @@ "livesBonusText": "Bonus života", "loadingText": "načítám", "loadingTryAgainText": "Načítání; zkuste to znovu za chvíli...", - "macControllerSubsystemBothText": "Obojí (může způsobovat chyby)", + "macControllerSubsystemBothText": "Obojí (nedoporučeno)", "macControllerSubsystemClassicText": "Klasický", - "macControllerSubsystemDescriptionText": "(zkus toto změnit pokud vám blbnou ovladače)", - "macControllerSubsystemMFiNoteText": "Ddetekován IOS/Mac ovladač;\nPokud jej chcete použít, povolte je v Nastvení > Ovladače", + "macControllerSubsystemDescriptionText": "(zkuste toto změnit pokud Vám nefungují ovladače)", + "macControllerSubsystemMFiNoteText": "Ddetekován iOS/Mac ovladač;\nPokud jej chcete použít, povolte je v Nastvení->Ovladače", "macControllerSubsystemMFiText": "iOS/Mac ovladače", - "macControllerSubsystemTitleText": "Podporované ovladače", + "macControllerSubsystemTitleText": "Podpora ovladačů", "mainMenu": { "creditsText": "Tvůrci", "demoMenuText": "Demo menu", - "endGameText": "Konec Hry", - "endTestText": "Konec Testu", - "exitGameText": "Ukončit Hru", + "endGameText": "Konec hry", + "endTestText": "Konec testu", + "exitGameText": "Ukončit hru", "exitToMenuText": "Vrátit se do menu?", "howToPlayText": "Jak hrát", "justPlayerText": "(Jen ${NAME})", - "leaveGameText": "Opustit Hru", - "leavePartyConfirmText": "Opravdu opustit partu?", - "leavePartyText": "Opustit partu", + "leaveGameText": "Opustit hru", + "leavePartyConfirmText": "Opravdu opustit Partu?", + "leavePartyText": "Opustit Partu", "quitText": "Konec", "resumeText": "Pokračovat", "settingsText": "Nastavení" @@ -1036,50 +1083,57 @@ "mapSelectTitleText": "${GAME} Mapy", "mapText": "Mapa", "maxConnectionsText": "Max připojitelných hráčů", - "maxPartySizeText": "Maximální velikost party", + "maxPartySizeText": "Maximální velikost Party", "maxPlayersText": "Max hráčů", - "merchText": "Pro fanoušky!", + "merchText": "Merch!", "modeArcadeText": "Arkádový mód", "modeClassicText": "Klasický mód", "modeDemoText": "Ukázkový mód", + "moreSoonText": "Další již brzy ...", + "mostDestroyedPlayerText": "Nejvíce rozdrcený hráč", "mostValuablePlayerText": "Nejcennější hráč", "mostViolatedPlayerText": "Nejvíce obětovaný hráč", - "mostViolentPlayerText": "Nejvíce násilný hráč", + "mostViolentPlayerText": "Nejnásilnější hráč", "moveText": "Pohyb", "multiKillText": "${COUNT}-ZABITÍ!!!", - "multiPlayerCountText": "${COUNT} - počet hráčů", - "mustInviteFriendsText": "Poznámka: Musíte pozvat přátele\npomocí tlačítka \"${GATHER}\", nebo\npžipojit ovladače pro hraní s více hráči.", - "nameBetrayedText": "${NAME} zradil ${VICTIM}", - "nameDiedText": "${NAME} zemřel.", - "nameKilledText": "${NAME} zabil ${VICTIM}.", + "multiPlayerCountText": "Počet hráčů: ${COUNT}", + "mustInviteFriendsText": "Poznámka: Musíte pozvat přátele\npomocí tlačítka „${GATHER}“, nebo\npžipojit ovladače pro hraní s více hráči.", + "nameBetrayedText": "${NAME} podráží ${VICTIM}", + "nameDiedText": "${NAME} umírá.", + "nameKilledText": "${NAME} zajíbí ${VICTIM}.", "nameNotEmptyText": "Jméno nemůže být prázdné!", - "nameScoresText": "${NAME} Skóruje!", - "nameSuicideKidFriendlyText": "${NAME} zemřel nešťastnou náhodou.", - "nameSuicideText": "${NAME} spáchal sebevraždu.", + "nameScoresText": "${NAME} skóruje!", + "nameSuicideKidFriendlyText": "${NAME} umírá nešťastnou náhodou.", + "nameSuicideText": "${NAME} páchá sebevraždu.", "nameText": "Jméno", "nativeText": "Nativní", + "newExclaimText": "Nově!", "newPersonalBestText": "Nový osobní rekord!", "newTestBuildAvailableText": "Novější testovací build je dostupný! (${VERSION} build ${BUILD}).\nZískejte ho na ${ADDRESS}", "newText": "Nový", "newVersionAvailableText": "Je dostupná novější verze ${APP_NAME}! (${VERSION})", "nextAchievementsText": "Další ocenění:", - "nextLevelText": "Další Level", + "nextLevelText": "Další level", "noAchievementsRemainingText": "- žádný", "noContinuesText": "(bez pokračování)", "noExternalStorageErrorText": "Žádné externí úložiště nebylo na tomto zařízení nalezeno", "noGameCircleText": "Chyba: nejste přihlášeni do Game Circle", + "noMessagesText": "Žádné zprávy.", + "noPluginsInstalledText": "Nenainstalovány žádné pluginy", "noProfilesErrorText": "Nemáte žádné herní profily, takže Vám bylo podstrčeno jméno '${NAME}'.\nJděte do Nastavení->Herní Profily pro vytvoření svého profilu.", "noScoresYetText": "Zatím žádné výsledky.", - "noThanksText": "Ne, Děkuji", - "noTournamentsInTestBuildText": "VAROVÁNÍ: Skore z turnajů z tohoto účtu budou ignorována.", + "noServersFoundText": "Nenalezeny žádné servery.", + "noThanksText": "Ne, děkuji", + "noTournamentsInTestBuildText": "VAROVÁNÍ: Skóre z turnajů z tohoto testovacího buildu budou ignorovány.", "noValidMapsErrorText": "Nebyly nalezeny žádné platné mapy pro tento typ hry.", - "notEnoughPlayersRemainingText": "Nezbývá dostatek hráčů; ukončete a zapněte novou hru", + "notEnoughPlayersRemainingText": "Zbývá nedostatečný počet hráčů; ukončete a začněte novou hru", "notEnoughPlayersText": "Potřebujete nejméně ${COUNT} hráčů pro spuštění této hry!", - "notNowText": "Teď Ne", + "notEnoughTicketsText": "Nedostatek ticketů!", + "notNowText": "Teď ne", "notSignedInErrorText": "Pro tuto akci se musíte přihlásit", "notSignedInGooglePlayErrorText": "Pro tuto akci se musíte přihlásit přes Google Play", "notSignedInText": "nepřihlášen", - "notUsingAccountText": "Poznámka: nevyužívaný ${SERVICE} account.\nJděte do 'Účet -> Přihlásit se službou ${SERVICE}' pokud chcete účet používat.", + "notUsingAccountText": "Poznámka: ignoruji ${SERVICE} account.\nJděte do Účet -> Přihlásit se službou ${SERVICE} pokud chcete účet používat.", "nothingIsSelectedErrorText": "Nic není vybráno!", "numberText": "#${NUMBER}", "offText": "Vyp", @@ -1087,25 +1141,28 @@ "onText": "Zap", "oneMomentText": "Chvilku strpení...", "onslaughtRespawnText": "${PLAYER} se oživí ve vlně ${WAVE}", + "openMeText": "Otevři Mě!", + "openNowText": "Otevřte hned", + "openText": "Otevřít", "orText": "${A} nebo ${B}", "otherText": "Ostatní...", "outOfText": "(#${RANK} z ${ALL})", - "ownFlagAtYourBaseWarning": "Vaše vlajka musí být\nna vaší základně, abyste mohli skórovat!", + "ownFlagAtYourBaseWarning": "Vaše vlajka musí být na Vaší\nzákladně, abyste mohli skórovat!", "packageModsEnabledErrorText": "Hra po síti není povolena pokud jsou zapnuty lokální-balíčky-modů (Koukněte se do Nastavení->Pokročilé)", "partyWindow": { "chatMessageText": "Zpráva do chatu", - "emptyText": "Vaše parta nemá žádného člena", + "emptyText": "Vaše Parta nemá žádného člena", "hostText": "(hostitel)", "sendText": "Odeslat", "titleText": "Vaše Parta" }, "pausedByHostText": "(pozastaveno hostitelem)", - "perfectWaveText": "Perfektní Vlna!", + "perfectWaveText": "Perfektní vlna!", "pickUpText": "Zvednout", "playModes": { "coopText": "Co-op", - "freeForAllText": "Všichni-proti-Všem", - "multiTeamText": "Multi-Team", + "freeForAllText": "Všichni proti Všem", + "multiTeamText": "Multi Týmy", "singlePlayerCoopText": "Pro jednoho hráče / Co-op", "teamsText": "Týmy" }, @@ -1115,31 +1172,35 @@ "titleText": "Hrát", "twoToEightPlayersText": "2-8 hráčů" }, - "playerCountAbbreviatedText": "${COUNT}p", + "playerCountAbbreviatedText": "${COUNT} hr.", "playerDelayedJoinText": "${PLAYER} vstoupí na začátku dalšího kola.", "playerInfoText": "Info o hráči", - "playerLeftText": "${PLAYER} opustil hru.", - "playerLimitReachedText": "Limit hráčů (${COUNT}) byl dosažen; žádní ostatní připojovaní nejsou povoleni.", + "playerLeftText": "${PLAYER} opouští hru.", + "playerLimitReachedText": "Limit hráčů (${COUNT}) byl dosažen; nová připojení nejsou povolena.", "playerLimitReachedUnlockProText": "Upgradujte v obchodě na \"${PRO}\", abyste mohli hrát s více než ${COUNT} hráči.", "playerProfilesWindow": { "cantDeleteAccountProfileText": "Nemůžete odstranit Váš profil s účtem.", - "deleteButtonText": "Odstranit\nProfil", - "deleteConfirmText": "Odstranit '${PROFILE}'?", - "editButtonText": "Upravit\nProfil", + "deleteButtonText": "Odstranit\nprofil", + "deleteConfirmText": "Odstranit „${PROFILE}“?", + "editButtonText": "Upravit\nprofil", "explanationText": "(různé přezdívky a vzhledy pro hráče na tomto účtu)", - "newButtonText": "Nový\nProfil", - "titleText": "Herní Profily" + "newButtonText": "Nový\nprofil", + "titleText": "Herní profily" }, "playerText": "Hráč", "playlistNoValidGamesErrorText": "Tento playlist neobsahuje žádné platné odemčené hry.", "playlistNotFoundText": "playlist nenalezen", "playlistText": "Playlist", "playlistsText": "Playlisty", - "pleaseRateText": "Jestliže Vás ${APP_NAME} baví, zvažte prosím, jestli si nechcete udělat\nchvilku na ohodnocení nebo napsání recenze. Poskytuje to užitečnou\nzpětnou vazbu a pomáhá podporovat budoucí vývoj.\n\nDíky!\n-eric", - "pleaseWaitText": "Prosím čekejte...", - "pluginClassLoadErrorText": "Chyba při načítání třídy pluginu '${PLUGIN}': ${ERROR}", - "pluginInitErrorText": "Chyba při inicializaci pluginu '${PLUGIN}': ${ERROR}", + "pleaseRateText": "Jestliže Vás ${APP_NAME} baví, zvažte prosím, jestli si nechcete udělat\nchvilku na ohodnocení nebo napsání recenze. Poskytuje to užitečnou\nzpětnou vazbu a pomáhá podporovat budoucí vývoj.\n\nDíky!\n- Eric", + "pleaseWaitText": "Chvilku strpení...", + "pluginClassLoadErrorText": "Chyba při načítání třídy pluginu „${PLUGIN}“: ${ERROR}", + "pluginInitErrorText": "Chyba při inicializaci pluginu „${PLUGIN}“: ${ERROR}", + "pluginSettingsText": "Nastavení pluginů", + "pluginsAutoEnableNewText": "Automaticky povolit nové pluginy", "pluginsDetectedText": "Nové plugin(y) nalezeny. Pro aktivaci restartujte, nebo konfigurujte v nastavení.", + "pluginsDisableAllText": "Zakázat všechny pluginy", + "pluginsEnableAllText": "Povolit všechny pluginy", "pluginsRemovedText": "${NUM} plugin(y) nenalezeny.", "pluginsText": "Pluginy", "practiceText": "Cvičení", @@ -1149,10 +1210,10 @@ "pressAnyKeyButtonPlayAgainText": "Stiskněte libovolnou klávesu/tlačítko pro opakování hry...", "pressAnyKeyButtonText": "Stiskněte libovolnou klávesu/tlačítko pro pokračování...", "pressAnyKeyText": "Stiskněte libovolnou klávesu...", - "pressJumpToFlyText": "** Stiskněte opakovaně skok pro létání **", + "pressJumpToFlyText": "** Opakovaně stiskněte skok pro létání **", "pressPunchToJoinText": "stiskněte PRAŠTIT pro připojení...", "pressToOverrideCharacterText": "stiskněte ${BUTTONS} pro nahrazení vaší postavy", - "pressToSelectProfileText": "Stiskněte ${BUTTONS} pro zvolení hráče", + "pressToSelectProfileText": "stiskněte ${BUTTONS} pro zvolení hráče", "pressToSelectTeamText": "stiskněte ${BUTTONS} pro vybrání týmu", "promoCodeWindow": { "codeText": "Kód", @@ -1161,26 +1222,28 @@ }, "promoSubmitErrorText": "Chyba při odesílání kódu; zkontrolujte internetové připojení", "ps3ControllersWindow": { - "macInstructionsText": "Vypněte na zadní straně své PS3, ujistěte se, že\nje na Vašem Mac zaplý Bluetooth, a poté připojte Váš ovladač\nk vašemu Mac přes USB kabel, abyste je mohli spárovat. Odteď\nmůžete použít na ovladači tlačítko home (domů) pro připojení k Vašemu\nMacu ať už v kabelovém (USB) nebo bezdrátovém (Bluetooth) módu.\n\nNa některých Mac zařízeních můžete být při párování vyzváni k zadání passcode.\nJestliže se tohle stane, podívejte se na následující tutorial, nebo zkuste hledat na google.\n\n\n\n\nOvladače PS3, připojené bezdrátově, by se měly zobrazit v seznamu v\nSystémová nastavení->Bluetooth. Možná je budete potřebovat odstranit, pokud \nje budete chtít znovu použít s Vaším PS3.\n\nTaké se ujistěte, že je odpojíte od Bluetooth když nejsou používané,\nprotože jinak se jejich baterie budou stále vybíjet.\n\nBluetooth by měl zvládnout až 7 připojených zařízení,\nale to se může lišit.", - "ouyaInstructionsText": "Pro použití ovladače s Vaším OUYA, ho prostě jednou připojte přes USB kabel\nkvůli spárování. Ovšem při tomto kroku se mohou odpojit ostatní ovladače,\ntakže byste měli restartovat Vaši OUYA a odpojit USB kabel.\n\nOdteď budete schopni použít tlačítko HOME na ovladači k jeho připojení\nbezdrátově. Poté co dohrajete, držte tlačítko HOME 10 sekund, aby se\novladač vypl; jinak může zůstat zaplý\na vybíjet baterie.", + "macInstructionsText": "Vypněte na zadní straně své PS3, ujistěte se, že je na Vašem Macu\nzapnutý Bluetooth a poté připojte Váš ovladač k vašemu Macu přes USB kabel, \nabyste je mohli spárovat. Odteď můžete použít na ovladači tlačítko home (domů)\npro připojení k Vašemu Macu ať už v kabelovém (USB) nebo bezdrátovém (Bluetooth) módu.\n\nNa některých Macích můžete být při párování vyzváni k zadání hesla.\nJestliže se tohle stane, podívejte se na následující tutorial, nebo zkuste hledat na internetu.\n\n\n\n\nOvladače PS3 připojené bezdrátově by se měly zobrazit v seznamu v\nSystémová nastavení->Bluetooth. Možná je budete muset odstranit, pokud \nje budete chtít znovu použít s Vaším PS3.\n\nTaké se ujistěte, že je odpojíte od Bluetooth když nejsou používané, jinak se jejich baterie budou nadále vybíjet.\n\nBluetooth by měl zvládnout až 7 připojených zařízení, ale to se může lišit.", + "ouyaInstructionsText": "Pro použití PS3 ovladače s Vaší OUYA ho prostě jednou připojte přes USB kabel pro spárování. Při tomto kroku se mohou odpojit ostatní ovladače,\ntakže byste měli restartovat Vaši OUYA a odpojit USB kabel.\n\nOdteď budete mít možnost použít tlačítko HOME na ovladači k jeho bezdrátovému připojení. Poté co dohrajete, držte tlačítko HOME 10 sekund, aby se\novladač vypl; jinak se jeho baterie budou nadále vybíjet.", "pairingTutorialText": "video tutorial o párování", "titleText": "Používání PS3 Ovladače s ${APP_NAME}:" }, "punchBoldText": "PRAŠTIT", "punchText": "Praštit", "purchaseForText": "Koupit za ${PRICE}", - "purchaseGameText": "Koupit Hru", + "purchaseGameText": "Zakoupit hru", + "purchaseNeverAvailableText": "Bohužel, transakce nejsou dostupné na této sestavě.\nZkuste přihlásit svůj účet na jiné platformě a na ní provést nákup.", + "purchaseNotAvailableText": "Tento nákup není dostupný.", "purchasingText": "Probíhá transakce...", "quitGameText": "Ukončit ${APP_NAME}?", "quittingIn5SecondsText": "Ukončuji za 5 sekund...", - "randomPlayerNamesText": "DEFAULT_NAMES", + "randomPlayerNamesText": "Jenda, Kuba, Saša, Péťa, Pepa, Kája, Pája, Klára, Monča, Dita, Máša, David, Mirek, Jana, Hanka, Vítek, Lenka, Áďa, Franta, DEFAULT_NAMES", "randomText": "Náhodně", "rankText": "Rank", "ratingText": "Hodnocení", "reachWave2Text": "Pro hodnocení se dostaňte do vlny 2.", "readyText": "připraven", "recentText": "Poslední", - "remoteAppInfoShortText": "${APP_NAME} je zábavnější hrát s rodinou & přáteli.\nPřipoj jedno nebo více hardwerových ovladačů nebo \nnainstaluj ${REMOTE_APP_NAME} na telefon nebo tablet \nk jejich použití jako ovladač.", + "remoteAppInfoShortText": "${APP_NAME} je zábavnější hrát s rodinou & přáteli.\nPřipojte jeden nebo více fyzických ovladačů nebo \nnainstalujte ${REMOTE_APP_NAME} na telefon nebo tablet \nk jejich použití jako ovladač.", "remote_app": { "app_name": "BombSquad Ovladač", "app_name_short": "BSOvladač", @@ -1189,35 +1252,36 @@ "cant_resolve_host": "Hostitel nebyl nalezen.", "capturing": "Zachytávám...", "connected": "Připojen.", - "description": "Použijte Váš telefon či tablet jako ovladač pro BombSquad.\nNajednou lze připojit až 8 zařízení k lokálnímu multiplayerovému šílenství na televizi či tabletu.", + "description": "Použijte Váš telefon či tablet jako ovladač pro BombSquad.\nNajednou lze připojit až 8 zařízení k epickému lokálnímu multiplayerovému šílenství na televizi či tabletu.", "disconnected": "Odpojen serverem.", "dpad_fixed": "statický", "dpad_floating": "plovoucí", - "dpad_position": "Pozice D-Pad", - "dpad_size": "Velikost D-Pad", - "dpad_type": "Typ D-Pad", + "dpad_position": "Pozice D-Padu", + "dpad_size": "Velikost D-Padu", + "dpad_type": "Typ D-Padu", "enter_an_address": "Zadejte adresu", "game_full": "Hra je již zaplněna hráči nebo nepřijímá připojení.", "game_shut_down": "Hra byla vypnuta.", "hardware_buttons": "Hardwarová tlačítka", "join_by_address": "Připojit se k adrese...", "lag": "Prodleva: ${SECONDS} sekund", - "reset": "Navrátit základní", + "reset": "Navrátit výchozí", "run1": "Běh 1", "run2": "Běh 2", "searching": "Probíhá hledání aktivních her BombSquad...", - "searching_caption": "Pro připojení se dotkněte jména hry.\nUjistěte se, že jste na stejné síti wifi.", + "searching_caption": "Pro připojení se dotkněte jména hry.\nUjistěte se, že jste na stejné síti WiFi.", "start": "Start", "version_mismatch": "Neshoda verzí.\nUjistěte se, že BombSquad a BombSquad Ovladač\njsou aktualizované na poslední verzi, a zkuste to znovu." }, - "removeInGameAdsText": "Odemkněte \"${PRO}\" v obchodě pro odstranění reklam ve hře.", + "removeInGameAdsText": "Odemkněte „${PRO}“ v obchodě pro odstranění reklam ve hře.", + "removeInGameAdsTokenPurchaseText": "LIMITOVANÁ NABÍDKA: Zakoupením JAKÉHOKOLI balíčku tokenů odstraníte reklamy.", "renameText": "Přejmenovat", "replayEndText": "Ukončit Záznam", "replayNameDefaultText": "Záznam Poslední Hry", "replayReadErrorText": "Chyba při čtení souboru záznamu.", - "replayRenameWarningText": "Přejmenujte \"${REPLAY}\" po odehrané hře, pokud ho chcete zachovat; jinak bude přepsán", + "replayRenameWarningText": "Přejmenujte „${REPLAY}“ po odehrané hře, pokud ho chcete zachovat; jinak bude přepsán.", "replayVersionErrorText": "Omlouváme se, ale tento záznam byl vytvořen\nv jiné verzi hry a nemůže být přehrán.", - "replayWatchText": "Podívat se na Záznam", + "replayWatchText": "Podívat se na záznam", "replayWriteErrorText": "Chyba při zápisu souboru záznamu.", "replaysText": "Záznamy", "reportPlayerExplanationText": "Použijte tento email pro nahlášení podvádění, nevhodného vyjadřování či jiného špatného chování.\nProsím popište níže:", @@ -1231,7 +1295,9 @@ "revertText": "Navrátit", "runText": "Běh", "saveText": "Uložit", - "scanScriptsErrorText": "Chyba při skenování skriptů; shlédni záznam pro více informací.", + "scanScriptsErrorText": "Chyba při skenování skriptů. Shlédni záznam pro více informací.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} a ${NUM} dalších modulů musí být aktualizováno pro API ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} musí být aktualizován pro API ${API}.", "scoreChallengesText": "Skóre Výzev", "scoreListUnavailableText": "Seznam skóre nedostupný", "scoreText": "Skóre", @@ -1242,6 +1308,7 @@ }, "scoreWasText": "(předchozí ${COUNT})", "selectText": "Zvolit", + "sendInfoDescriptionText": "Pošle informace stavu aplikace a účtu vývojářovi.\nProsím zahrňte své jméno nebo důvod k poslání.", "seriesWinLine1PlayerText": "VYHRÁVÁ", "seriesWinLine1TeamText": "VYHRÁVÁ", "seriesWinLine1Text": "VYHRÁVÁ", @@ -1257,9 +1324,10 @@ "titleText": "Nastavení" }, "settingsWindowAdvanced": { - "alwaysUseInternalKeyboardDescriptionText": "(jednoduchá, ovládáním přátelská, klávesnice na obrazovce pro úpravu textu)", - "alwaysUseInternalKeyboardText": "Vždy Použít Interní klávesnici", - "benchmarksText": "Benchmarky a Testy výdrže", + "alwaysUseInternalKeyboardDescriptionText": "(jednoduchá, ovládáním přátelská klávesnice na obrazovce pro úpravu textu)", + "alwaysUseInternalKeyboardText": "Vždy použít interní klávesnici", + "benchmarksText": "Benchmarky a testy výdrže", + "devToolsText": "Nástroje pro Vývojáře", "disableCameraGyroscopeMotionText": "Vypnout gyroskopický pohyb kamery", "disableCameraShakeText": "Vypnout otřes kamery", "disableThisNotice": "(můžete si toto oznámení vypnout v pokročilých nastaveních)", @@ -1268,23 +1336,31 @@ "enterPromoCodeText": "Zadat kód", "forTestingText": "Poznámka: Tyto hodnoty sou pouze pro test. Obnoví se po restartu.", "helpTranslateText": "Jiné než anglické verze ${APP_NAME} jsou komunitně\npodporovanou záležitostí. Pokud byste chtěli přidat\nnebo opravit překlad, následujte odkaz níže. Předem děkujeme!", - "kickIdlePlayersText": "Vyhazovat Neaktivní Hráče", - "kidFriendlyModeText": "Dětský Mód (sníženo násilí, atd.)", + "insecureConnectionsDescriptionText": "není doporučeno, ale může povolit online hru\n v zakázaných zemích nebo sítích", + "insecureConnectionsText": "Použít nezabezpečené připojení", + "kickIdlePlayersText": "Vykopnout neaktivní hráče", + "kidFriendlyModeText": "Dětský mód (snížené násilí, atd.)", "languageText": "Jazyk", "moddingGuideText": "Příručka módů", + "moddingToolsText": "Modovací možnosti", "mustRestartText": "Musíte restartovat hru, aby se změny projevily.", - "netTestingText": "Testování Sítě", + "netTestingText": "Testování sítě", "resetText": "Obnovit", - "showBombTrajectoriesText": "Ukázat trajektorii bomb", - "showPlayerNamesText": "Jména hráčů", - "showUserModsText": "Zobrazit Složku s Módy", + "sendInfoText": "Poslat info", + "showBombTrajectoriesText": "Ukazovat trajektorii bomb", + "showDemosWhenIdleText": "Zobrazit demo při nečinnosti", + "showDeprecatedLoginTypesText": "Zobrazit zastaralé způsoby přihlášení", + "showDevConsoleButtonText": "Zobrazit tlačítko vývojářské konzole", + "showInGamePingText": "Zobrazit herní ping", + "showPlayerNamesText": "Ukazovat jména hráčů", + "showUserModsText": "Zobrazit složku s módy", "titleText": "Pokročilé", - "translationEditorButtonText": "${APP_NAME} Editor Překladu", + "translationEditorButtonText": "${APP_NAME} editor překladu", "translationFetchErrorText": "stav překladu nedostupný", "translationFetchingStatusText": "zjišťuji stav překladu...", "translationInformMe": "Oznamte mi když bude můj jazyk potřebovat aktualizaci", - "translationNoUpdateNeededText": "tento jazyk je aktuální; woohoo!", - "translationUpdateNeededText": "** jazyk potřebuje aktualizovat!! **", + "translationNoUpdateNeededText": "Tento jazyk je aktuální; hurá! :)", + "translationUpdateNeededText": "** Jazyk potřebuje aktualizovat!! **", "vrTestingText": "VR Test" }, "shareText": "Sdílet", @@ -1293,33 +1369,37 @@ "signInForPromoCodeText": "Musíte se přihlásit k účtu, aby mohly kódy fungovat.", "signInWithGameCenterText": "Pro použití účtu Game Center se přihlaste\ns pomocí aplikace Game Center.", "singleGamePlaylistNameText": "Jen ${GAME}", - "singlePlayerCountText": "1 Hráč", + "singlePlayerCountText": "1 hráč", + "sizeLargeText": "Velký", + "sizeMediumText": "Středně velký", + "sizeSmallText": "Malý", "soloNameFilterText": "Sólo ${NAME}", "soundtrackTypeNames": { - "CharSelect": "Vybírání Postavy", + "CharSelect": "Vybírání postavy", "Chosen One": "Vyvolený", - "Epic": "Hry v Epickém Módu", + "Epic": "Hry v Epickém módu", "Epic Race": "Epický závod", "FlagCatcher": "Seberte vlajku", - "Flying": "Veselé Myšlenky", + "Flying": "Veselé myšlenky", "Football": "Ragby", "ForwardMarch": "Přepadení", "GrandRomp": "Dobývání", "Hockey": "Hokej", - "Keep Away": "Držte se Dál", + "Keep Away": "Držte se stranou", "Marching": "Obrana", "Menu": "Hlavní menu", "Onslaught": "Útok", "Race": "Závod", - "Scary": "Král Kopce", - "Scores": "Obrazovka Skóre", - "Survival": "Zneškodnění", - "ToTheDeath": "Zápas Smrti", - "Victory": "Obrazovka Konečného Skóre" + "Scary": "Král kopce", + "Scores": "Obrazovka skóre", + "Survival": "Eliminace", + "ToTheDeath": "Zápas smrti", + "Victory": "Obrazovka konečného skóre" }, "spaceKeyText": "mezera", "statsText": "Statistiky", - "storagePermissionAccessText": "Tohle vyžaduje přístup k úložišti", + "stopRemindingMeText": "Dále Nepřipomínat", + "storagePermissionAccessText": "Toto vyžaduje přístup k úložišti", "store": { "alreadyOwnText": "Už vlastníš ${NAME}!", "bombSquadProDescriptionText": "• Zdvojnásobuje kupóny získané za achievementy\n• Odstraňuje reklamy ve hře\n• Obsahuje ${COUNT} bonusových kupónů\n• +${PERCENT}% bonus ke skóre ligy\n• Odemyká '${INF_ONSLAUGHT}' a \n '${INF_RUNAROUND}' co-op mapy", @@ -1330,34 +1410,34 @@ "charactersText": "Postavy", "comingSoonText": "Již brzy...", "extrasText": "Bonusy", - "freeBombSquadProText": "BombSquad je nyní zdarma, ale pokud jste si ho dříve zakoupili,\ndostáváte BombSquad Pro upgrade a ${COUNT} kupónů jako poděkování.\nUžijte si nové možnosti a děkujeme za vaši podporu!\n-Eric", + "freeBombSquadProText": "BombSquad je nyní zdarma, ale pokud jste si ho dříve zakoupili,\ndostáváte BombSquad Pro upgrade a ${COUNT} kupónů jako poděkování.\nUžijte si nové možnosti a díky za podporu!\n- Eric", "gameUpgradesText": "Vylepšení hry", - "holidaySpecialText": "Vánoční speciál", - "howToSwitchCharactersText": "(jděte do \"${SETTINGS} -> ${PLAYER_PROFILES}\" k použití nebo úpravě postav)", + "holidaySpecialText": "Sváteční Speciál", + "howToSwitchCharactersText": "(jděte do ${SETTINGS} -> ${PLAYER_PROFILES} k použití nebo úpravě postav)", "howToUseIconsText": "(vytvořte si globální herní účet (v okně účtů) abyste je mohli použít)", - "howToUseMapsText": "(použijte tyto mapy ve vlastních týmových/všichni-proti-všem seznamech)", + "howToUseMapsText": "(použijte tyto mapy ve vlastních týmových/všichni proti všem seznamech)", "iconsText": "Ikony", - "loadErrorText": "Nelze načíst.\nZkontrolujte připojení.", + "loadErrorText": "Nelze načíst stránku.\nZkontrolujte připojení k internetu.", "loadingText": "Načítání...", "mapsText": "Mapy", "miniGamesText": "MiniHry", "oneTimeOnlyText": "(pouze jednou)", "purchaseAlreadyInProgressText": "Koupě této položky již probíhá.", "purchaseConfirmText": "Zakoupit ${ITEM}?", - "purchaseNotValidError": "Nákup je neplatný.\nKontaktuje ${EMAIL} pokuď je to chyba.", + "purchaseNotValidError": "Nákup je neplatný.\nKontaktuje ${EMAIL} jedná-li se o omyl.", "purchaseText": "Zakoupit", "saleBundleText": "Balíček ve slevě!", "saleExclaimText": "Sleva!", "salePercentText": "(o ${PERCENT}% levnější)", "saleText": "VÝPRODEJ", "searchText": "Hledat", - "teamsFreeForAllGamesText": "Týmy / Všichni-proti-Všem Hry", + "teamsFreeForAllGamesText": "Týmové / Všichni proti Všem Hry", "totalWorthText": "***JEDNOTLIVĚ STOJÍ ${TOTAL_WORTH}! ***", "upgradeQuestionText": "Aktivovat?", - "winterSpecialText": "Zimní Speciál", + "winterSpecialText": "Zimní speciál", "youOwnThisText": "- již vlastníte -" }, - "storeDescriptionText": "Šílená Hra s Osmi Hráči v Partě!\n\nVyhoďte do vzduchu své přátele (nebo počítač) v turnaji explozivních miniher jako je třeba Seber Vlajku, Bomber-Hokej, a Epický-Slow-Motion-Zápas-Smrti!\n\nJednoduché ovládání a široká podpora ovladačů tvoří jednoduchou vlastnost připojit až 8 lidí do akce; a také můžete použít své mobilní zařízení jako ovladače přes aplikaci 'BombSquad Remote', která je zdarma!\n\nOdhoďte Bomby\n\nPro více informací navštivte stránku www.froemling.net/bombsquad", + "storeDescriptionText": "Šílenství pro osm hráčů!\n\nVyhoďte do vzduchu své přátele (nebo počítač) v turnaji bombastických miniher jako třeba Seberte vlajku, Bomber hokej, nebo Zápas smrti v Epickém zpomaleném záběru!\n\nJednoduché ovládání a široká podpora ovladačů umožňují do akce zapojit až 8 lidí; a také můžete použít své mobilní zařízení jako ovladače přes aplikaci „BombSquad Remote“, která je zdarma!\n\nBombám zdar!\n\nPro více informací navštivte stránku www.froemling.net/bombsquad", "storeDescriptions": { "blowUpYourFriendsText": "Vyhoďte přátele do vzduchu.", "competeInMiniGamesText": "Utkejte se v minihrách od závodění po létání.", @@ -1369,18 +1449,21 @@ "storeText": "Obchod", "submitText": "Odeslat", "submittingPromoCodeText": "Odesílám kód...", - "teamNamesColorText": "Týmové Jména/Barvy...", + "successText": "Úspěch!", + "supportEmailText": "Pokud máte jakékoliv problémy s aplikací, prosím \nnapište na email ${EMAIL}.", + "teamNamesColorText": "Jména/Barvy týmů...", "telnetAccessGrantedText": "Přístup k telnetu zapnut.", "telnetAccessText": "Detekován přístup k telnetu; povolit?", "testBuildErrorText": "Tento testovací build již není dlouho aktivní; podívejte se prosím po nové verzi.", - "testBuildText": "Testovací Build", + "testBuildText": "Testovací build", "testBuildValidateErrorText": "Nebylo možné ověřit testovací build. (žádné internetové připojení?)", - "testBuildValidatedText": "Testovací Build Ověřen; Užívejte!", + "testBuildValidatedText": "Testovací build Ověřen; Užívejte!", "thankYouText": "Děkujeme Vám za podporu! Užijte si hru!!", "threeKillText": "TŘI ZABITÍ!!!", - "timeBonusText": "Časový Bonus", - "timeElapsedText": "Uplynulý Čas", - "timeExpiredText": "Čas Vypršel", + "ticketsDescriptionText": "Kupóny mohou být použity na odemykání postav,\nmap, miniher a mnoho dalšího v obchodě.\n\nKupóny lze nalézt v truhlách vyhraných díky\nkampaním, turnajům a trofejím.", + "timeBonusText": "Časový bonus", + "timeElapsedText": "Uplynulý čas", + "timeExpiredText": "Čas vypršel", "timeSuffixDaysText": "${COUNT}d", "timeSuffixHoursText": "${COUNT}h", "timeSuffixMinutesText": "${COUNT}m", @@ -1388,11 +1471,25 @@ "tipText": "Tip", "titleText": "BombSquad", "titleVRText": "BombSquad VR", - "topFriendsText": "Nejlepší Přátelé", - "tournamentCheckingStateText": "Zjišťuji stav turnaje; Počkejte prosím...", + "tokens": { + "getTokensText": "Získat Tokeny", + "notEnoughTokensText": "Nedostatek tokenů!", + "numTokensText": "${COUNT} Tokenů", + "openNowDescriptionText": "Máte dostatek tokenů na \nOtevření nyní - Netřeba\nčekat.", + "shinyNewCurrencyText": "Nová blištivá měna BombSquadu.", + "tokenPack1Text": "Malý Tokenový Balíček", + "tokenPack2Text": "Střední Tokenový Balíček", + "tokenPack3Text": "Velký Tokenový Balíček", + "tokenPack4Text": "Obrovský Tokenový Balíček", + "tokensDescriptionText": "Tokeny se používají na urychlení odemykání\ntruhel a na další funkce hry a účtu.\n\nTokeny můžete vyhrát ve hře nebo si je zakoupit\nv balíčcích. Nebo si můžete koupit Gold Pass pro\nnekonečný počet tokenů a nemusíte se o ně starat.", + "youHaveGoldPassText": "Vlastníte Gold Pass.\nVšechny nákupy za tokeny jsou zdarma.\nUžívejte!" + }, + "topFriendsText": "Nejlepší přátelé", + "tournamentCheckingStateText": "Zjišťuji stav turnaje; chvilku strpení...", "tournamentEndedText": "Tento turnaj již skončil. Brzy ale začne další.", "tournamentEntryText": "Vstup do turnaje", - "tournamentResultsRecentText": "Vysledky predchozich turnaju", + "tournamentFinalStandingsText": "Konečné umístění", + "tournamentResultsRecentText": "Výsledky předchozích turnajů", "tournamentStandingsText": "Pořadí v turnaji", "tournamentText": "Turnaj", "tournamentTimeExpiredText": "Čas turnaje vypršel", @@ -1447,16 +1544,28 @@ "Uber Onslaught": "Útok - Megatěžké", "Uber Runaround": "Obrana - Megatěžká" }, + "displayItemNames": { + "${C} Tickets": "${C} Ticketů", + "${C} Tokens": "${C} Tokenů", + "Chest": "Truhla", + "L1 Chest": "Truhla L1", + "L2 Chest": "Truhla L2", + "L3 Chest": "Truhla L3", + "L4 Chest": "Truhla L4", + "L5 Chest": "Truhla L5", + "L6 Chest": "Truhla L6", + "Unknown Chest": "Neznámá truhla" + }, "gameDescriptions": { - "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Staňte se vyvoleným po dlouhý čas, abyste vyhráli.\nZabijte vyvoleného, abyste se jím stali.", - "Bomb as many targets as you can.": "Vybombardujte tolik cílů, kolik dokážete.", + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Buďte vyvoleným dostatečně dlouho, abyste vyhráli.\nZabijte vyvoleného, abyste se jím stali.", + "Bomb as many targets as you can.": "Odpalte tolik cílů, kolik dokážete.", "Carry the flag for ${ARG1} seconds.": "Držte vlajku po dobu ${ARG1} sekund.", "Carry the flag for a set length of time.": "Držte vlajku po nastavený čas.", "Crush ${ARG1} of your enemies.": "Rozdrťte ${ARG1} Vašich nepřátel.", - "Defeat all enemies.": "Porazte všechny nepřátele", + "Defeat all enemies.": "Porazte všechny nepřátele.", "Dodge the falling bombs.": "Vyhněte se padajícím bombám.", - "Final glorious epic slow motion battle to the death.": "Finální úžasný epický slow motion souboj na smrt.", - "Gather eggs!": "Sbírání vajec!", + "Final glorious epic slow motion battle to the death.": "Ultimátní krutopřísný epický zpomalený souboj na smrt.", + "Gather eggs!": "Sbírejte velikonoční vajíčka!", "Get the flag to the enemy end zone.": "Dostaňte vlajku na nepřátelskou koncovou zónu.", "How fast can you defeat the ninjas?": "Jak rychle dokážete porazit ninja bojovníky?", "Kill a set number of enemies to win.": "Zabijte určený počet nepřátel, abyste vyhráli.", @@ -1464,8 +1573,8 @@ "Last remaining alive wins.": "Poslední zbývající živý vyhrává.", "Last team standing wins.": "Poslední vzdorující tým vyhrává.", "Prevent enemies from reaching the exit.": "Zabraňte nepřátelům dostat se na konec.", - "Reach the enemy flag to score.": "Dostaňte nepřátelskou vlajku, abyste skórovali.", - "Return the enemy flag to score.": "Vraťe nepřátelskou vlajku pro skórování.", + "Reach the enemy flag to score.": "Dotkněte se nepřátelské vlajky, abyste skórovali.", + "Return the enemy flag to score.": "Přineste nepřátelskou vlajku pro skórování.", "Run ${ARG1} laps.": "Uběhněte ${ARG1} kol/a.", "Run ${ARG1} laps. Your entire team has to finish.": "Uběhněte ${ARG1} kol. Celý Váš tým musí dokončit.", "Run 1 lap.": "Uběhněte 1 kolo.", @@ -1482,15 +1591,15 @@ "Secure the flag for a set length of time.": "Zajistěte vlajku po určený čas.", "Steal the enemy flag ${ARG1} times.": "Ukradněte ${ARG1}x nepřátelskou vlajku.", "Steal the enemy flag.": "Ukradněte nepřátelskou vlajku.", - "There can be only one.": "Tady může být jen jedna.", + "There can be only one.": "Tady může být jen jeden.", "Touch the enemy flag ${ARG1} times.": "Dotkněte se ${ARG1}x nepřátelské vlajky.", "Touch the enemy flag.": "Dotkněte se nepřátelské vlajky.", - "carry the flag for ${ARG1} seconds": "Držte vlajku po dobu ${ARG1} sekund", + "carry the flag for ${ARG1} seconds": "držte vlajku po dobu ${ARG1} sekund", "kill ${ARG1} enemies": "zabijte ${ARG1} nepřátel", "last one standing wins": "poslední vzdorující vyhrává", "last team standing wins": "poslední vzdorující tým vyhrává", - "return ${ARG1} flags": "vraťte ${ARG1} vlajek", - "return 1 flag": "vraťte 1 vlajku", + "return ${ARG1} flags": "přineste ${ARG1} vlajek", + "return 1 flag": "přineste 1 vlajku", "run ${ARG1} laps": "uběhněte ${ARG1} kol/a", "run 1 lap": "uběhněte 1 kolo", "score ${ARG1} goals": "dejte góly - ${ARG1}", @@ -1504,22 +1613,22 @@ }, "gameNames": { "Assault": "Přepadení", - "Capture the Flag": "Seberte Vlajku", + "Capture the Flag": "Seberte vlajku", "Chosen One": "Vyvolený", "Conquest": "Dobývání", - "Death Match": "Zápas Smrti", - "Easter Egg Hunt": "Lovení velikonočních vajíček", - "Elimination": "Zneškodnění", + "Death Match": "Zápas smrti", + "Easter Egg Hunt": "Lovení vajíček", + "Elimination": "Eliminace", "Football": "Ragby", "Hockey": "Hokej", - "Keep Away": "Držte se Dál", - "King of the Hill": "Král Kopce", - "Meteor Shower": "Smršť Meteoritů", + "Keep Away": "Držte se stranou", + "King of the Hill": "Král kopce", + "Meteor Shower": "Smršť meteoritů", "Ninja Fight": "Souboj Ninja bojovníků", "Onslaught": "Útok", "Race": "Závod", "Runaround": "Obrana", - "Target Practice": "Trénování Cílů", + "Target Practice": "Odpalování terčů", "The Last Stand": "Poslední vzdor" }, "inputDeviceNames": { @@ -1527,7 +1636,7 @@ "Keyboard P2": "Klávesnice P2" }, "languages": { - "Arabic": "Arabsky", + "Arabic": "Arabština", "Belarussian": "Běloruština", "Chinese": "Zjednodušená Čínština", "ChineseTraditional": "Tradiční Čínština", @@ -1551,6 +1660,7 @@ "Korean": "Korejština", "Malay": "Malajština", "Persian": "Perština", + "PirateSpeak": "Řeč pirátů", "Polish": "Polština", "Portuguese": "Portugalština", "Romanian": "Rumunština", @@ -1560,7 +1670,7 @@ "Spanish": "Španělština", "Swedish": "Švédština", "Tamil": "Tamiština", - "Thai": "Thaiština", + "Thai": "Thajština", "Turkish": "Turečtina", "Ukrainian": "Ukrajinština", "Venetian": "Benátština", @@ -1576,24 +1686,24 @@ "Big G": "Velké G", "Bridgit": "Mostík", "Courtyard": "Nádvoří", - "Crag Castle": "Skalní Hrad", - "Doom Shroom": "Houba Zkázy", - "Football Stadium": "Ragby Stadion", - "Happy Thoughts": "Veselé Myšlenky", - "Hockey Stadium": "Hokejový Stadion", - "Lake Frigid": "Jezero Zmrzlík", - "Monkey Face": "Opičí Tvář", + "Crag Castle": "Skalní hrad", + "Doom Shroom": "Houba zkázy", + "Football Stadium": "Ragby stadion", + "Happy Thoughts": "Veselé myšlenky", + "Hockey Stadium": "Hokejový stadion", + "Lake Frigid": "Jezero zmrzlík", + "Monkey Face": "Opičí tvář", "Rampage": "Zuřivost", - "Roundabout": "Kruhový Objezd", + "Roundabout": "Kruhový objezd", "Step Right Up": "Zmatené schody", "The Pad": "Podložka", - "Tip Top": "Tip Ťop", + "Tip Top": "Tip ťop", "Tower D": "Věž D", "Zigzag": "Cikcak" }, "playlistNames": { - "Just Epic": "Jen Epické", - "Just Sports": "Jen Sporty" + "Just Epic": "Jen epické", + "Just Sports": "Jen sporty" }, "scoreNames": { "Flags": "Vlajky", @@ -1601,7 +1711,7 @@ "Score": "Skóre", "Survived": "Přežil", "Time": "Čas", - "Time Held": "Čas Držen" + "Time Held": "Čas držení" }, "serverResponses": { "A code has already been used on this account.": "Kód již byl pro tento účet použit.", @@ -1609,19 +1719,20 @@ "Account linking successful!": "Spojení účtu úspěšné!", "Account unlinking successful!": "Účet úspěšně odpojen!", "Accounts are already linked.": "Účty jsou již spojeny.", - "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Zhlédnutí reklamy nebylo ověřeno.\nProsím ujistěte se, že máte oficiální a updatovanou hru.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Zhlédnutí reklamy nebylo ověřeno.\nUjistěte se prosím, že máte oficiální a aktualizovanou hru.", "An error has occurred; (${ERROR})": "Nastala chyba; (${ERROR})", "An error has occurred; please contact support. (${ERROR})": "Nastala chyba; kontaktujete prosím podporu. (${ERROR})", - "An error has occurred; please contact support@froemling.net.": "Stala se chyba; prosím kontaktujte support@froemling.net.", - "An error has occurred; please try again later.": "Vyskytla se chyba; prosím zkuste to znova za chvilku", + "An error has occurred; please contact support@froemling.net.": "Nastala chyba; prosím kontaktujte support@froemling.net.", + "An error has occurred; please try again later.": "Nastala chyba; prosím zkuste to znova za chvilku", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Jste si jisti, že chcete propojit tyto účty?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTuto akci nelze vrátit zpět!", "BombSquad Pro unlocked!": "BombSquad Pro odemčen!", - "Can't link 2 accounts of this type.": "Nelze spojit 2 účty tohodle typu.", + "Can't link 2 accounts of this type.": "Nelze spojit 2 účty tohoto typu.", "Can't link 2 diamond league accounts.": "Nelze spojit 2 účty diamantové ligy.", "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nelze propojit; převýšily maximum ${COUNT} propojených účtů.", "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Detekováno podvádění; skóre a ceny pozastaveny na ${COUNT} dní", "Could not establish a secure connection.": "Nelze navázat bezpečné připojení.", "Daily maximum reached.": "Dosaženo denní maximum.", + "Daily sign-in reward": "Denní odměna za přihlášení", "Entering tournament...": "Vstupujete do turnaje...", "Invalid code.": "Neplatný kód.", "Invalid payment; purchase canceled.": "Neplatná platební maetoda; platba zrušena.", @@ -1629,94 +1740,108 @@ "Invalid purchase.": "Neplatná koupě.", "Invalid tournament entry; score will be ignored.": "Neplatný turnaj; skóre bude ignorováno.", "Item unlocked!": "Položka odemčena!", - "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "Propojení zamítnuto. ${ACCOUNT} obsahuje\nznačné data, které by byly ZCELA ZTRACENY.\nPokud chcete, můžete připojit účet v opačném\npořadí (a ztratit tak data TOHOTO účtu)", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "PROPOJENÍ ZAMÍTNUTO. ${ACCOUNT} obsahuje\nznačná data, která by byla ZCELA ZTRACENA.\nPokud chcete, můžete připojit účet v opačném\npořadí (a ztratit tak data TOHOTO účtu)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Chcete spojit účet ${ACCOUNT} s tímto účtem?\nVšechna data na účtě ${ACCOUNT} budou smazána.\nTuto akci nelze navrátit zpět. Jste si jisti?", - "Max number of playlists reached.": "Dosazano maximalniho počtu výpisů", + "Longer streaks lead to better rewards.": "Delší série přihláśení vede k lepším odměnám.", + "Max number of playlists reached.": "Dosazano maximalniho počtu playlistů", "Max number of profiles reached.": "Dosaženo maximalního počtu profilů", - "Maximum friend code rewards reached.": "Kamarádova maximální výhra na kódu.", + "Maximum friend code rewards reached.": "Dosaženo maximum odměn za kódy přátel.", "Message is too long.": "Zpráva je příliš dlouhá.", + "New tournament result!": "Nový výsledek turnaje!", "No servers are available. Please try again soon.": "Žádné servery nejsou nyní dostupné. Zkuste to prosím později.", - "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" byl úspěšně přeměněn.", - "Profile could not be upgraded.": "Profil nelze přeměnit.", - "Purchase successful!": "Koupě se zdařila!", + "No slots available. Free a slot and try again.": "Všechna místa obsazená. Uvolněte místo a zkuste to znovu.", + "Profile \"${NAME}\" upgraded successfully.": "Profil „${NAME}“ byl úspěšně povýšen.", + "Profile could not be upgraded.": "Profil nelze povýšit.", + "Purchase successful!": "Nákup úspěšný!", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Získali jste ${COUNT} kupónů za přihlášení.\nVraťte se zítra, abyste jich obdrželi ${TOMORROW_COUNT}.", - "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Server běží na novější verzi a tu vaši nepodporuje,\naktualizujte hru pro připojení.", - "Sorry, there are no uses remaining on this code.": "Omlouváme se, ale již zde nejsou žádné zbývající použití pro tento kód.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Funkce serveru již nejsou podporovány v této verzi hry;\nAktualizujte prosím na novější verzi.", + "Sorry, there are no uses remaining on this code.": "Omlouváme se, ale již zde nejsou žádná zbývající použití pro tento kód.", "Sorry, this code has already been used.": "Omlouváme se, ale tento kód již byl použit.", "Sorry, this code has expired.": "Omlouváme se, ale platnost tohoto kódu vypršela.", "Sorry, this code only works for new accounts.": "Omlouváme se, ale tento kód je platný pouze pro nové účty.", - "Still searching for nearby servers; please try again soon.": "Stále se vyhledávají lokální servery; Prosím zkuste to později.", - "Temporarily unavailable; please try again later.": "Dočasně nedostupné; zkuste to později.", - "The tournament ended before you finished.": "Turnaj skončil než jste ho dokončili.", + "Sorry, this has expired.": "Promiň, vypršela platnost.", + "Still searching for nearby servers; please try again soon.": "Stále se vyhledávají lokální servery; zkuste to prosím později.", + "Streak: ${NUM} days": "Série: ${NUM} dní", + "Temporarily unavailable; please try again later.": "Dočasně nedostupné; zkuste to prosím později.", + "The tournament ended before you finished.": "Turnaj skončil než jste ho stihli dokončit.", "This account cannot be unlinked for ${NUM} days.": "Tento účet nelze odpojit po dobu ${NUM} dnů.", "This code cannot be used on the account that created it.": "Tento kód nemůže být použit na účtu, na kterém byl vytvořen.", - "This is currently unavailable; please try again later.": "Tato možnost je momentálně nedostupná; prosím zkuste to později.", + "This is currently unavailable; please try again later.": "Tato možnost je momentálně nedostupná; zkuste to prosím později.", "This requires version ${VERSION} or newer.": "Toto vyžaduje verzi ${VERSION} nebo vyšší.", - "Tournaments disabled due to rooted device.": "Turnaje nedostupné na zařízeních s rootem.", + "Tournaments disabled due to rooted device.": "Turnaje jsou nedostupné na zařízeních s rootem.", "Tournaments require ${VERSION} or newer": "Turnaje vyžadují ${VERSION} nebo novější", - "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Odpojit ${ACCOUNT} od tohoto účtu?\nVeškerá data na účtě ${ACCOUNT} se resetují.\n(výjimka jsou v některých případech úspěchy)", - "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "VAROVÁNÍ: Byla proti vám vznešena obvinění z podvádění ve hře.\nÚčty o kterých se prokáže že používají ulehčující módy budou smazány, hrajte prosím férově.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Odpojit ${ACCOUNT} od tohoto účtu?\nVeškerá data na účtě ${ACCOUNT} se resetují.\n(výjimka jsou v některých případech Trofeje)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "VAROVÁNÍ: Byla proti Vám vznesena obvinění z podvádění ve hře.\nÚčty, o kterých se prokáže, že používají hacky, budou zabanovány. Hrajte prosím férově.", + "Wait reduced!": "Čekání zkráceno!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Upozornění: Tato verze hry je omezená starými daty účtu; některé věcy mohou chybět nebo jsou zastaralé.\nProsím aktualizujte si hru na nejnovější verzi,aby jste viděli nejnovější data na svém účtu.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Přejete si propojit Váš účet zařízení k tomuto?\n\nÚčet vašeho zařízení je ${ACCOUNT1}\nTento účet je ${ACCOUNT2}\n\nTato akce Vám umožní zachovat si stávající postup.\nVarování: Nelze vrátit zpět!", "You already own this!": "Toto již vlastníte!", "You can join in ${COUNT} seconds.": "Připojit se můžete až za ${COUNT} sek.", - "You don't have enough tickets for this!": "Na toto bohužel nemáte dostatek kupónů!", - "You don't own that.": "Nevlastníte tuto věc.", - "You got ${COUNT} tickets!": "Získal jste ${COUNT} kupónů!", - "You got a ${ITEM}!": "Získaly jste ${ITEM}!", + "You don't have enough tickets for this!": "Na toto nemáte dostatek kupónů!", + "You don't own that.": "Toto nevlastníte.", + "You got ${COUNT} tickets!": "Získali jste ${COUNT} kupónů!", + "You got ${COUNT} tokens!": "Máš ${COUNT} tokenů!", + "You got a ${ITEM}!": "Získali jste ${ITEM}!", + "You got a chest!": "Získal jste truhlu!", + "You got an achievement reward!": "Dostali jste odměnu za trofej!", "You have been promoted to a new league; congratulations!": "Byli jste povýšeni do další ligy; gratulujeme!", - "You must update to a newer version of the app to do this.": "Musíš updatovat na novější verzi aplikace k udělání tohodle.", + "You lost a chest! (All your chest slots were full)": "Ztratil jste truhlu! (Všechna místa byla obsazena)", + "You must update the app to view this.": "Pro zobrazení aktualizujte aplikaci.", + "You must update to a newer version of the app to do this.": "Musíte aktualizovat na novější verzi aplikace k udělání tohoto.", "You must update to the newest version of the game to do this.": "Vaše verze hry tuto akci nepodporuje, aktualizujte hru na nejnovější verzi.", "You must wait a few seconds before entering a new code.": "Před zadáním nového kódu počkejte pár sekund.", - "You ranked #${RANK} in the last tournament. Thanks for playing!": "V posledním turnaji jste se umístil na #${RANK} pozici. Děkujeme!", - "Your account was rejected. Are you signed in?": "Váš účet byl odmítnut. Jste přihlášen?", + "You placed #${RANK} in a tournament!": "V turnaji jste byl #${RANK}!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "V posledním turnaji jste se umístili na #${RANK} pozici. Děkujeme za hraní!", + "Your account was rejected. Are you signed in?": "Váš účet byl odmítnut. Jste přihlášeni?", + "Your ad views are not registering. Ad options will be limited for a while.": "Nezaznamenali jsme sledování reklamy. Nastavení reklamy budou chvíli omezené.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Vaše kopie hry byla pozměněna.\nVraťte prosím všechny změny a zkuste to znovu.", "Your friend code was used by ${ACCOUNT}": "Váš kód pro přátele byl použit hráčem ${ACCOUNT}" }, "settingNames": { - "1 Minute": "1 Minuta", - "1 Second": "1 Sekunda", - "10 Minutes": "10 Minut", - "2 Minutes": "2 Minuty", - "2 Seconds": "2 Sekundy", - "20 Minutes": "20 Minut", - "4 Seconds": "4 Sekundy", - "5 Minutes": "5 Minut", - "8 Seconds": "8 Sekund", + "1 Minute": "1 minuta", + "1 Second": "1 sekunda", + "10 Minutes": "10 minut", + "2 Minutes": "2 minuty", + "2 Seconds": "2 sekundy", + "20 Minutes": "20 minut", + "4 Seconds": "4 sekundy", + "5 Minutes": "5 minut", + "8 Seconds": "8 sekund", "Allow Negative Scores": "Povolit negativní skóre", - "Balance Total Lives": "Rovnovážný Počet Životů", - "Bomb Spawning": "Objevení bomby", - "Chosen One Gets Gloves": "Vyvolený získal rukavice", - "Chosen One Gets Shield": "Vyvolený získal štít", - "Chosen One Time": "Čas Vyvoleného", - "Enable Impact Bombs": "Zapnout Nárazové Bomby", - "Enable Triple Bombs": "Zapnout Trojité Bomby", - "Entire Team Must Finish": "Celý tým musí skončit", - "Epic Mode": "Epický Mód", - "Flag Idle Return Time": "Čas Návratu Neaktivní Vlajky", - "Flag Touch Return Time": "Čas Návratu Dotknuté Vlajky", - "Hold Time": "Čas Držení", - "Kills to Win Per Player": "Počet Zabití pro vítězství", + "Balance Total Lives": "Rovnovážný počet životů", + "Bomb Spawning": "Vytváření bomb", + "Chosen One Gets Gloves": "Vyvolený získá rukavice", + "Chosen One Gets Shield": "Vyvolený získá štít", + "Chosen One Time": "Čas Vyvoleného k výhře", + "Enable Impact Bombs": "Povolit Nárazové Bomby", + "Enable Triple Bombs": "Povolit Trojité Bomby", + "Entire Team Must Finish": "Celý tým musí dokončit", + "Epic Mode": "Epický mód", + "Flag Idle Return Time": "Čas návratu neaktivní vlajky", + "Flag Touch Return Time": "Čas návratu dotknuté vlajky", + "Hold Time": "Čas držení", + "Kills to Win Per Player": "Počet zabití pro vítězství", "Laps": "Kola", - "Lives Per Player": "Životy na Hráče", + "Lives Per Player": "Životy na hráče", "Long": "Dlouhý", "Longer": "Delší", - "Mine Spawning": "Přidávání Min", - "No Mines": "Bez Min", + "Mine Spawning": "Přidávání min", + "No Mines": "Bez min", "None": "Žádný", "Normal": "Normální", - "Pro Mode": "Pro(fi) mód", - "Respawn Times": "Časy Znovuzrození", - "Score to Win": "Skóre pro Výhru", + "Pro Mode": "Profi mód", + "Respawn Times": "Čas znovuzrození", + "Score to Win": "Skóre pro pýhru", "Short": "Krátký", "Shorter": "Kratší", - "Solo Mode": "Sólo Mód", + "Solo Mode": "Sólo mód", "Target Count": "Počet cílů", - "Time Limit": "Časový Limit" + "Time Limit": "Časový limit" }, "statements": { - "${TEAM} is disqualified because ${PLAYER} left": "Diskvalifikuji ${TEAM} tým protože ${PLAYER} opustil hru.", - "Killing ${NAME} for skipping part of the track!": "Zabíjím ${NAME} kvůli přeskočení části tratě!", - "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Varování pro ${NAME}: Turbo / spamování tlačítek tě vyhodí" + "${TEAM} is disqualified because ${PLAYER} left": "Diskvalifikuji tým ${TEAM}, protože ${PLAYER} opouští hru.", + "Killing ${NAME} for skipping part of the track!": "Zabíjím ${NAME} za přeskočení části tratě!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Varování pro ${NAME}: turbo / spamování tlačítek tě vyhodí" }, "teamNames": { "Bad Guys": "Padouši", @@ -1725,144 +1850,151 @@ "Red": "Červený" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfektně načasovaný Běh-výskok-otočka-úder může zabít na jednu ránu\na zajistit vám doživotní respekt od vašich přátel.", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfektně načasovaný rozběh, výskok, otočka a úder může zabít nepřítelena\njednu ránu a zajistit Vám doživotní respekt od vašich přátel.", "Always remember to floss.": "Nikdy nezapomeňte na zubní nit.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Vytvořte herní profily pro Vás i Vaše přátele s Vašimi\npreferovanými jmény a vzhledy místo používání náhodně generovaných.", - "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Prokletí vás změní v časovanou bombu.\nJediná protilátka je rychle sebrat lékárničku.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Prokletí vás změní v časovanou bombu.\nJediná záchrana je rychle sebrat lékárničku.", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Kromě vzhledu mají všechny postavy stejné vlastnosti\ntakže si prostě vyberte toho, který se Vám nejvíc podobá.", "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Radši s tím štítem nebuďte moc namyšlení; pořád můžete vypadnout pryč z mapy.", "Don't run all the time. Really. You will fall off cliffs.": "Nepobíhejte pořád. Vážně. Vypadnete z mapy.", - "Don't spin for too long; you'll become dizzy and fall.": "Netoč se moc dlouho, bude ti špatně.", - "Hold any button to run. (Trigger buttons work well if you have them)": "Pro sprint držte jakékoliv tlačítko.(Pokuď máte ovladač, fungují i ostatní tlačítka)", - "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Držte jakékoliv tlačítko pro sprint. Budete rychlejší.¨\nAle dávejte si pozor na okraje mapy.", - "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ledové Bomby nejsou moc silné, ale zmrazí vše, \nčeho se dotknou, a zanechají je náchylné k rozbití.", - "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Pokuď vás někdo chytne, udeřte ho a on vás pustí.\nTak to funguje i v reálném životě.", - "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Pokud jste krátký na řadičích, nainstalujte '${REMOTE_APP_NAME}' app \nna svých mobilních zařízení k jejich použití jako regulátorů.", + "Don't spin for too long; you'll become dizzy and fall.": "Netočte se moc dlouho, bude Vám špatně.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pro sprint držte jakékoliv tlačítko. (spouště fungují skvěle pokud je máte)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Držte jakékoliv tlačítko pro sprint. Budete rychlejší.\nDávejte si ale pozor na okraje mapy.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ledové bomby nejsou moc silné, ale zmrazí vše, \nčeho se dotknou, a zanechají to náchylné k rozbití.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Pokuď vás někdo chytne, udeřte ho a on vás pustí.\nTento trik funguje i v reálném životě.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Pokud nemáte dost ovladačů, nainstalujte „${REMOTE_APP_NAME}“ \nna své mobilní zařízení a použijte ho jako ovladač.", "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Pokuď nemáte ovladač, nainstalujte si aplikaci 'BombSquad Remote'\nna vaše druhé zařízení a používejte ho jako ovladač.", - "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Když se k Vám přilepí Lepivá Bomba, skákejte jako diví a točte se v kruzích.\nMožná setřesete bombu, nebo, když už nic jiného, budou Vaše poslední chvilky zajímavé.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Když se na Vás přilepí Lepivá bomba, skákejte a točte se v kruzích. Možná\nbombu setřesete, nebo budou alespoň Vaše poslední chvilky vtipné.", "If you kill an enemy in one hit you get double points for it.": "Pokuď někoho zabijete na jednu ránu, dostanete dvojnásobek bodů.", - "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Pokud seberete prokletí, vaší jedinou nadějí na přežití\nje, v následujících pár sekundách, najít lékárničku.", - "If you stay in one place, you're toast. Run and dodge to survive..": "Pokuď budete stát na místě, bude z vás toust. Běhejte a uhýbejte abyste přežili..", - "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jestliže máte hodně hráčů, kteří přichází a odchází, zapněte 'automatické vyhazování neaktivních hráčů'\nv nastavení, pro případ, že někdo zapomene opustit hru.", - "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Pokud se vaše zařízení zahřívá nebo byste chtěli šetřit baterii,\nsnižte kvalitu \"Detailů\" nebo \"Rozlišení\" v Nastavení->Grafika", - "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Pokud se vám začne sekat obraz, zkuste si snížit\n\"Rozlišení\" nebo \"Detaily\" v Nastavení->Grafika", - "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "V Seberte Vlajku, Vaše vlajka musí být na vaší základně, abyste mohli skórovat.\nJestliže chce druhý tým skórovat, krádež jejich vlajky může být dobrý způsob jejich zastavení.", - "In hockey, you'll maintain more speed if you turn gradually.": "V Hokeji získáte větší rychlost, když se budete točit pomalu.", - "It's easier to win with a friend or two helping.": "Je jednodušší vyhrát když vám pomáhají přátelé.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Pokud seberete prokletí, vaší jedinou nadějí na přežití je\nv následujících pár sekundách najít lékárničku.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Pokuď budete stát na místě, bude z Vás brzy pečínka. Běhejte a uhýbejte, abyste přežili...", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jestliže máte hodně hráčů, kteří přichází a odchází, zapněte „automatické vyhazování neaktivních hráčů“ v nastavení, pro případ, že někdo zapomene opustit hru.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Pokud se Vaše zařízení zahřívá nebo byste chtěli šetřit baterii,\nsnižte kvalitu „Detailů“ nebo „Rozlišení“ v Nastavení->Grafika", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Pokud se Vám začne sekat obraz, snižte kvalitu „Detailů“ nebo „Rozlišení“ v Nastavení->Grafika", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "V Seberte vlajku musí být Vaše vlajka na Vaší základně, abyste mohli skórovat.\nJestliže chce druhý tým skórovat, krádež jejich vlajky může být dobrý způsob, jak je zastavit.", + "In hockey, you'll maintain more speed if you turn gradually.": "V Hokeji si udržíte vyšší rychlost, když se budete točit pozvolna.", + "It's easier to win with a friend or two helping.": "Je jednodušší vyhrát, když Vám pomáhají přátelé.", "Jump just as you're throwing to get bombs up to the highest levels.": "Když během házení bomby vyskočité, bomby doletí výš a dál.", "Land-mines are a good way to stop speedy enemies.": "Miny jsou dobré na zastavení rychlých padouchů.", - "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Spousty věcí může být sebráno a hozeno, včetně ostatních hráčů.\nVrhání Vašich nepřátel z útesu může být efektivní a emočně naplňující strategií.", - "No, you can't get up on the ledge. You have to throw bombs.": "Ne, nemůžete lézt po římsách. Musíte házet bomby.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Spousta věcí může být sebrána a hozena, včetně ostatních hráčů.\nVrhání Vašich nepřátel z útesu může být efektivní a emočně naplňující strategií.", + "No, you can't get up on the ledge. You have to throw bombs.": "Ne, na ty římsy nevylezete. Musíte házet bomby.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Hráči se mohou připojit a odpojit i v průběhu hry\na také lze během hry připojovat a odpojovat ovladače.", - "Practice using your momentum to throw bombs more accurately.": "Vyzkoušejte si přesnější házení bomb za použití Vaší kinetické energie.", + "Practice using your momentum to throw bombs more accurately.": "Nacvičte si použití vlastní rychlosti, abyste házeli přesněji.", "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Čím rychleji se pohybujete, tím větší zranění Vaše pěsti vytvoří,\ntakže zkoušejte běhat, skákat, a točit se jako šílenec.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Běhejte tam a zpět před odhozením bomby,\nabyste se rozmáchli a odhodili ji dále.", - "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Zabijte víc padouchů tím že\ndáte bombu hned vedle TNT.", - "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Hlava je nezranitelnější část, takže Lepivá Bomba\nna hlavě většinou končí koncem hry.", - "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Tento level nikdy nezkončí, ale zdejší vysoké skóre\nnaučí hráče respektovat Vás po celém světě.", - "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Síla hodu je založena na směru který držíte.\nPro jemné odhození něčeho přímo před Vás, nedržte žádný směr.", - "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Unavuje vás SoundTrack? Nastavte si svůj vlastní!\nNastavení->Zvuk->Soundtrack", - "Try 'Cooking off' bombs for a second or two before throwing them.": "Zkuste bomby chvilku držet před tím než je hodíte.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Zabijte víc padouchů tím, že\nodpálíte bombu hned vedle TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Hlava je nezranitelnější část, takže Lepivá bomba\nna kebuli většinou znamená konec.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Tento level nikdy neskončí, ale vysoké skóre\nVám získá věčný respekt po celém světě.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Síla hodu je založena na směru, který držíte.\nPro jemné odhození něčeho přímo před Vás, nedržte žádný směr.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Unavuje vás soundtrack? Nastavte si svůj vlastní!\nNastavení->Zvuk->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Zkuste bomby chvilku držet před tím, než je hodíte.", "Try tricking enemies into killing eachother or running off cliffs.": "Obelstěte padouchy, aby se zabili navzájem nebo vypadli pryč z mapy.", - "Use the pick-up button to grab the flag < ${PICKUP} >": "Na sebrání vlajky použijte < ${PICKUP} >", - "Whip back and forth to get more distance on your throws..": "Švihněte sebou dozadu a dopředu abyste bombu dohodily dál..", - "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Můžete 'mířit' svoje údery točením se doleva nebo doprava.\nJe to užitečné pro shazování padouchů z hran nebo skórování v hokeji.", - "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Můžete usoudit kdy se bomba chystá vybouchnout podle\nbarvy jisker z její rozbušky: žlutá..oranžová..červená..BUM.", - "You can throw bombs higher if you jump just before throwing.": "Můžete bomby házet výš když vyskočíte těsně před hodem.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Když se o něco bouchnete hlavou.. můžete se zranit\ntak bych to být Vámi nezkoušel.", - "Your punches do much more damage if you are running or spinning.": "Pokuď se točíte nebo běžíte tak vaše údery budou silnější." + "Use the pick-up button to grab the flag < ${PICKUP} >": "Pro sebrání vlajky použijte < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Švihněte sebou dozadu a dopředu, abyste bombu dohodili dál...", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Můžete „mířit“ svoje údery točením se doleva nebo doprava.\nJe to užitečné pro shazování padouchů z hran nebo skórování v hokeji.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Můžete usoudit, kdy se bomba chystá vybouchnout podle\nbarvy jisker z její rozbušky: žlutá... oranžová... červená... BUM.", + "You can throw bombs higher if you jump just before throwing.": "Můžete bomby házet výš, když vyskočíte těsně před hodem.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Zraníte se, pokud hlavou do něčeho narazíte,\ntak bych to být Vámi nezkoušel.", + "Your punches do much more damage if you are running or spinning.": "Pokuď se točíte nebo běžíte, jsou vaše údery silnější." } }, - "trophiesRequiredText": "To vyžaduje minimálně ${NUMBER} trofeje.", - "trophiesText": "- Trofeje", - "trophiesThisSeasonText": "Trofeje tuto sezónu", + "trophiesRequiredText": "To vyžaduje minimálně ${NUMBER} pohárů.", + "trophiesText": "Poháry", + "trophiesThisSeasonText": "Poháry tuto sezónu", "tutorial": { - "cpuBenchmarkText": "Spuštění tutorialu ve směšné rychlosti (testuje hlavně rychlost CPU)", - "phrase01Text": "Ahoj, ty tam!", - "phrase02Text": "Vítejte v ${APP_NAME}u!", - "phrase03Text": "Tady máte pár tipů jak ovládat postavu:", - "phrase04Text": "Většina věcí v ${APP_NAME}u je založena na fyzice.", + "cpuBenchmarkText": "Spuštění návodu ve směšné rychlosti (testuje hlavně rychlost CPU)", + "phrase01Text": "Zdravíčko!", + "phrase02Text": "Vítejte v ${APP_NAME}!", + "phrase03Text": "Tady máte pár tipů, jak ovládat postavu:", + "phrase04Text": "Většina věcí v ${APP_NAME} je založena na fyzice.", "phrase05Text": "Například, když někoho udeříte,...", - "phrase06Text": "..záleží na tom jak rychlá je vaše pěst.", - "phrase07Text": "Vidíte? Nehýbal jsem se, takže to ${NAME}e sotva bolelo.", + "phrase06Text": "..záleží na tom jak rychlá je Vaše pěst.", + "phrase07Text": "Vidíte? Nehýbal jsem se, takže to ${NAME}a sotva bolelo.", "phrase08Text": "Teď výskok a otočka pro větší rychlost.", - "phrase09Text": "Ha, to je lepší.", + "phrase09Text": "Ha, to už je lepší.", "phrase10Text": "Běh taky pomáhá.", - "phrase11Text": "Pro běh držte JAKÉKOLIV tlačítko.", - "phrase12Text": "Pro super údery, zkuste běh a otočku.", - "phrase13Text": "Ježiš, to jsem nechtěl ${NAME}i.", - "phrase14Text": "Některé věci můžete chytit a hodit. Třeba vlajky.. nebo ${NAME}e.", - "phrase15Text": "A to nejlepší, jsou tu bomby.", + "phrase11Text": "Pro běh držte libovolné tlačítko.", + "phrase12Text": "Pro super silné údery zkuste běh a otočku.", + "phrase13Text": "Jejda; promiň mi to, ${NAME}e.", + "phrase14Text": "Některé věci můžete chytit a hodit. Třeba vlajky... nebo ${NAME}e.", + "phrase15Text": "A nakonec tu jsou bomby.", "phrase16Text": "Naučit se házet bomby zabere čas.", "phrase17Text": "Jau! To nebyl moc dobrý hod.", - "phrase18Text": "Pohyb vám pomůže dohodit dál.", - "phrase19Text": "Skákání vám pomůže házet výš.", + "phrase18Text": "Pohyb Vám pomůže dohodit dál.", + "phrase19Text": "Skákání Vám pomůže házet výš.", "phrase20Text": "Pro ještě větší vzdálenost zkuste malou otočku.", "phrase21Text": "Správné načasovaní je dost užitečné.", - "phrase22Text": "Krucipísek.", + "phrase22Text": "Sakra.", "phrase23Text": "Zkuste si s hodem počkat vteřinku nebo dvě.", "phrase24Text": "Hurá! Dokonale načasováno.", - "phrase25Text": "Nu, to bude asi všechno.", - "phrase26Text": "Teď běž, tygře!!!", - "phrase27Text": "Pamatuj na trénink, a určitě se vrátíš živý!", - "phrase28Text": "...teda, možná...", + "phrase25Text": "No, to bude asi všechno.", + "phrase26Text": "A teď se do nich pusťte, divochu!", + "phrase27Text": "Pamatujte na trénink, a určitě se vrátíte naživu!", + "phrase28Text": "...no, snad...", "phrase29Text": "Přeji hodně štěstí!", - "randomName1Text": "Lukáš", - "randomName2Text": "Marek", - "randomName3Text": "Daniel", + "randomName1Text": "Filip", + "randomName2Text": "Jindra", + "randomName3Text": "Martin", "randomName4Text": "Matěj", "randomName5Text": "Pepa", - "skipConfirmText": "Opravdu chcete přeskočit Tutorial? Klikněte pro potvrzení.", + "skipConfirmText": "Opravdu chcete přeskočit návod? Klikněte pro potvrzení.", "skipVoteCountText": "${COUNT}/${TOTAL} přeskočení", - "skippingText": "Přeskakuji Tutorial...", - "toSkipPressAnythingText": "(Stistkni cokoli pro přeskočení Tutorialu)" + "skippingText": "Přeskakuji návod...", + "toSkipPressAnythingText": "(stiskněte cokoliv pro přeskočení návodu)" }, "twoKillText": "DVĚ ZABITÍ!!!", + "uiScaleText": "Velikost UI", "unavailableText": "Nedostupné", + "unclaimedPrizesText": "Máte Nevyzvednuté Odměny!", "unconfiguredControllerDetectedText": "Zaznamenán nenakonfigurovaný ovladač:", "unlockThisInTheStoreText": "Toto musí být nejdříve odemknuto v obchodě.", - "unlockThisProfilesText": "Pro vytvoření více než ${NUM} profilů, potřebuješ:", - "unlockThisText": "Pro odemknutí tohoto je zapotřebí:", + "unlockThisProfilesText": "Pro vytvoření více než ${NUM} profilů, potřebujete:", + "unlockThisText": "Pro odemknutí tohoto potřebujete:", + "unsupportedControllerText": "Je mi líto, ovladač \"${NAME}\" není podporován.", "unsupportedHardwareText": "Omlouváme se, ale tento hardware není porporován tímto buildem hry.", "upFirstText": "První:", "upNextText": "Další, ${COUNT}. hra bude:", "updatingAccountText": "Aktualizuji Váš účet...", "upgradeText": "Přeměnit", - "upgradeToPlayText": "Upgradujte na \"${PRO}\" v herním obchodě, abyste toto mohli hrát.", - "useDefaultText": "Použít Výchozí", + "upgradeToPlayText": "Upgradujte na „${PRO}“ v herním obchodě, abyste toto mohli hrát.", + "useDefaultText": "Použít výchozí", + "userSystemScriptsCreateText": "Vytvořit Uživatelská Systémová Skripta", + "userSystemScriptsDeleteText": "Smazat Uživatelská Systémová Skripta", "usesExternalControllerText": "Tato hra používá jako vstup externí ovladač.", - "usingItunesText": "Používám Music App pro soundtrack", + "usingItunesText": "Používám aplikaci hudby pro soundtrack...", "usingItunesTurnRepeatAndShuffleOnText": "Ujistěte se prosím, že je zaplý shuffle, a opakovat VŠE v iTunes,", - "v2AccountLinkingInfoText": "Pro propojení V2 účtů, stiskněte tlačítko 'Spravovat Účet'", - "validatingTestBuildText": "Ověřuji Testovací Build...", - "victoryText": "Vítězství!!!", + "v2AccountLinkingInfoText": "Pro propojení V2 účtů stiskněte tlačítko „Spravovat účet“", + "v2AccountRequiredText": "Toto vyžaduje V2 účet. Upgradujte svůj účet a zkuste to znovu.", + "validatingTestBuildText": "Ověřuji testovací build...", + "viaText": "skrze", + "victoryText": "Vítězství!", "voteDelayText": "Nelze spustit další hlas za ${NUMBER} sekund", "voteInProgressText": "Hlasování již probíhá.", - "votedAlreadyText": "Již jste hlasoval", + "votedAlreadyText": "Již jste hlasovali", "votesNeededText": "${NUMBER} hlasů potřebných", "vsText": "vs.", "waitingForHostText": "(čeká se na ${HOST})", - "waitingForPlayersText": "Čeká se na jiného hráče...", - "waitingInLineText": "Čekání ve frontě (parta plná)", - "watchAVideoText": "Zkoukni reklamu", - "watchAnAdText": "Zkouknout Reklamu", + "waitingForPlayersText": "čeká se na připojení hráčů...", + "waitingInLineText": "Čekání ve frontě (Parta je plná)", + "watchAVideoText": "Zkouknout video", + "watchAnAdText": "Zkouknout reklamu", "watchWindow": { - "deleteConfirmText": "Vymazat \"${REPLAY}\"?", - "deleteReplayButtonText": "Vymazat\nZáznam", + "deleteConfirmText": "Vymazat „${REPLAY}“?", + "deleteReplayButtonText": "Vymazat\nzáznam", "myReplaysText": "Moje záznamy", "noReplaySelectedErrorText": "Nevybrán žádný záznam", "playbackSpeedText": "Rychlost přehrávání: ${SPEED}", - "renameReplayButtonText": "Přejmenovat\nZáznam", - "renameReplayText": "Přejmenovat \"${REPLAY}\" na:", + "renameReplayButtonText": "Přejmenovat\nzáznam", + "renameReplayText": "Přejmenovat „${REPLAY}“ na:", "renameText": "Přejmenovat", "replayDeleteErrorText": "Chyba při mazání záznamu.", - "replayNameText": "Jméno Záznamu", + "replayNameText": "Jméno záznamu", "replayRenameErrorAlreadyExistsText": "Záznam s tímto jménem již existuje.", - "replayRenameErrorInvalidName": "Nelze přejmenovat; chybné jméno.", + "replayRenameErrorInvalidName": "Nelze přejmenovat; nelatné jméno.", "replayRenameErrorText": "Chyba při přejmenování záznamu.", - "sharedReplaysText": "Sdílené Záznamy", + "sharedReplaysText": "Sdílené záznamy", "titleText": "Záznamy", - "watchReplayButtonText": "Shlédnout\nZáznam" + "watchReplayButtonText": "Shlédnout\nzáznam" }, "waveText": "Vlna", "wellSureText": "Nuže dobrá!", @@ -1871,33 +2003,34 @@ "titleText": "DarwiinRemote Copyright" }, "wiimoteListenWindow": { - "listeningText": "Hledám Wiimotes...", - "pressText": "Stiskněte současně Tlačítka Wiimote 1 a 2.", - "pressText2": "Na novějších Wiimote ovladačích s vestavěným Motion Plus stiskněte červené 'synchroznizační' tlačítko v zadní části." + "listeningText": "Hledám Wiimote ovladače...", + "pressText": "Stiskněte současně tlačítka Wiimote 1 a 2.", + "pressText2": "Na novějších Wiimote ovladačích s vestavěným Motion Plus stiskněte červené synchroznizační tlačítko v zadní části." }, "wiimoteSetupWindow": { "copyrightText": "DarwiinRemote Copyright", "listenText": "Poslouchat", - "macInstructionsText": "Ujistěte se, že je Vaše Wii vyplé a Bluetooth je na vašem\nMac zařízení zaplý, a poté stistkněte 'Poslouchat'. Podpora\nWiimote může být trochu horší, a možná bude potřeba to párkrát\nzkusit, než se Vám podaří ho připojit.\n\nZařízení Bluetooth dokáže mít připojených až 7 zařízení,\nale to se může lišit\n\nBombSquad podporuje originální Wiimote, Nunchuk,\na klasický ovladač\nNovější Wii Remote Plus nyní funguje také,\nale bez přídavků.", - "thanksText": "Děkujeme týmu DarwiinRemote,\nže tohle uskutečnili.", + "macInstructionsText": "Ujistěte se, že je Vaše Wii vypnuté a Bluetooth je na vašem\nMacu zapnutý, a poté stistkněte 'Poslouchat'. Podpora\nWiimote může být trochu horší, a možná to bude potřeba párkrát\nzkusit, než se Vám ho podaří připojit.\n\nBluetooth by měl zvládnout až 7 připojených zařízení,\nale to se může lišit.\n\nBombSquad podporuje originální Wiimote, Nunčak,\na Classic Controller.\nNovější Wii Remote Plus nyní funguje také,\nale bez příslušenství.", + "thanksText": "Děkujeme týmu DarwiinRemote,\nže toto umožnil.", "titleText": "Nastavení Wiimote" }, - "winsPlayerText": "${NAME} Vyhrál!", - "winsTeamText": "${NAME} Vyhrál!", - "winsText": "${NAME} Vyhrál!", + "winsPlayerText": "${NAME} Vítězí!", + "winsTeamText": "${NAME} Vítězí!", + "winsText": "${NAME} Vítězí!", "workspaceSyncErrorText": "Chyba synchronizace ${WORKSPACE}. Podrobnosti v logu.", - "workspaceSyncReuseText": "Nelze synchronizovat ${WORKSPACE}. Opětovné použití předchozí synchronizované verze.", + "workspaceSyncReuseText": "Nelze synchronizovat ${WORKSPACE}. Používám předchozí synchronizovanou verzi.", "worldScoresUnavailableText": "Světové skóre nepřístupné.", "worldsBestScoresText": "Světové nejlepší skóre", "worldsBestTimesText": "Světové nejlepší časy", "xbox360ControllersWindow": { "getDriverText": "Získat Driver", - "macInstructions2Text": "Pro bezdrátové použití ovladače také potřebujete příjmač, který\nje součástí 'Xbox 360 Wireless Controller for Windows'.\nJeden příjmač dovoluje připojit až 4 zařízení.\n\nDůležité: příjmače třetích stran s tímto driverem nebudou fungovat;\nujistěte se, že je na Vašem příjmači 'Microsoft' a ne 'XBOX 360'.\nMicrosoft už tyto příjmače neprodává samostatně, takže budete muset\njeden koupit s ovladačem dohromady, nebo hledat na ebay.\n\nJestliže je pro Vás toto užitečné, zvažte prosím přispění \ntvůrci driveru na jeho stránce.", - "macInstructionsText": "Pro použití ovladače Xbox 360, potřebujete nainstalovat\nMac Driver který naleznete na odkazu napsaném níže.\nFunguje s drátovou i s bezdrátovou verzí ovladače.", - "ouyaInstructionsText": "Pro použití kabelových Xbox 360 ovladačů pro BombSquad, je jednoduše\npřipojte do USB portu vašeho zařízení. Můžete použít USB hub\npro připojení více ovladačů.\n\nPro použití bezdrátových ovladačů budete potřebovat bezdrátový příjmač,\ndostupný jako součást \"Xbox 360 wirelles Controller for Windows\"\nbalíčku nebo prodávaného samostatně. Každý příjmač zapojíte do USB portu\na každý z nich Vám dovolí připojit až 4 bezdrátové ovladače.", - "titleText": "Hrát ${APP_NAME} s ovladačem Xbox 360:" + "macInstructions2Text": "Pro bezdrátové použití ovladače také potřebujete příjmač, který\nje součástí Xbox 360 bezdrátového ovladače pro Windows.\nJeden příjmač umožňuje připojit až 4 zařízení.\n\nDůležité: Příjmače třetích stran s tímto driverem nebudou fungovat;\nujistěte se, že je na Vašem příjmači „Microsoft“ a ne „XBOX 360“.\nMicrosoft už tyto příjmače neprodává samostatně, takže jej budete\nmuset koupit s ovladačem dohromady, nebo hledat na eBay.\n\nJestliže je pro Vás toto užitečné, zvažte prosím přispění \ntvůrci driveru na jeho stránce.", + "macInstructionsText": "Pro použití ovladače Xbox 360 musíte nainstalovat\nMac Driver, který naleznete na odkazu níže.\nFunguje s drátovou i s bezdrátovou verzí ovladače.", + "ouyaInstructionsText": "Pro použití kabelových Xbox 360 ovladačů s BombSquad je jednoduše\npřipojte do USB portu vašeho zařízení. Můžete použít USB hub\npro připojení více ovladačů.\n\nPro použití bezdrátových ovladačů budete potřebovat bezdrátový příjmač,\ndostupný jako součást balíčku „Xbox 360 bezdrátového ovladače pro Windows“\nnebo prodávaný samostatně. Každý příjmač zapojíte do USB portu\na každý z nich Vám dovolí připojit až 4 bezdrátové ovladače.", + "titleText": "Použidí ovladačů Xbox 360 s ${APP_NAME}:" }, - "yesAllowText": "Ano, Povolit!", + "yesAllowText": "Ano, povolit!", "yourBestScoresText": "Vaše nejlepší skóre", - "yourBestTimesText": "Váš nejlepší čas" + "yourBestTimesText": "Váš nejlepší čas", + "yourPrizeText": "Vaše cena:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/danish.json b/dist/ba_data/data/languages/danish.json index 0a31603c..69542308 100644 --- a/dist/ba_data/data/languages/danish.json +++ b/dist/ba_data/data/languages/danish.json @@ -1616,7 +1616,7 @@ "macInstructions2TextScale": 0.76, "macInstructionsText": "For at bruge Xbox 360-controllere skal du installere en\nMacdriver, der er tilgængelig i linket herunder.\nDet virker både med controllere med og uden ledninger.", "macInstructionsTextScale": 0.8, - "ouyaInstructionsText": "For at bruge Xbox 360-controllere til BombSquad, tilslut dem din enheds USB-port.\nDu kan bruge en USB-hub\ntil at forbinde flere controllere. \n\nFor at bruge trådløse controllere skal du bruge en trådløs modtager,\ntilgængelig som en del af \"Xbox 360 wireless Controller for Windows\"-\npakken eller solgt seperat. Hver modtager puttes ind i en USB port\nog tillader dig at forbinde op til 4 trådløse controllers.", + "ouyaInstructionsText": "For at bruge Xbox 360-controllere til BombSquad, tilslut dem din enheds USB-port.\nDu kan bruge en USB-hub\ntil at forbinde flere controllere. \n\nFor at bruge trådløse controllere skal du bruge en trådløs modtager,\ntilgængelig som en del af \"Xbox 360 wireless Controller for Windows\"-\npakken eller solgt seperat. Hver modtager puttes ind i en USB port\nog tillader dig at forbinde op til 4 trådløse controllers. ", "ouyaInstructionsTextScale": 0.8, "titleText": "Hvordan man bruger Xbox 360-controllere med BombSquad:" }, diff --git a/dist/ba_data/data/languages/dutch.json b/dist/ba_data/data/languages/dutch.json index a706cfcb..e63784a5 100644 --- a/dist/ba_data/data/languages/dutch.json +++ b/dist/ba_data/data/languages/dutch.json @@ -7,8 +7,11 @@ "campaignProgressText": "Campagne Voortgang [Moeilijk]: ${PROGRESS}", "changeOncePerSeason": "U kunt dit maar een keer per seizoen wijzigen.", "changeOncePerSeasonError": "U moet wachten tot het volgende seizoen om dit te veranderen (${NUM} dagen)", + "createAnAccountText": "Maak een account", "customName": "Aangepaste naam", + "deleteAccountText": "Verwijder Account", "deviceSpecificAccountText": "U gebruikt nu het apparaat-specifieke account: ${NAME}", + "googlePlayGamesAccountSwitchText": "Als je een ander Google-account \nwilt gebruiken, gebruik dan de Google Play Games-app om over te schakelen.", "linkAccountsEnterCodeText": "Voer Code In", "linkAccountsGenerateCodeText": "Genereer Code", "linkAccountsInfoText": "(deel voortgang over verschillende platformen)", @@ -16,6 +19,7 @@ "linkAccountsInstructionsText": "Om twee accounts te koppelen, genereer je bij een\ndaar van een code die je invult bij de ander.\nVoortgang en inventaris worden dan samengevoegd.\nJe kan maximaal ${COUNT} accounts koppelen.\n\nBELANGRIJK: Koppel alleen accounts die jij bezit!\nAls je accounts van vrienden koppelt kan je niet \nmeer tegelijkertijd spelen!\n\nOok: Dit kan momenteel niet ongedaan gemaakt worden, dus pas op!", "linkAccountsText": "Koppel Accounts", "linkedAccountsText": "Verbonden Accounts:", + "manageAccountText": "Beheer account", "nameChangeConfirm": "Verander je account naam naar ${NAME}?", "notLoggedInText": "", "resetProgressConfirmNoAchievementsText": "Dit reset uw co-op campagne voortgang en\nlokale high-scores (maar niet uw tickets).\nDit kan niet ongedaan worden gemaakt. Weet u het zeker?", @@ -24,15 +28,17 @@ "setAccountName": "Stel account naam in", "setAccountNameDesc": "Selecteer de naam om weer te geven voor uw account.\nU kan de naam gebruiken van een van de verbonden accounts\nof maak een unieke naam aan.", "signInInfoText": "Log in om tickets te verzamelen, online te concurreren,\nen om je voortgang te delen tussen apparaten.", - "signInText": "Log In", + "signInText": "Inloggen", + "signInWithAnEmailAddressText": "Inloggen met e-mailadres", "signInWithDeviceInfoText": "(een automatisch account is alleen beschikbaar op dit apparaat)", - "signInWithDeviceText": "Log in met apparaat account", + "signInWithDeviceText": "Inloggen met apparaat account", "signInWithGameCircleText": "Log in met Game Circle", "signInWithGooglePlayText": "Log in met Google Play", "signInWithTestAccountInfoText": "(oudere account type; gebruik device account gaat door)", "signInWithTestAccountText": "Log in met test account", + "signInWithText": "Inloggen met ${SERVICE}", "signInWithV2InfoText": "(een account dat op alle platforms werkt)", - "signInWithV2Text": "Inloggen met een BombSquad rekening", + "signInWithV2Text": "Inloggen met een ${APP_NAME} account", "signOutText": "Log Uit", "signingInText": "Inloggen...", "signingOutText": "Uitloggen...", @@ -43,6 +49,7 @@ "titleText": "Profiel", "unlinkAccountsInstructionsText": "Selecteer een account om los te koppelen.", "unlinkAccountsText": "Koppel accounts los.", + "unlinkLegacyV1AccountsText": "Ontkoppel oude (V1) accounts", "v2LinkInstructionsText": "Gebruik deze link om een ​​account aan te maken of in te loggen.", "viaAccount": "(via account ${NAME})", "youAreLoggedInAsText": "Je bent ingelogd als:", @@ -332,13 +339,19 @@ "achievementsRemainingText": "Resterende Prestaties:", "achievementsText": "Prestaties", "achievementsUnavailableForOldSeasonsText": "Sorry, prestatie gegevens voor oude seizoenen zijn niet beschikbaar.", + "activatedText": "${THING} geactiveerd.", "addGameWindow": { "getMoreGamesText": "Verkrijg Meer Spellen...", "titleText": "Voeg Game toe" }, + "addToFavoritesText": "Toevoegen aan favorieten", + "addedToFavoritesText": "'${NAME}' toegevoegd aan Favorieten.", + "allText": "Alle", "allowText": "Toestaan", "alreadySignedInText": "Uw account is al ingelogd op een ander apparaat;\nVerander van account of sluit het spel op uw andere\napparaten en probeer het opnieuw.", "apiVersionErrorText": "Kan module ${NAME} niet laden; deze gebruikt api-versie ${VERSION_USED}; benodigd is ${VERSION_REQUIRED}.", + "applyText": "Toepassen", + "areYouSureText": "Weet je het zeker?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" activeert dit alleen als een koptelefoon is aangesloten)", "headRelativeVRAudioText": "Hoofd-Relatieve VR Geluid", @@ -363,14 +376,24 @@ "boostText": "Boost", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} is geconfigureerd in de app zelf.", "buttonText": "knop", - "canWeDebugText": "Wilt u dat BombSquad automatisch bugs, crashes,\nen basisgebruik info naar de ontwikkelaar rapporteert?\n\nDeze gegevens bevatten geen persoonlijke informatie\nen helpen om het spel soepel en bug-vrij te houden.", + "canWeDebugText": "Wilt u dat ${APP_NAME} automatisch bugs, crashes,\nen basisgebruik info naar de ontwikkelaar rapporteert?\n\nDeze gegevens bevatten geen persoonlijke informatie\nen helpen om het spel soepel en bug-vrij te houden.", "cancelText": "Annuleer", "cantConfigureDeviceText": "Sorry, $ {DEVICE} niet configureerbaar.", "challengeEndedText": "Deze uitdaging is beëindigd.", "chatMuteText": "Chat negeren", "chatMutedText": "berichten gedempt", "chatUnMuteText": "maak de chat ongedaan", + "chests": { + "prizeOddsText": "Prijs Kansen", + "reduceWaitText": "Verminder Wachttijd", + "slotDescriptionText": "Hier is plek voor een schatkist.\n\nVerdien schatkisten door campagnelevels te spelen,\nje te plaatsen in toernooien en met het voltooien\nvan prestaties.", + "slotText": "Schatkist plaats ${NUM}", + "slotsFullWarningText": "WAARSCHUWING: Al je schatkist plaatsen zijn vol.\nElke schatkist die je dit spel nog verdient, gaat verloren.", + "unlocksInText": "Ontgrendeld Over" + }, "choosingPlayerText": "", + "claimText": "Claim", + "codesExplainText": "Codes worden door de \nontwikkelaar verstrekt om accountproblemen te diagnosticeren en te corrigeren.", "completeThisLevelToProceedText": "U moet dit level voltooien\nom door te gaan!", "completionBonusText": "Voltooiing Bonus", "configControllersWindow": { @@ -454,6 +477,7 @@ "titleText": "Configureer Touchscreen", "touchControlsScaleText": "Touch Besturing Schalen" }, + "configureDeviceInSystemSettingsText": "${DEVICE} kan worden geconfigureerd in de Systeeminstellingen-app.", "configureItNowText": "Nu configureren?", "configureText": "Configureren", "connectMobileDevicesWindow": { @@ -509,6 +533,7 @@ "welcome2Text": "U kunt ook tickets verdienen van veel van dezelfde activiteiten.\nTickets kunnen gebruikt worden om mee te doen aan toernooien,\nvoor het vrijspelen van nieuwe karakters, speelvelden, mini-spellen en meer.", "yourPowerRankingText": "Uw Macht Klassement:" }, + "copyConfirmText": "Gekopieerd naar het klembord.", "copyOfText": "${NAME} Kopie", "copyText": "Kopiëren", "copyrightText": "© 2013 Eric Froemling", @@ -562,7 +587,10 @@ "deleteText": "Verwijder", "demoText": "demonstratie", "denyText": "Weigeren", + "deprecatedText": "Verouderd", + "descriptionText": "Beschrijving", "desktopResText": "Bureaublad Resolutie", + "deviceAccountUpgradeText": "Waarschuwing: u bent ingelogd met een apparaataccount (${NAME}). \nApparaataccounts worden in een toekomstige update verwijderd. \nUpgrade naar een V2-account als u uw voortgang wilt \nbehouden.", "difficultyEasyText": "Makkelijk", "difficultyHardOnlyText": "Alleen moeilijk", "difficultyHardText": "Moeilijk", @@ -571,6 +599,10 @@ "disableRemoteAppConnectionsText": "Schakel Afstandsbediening-App connecties uit", "disableXInputDescriptionText": "Staat meer dan 4 controllers toe, maar werkt misschien niet helemaal goed.", "disableXInputText": "Schakel XInput uit", + "disabledText": "Gehandicapt", + "discardText": "Gooi weg", + "discordFriendsText": "Wil je op zoek naar nieuwe mensen om mee te spelen? \nSluit je aan bij onze Discord en vind nieuwe vrienden!", + "discordJoinText": "Sluit je aan bij de onenigheid", "doneText": "Klaar", "drawText": "Gelijk", "duplicateText": "Kopieer", @@ -605,6 +637,7 @@ "localProfileText": "(lokaal profiel)", "nameDescriptionText": "Speler Naam", "nameText": "Naam", + "profileAlreadyExistsText": "Een profiel met dat naam bestaat al.", "randomText": "willekeurig", "titleEditText": "Profiel Aanpassen", "titleNewText": "Nieuw Profiel", @@ -644,15 +677,20 @@ "useMusicFolderText": "Map met Muziek Bestanden" }, "editText": "Bewerk", + "enabledText": "Ingeschakeld", "endText": "Einde", "enjoyText": "Geniet!", "epicDescriptionFilterText": "${DESCRIPTION} In epische slow motion.", "epicNameFilterText": "Epische ${NAME}", "errorAccessDeniedText": "toegang geweigerd", + "errorDeviceTimeIncorrectText": "De tijd van je apparaat is ${HOURS} uur \nonjuist. Dit zal waarschijnlijk problemen \nveroorzaken. Controleer uw tijd- en tijdzone-instellingen.", "errorOutOfDiskSpaceText": "schuifruimte vol", + "errorSecureConnectionFailText": "Kan geen veilige cloudverbinding tot stand brengen; netwerkfunctionaliteit kan mislukken.", "errorText": "Fout", "errorUnknownText": "onbekende fout", "exitGameText": "${APP_NAME} Verlaten?", + "expiredAgoText": "${T} geleden verlopen", + "expiresInText": "Verloopt over ${T}", "exportSuccessText": "'${NAME}' geëxporteerd.", "externalStorageText": "Externe Opslag", "failText": "Faal", @@ -689,6 +727,8 @@ "editText": "Bewerk\nSpeellijst", "gameListText": "Spellen Lijst", "newText": "Nieuwe\nSpeellijst", + "pointsToWinText": "Punten om te winnen", + "seriesLengthText": "Series lengte", "showTutorialText": "Uitleg Weergeven", "shuffleGameOrderText": "Willekeurige Spel Volgorde", "titleText": "Pas ${TYPE} Speellijst aan" @@ -717,6 +757,7 @@ "copyCodeConfirmText": "Code gekopieerd naar klembord", "copyCodeText": "Kopieer Code", "dedicatedServerInfoText": "Voor het beste resultaat, zet dan een dedicated server op. Zie bombsquadgame.com/server om te leren hoe.", + "descriptionShortText": "Gebruik het Verzamel venster om een partij samen te stellen", "disconnectClientsText": "Hierdoor verbreekt de verbinding met ${COUNT} spelers(s)\nvan uw partij. Weet u het zeker?", "earnTicketsForRecommendingAmountText": "Vrienden ontvangen ${COUNT} tickets als ze het spel proberen\n(en jij ontvangt ${YOU_COUNT} voor elke vriend die dit doet)", "earnTicketsForRecommendingText": "Deel de game \nVoor gratis tickets...", @@ -729,10 +770,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tickets van ${NAME}", "friendPromoCodeAwardText": "Je krijgt ${COUNT} tickets elke keer het is gebruikt.", "friendPromoCodeExpireText": "Deze code zal vervallen in ${EXPIRE_HOURS} uren en werkt alleen met nieuwe spelers.", - "friendPromoCodeInstructionsText": "Om het te gebruiken, open je ${APP_NAME} en ga je naar 'Instellingen-> Geavanceerd-> Voer code in'.\nZie bombsquadgame.com voor downloadlinks voor alle ondersteunde platforms.", + "friendPromoCodeInstructionsText": "Om het te gebruiken, open je ${APP_NAME} en ga je naar 'Instellingen-> Geavanceerd-> Stuur info'.\nZie bombsquadgame.com voor downloadlinks voor alle ondersteunde platforms.", "friendPromoCodeRedeemLongText": "Het kan ingewisseld worden voor ${COUNT} gratis tickets met tot en met ${MAX_USES} mensen.", "friendPromoCodeRedeemShortText": "Het kan ingewisseld worden voor ${COUNT} in het spel", - "friendPromoCodeWhereToEnterText": "(in \"Instellingen-> Geavanceerd-> Voer code in\")", + "friendPromoCodeWhereToEnterText": "(in \"Instellingen-> Geavanceerd-> Stuur info\")", "getFriendInviteCodeText": "Krijg een uitnodigingscode", "googlePlayDescriptionText": "Nodig Google Play spelers uit voor uw partij:", "googlePlayInviteText": "Uitnodigen", @@ -764,6 +805,7 @@ "manualYourLocalAddressText": "Uw lokale adres:", "nearbyText": "Dichtbij", "noConnectionText": "", + "noPartiesAddedText": "Geen partijen toegevoegd", "otherVersionsText": "(andere versies)", "partyCodeText": "Partijcode", "partyInviteAcceptText": "Accepteren", @@ -837,16 +879,26 @@ "youHaveShortText": "Je hebt ${COUNT}", "youHaveText": "U heeft ${COUNT} tickets" }, + "goldPass": { + "desc1InfTokensText": "Oneindig tokens.", + "desc2NoAdsText": "Geen reclame.", + "desc3ForeverText": "Voor altijd.", + "goldPassText": "Goud pas" + }, "googleMultiplayerDiscontinuedText": "Sorry, de Google Play multi-player functie is nu even niet beschikbaar. \nIk werk hard aan een vervanger. \nProbeer nu alsjeblieft een andere connectie mogelijkheid.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google Play-aankopen zijn niet beschikbaar. \nMogelijk moet u uw winkel-app updaten.", + "googlePlayServicesNotAvailableText": "Google Play-services zijn niet beschikbaar. \nSommige app-functionaliteit is mogelijk uitgeschakeld.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Altijd", "fullScreenCmdText": "Volledig scherm (Cmd-F)", "fullScreenCtrlText": "Volledig scherm (Cmd-F)", + "fullScreenText": "Volledig scherm", "gammaText": "Gamma", "highText": "Hoog", "higherText": "Hoger", "lowText": "Laag", + "maxFPSText": "Maximale FPS", "mediumText": "Gemiddeld", "neverText": "Nooit", "resolutionText": "Resolutie", @@ -858,7 +910,7 @@ "visualsText": "Visuele" }, "helpWindow": { - "bombInfoText": "- Bom -\nSterker dan slagen, maar kan\nresulteren in ernstige zelfverwonding.\nVoor het beste resultaat, gooi richting\nvijand voordat lont op raakt.", + "bombInfoText": "- Bom -\nSterker dan slaan, maar kan\nresulteren in ernstige zelfverwonding.\nVoor het beste resultaat, gooi richting\nvijand voordat de lont op raakt.", "canHelpText": "${APP_NAME} kan helpen.", "controllersInfoText": "U kan ${APP_NAME} spelen met vrienden via een netwerk, of u\nkan het allemaal op hetzelfde apparaat spelen als u genoeg controllers hebt.\n${APP_NAME} ondersteunt er een verscheidenheid van; u kunt zelfs uw telefoons\nals controller gebruiken met de gratis '${REMOTE_APP_NAME}' app.\nZie Instellingen->Controllers voor meer info.", "controllersInfoTextFantasia": "Een speler kan de afstandbediening gebruiken als controller,\nmaar gamepads zijn sterk aanbevolen. Je kunt ook mobiele-apparaten\ngebruiken als controllers via de gratis 'Bombsquad Remote' app.\nZie 'Controllers' onder 'Instellingen' voor meer info.", @@ -874,7 +926,7 @@ "friendsText": "Vrienden", "jumpInfoText": "- Springen -\nSpring over kleine openingen,\nom dingen hoger te gooien, en om\ngevoelens van vreugde uit te drukken.", "orPunchingSomethingText": "Of iets slaan, van een klif gooien, en op de weg naar beneden opblazen met een kleverige bom.", - "pickUpInfoText": "- Op Pakken -\nPak vlaggen, vijanden, of iets\nanders niet vastgeschroefd aan de\ngrond. Druk opnieuw om te gooien.", + "pickUpInfoText": "- Op Pakken -\nPak vlaggen, vijanden, of iets\nanders dat niet vast zit aan de\ngrond. Druk opnieuw om te gooien.", "powerupBombDescriptionText": "Laat u drie bommen opzwepen\nachter elkaar in plaats van maar een.", "powerupBombNameText": "Drievoudige-Bommen", "powerupCurseDescriptionText": "Waarschijnlijk wilt u deze te vermijden.\n  ...of toch niet?", @@ -910,6 +962,7 @@ "importText": "Importeer", "importingText": "Aan het importeren...", "inGameClippedNameText": "zal in-game worden\n\"${NAME}\"", + "inboxText": "Inbox", "installDiskSpaceErrorText": "FOUT: Niet in staat om de installatie te voltooien.\nHet kan zijn dat er gaan ruimte meer is op uw apparaat.\nMaak wat vrij en probeer opnieuw.", "internal": { "arrowsToExitListText": "druk ${LEFT} of ${RIGHT} om de lijst te verlaten", @@ -966,12 +1019,14 @@ "touchScreenJoinWarningText": "U doet mee met een aanraakscherm.\nAls dit een vergissing was, druk er mee op 'Menu->Verlaat Spel'.", "touchScreenText": "TouchScreen", "trialText": "proefperiode", + "unableToCompleteTryAgainText": "Voltooien op dit moment mislukt.\nProbeer het later nog eens.", "unableToResolveHostText": "Error: kan de host niet resolven.", "unavailableNoConnectionText": "Dit is momenteel niet beschikbaar (geen internet verbinding?)", "vrOrientationResetCardboardText": "Hiermee reset je de VR oriëntatie.\nOm het spel te spelen heb je een externe controller nodig.", "vrOrientationResetText": "VR oriëntatie reset.", "willTimeOutText": "(totdat u inactief bent)" }, + "inventoryText": "Inventaris", "jumpBoldText": "SPRING", "jumpText": "Spring", "keepText": "houd", @@ -1018,8 +1073,11 @@ "seasonEndsMinutesText": "Seizoen eindigt in ${NUMBER} minuten.", "seasonText": "Seizoen ${NUMBER}", "tournamentLeagueText": "Haal de ${NAME} competitie om aan dit toernooi mee te doen.", - "trophyCountsResetText": "Trofee telling reset in het volgende seizoen." + "trophyCountsResetText": "Trofee telling reset in het volgende seizoen.", + "upToDateBonusDescriptionText": "Spelers met een recente versie van het\nspel krijgen hier een ${PERCENT}% bonus.", + "upToDateBonusText": "Up-To-Date Bonus" }, + "learnMoreText": "Meer informatie", "levelBestScoresText": "Beste scores voor ${LEVEL}", "levelBestTimesText": "Beste tijden voor ${LEVEL}", "levelFastestTimesText": "Snelste tijden in ${LEVEL}", @@ -1041,6 +1099,7 @@ "creditsText": "Credits", "demoMenuText": "Voorbeeld Menu", "endGameText": "Beëindig Spel", + "endTestText": "Einde proef", "exitGameText": "Verlaat Spel", "exitToMenuText": "Verlaat naar menu?", "howToPlayText": "Hoe te Spelen", @@ -1061,9 +1120,12 @@ "maxConnectionsText": "Max Connecties", "maxPartySizeText": "Max Partij Grootte", "maxPlayersText": "Max Spelers", + "merchText": "Koopwaar!", "modeArcadeText": "Speelhal Modus", "modeClassicText": "Klassieke Modus", "modeDemoText": "Demo Modus", + "moreSoonText": "Binnenkort meer...", + "mostDestroyedPlayerText": "Meest Vernietigde Speler", "mostValuablePlayerText": "Meest Waardevolle Speler", "mostViolatedPlayerText": "Meest Geschonden Speler", "mostViolentPlayerText": "Meest Gewelddadige Speler", @@ -1080,6 +1142,7 @@ "nameSuicideText": "${NAME} pleegde zelfmoord.", "nameText": "Naam", "nativeText": "van apparaat", + "newExclaimText": "Nieuw!", "newPersonalBestText": "Nieuw persoonlijk record!", "newTestBuildAvailableText": "Er is een nieuwere testversie beschikbaar! (${VERSION} build ${BUILD}).\nDownload hier ${ADDRESS}", "newText": "Nieuw", @@ -1091,17 +1154,22 @@ "noExternalStorageErrorText": "Geen externe opslag gevonden op dit apparaat", "noGameCircleText": "Fout: niet aangemeld bij GameCircle", "noJoinCoopMidwayText": "Je kan niet halverwegen inspringen bij coöperatieve spellen.", + "noMessagesText": "Geen berichten.", + "noPluginsInstalledText": "Geen plug-ins geïnstalleerd", "noProfilesErrorText": "U heeeft geen speler profielen, dus zit u vast aan '${NAME}'.\nGa naar Instellingen->Speler Profielen om een profiel te maken voor uzelf.", "noScoresYetText": "Nog geen scores.", + "noServersFoundText": "Geen servers gevonden.", "noThanksText": "Nee Bedankt", "noTournamentsInTestBuildText": "PAS OP: De punten van deze test tournament worden niet meegerekend.", "noValidMapsErrorText": "Geen geldige gebieden gevonden voor dit speltype.", "notEnoughPlayersRemainingText": "Niet genoeg spelers over; stop en start een nieuw spel.", "notEnoughPlayersText": "U heeft minstens ${COUNT} spelers nodig om dit spel te starten!", + "notEnoughTicketsText": "Onvoldoende tickets!", "notNowText": "Niet Nu", "notSignedInErrorText": "Je moet inloggen om dit te doen.", "notSignedInGooglePlayErrorText": "Je moet ingelogd zijn met Google Play om dit te doen.", "notSignedInText": "niet ingelogd", + "notUsingAccountText": "Opmerking: ${SERVICE}-account negeren. \nGa naar 'Account -> Inloggen met ${SERVICE}' als je hier gebruik van wilt maken.", "nothingIsSelectedErrorText": "Er is niks geselecteerd!", "numberText": "#${NUMBER}", "offText": "Uit", @@ -1109,6 +1177,9 @@ "onText": "Aan", "oneMomentText": "Een Moment..", "onslaughtRespawnText": "${PLAYER} zal respawnen in golf ${WAVE}", + "openMeText": "Maak Mij Open!", + "openNowText": "Nu Openen", + "openText": "Openen", "orText": "${A} of ${B}", "otherText": "Andere ...", "outOfText": "(#${RANK} van de ${ALL})", @@ -1163,7 +1234,14 @@ "playlistsText": "Speellijsten", "pleaseRateText": "Als u geniet van ${APP_NAME}, zou u dan een moment willen\nnemen om een waardering te geven of recensie te schrijven.\nDit geeft ons nuttige feedback voor toekomstige ontwikkelingen.\n\nBedankt!\n-eric", "pleaseWaitText": "Even geduld...", + "pluginClassLoadErrorText": "Fout bij het laden van plug-inklasse '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Fout bij het starten van plug-in '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Plugin-instellingen", + "pluginsAutoEnableNewText": "Schakel nieuwe plug-ins automatisch in", "pluginsDetectedText": "Nieuw contact gedecteerd. Schakel in/configureer in de instellingen.", + "pluginsDisableAllText": "Schakel alle plug-ins uit", + "pluginsEnableAllText": "Schakel alle plug-ins in", + "pluginsRemovedText": "${NUM} plug-in(s) niet meer gevonden.", "pluginsText": "Contacten", "practiceText": "Oefenen", "pressAnyButtonPlayAgainText": "Druk een knop om opnieuw te spelen...", @@ -1195,6 +1273,8 @@ "punchText": "Slaan", "purchaseForText": "Koop voor ${PRICE}", "purchaseGameText": "Koop Spel", + "purchaseNeverAvailableText": "Sorry, aankopen zijn niet beschikbaar voor deze build.\nProbeer in te loggen op uw account op een ander platform en daar aankopen te doen.", + "purchaseNotAvailableText": "Deze aankoop is niet beschikbaar.", "purchasingText": "Aanschaffen...", "quitGameText": "${APP_NAME} Verlaten?", "quittingIn5SecondsText": "Sluiten in 5 seconden...", @@ -1237,6 +1317,7 @@ "version_mismatch": "Versie ongelijk.\nZorg er voor dat BombSquad en BombSquad Afstandsbediening\nde nieuwste versie zijn en probeer het opnieuw." }, "removeInGameAdsText": "Koop \"${PRO}\" in de winkel om de in-game advertenties te verwijderen.", + "removeInGameAdsTokenPurchaseText": "TIJDELIJK AANBOD: Koop een willekeurig token paket om de in-game advertenties te verwijderen.", "renameText": "Hernoemen", "replayEndText": "Stop Herhaling", "replayNameDefaultText": "Herhaling Laatste Spel", @@ -1259,6 +1340,8 @@ "runText": "Ren", "saveText": "Opslaan", "scanScriptsErrorText": "Fout(en) bij inlezen scripts; zie log voor details.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} en ${NUM} andere module(s) moeten worden bijgewerkt voor api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} moet worden bijgewerkt voor API ${API}.", "scoreChallengesText": "Score Uitdagingen", "scoreListUnavailableText": "Score lijst niet beschikbaar.", "scoreText": "Score", @@ -1269,6 +1352,7 @@ }, "scoreWasText": "(was ${COUNT})", "selectText": "Selecteren", + "sendInfoDescriptionText": "Stuurt account en app status info naar de developer. \nVergeet niet je naam of reden voor het sturen.", "seriesWinLine1PlayerText": "WINT DE", "seriesWinLine1TeamText": "WINT DE", "seriesWinLine1Text": "WINT DE", @@ -1285,9 +1369,10 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(een simpele, controller-vriendelijke toetsenbord op het scherm voor tekstbewerking)", - "alwaysUseInternalKeyboardText": "Gebruik altijd Interne Toetsenbord", + "alwaysUseInternalKeyboardText": "Gebruik altijd interne toetsenbord", "benchmarksText": "Maatstaven en Stress-Testen", - "disableCameraGyroscopeMotionText": "Schakel de Camera Gyroscoop beweging uit", + "devToolsText": "Dev Tools", + "disableCameraGyroscopeMotionText": "Schakel de camera gyroscoop beweging uit", "disableCameraShakeText": "Schakel schuddende camera uit", "disableThisNotice": "(U kunt deze melding uitschakelen in de geavanceerde instellingen)", "enablePackageModsDescriptionText": "(Geeft extra aanpassingsmogelijkheden maar deactiveert net-spel)", @@ -1296,15 +1381,23 @@ "forTestingText": "Let op: deze waarden zijn alleen voor testen en zullen verloren gaan als de app gesloten wordt.", "helpTranslateText": "${APP_NAME}'s niet-Engelse vertalingen is een gezamenlijke\ninspanning van de gemeenschap. Als u daar aan wilt bijdragen of een vertaling\nwilt corrigeren, klik dan op de link hieronder. Bij voorbaat dank!", "helpTranslateTextScale": 1.0, - "kickIdlePlayersText": "Verstoot Afwezige Spelers", + "insecureConnectionsDescriptionText": "niet aanbevolen, maar zou online spelen kunnen toestaan\nvanuit beperkte landen en netwerken", + "insecureConnectionsText": "Gebruik onveilige connecties", + "kickIdlePlayersText": "Verstoot afwezige spelers", "kidFriendlyModeText": "Kind Vriendelijke Modus (minder geweld, etc.)", "languageText": "Taal", "languageTextScale": 1.0, "moddingGuideText": "Aanpasgids", + "moddingToolsText": "Modding Tools", "mustRestartText": "U moet het spel herstarten voordat dit effect heeft.", "netTestingText": "Netwerk Testen", "resetText": "Reset", + "sendInfoText": "Stuur Informatie", "showBombTrajectoriesText": "Baan van de bom weergeven", + "showDemosWhenIdleText": "Toon demo's wanneer je inactief gaat", + "showDeprecatedLoginTypesText": "Laat vervallen login types zien", + "showDevConsoleButtonText": "Toon dev-consoleknop", + "showInGamePingText": "Toon in-game ping", "showPlayerNamesText": "Toon Namen Spelers", "showUserModsText": "Toon Aanpassingen Map", "titleText": "Geavanceerd", @@ -1313,7 +1406,7 @@ "translationFetchingStatusText": "vertaalstatus controleren...", "translationInformMe": "Meld het wanneer mijn taal updates nodig heeft.", "translationNoUpdateNeededText": "De huidige taal is up to date; woohoo!", - "translationUpdateNeededText": "** de huidige taal heeft updates nodig!! **", + "translationUpdateNeededText": "** De huidige taal heeft updates nodig!! **", "vrTestingText": "VR Testen" }, "shareText": "Deel", @@ -1323,6 +1416,9 @@ "signInWithGameCenterText": "Om een Game Center account te gebruiken,\nlogt u in bij de Game Center app.", "singleGamePlaylistNameText": "Alleen ${GAME}", "singlePlayerCountText": "1 speler", + "sizeLargeText": "Groot", + "sizeMediumText": "Medium", + "sizeSmallText": "Klein", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Karakter selectie", @@ -1348,6 +1444,7 @@ }, "spaceKeyText": "spatie", "statsText": "stats", + "stopRemindingMeText": "Niet Meer Herinneren", "storagePermissionAccessText": "Dit vereist toegang tot opslag", "store": { "alreadyOwnText": "U bent al de eigenaar van ${NAME}!", @@ -1399,6 +1496,8 @@ "storeText": "Winkel", "submitText": "Voorleggen", "submittingPromoCodeText": "Code verzenden ...", + "successText": "Succes!", + "supportEmailText": "Als u problemen ondervindt met de app, \nkunt u een e-mail sturen naar ${EMAIL}.", "teamNamesColorText": "Teamnamen / kleuren ...", "teamsText": "Teams", "telnetAccessGrantedText": "Telnet toegang ingeschakeld.", @@ -1409,6 +1508,7 @@ "testBuildValidatedText": "Test Versie Gevalideerd; Veel Plezier!", "thankYouText": "Bedankt voor uw ondersteuning! Veel plezier met het spel!!", "threeKillText": "DRIEDUBBELE DOOD!!", + "ticketsDescriptionText": "Tickets kunnen worden gebruikt om in de winkel karakters, \nspeelvelden, mini-spellen en meer beschikbaar te maken.\n\nTickets kunnen in schatkisten worden gevonden,\ndie je kan winnen in campagnes, toernooien en prestaties.", "timeBonusText": "Tijd Bonus", "timeElapsedText": "Tijd Verstreken", "timeExpiredText": "Tijd Verstreken", @@ -1419,14 +1519,29 @@ "tipText": "Tip", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Krijg Tokens", + "notEnoughTokensText": "Niet genoeg tokens!", + "numTokensText": "${COUNT} Tokens", + "openNowDescriptionText": "Je hebt voldoende tokens\nom nu te openen - je hoeft\nNiet te wachten.", + "shinyNewCurrencyText": "BombSquad's glimmende nieuwe valuta.", + "tokenPack1Text": "Klein Token Pakje", + "tokenPack2Text": "Middelgroot Token Pakje", + "tokenPack3Text": "Grote Token Pak", + "tokenPack4Text": "Jumbo Token Pak", + "tokensDescriptionText": "Tokens worden gebruikt om schatkisten sneller te openen\nen voor andere spel- en account opties.\n\nJe kan tokens winnen in het spel of kopen\nin pakketten. Of koop een Gouden Pas voor een oneindig\naantal tokens en om nooit meer van ze te horen.", + "youHaveGoldPassText": "Je hebt een Gouden Pas.\nAlle token aankopen zijn gratis.\nGeniet!" + }, "topFriendsText": "Top Vrienden", "tournamentCheckingStateText": "Toernooi status nakijken; even geduld aub...", "tournamentEndedText": "Dit toernooi is beëindigd. Er zal snel een nieuwe beginnen.", "tournamentEntryText": "Toernooi Inschrijving", + "tournamentFinalStandingsText": "Eindstand", "tournamentResultsRecentText": "Recente Toernooi Uitslagen", "tournamentStandingsText": "Toernooi Stand", "tournamentText": "Toernooi", "tournamentTimeExpiredText": "Toernooi Tijd Verlopen", + "tournamentsDisabledWorkspaceText": "Toernooien zijn uitgeschakeld als werkruimten actief zijn. \nOm toernooien opnieuw in te schakelen, schakelt u uw werkruimte uit en start u opnieuw op.", "tournamentsText": "Toernooien", "translations": { "characterNames": { @@ -1495,6 +1610,18 @@ "Uber Onslaught": "Uber Afslachting", "Uber Runaround": "Uber Omlopen" }, + "displayItemNames": { + "${C} Tickets": "${C} Tickets", + "${C} Tokens": "${C} Tokens", + "Chest": "Schatkist", + "L1 Chest": "L1 Schatkist", + "L2 Chest": "L2 Schatkist", + "L3 Chest": "L3 Schatkist", + "L4 Chest": "L4 Schatkist", + "L5 Chest": "L5 Schatkist", + "L6 Chest": "L6 Schatkist", + "Unknown Chest": "Onbekende Schatkist" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Ben de uitverkorene voor een bepaalde tijd om te winnen.\nDood de uitverkorene om het te worden.", "Bomb as many targets as you can.": "Bombardeer zo veel mogelijk doelwitten als u kan.", @@ -1578,7 +1705,7 @@ "languages": { "Arabic": "Arabisch", "Belarussian": "Belarusian", - "Chinese": "Vereenvoudigd Chinees", + "Chinese": "Vereenvoudigd Chinees ", "ChineseTraditional": "Traditioneel Chinees", "Croatian": "Kroatisch", "Czech": "Tsjechisch", @@ -1598,7 +1725,9 @@ "Italian": "Italiaans", "Japanese": "Japans", "Korean": "Koreaans", + "Malay": "Maleis", "Persian": "Perzisch", + "PirateSpeak": "Piraat Praat", "Polish": "Pools", "Portuguese": "Portugees", "Romanian": "Roemeens", @@ -1673,6 +1802,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Valsspelen ontdekt; scores en prijzen geschorst voor ${COUNT} dagen.", "Could not establish a secure connection.": "Kon geen beveiligde verbinding tot stand brengen.", "Daily maximum reached.": "Dagelijkse maximum bekijkt.", + "Daily sign-in reward": "Dagelijkse inlog beloning", "Entering tournament...": "Toernooi betreden...", "Invalid code.": "Ongeldige code.", "Invalid payment; purchase canceled.": "Ongeldige betaling; aankoop geannuleerd.", @@ -1682,11 +1812,14 @@ "Item unlocked!": "item ontgrendeld!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKENDE ONTKENNING. ${ACCOUNT} bevat\nsignificante gegevens die ALLES ZIJN VERLOREN.\nJe kunt in omgekeerde volgorde linken als je wilt\n(en verlies de gegevens van DIT account in plaats daarvan)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Verbind account ${ACCOUNT} aan dit account?\nAlle bestaande data op ${ACCOUNT} zal verloren gaan.\nDit kan niet ongedaan worden gemaakt. Weet je het zeker?", + "Longer streaks lead to better rewards.": "Langere reeksen leiden tot betere beloningen.", "Max number of playlists reached.": "Maximaal aantal speellijsten bereikt.", "Max number of profiles reached.": "Maximaal aantal profielen bereikt.", "Maximum friend code rewards reached.": "Maximum vriend code beloning behaald", "Message is too long.": "Bericht is te lang.", + "New tournament result!": "Nieuwe toernooi uitslag!", "No servers are available. Please try again soon.": "Er zijn geen servers beschikbaar. Probeer het binnenkort opnieuw.", + "No slots available. Free a slot and try again.": "Geen plaatsen beschikbaar. Maak er een vrij en probeer opnieuw.", "Profile \"${NAME}\" upgraded successfully.": "Profiel \"${NAME}\" is succesvol opgewaardeerd.", "Profile could not be upgraded.": "Profiel kon niet worden opgewaardeerd.", "Purchase successful!": "Aankoop succesvol!", @@ -1696,7 +1829,9 @@ "Sorry, this code has already been used.": "Sorry, deze code is al gebruikt.", "Sorry, this code has expired.": "Sorry, deze code is verlopen.", "Sorry, this code only works for new accounts.": "Sorry, deze code werkt alleen op nieuwe accounts.", + "Sorry, this has expired.": "Sorry, dit is verlopen.", "Still searching for nearby servers; please try again soon.": "Nog steeds op zoek naar servers in de buurt; probeer het snel opnieuw.", + "Streak: ${NUM} days": "Reeks: ${NUM} dagen", "Temporarily unavailable; please try again later.": "Tijdelijk niet beschikbaar; probeer het later opnieuw.", "The tournament ended before you finished.": "Het toernooi eindigde voordat u klaar was.", "This account cannot be unlinked for ${NUM} days.": "Dit account kan gedurende ${NUM} dagen niet worden ontkoppeld.", @@ -1707,19 +1842,28 @@ "Tournaments require ${VERSION} or newer": "toernooi vereist ${VERSION} of nieuwer", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Koppel ${ACCOUNT} los van dit account?\nAlle gegevens over ${ACCOUNT} worden opnieuw ingesteld.\n(behalve voor prestaties in sommige gevallen)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "WAARSCHUWING: klachten over hacking zijn afgegeven tegen uw account.\nAccounts die hacken blijken te zijn, worden verbannen. Speel alsjeblieft eerlijk.", + "Wait reduced!": "Wachttijd verminderd!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Waarschuwing: Deze versie van het spel is beperkt tot oude accountgegevens; gegevens kunnen ontbreken of verouderd lijken.\nUpgrade naar een nieuwere versie van het spel om je meest recente accountgegevens te bekijken.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Wilt u uw apparaat account hieraan koppelen?\n\nUw apparaat account is ${ACCOUNT1}\nDit account is ${ACCOUNT2}\n\nDit zal u toelaten om uw bestaande vooruitgang te houden.\nWaarschuwing: dit kan niet ongedaan gemaakt worden!", "You already own this!": "U bezit dit al!", "You can join in ${COUNT} seconds.": "Je kan meedoen in ${COUNT} seconden.", "You don't have enough tickets for this!": "U heeft hier niet genoeg tickets voor!", "You don't own that.": "Je bezit dat niet.", - "You got ${COUNT} tickets!": "U krijgt ${COUNT} tickets!", - "You got a ${ITEM}!": "U hebt een ${ITEM}!", + "You got ${COUNT} tickets!": "Je krijgt ${COUNT} tickets!", + "You got ${COUNT} tokens!": "Je krijgt ${COUNT} tokens!", + "You got a ${ITEM}!": "Je krijgt een ${ITEM}!", + "You got a chest!": "Je hebt een schatkist!", + "You got an achievement reward!": "Je krijgt een prestatie beloning!", "You have been promoted to a new league; congratulations!": "U bent gepromoveerd naar een nieuwe competitie; gefeliciteerd!", + "You lost a chest! (All your chest slots were full)": "Je bent een schatkist verloren! (Alle plaatsen waren vol)", + "You must update the app to view this.": "Je moet de app updaten om dit te bekijken.", "You must update to a newer version of the app to do this.": "Om dit te kunnen doen moet u de app updaten naar een nieuwere versie.", "You must update to the newest version of the game to do this.": "Je moet dit bijwerken naar de nieuwste versie van het spel.", "You must wait a few seconds before entering a new code.": "U moet een paar seconden wachten voordat een nieuwe code ingevoerd kan worden.", + "You placed #${RANK} in a tournament!": "Je hebt plaats #${RANK} in een toernooi!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "U eindigde op rang #${RANK} in het laatste toernooi. Bedankt voor het spelen!", "Your account was rejected. Are you signed in?": "Je account is geweigerd. Ben je ingelogd?", + "Your ad views are not registering. Ad options will be limited for a while.": "Je bekeken advertenties worden niet geregistreerd. Advertentie opties worden voorlopig beperkt.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Uw versie van het spel is aangepast.\nMaakt de veranderingen ongedaan en probeer het opnieuw.", "Your friend code was used by ${ACCOUNT}": "Uw Vriend code is gebruikt door ${ACCOUNT}" }, @@ -1873,11 +2017,14 @@ "toSkipPressAnythingText": "(tik of druk op iets om de les over te slaan)" }, "twoKillText": "TWEE VLIEGEN IN 1 KLAP!", + "uiScaleText": "UI-Schaal", "unavailableText": "niet beschikbaar", + "unclaimedPrizesText": "Je hebt niet-opgehaalde prijzen!", "unconfiguredControllerDetectedText": "Niet geconfigureerde controller ontdekt:", "unlockThisInTheStoreText": "Hiervoor moet een aankoop gedaan worden in de winkel.", "unlockThisProfilesText": "Om meer dan ${NUM} profielen te maken heb je nodig:", "unlockThisText": "Om dit te ontgrendelen, moet u:", + "unsupportedControllerText": "Sorry, controller \"${NAME}\" wordt niet ondersteund.", "unsupportedHardwareText": "Sorry, deze hardware wordt niet ondersteunt door deze versie van het spel.", "upFirstText": "Als eerste:", "upNextText": "Daarna volgt in potje ${COUNT}:", @@ -1885,11 +2032,16 @@ "upgradeText": "Opwaarderen", "upgradeToPlayText": "Ontgrendel \"${PRO}\" in de winkel binnen het spel om dit te spelen.", "useDefaultText": "Gebruik Standaard", + "userSystemScriptsCreateText": "Maak Gebruiker Systeem Scripts", + "userSystemScriptsDeleteText": "Verwijder Gebruiker Systeem Scripts", "usesExternalControllerText": "Dit spel maakt gebruik van een externe controller als input.", "usingItunesText": "De muziek app wordt gebruikt voor de muziek...", "usingItunesTurnRepeatAndShuffleOnText": "Zorg er er voor dat shuffle AAN staat en herhalen op ALLES staat in iTunes.", + "v2AccountLinkingInfoText": "Om V2-accounts te koppelen, gebruikt u de knop 'Account beheren'.", + "v2AccountRequiredText": "Dit vereist een V2 account, upgrade uw account en probeer opnieuw.", "validatingBetaText": "Beta wordt Gevalideerd...", "validatingTestBuildText": "Valideren Test Versie...", + "viaText": "via", "victoryText": "Overwinning!", "voteDelayText": "Je kan geen andere stemming starten voor ${NUMBER} seconden", "voteInProgressText": "Er is al een stemming bezig.", @@ -1922,6 +2074,7 @@ }, "waveText": "Ronde", "wellSureText": "Maar Natuurlijk!", + "whatIsThisText": "Wat is dit?", "wiimoteLicenseWindow": { "licenseTextScale": 0.62, "titleText": "DarwiinRemote Copyright" @@ -1946,6 +2099,8 @@ "winsPlayerText": "${NAME} Wint!", "winsTeamText": "${NAME} Wint!", "winsText": "${NAME} Wint!", + "workspaceSyncErrorText": "Fout bij synchroniseren van ${WORKSPACE}. Zie logboek voor details.", + "workspaceSyncReuseText": "Kan ${WORKSPACE} niet synchroniseren. Hergebruik van de vorige gesynchroniseerde versie.", "worldScoresUnavailableText": "Wereldwijde scores niet beschikbaar.", "worldsBestScoresText": "'s Werelds Beste Scores", "worldsBestTimesText": "'s Werelds Beste Tijden", @@ -1961,5 +2116,6 @@ }, "yesAllowText": "Ja, Toestaan!", "yourBestScoresText": "Uw Beste Scores", - "yourBestTimesText": "Uw Beste Tijden" + "yourBestTimesText": "Uw Beste Tijden", + "yourPrizeText": "Jouw prijs:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/english.json b/dist/ba_data/data/languages/english.json index 33b42dea..685e0556 100644 --- a/dist/ba_data/data/languages/english.json +++ b/dist/ba_data/data/languages/english.json @@ -6,7 +6,9 @@ "campaignProgressText": "Campaign Progress [Hard]: ${PROGRESS}", "changeOncePerSeason": "You can only change this once per season.", "changeOncePerSeasonError": "You must wait until next season to change this again (${NUM} days)", + "createAnAccountText": "Create an Account", "customName": "Custom Name", + "deleteAccountText": "Delete Account", "googlePlayGamesAccountSwitchText": "If you want to use a different Google account,\nuse the Google Play Games app to switch.", "linkAccountsEnterCodeText": "Enter Code", "linkAccountsGenerateCodeText": "Generate Code", @@ -23,14 +25,12 @@ "setAccountNameDesc": "Select the name to display for your account.\nYou can use the name from one of your linked\naccounts or create a unique custom name.", "signInInfoText": "Sign in to collect tickets, compete online,\nand share progress across devices.", "signInText": "Sign In", + "signInWithAnEmailAddressText": "Sign in with an email address", "signInWithDeviceInfoText": "(an automatic account only available from this device)", "signInWithDeviceText": "Sign in with device account", - "signInWithGameCircleText": "Sign in with Game Circle", - "signInWithGooglePlayText": "Sign in with Google Play", - "signInWithTestAccountInfoText": "(legacy account type; use device accounts going forward)", - "signInWithTestAccountText": "Sign in with test account", + "signInWithText": "Sign in with ${SERVICE}", "signInWithV2InfoText": "(an account that works on all platforms)", - "signInWithV2Text": "Sign in with a BombSquad account", + "signInWithV2Text": "Sign in with a ${APP_NAME} account", "signOutText": "Sign Out", "signingInText": "Signing in...", "signingOutText": "Signing out...", @@ -332,9 +332,14 @@ "getMoreGamesText": "Get More Games...", "titleText": "Add Game" }, + "addToFavoritesText": "Add to Favorites", + "addedToFavoritesText": "Added '${NAME}' to Favorites.", + "allText": "All", "allowText": "Allow", "alreadySignedInText": "Your account is signed in from another device;\nplease switch accounts or close the game on your\nother devices and try again.", "apiVersionErrorText": "Can't load module ${NAME}; it targets api-version ${VERSION_USED}; we require ${VERSION_REQUIRED}.", + "applyText": "Apply", + "areYouSureText": "Are you sure?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" enables this only when headphones are plugged in)", "headRelativeVRAudioText": "Head-Relative VR Audio", @@ -357,14 +362,24 @@ "boostText": "Boost", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} is configured in the app itself.", "buttonText": "button", - "canWeDebugText": "Would you like BombSquad to automatically report\nbugs, crashes, and basic usage info to the developer?\n\nThis data contains no personal information and helps\nkeep the game running smoothly and bug-free.\n", + "canWeDebugText": "Would you like ${APP_NAME} to automatically report\nbugs, crashes, and basic usage info to the developer?\n\nThis data contains no personal information and helps\nkeep the game running smoothly and bug-free.\n", "cancelText": "Cancel", "cantConfigureDeviceText": "Sorry, ${DEVICE} is not configurable.", "challengeEndedText": "This challenge has ended.", "chatMuteText": "Mute Chat", "chatMutedText": "Chat Muted", "chatUnMuteText": "Unmute Chat", + "chests": { + "prizeOddsText": "Prize Odds", + "reduceWaitText": "Reduce Wait", + "slotDescriptionText": "This slot can hold a chest.\n\nEarn chests by playing campaign levels,\nplacing in tournaments, and completing\nachievements.", + "slotText": "Chest Slot ${NUM}", + "slotsFullWarningText": "WARNING: All your chest slots are full.\nAny chests you earn this game will be lost.", + "unlocksInText": "Unlocks In" + }, "choosingPlayerText": "", + "claimText": "Claim", + "codesExplainText": "Codes are provided by the developer to\ndiagnose and correct account issues.", "completeThisLevelToProceedText": "You must complete\nthis level to proceed!", "completionBonusText": "Completion Bonus", "configControllersWindow": { @@ -445,6 +460,7 @@ "swipeText": "swipe", "titleText": "Configure Touchscreen" }, + "configureDeviceInSystemSettingsText": "${DEVICE} can be configured in the System Settings app.", "configureItNowText": "Configure it now?", "configureText": "Configure", "connectMobileDevicesWindow": { @@ -548,6 +564,7 @@ "demoText": "Demo", "denyText": "Deny", "deprecatedText": "Deprecated", + "descriptionText": "Description", "desktopResText": "Desktop Res", "deviceAccountUpgradeText": "Warning:\nYou are signed in with a device account (${NAME}).\nDevice accounts will be removed in a future update.\nUpgrade to a V2 Account if you want to keep your progress.", "difficultyEasyText": "Easy", @@ -558,6 +575,10 @@ "disableRemoteAppConnectionsText": "Disable Remote-App Connections", "disableXInputDescriptionText": "Allows more than 4 controllers but may not work as well.", "disableXInputText": "Disable XInput", + "disabledText": "Disabled", + "discardText": "Discard", + "discordFriendsText": "Want to look for new people to play with?\nJoin our Discord and find new friends!", + "discordJoinText": "Join the Discord", "doneText": "Done", "drawText": "Draw", "duplicateText": "Duplicate", @@ -590,6 +611,7 @@ "localProfileText": "(local profile)", "nameDescriptionText": "Player Name", "nameText": "Name", + "profileAlreadyExistsText": "A profile with that name already exists.", "randomText": "random", "titleEditText": "Edit Profile", "titleNewText": "New Profile", @@ -625,6 +647,7 @@ "useMusicFolderText": "Folder of Music Files" }, "editText": "Edit", + "enabledText": "Enabled", "endText": "End", "enjoyText": "Enjoy!", "epicDescriptionFilterText": "${DESCRIPTION} In epic slow motion.", @@ -636,6 +659,8 @@ "errorText": "Error", "errorUnknownText": "unknown error", "exitGameText": "Exit ${APP_NAME}?", + "expiredAgoText": "Expired ${T} ago", + "expiresInText": "Expires in ${T}", "exportSuccessText": "'${NAME}' exported.", "externalStorageText": "External Storage", "failText": "Fail", @@ -658,8 +683,6 @@ "flawlessWaveText": "Flawless Wave!", "fourKillText": "QUAD KILL!!!", "friendScoresUnavailableText": "Friend scores unavailable.", - "gameCenterText": "GameCenter", - "gameCircleText": "GameCircle", "gameLeadersText": "Game ${COUNT} Leaders", "gameListWindow": { "cantDeleteDefaultText": "You can't delete the default playlist.", @@ -670,6 +693,8 @@ "duplicateText": "Duplicate\nPlaylist", "editText": "Edit\nPlaylist", "newText": "New\nPlaylist", + "pointsToWinText": "Points To Win", + "seriesLengthText": "Series Length", "showTutorialText": "Show Tutorial", "shuffleGameOrderText": "Shuffle Game Order", "titleText": "Customize ${TYPE} Playlists" @@ -695,6 +720,7 @@ "copyCodeConfirmText": "Code copied to clipboard.", "copyCodeText": "Copy Code", "dedicatedServerInfoText": "For best results, set up a dedicated server. See bombsquadgame.com/server to learn how.", + "descriptionShortText": "Use the gather window to assemble a party.", "disconnectClientsText": "This will disconnect the ${COUNT} player(s)\nin your party. Are you sure?", "earnTicketsForRecommendingAmountText": "Friends will receive ${COUNT} tickets if they try the game\n(and you will receive ${YOU_COUNT} for each who does)", "earnTicketsForRecommendingText": "Share the game\nfor free tickets...", @@ -707,10 +733,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tickets from ${NAME}", "friendPromoCodeAwardText": "You will receive ${COUNT} tickets each time it is used.", "friendPromoCodeExpireText": "The code will expire in ${EXPIRE_HOURS} hours and only works for new players.", - "friendPromoCodeInstructionsText": "To use it, open ${APP_NAME} and go to \"Settings->Advanced->Enter Code\".\nSee bombsquadgame.com for download links for all supported platforms.", + "friendPromoCodeInstructionsText": "To use it, open ${APP_NAME} and go to \"Settings->Advanced->Send Info\".\nSee bombsquadgame.com for download links for all supported platforms.", "friendPromoCodeRedeemLongText": "It can be redeemed for ${COUNT} free tickets by up to ${MAX_USES} people.", "friendPromoCodeRedeemShortText": "It can be redeemed for ${COUNT} tickets in the game.", - "friendPromoCodeWhereToEnterText": "(in \"Settings->Advanced->Enter Code\")", + "friendPromoCodeWhereToEnterText": "(in \"Settings->Advanced->Send Info\")", "getFriendInviteCodeText": "Get Friend Invite Code", "googlePlayDescriptionText": "Invite Google Play players to your party:", "googlePlayInviteText": "Invite", @@ -742,11 +768,11 @@ "manualYourLocalAddressText": "Your local address:", "nearbyText": "Nearby", "noConnectionText": "", + "noPartiesAddedText": "No Parties Added", "otherVersionsText": "(other versions)", "partyCodeText": "Party Code", "partyInviteAcceptText": "Accept", "partyInviteDeclineText": "Decline", - "partyInviteGooglePlayExtraText": "(see the 'Google Play' tab in the 'Gather' window)", "partyInviteIgnoreText": "Ignore", "partyInviteText": "${NAME} has invited\nyou to join their party!", "partyNameText": "Party Name", @@ -779,7 +805,6 @@ "wifiDirectOpenWiFiSettingsText": "Open Wi-Fi Settings", "wifiDirectText": "Wi-Fi Direct", "worksBetweenAllPlatformsText": "(works between all platforms)", - "worksWithGooglePlayDevicesText": "(works with devices running the Google Play (android) version of the game)", "youHaveBeenSentAPromoCodeText": "You have been sent a ${APP_NAME} promo code:" }, "getTicketsWindow": { @@ -805,7 +830,12 @@ "youHaveShortText": "you have ${COUNT}", "youHaveText": "you have ${COUNT} tickets" }, - "googleMultiplayerDiscontinuedText": "Sorry, Google’s multiplayer service is no longer available.\nI am working on a replacement as fast as possible.\nUntil then, please try another connection method.\n-Eric", + "goldPass": { + "desc1InfTokensText": "Infinite tokens.", + "desc2NoAdsText": "No ads.", + "desc3ForeverText": "Forever.", + "goldPassText": "Gold Pass" + }, "googlePlayPurchasesNotAvailableText": "Google Play purchases are not available.\nYou may need to update your store app.", "googlePlayServicesNotAvailableText": "Google Play Services is not available.\nSome app functionality may be disabled.", "googlePlayText": "Google Play", @@ -813,10 +843,12 @@ "alwaysText": "Always", "fullScreenCmdText": "Fullscreen (Cmd-F)", "fullScreenCtrlText": "Fullscreen (Ctrl-F)", + "fullScreenText": "Fullscreen", "gammaText": "Gamma", "highText": "High", "higherText": "Higher", "lowText": "Low", + "maxFPSText": "Max FPS", "mediumText": "Medium", "neverText": "Never", "resolutionText": "Resolution", @@ -885,6 +917,7 @@ "importText": "Import", "importingText": "Importing...", "inGameClippedNameText": "in-game will be\n\"${NAME}\"", + "inboxText": "Inbox", "installDiskSpaceErrorText": "ERROR: Unable to complete the install.\nYou may be out of space on your device.\nClear some space and try again.", "internal": { "arrowsToExitListText": "press ${LEFT} or ${RIGHT} to exit list", @@ -939,12 +972,14 @@ "timeOutText": "(times out in ${TIME} seconds)", "touchScreenJoinWarningText": "You have joined with the touchscreen.\nIf this was a mistake, tap 'Menu->Leave Game' with it.", "touchScreenText": "TouchScreen", + "unableToCompleteTryAgainText": "Unable to complete this right now.\nPlease try again.", "unableToResolveHostText": "Error: unable to resolve host.", "unavailableNoConnectionText": "This is currently unavailable (no internet connection?)", "vrOrientationResetCardboardText": "Use this to reset the VR orientation.\nTo play the game you'll need an external controller.", "vrOrientationResetText": "VR orientation reset.", "willTimeOutText": "(will time out if idle)" }, + "inventoryText": "Inventory", "jumpBoldText": "JUMP", "jumpText": "Jump", "keepText": "Keep", @@ -991,8 +1026,11 @@ "seasonEndsMinutesText": "Season ends in ${NUMBER} minutes.", "seasonText": "Season ${NUMBER}", "tournamentLeagueText": "You must reach ${NAME} league to enter this tournament.", - "trophyCountsResetText": "Trophy counts will reset next season." + "trophyCountsResetText": "Trophy counts will reset next season.", + "upToDateBonusDescriptionText": "Players running a recent version of the\ngame receive a ${PERCENT}% bonus here.", + "upToDateBonusText": "Up-To-Date Bonus" }, + "learnMoreText": "Learn More", "levelBestScoresText": "Best scores on ${LEVEL}", "levelBestTimesText": "Best times on ${LEVEL}", "levelIsLockedText": "${LEVEL} is locked.", @@ -1036,6 +1074,8 @@ "modeArcadeText": "Arcade Mode", "modeClassicText": "Classic Mode", "modeDemoText": "Demo Mode", + "moreSoonText": "More coming soon...", + "mostDestroyedPlayerText": "Most Destroyed Player", "mostValuablePlayerText": "Most Valuable Player", "mostViolatedPlayerText": "Most Violated Player", "mostViolentPlayerText": "Most Violent Player", @@ -1052,6 +1092,7 @@ "nameSuicideText": "${NAME} committed suicide.", "nameText": "Name", "nativeText": "Native", + "newExclaimText": "New!", "newPersonalBestText": "New personal best!", "newTestBuildAvailableText": "A newer test build is available! (${VERSION} build ${BUILD}).\nGet it at ${ADDRESS}", "newText": "New", @@ -1062,12 +1103,16 @@ "noContinuesText": "(no continues)", "noExternalStorageErrorText": "No external storage found on this device", "noGameCircleText": "Error: not logged into GameCircle", + "noMessagesText": "No messages.", + "noPluginsInstalledText": "No Plugins Installed", "noScoresYetText": "No scores yet.", + "noServersFoundText": "No servers found.", "noThanksText": "No Thanks", "noTournamentsInTestBuildText": "WARNING: Tournament scores from this test build will be ignored.", "noValidMapsErrorText": "No valid maps found for this game type.", "notEnoughPlayersRemainingText": "Not enough players remaining; exit and start a new game.", "notEnoughPlayersText": "You need at least ${COUNT} players to start this game!", + "notEnoughTicketsText": "Not enough tickets!", "notNowText": "Not Now", "notSignedInErrorText": "You must sign in to do this.", "notSignedInGooglePlayErrorText": "You must sign in with Google Play to do this.", @@ -1080,6 +1125,9 @@ "onText": "On", "oneMomentText": "One Moment...", "onslaughtRespawnText": "${PLAYER} will respawn in wave ${WAVE}", + "openMeText": "Open Me!", + "openNowText": "Open Now", + "openText": "Open", "orText": "${A} or ${B}", "otherText": "Other...", "outOfText": "(#${RANK} out of ${ALL})", @@ -1166,6 +1214,8 @@ "punchText": "Punch", "purchaseForText": "Purchase for ${PRICE}", "purchaseGameText": "Purchase Game", + "purchaseNeverAvailableText": "Sorry, purchases are not available on this build.\nTry signing into your account on another platform and making purchases from there.", + "purchaseNotAvailableText": "This purchase is not available.", "purchasingText": "Purchasing...", "quitGameText": "Quit ${APP_NAME}?", "quittingIn5SecondsText": "Quitting in 5 seconds...", @@ -1207,6 +1257,7 @@ "version_mismatch": "Version mismatch.\nMake sure BombSquad and BombSquad Remote\nare the latest versions and try again." }, "removeInGameAdsText": "Unlock \"${PRO}\" in the store to remove in-game ads.", + "removeInGameAdsTokenPurchaseText": "LIMITED TIME OFFER: Purchase ANY token pack to remove in-game ads.", "renameText": "Rename", "replayEndText": "End Replay", "replayNameDefaultText": "Last Game Replay", @@ -1227,7 +1278,9 @@ "revertText": "Revert", "runText": "Run", "saveText": "Save", - "scanScriptsErrorText": "Error(s) scanning scripts; see log for details.", + "scanScriptsErrorText": "Error(s) scanning scripts. See log for details.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} and ${NUM} other module(s) need to be updated for api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} needs to be updated for api ${API}.", "scoreChallengesText": "Score Challenges", "scoreListUnavailableText": "Score list unavailable.", "scoreText": "Score", @@ -1238,6 +1291,7 @@ }, "scoreWasText": "(was ${COUNT})", "selectText": "Select", + "sendInfoDescriptionText": "Sends account and app state info to the developer.\nPlease include your name or reason for sending.", "seriesWinLine1PlayerText": "WINS THE", "seriesWinLine1TeamText": "WINS THE", "seriesWinLine1Text": "WINS THE", @@ -1253,23 +1307,31 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(a simple, controller-friendly on-screen keyboard for text editing)", - "alwaysUseInternalKeyboardText": "Always Use Internal Keyboard", + "alwaysUseInternalKeyboardText": "Always use internal keyboard", "benchmarksText": "Benchmarks & Stress-Tests", - "disableCameraGyroscopeMotionText": "Disable Camera Gyroscope Motion", - "disableCameraShakeText": "Disable Camera Shake", + "devToolsText": "Dev Tools", + "disableCameraGyroscopeMotionText": "Disable camera gyroscope motion", + "disableCameraShakeText": "Disable camera shake", "disableThisNotice": "(you can disable this notice in advanced settings)", "enterPromoCodeText": "Enter Code", "forTestingText": "Note: these values are only for testing and will be lost when the app exits.", "helpTranslateText": "${APP_NAME}'s non-English translations are a community\nsupported effort. If you'd like to contribute or correct\na translation, follow the link below. Thanks in advance!", - "kickIdlePlayersText": "Kick Idle Players", + "insecureConnectionsDescriptionText": "not recommended, but may allow online play\nfrom restricted countries or networks", + "insecureConnectionsText": "Use insecure connections", + "kickIdlePlayersText": "Kick idle players", "kidFriendlyModeText": "Kid-Friendly Mode (reduced violence, etc)", "languageText": "Language", "moddingGuideText": "Modding Guide", + "moddingToolsText": "Modding Tools", "mustRestartText": "You must restart the game for this to take effect.", "netTestingText": "Network Testing", "resetText": "Reset", + "sendInfoText": "Send Info", "showBombTrajectoriesText": "Show Bomb Trajectories", - "showInGamePingText": "Show In-Game Ping", + "showDemosWhenIdleText": "Show demos when idle", + "showDeprecatedLoginTypesText": "Show deprecated login types", + "showDevConsoleButtonText": "Show dev console button", + "showInGamePingText": "Show in-game ping", "showPlayerNamesText": "Show Player Names", "showUserModsText": "Show Mods Folder", "titleText": "Advanced", @@ -1277,17 +1339,19 @@ "translationFetchErrorText": "translation status unavailable", "translationFetchingStatusText": "checking translation status...", "translationInformMe": "Inform me when my language needs updates", - "translationNoUpdateNeededText": "the current language is up to date; woohoo!", - "translationUpdateNeededText": "** the current language needs updates!! **", + "translationNoUpdateNeededText": "The current language is up to date; woohoo!", + "translationUpdateNeededText": "** The current language needs updates!! **", "vrTestingText": "VR Testing" }, "shareText": "Share", "sharingText": "Sharing...", "showText": "Show", "signInForPromoCodeText": "You must sign in to an account for codes to take effect.", - "signInWithGameCenterText": "To use a Game Center account,\nsign in with the Game Center app.", "singleGamePlaylistNameText": "Just ${GAME}", "singlePlayerCountText": "1 player", + "sizeLargeText": "Large", + "sizeMediumText": "Medium", + "sizeSmallText": "Small", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Character Selection", @@ -1313,6 +1377,7 @@ }, "spaceKeyText": "space", "statsText": "Stats", + "stopRemindingMeText": "Stop Reminding Me", "storagePermissionAccessText": "This requires storage access", "store": { "alreadyOwnText": "You already own ${NAME}!", @@ -1322,7 +1387,6 @@ "charactersText": "Characters", "comingSoonText": "Coming Soon...", "extrasText": "Extras", - "freeBombSquadProText": "BombSquad is now free, but since you originally purchased it you are\nreceiving the BombSquad Pro upgrade and ${COUNT} tickets as a thank-you.\nEnjoy the new features, and thank you for your support!\n-Eric", "holidaySpecialText": "Holiday Special", "howToSwitchCharactersText": "(go to \"${SETTINGS} -> ${PLAYER_PROFILES}\" to assign & customize characters)", "howToUseIconsText": "(create global player profiles (in the account window) to use these)", @@ -1360,6 +1424,8 @@ "storeText": "Store", "submitText": "Submit", "submittingPromoCodeText": "Submitting Code...", + "successText": "Success!", + "supportEmailText": "If you are experiencing any problems with the\napp, please email ${EMAIL}.", "teamNamesColorText": "Team Names/Colors...", "telnetAccessGrantedText": "Telnet access enabled.", "telnetAccessText": "Telnet access detected; allow?", @@ -1369,6 +1435,7 @@ "testBuildValidatedText": "Test Build Validated; Enjoy!", "thankYouText": "Thank you for your support! Enjoy the game!!", "threeKillText": "TRIPLE KILL!!", + "ticketsDescriptionText": "Tickets can be used to unlock characters,\nmaps, minigames, and more in the store.\n\nTickets can be found in chests won through\ncampaigns, tournaments, and achievements.", "timeBonusText": "Time Bonus", "timeElapsedText": "Time Elapsed", "timeExpiredText": "Time Expired", @@ -1379,10 +1446,24 @@ "tipText": "Tip", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Get Tokens", + "notEnoughTokensText": "Not enough tokens!", + "numTokensText": "${COUNT} Tokens", + "openNowDescriptionText": "You have enough tokens to\nopen this now - you don't\nneed to wait.", + "shinyNewCurrencyText": "BombSquad's shiny new currency.", + "tokenPack1Text": "Small Token Pack", + "tokenPack2Text": "Medium Token Pack", + "tokenPack3Text": "Large Token Pack", + "tokenPack4Text": "Jumbo Token Pack", + "tokensDescriptionText": "Tokens are used to speed up chest unlocks\nand for other game and account features.\n\nYou can win tokens in the game or buy them\nin packs. Or buy a Gold Pass for infinite\ntokens and never hear about them again.", + "youHaveGoldPassText": "You have a Gold Pass.\nAll token purchases are free.\nEnjoy!" + }, "topFriendsText": "Top Friends", "tournamentCheckingStateText": "Checking tournament state; please wait...", "tournamentEndedText": "This tournament has ended. A new one will start soon.", "tournamentEntryText": "Tournament Entry", + "tournamentFinalStandingsText": "Final Standings", "tournamentResultsRecentText": "Recent Tournament Results", "tournamentStandingsText": "Tournament Standings", "tournamentText": "Tournament", @@ -1438,6 +1519,18 @@ "Uber Onslaught": null, "Uber Runaround": null }, + "displayItemNames": { + "${C} Tickets": null, + "${C} Tokens": null, + "Chest": null, + "L1 Chest": null, + "L2 Chest": null, + "L3 Chest": null, + "L4 Chest": null, + "L5 Chest": null, + "L6 Chest": null, + "Unknown Chest": null + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": null, "Bomb as many targets as you can.": null, @@ -1520,8 +1613,8 @@ "languages": { "Arabic": null, "Belarussian": null, - "Chinese": "Chinese Simplified", - "ChineseTraditional": "Chinese Traditional", + "ChineseSimplified": "Chinese - Simplified", + "ChineseTraditional": "Chinese - Traditional", "Croatian": null, "Czech": null, "Danish": null, @@ -1542,13 +1635,16 @@ "Korean": null, "Malay": null, "Persian": null, + "PirateSpeak": "Pirate Speak", "Polish": null, - "Portuguese": null, + "PortugueseBrazil": "Portuguese - Brazil", + "PortuguesePortugal": "Portuguese - Portugal", "Romanian": null, "Russian": null, "Serbian": null, "Slovak": null, - "Spanish": null, + "SpanishLatinAmerica": "Spanish - Latin America", + "SpanishSpain": "Spanish - Spain", "Swedish": null, "Tamil": null, "Thai": null, @@ -1613,6 +1709,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": null, "Could not establish a secure connection.": null, "Daily maximum reached.": null, + "Daily sign-in reward": null, "Entering tournament...": null, "Invalid code.": null, "Invalid payment; purchase canceled.": null, @@ -1622,11 +1719,14 @@ "Item unlocked!": null, "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": null, "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": null, + "Longer streaks lead to better rewards.": null, "Max number of playlists reached.": null, "Max number of profiles reached.": null, "Maximum friend code rewards reached.": null, "Message is too long.": null, + "New tournament result!": null, "No servers are available. Please try again soon.": null, + "No slots available. Free a slot and try again.": null, "Profile \"${NAME}\" upgraded successfully.": null, "Profile could not be upgraded.": null, "Purchase successful!": null, @@ -1636,7 +1736,9 @@ "Sorry, this code has already been used.": null, "Sorry, this code has expired.": null, "Sorry, this code only works for new accounts.": null, + "Sorry, this has expired.": null, "Still searching for nearby servers; please try again soon.": null, + "Streak: ${NUM} days": null, "Temporarily unavailable; please try again later.": null, "The tournament ended before you finished.": null, "This account cannot be unlinked for ${NUM} days.": null, @@ -1647,19 +1749,28 @@ "Tournaments require ${VERSION} or newer": null, "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": null, "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": null, + "Wait reduced!": null, + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": null, "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": null, "You already own this!": null, "You can join in ${COUNT} seconds.": null, "You don't have enough tickets for this!": null, "You don't own that.": null, "You got ${COUNT} tickets!": null, + "You got ${COUNT} tokens!": null, "You got a ${ITEM}!": null, + "You got a chest!": null, + "You got an achievement reward!": null, "You have been promoted to a new league; congratulations!": null, + "You lost a chest! (All your chest slots were full)": null, + "You must update the app to view this.": null, "You must update to a newer version of the app to do this.": null, "You must update to the newest version of the game to do this.": null, "You must wait a few seconds before entering a new code.": null, + "You placed #${RANK} in a tournament!": null, "You ranked #${RANK} in the last tournament. Thanks for playing!": null, "Your account was rejected. Are you signed in?": null, + "Your ad views are not registering. Ad options will be limited for a while.": null, "Your copy of the game has been modified.\nPlease revert any changes and try again.": null, "Your friend code was used by ${ACCOUNT}": null }, @@ -1808,11 +1919,14 @@ "toSkipPressAnythingText": "(tap or press anything to skip tutorial)" }, "twoKillText": "DOUBLE KILL!", + "uiScaleText": "UI Scale", "unavailableText": "unavailable", + "unclaimedPrizesText": "You have unclaimed prizes!", "unconfiguredControllerDetectedText": "Unconfigured controller detected:", "unlockThisInTheStoreText": "This must be unlocked in the store.", "unlockThisProfilesText": "To create more than ${NUM} profiles, you need:", "unlockThisText": "To unlock this, you need:", + "unsupportedControllerText": "Sorry, controller \"${NAME}\" is not supported.", "unsupportedHardwareText": "Sorry, this hardware is not supported by this build of the game.", "upFirstText": "Up first:", "upNextText": "Up next in game ${COUNT}:", @@ -1820,10 +1934,14 @@ "upgradeText": "Upgrade", "upgradeToPlayText": "Unlock \"${PRO}\" in the in-game store to play this.", "useDefaultText": "Use Default", + "userSystemScriptsCreateText": "Create User System Scripts", + "userSystemScriptsDeleteText": "Delete User System Scripts", "usesExternalControllerText": "This game uses an external controller for input.", "usingItunesText": "Using Music App for soundtrack...", "v2AccountLinkingInfoText": "To link V2 accounts, use the 'Manage Account' button.", + "v2AccountRequiredText": "This requires a V2 account. Upgrade your account and try again.", "validatingTestBuildText": "Validating Test Build...", + "viaText": "via", "victoryText": "Victory!", "voteDelayText": "You can't start another vote for ${NUMBER} seconds", "voteInProgressText": "A vote is already in progress.", @@ -1856,21 +1974,6 @@ "waveText": "Wave", "wellSureText": "Well Sure!", "whatIsThisText": "What is this?", - "wiimoteLicenseWindow": { - "titleText": "DarwiinRemote Copyright" - }, - "wiimoteListenWindow": { - "listeningText": "Listening For Wiimotes...", - "pressText": "Press Wiimote buttons 1 and 2 simultaneously.\n", - "pressText2": "On newer Wiimotes with Motion Plus built in, press the red 'sync' button on the back instead." - }, - "wiimoteSetupWindow": { - "copyrightText": "DarwiinRemote Copyright", - "listenText": "Listen", - "macInstructionsText": "Make sure your Wii is off and Bluetooth is enabled\non your Mac, then press 'Listen'. Wiimote support can\nbe a bit flaky, so you may have to try a few times\nbefore you get a connection.\n\nBluetooth should handle up to 7 connected devices,\nthough your mileage may vary.\n\nBombSquad supports the original Wiimotes, Nunchuks,\nand the Classic Controller.\nThe newer Wii Remote Plus now works too\nbut not with attachments.", - "thanksText": "Thanks to the DarwiinRemote team\nFor making this possible.\n", - "titleText": "Wiimote Setup" - }, "winsPlayerText": "${NAME} Wins!", "winsTeamText": "${NAME} Wins!", "winsText": "${NAME} Wins!", @@ -1879,15 +1982,8 @@ "worldScoresUnavailableText": "World scores unavailable.", "worldsBestScoresText": "World's Best Scores", "worldsBestTimesText": "World's Best Times", - "xbox360ControllersWindow": { - "getDriverText": "Get Driver", - "macInstructions2Text": "To use controllers wirelessly, you'll also need the receiver that\ncomes with the 'Xbox 360 Wireless Controller for Windows'.\nOne receiver allows you to connect up to 4 controllers.\n\nImportant: 3rd-party receivers will not work with this driver;\nmake sure your receiver says 'Microsoft' on it, not 'XBOX 360'.\nMicrosoft no longer sells these separately, so you'll need to get\nthe one bundled with the controller or else search ebay.\n\nIf you find this useful, please consider a donation to the\ndriver developer at his site.", - "macInstructionsText": "To use Xbox 360 controllers, you'll need to install\nthe Mac driver available at the link below.\nIt works with both wired and wireless controllers.", - "macInstructionsTextScale": 0.8, - "ouyaInstructionsText": "To use wired Xbox 360 controllers with BombSquad, simply\nplug them into your device's USB port. You can use a USB hub\nto connect multiple controllers.\n\nTo use wireless controllers you'll need a wireless receiver,\navailable as part of the \"Xbox 360 wireless Controller for Windows\"\npackage or sold separately. Each receiver plugs into a USB port and\nallows you to connect up to 4 wireless controllers.", - "titleText": "Using Xbox 360 Controllers with ${APP_NAME}:" - }, "yesAllowText": "Yes, Allow!", "yourBestScoresText": "Your Best Scores", - "yourBestTimesText": "Your Best Times" + "yourBestTimesText": "Your Best Times", + "yourPrizeText": "Your prize:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/filipino.json b/dist/ba_data/data/languages/filipino.json index 1b7d4e80..73a28afb 100644 --- a/dist/ba_data/data/languages/filipino.json +++ b/dist/ba_data/data/languages/filipino.json @@ -1,76 +1,80 @@ { "accountSettingsWindow": { - "accountNameRules": "Marapat na ang pangalan ng account na iyon ay walang mga special characters o mga emoji", + "accountNameRules": "Ang pangalan ay hindi dapat naglalaman ng emoji o ano mang uri ng simbolo", "accountsText": "Mga Account", "achievementProgressText": "Mga Nakamtan: ${COUNT} sa ${TOTAL}", - "campaignProgressText": "Ang Progreso sa Laro [Mahirap]: ${PROGRESS}", - "changeOncePerSeason": "Mapapalit mo lang ito isa-isa kada season", - "changeOncePerSeasonError": "Kailangan mo muna maghintay ng susunod na season para mapalitan ito. (${NUM} araw)", - "customName": "Custom na Pangalan", - "googlePlayGamesAccountSwitchText": "Kung gusto mong gamitin ang iba ninyong Google Account,\nGumamit ka ng Google Play Games app upang maipalit.", - "linkAccountsEnterCodeText": "Ilagay ang Code", - "linkAccountsGenerateCodeText": "Gumawa ng Code", - "linkAccountsInfoText": "(ibahagi ang pag-usad sa iba't ibang platform)", - "linkAccountsInstructionsNewText": "Para maiugnay ang dalawang accounts, gumawa ka ng code sa una at ilagay \nyung code sa pangalawa. Data na galing sa pangalawang account ay \nmaibabahagi sa dalawa.\n(Data na nasa unang account ay mawawala)\n\nMaari kang magugnay ng hangang ${COUNT} accounts.\n\nIMPORTANTE: Iugnay lamang ang iyong mga accounts, \ndahil kapag iuugnay mo sa kaibigan mo ang iyong \naccount,hindi kayo makakapaglaro ng sabay.", + "campaignProgressText": "Ang Progreso sa Kampanya [Mahirap]: ${PROGRESS}", + "changeOncePerSeason": "Mapapalit mo lang ito isang beses kada season", + "changeOncePerSeasonError": "Kailangan mo muna maghintay ng susunod na panahon para mapalitan ito. (${NUM} na araw)", + "createAnAccountText": "Gumawa ng account", + "customName": "Sariling Pangalan", + "deleteAccountText": "Burahin ang Account", + "googlePlayGamesAccountSwitchText": "Kung gusto mong gamitin ang iba ninyong Google Account, \nkailangan mo gamitin ang Google Play Games app upang maipalit ito.", + "linkAccountsEnterCodeText": "Ilagay ang Kowd", + "linkAccountsGenerateCodeText": "Gumawa ng Kowd", + "linkAccountsInfoText": "(ibahagi ang pag-usad sa ibang mga platform)", + "linkAccountsInstructionsNewText": "Para maiugnay ang dalawang account, gumawa ng kowd sa una at ilagay \nyung kowd sa pangalawa. Ang mga datos na galing sa pangalawang account ay \nmaibabahagi sa dalawa.\n(Ang datos na nasa unang account ay mawawala)\n\nMaari kang mag-link ng hanggang ${COUNT} na account.\n\nIMPORTANTE: Iugnay lamang ang iyong mga account na may-ari mo, \ndahil kapag iuugnay mo sa kaibigan mo ang iyong \naccount,hindi kayo makakapaglaro ng sabay.", "linkAccountsInstructionsText": "Para mag-ugnay ng dalawang account, gumawa ng code\nsa isa at ilagay ang code na iyon sa kabila.\nAng iyong pag-usad at imbentaryo ay pagsasamahin.\nMaaari mong i-ugnay hanggang sa ${COUNT} accounts.\n\nBabala lang; hindi na ito maibabalik!", - "linkAccountsText": "Iugnay ang mga Account", - "linkedAccountsText": "Naka-ugnay na mga Account", - "manageAccountText": "I-Manage ang Account", - "nameChangeConfirm": "Baguhin ang pangalan ng iyong account sa ${NAME}?", - "resetProgressConfirmNoAchievementsText": "Ibabalik nito sa dati ang iyong pag-usad,\nat lokal na mga high-score (pwera sa ticket).\nHindi na ito maibabalik pa. Ipagpatuloy pa rin?", - "resetProgressConfirmText": "Ibabalik nito sa dati ang iyong pag-usad,\nmga nakamtan, at lokal na mga high-score\n(pwera sa ticket). Hindi na ito maibabalik\npa. Ipagpatuloy pa rin?", - "resetProgressText": "I-reset ang Progreso", - "setAccountName": "I-set ang Account name", + "linkAccountsText": "Ilink ang mga Account", + "linkedAccountsText": "Naka-link na mga Account", + "manageAccountText": "Mamahalahin ang Account", + "nameChangeConfirm": "Ipalitan ang pangalan ng iyong account sa ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Ibabalik nito sa dati ang iyong pag-usad,\nat lokal na mga iskor (parehas lamang ang bilang ng iyong tiket).\nHindi ito maibabalik. Ipagpatuloy pa rin?", + "resetProgressConfirmText": "Maaaring maulit ang iyong pag-usad,\nmga nakamtan, at lokal na mga matataas na iskor\n(ngunit Hindi ang mga tiket). Hindi na ito maibabalik sa dati\nulit. Ipagpatuloy pa rin?", + "resetProgressText": "Ulitin ang Progreso", + "setAccountName": "Itakda ang Pangalan ng Account", "setAccountNameDesc": "Piliin ang pangalan na ipapakita para sa iyong account.\nMaaari mong gamitin ang pangalan mula sa isa sa iyong mga naka-link \nna account o lumikha ng isang natatanging pasadyang pangalan.", - "signInInfoText": "Magsign-in para kumolekta ng mga ticket, makipagkompetensya online,\nat makabahagi ng pag-usad sa iba't ibang mga device.", - "signInText": "Mag-sign in", - "signInWithDeviceInfoText": "(isang automatic account na magagamit lamang sa device na ito)", - "signInWithDeviceText": "Mag-sign in gamit ang device", - "signInWithGameCircleText": "Magsign-in gamit ang Game Circle", - "signInWithGooglePlayText": "Magsign-in gamit ang Google Play", + "signInInfoText": "Pumasok o gumawa nang account para kumolekta ng mga ticket, makipagkompetensya online,\nat makabahagi ng pag-usad sa iba't ibang mga device.", + "signInText": "Pumasok sa account", + "signInWithAnEmailAddressText": "Pumasok gamit ang email address", + "signInWithDeviceInfoText": "(kusang account na ginagamit lamang sa device na ito.)", + "signInWithDeviceText": "Pumasok gamit ang device account", + "signInWithGameCircleText": "Pumasok sa account gamit ang Game Circle", + "signInWithGooglePlayText": "Pumasok sa account gamit ang Google Play", "signInWithTestAccountInfoText": "(uri ng legacy account; gamitin ang mga account ng device na pasulong)", - "signInWithTestAccountText": "Magsign in gamit ang test account", - "signInWithV2InfoText": "(ang account na gumagana sa lahat na platforms)", - "signInWithV2Text": "Mag sign in gamit ang BombSquad account", - "signOutText": "Mag-sign out", - "signingInText": "Nagsasign-in...", - "signingOutText": "Nagsasign-out...", - "ticketsText": "Mga ticket: ${COUNT}", - "titleText": "Account", - "unlinkAccountsInstructionsText": "Pumili ng account na i-uunlink", - "unlinkAccountsText": "I-unlink ang mga accounts", - "unlinkLegacyV1AccountsText": "I-unlink ang mga Legacy (V1) Account", - "v2LinkInstructionsText": "Gamitin ang link na ito para gumawa ng account o mag sign in.", - "viaAccount": "(sa pamamagitan ng account ${NAME})", - "youAreSignedInAsText": "Nakasign-in ka bilang:" + "signInWithTestAccountText": "Pumasok gamit ang test account", + "signInWithText": "Pumasok gamit ang ${SERVICE}", + "signInWithV2InfoText": "(ang account na pwede gamitin sa lahat ng plataporma)", + "signInWithV2Text": "Pumasok gamit ang ${APP_NAME} account", + "signOutText": "Umalis", + "signingInText": "Pumapasok sa account...", + "signingOutText": "Umaalis sa account...", + "ticketsText": "Mga tiket: ${COUNT}", + "titleText": "Manlalaro", + "unlinkAccountsInstructionsText": "Pumili ng account na tatanggalin dito.", + "unlinkAccountsText": "Tanggalin ang mga account", + "unlinkLegacyV1AccountsText": "Tanggalin ang mga Legacy (V1) na mga Account", + "v2LinkInstructionsText": "Gamitin ang link na ito para gumawa ng account o pumasok sa account.", + "viaAccount": "(sa pamamagitan ng ${NAME})", + "youAreSignedInAsText": "Nakapasok bilang:" }, - "achievementChallengesText": "Mga nakamit", - "achievementText": "Mga Nakamtan", + "achievementChallengesText": "Mga Hamon sa Pagkamit", + "achievementText": "Nakamtan", "achievements": { "Boom Goes the Dynamite": { - "description": "Mapasabog ang 3 kalaban gamit ang TNT", - "descriptionComplete": "Napasabog ang 3 kalaban gamit ang TNT", - "descriptionFull": "Mapasabog ang 3 kalaban gamit ang TNT sa ${LEVEL}", - "descriptionFullComplete": "Napasabog ang 3 kalabangamit ang TNT sa ${LEVEL}", - "name": "Sabog ang Sabi ng Dinamita" + "description": "Pasabugin ang mga 3 kalaban gamit ang TNT", + "descriptionComplete": "Pinasabog ang mga 3 kalaban gamit ang TNT", + "descriptionFull": "Sabugin ang mga 3 kalaban gamit ang TNT ${LEVEL}", + "descriptionFullComplete": "Napasabog ang 3 kalaban gamit ang TNT sa ${LEVEL}", + "name": "Sabog Ang Pinagsasabog" }, "Boxer": { - "description": "Manalo sa laro ng hindi gumagamit ng bomba", - "descriptionComplete": "Nanalo sa laro ng hindi gumagamit ng bomba", - "descriptionFull": "Tapusin ang ${LEVEL} na walang gamit na bomba", - "descriptionFullComplete": "Natapos ang ${LEVEL} na himdi gumagamit ng bomba", + "description": "Manalo sa laro nang hindi gumagamit ng mga bomba", + "descriptionComplete": "Manalo sa laro ng hindi gumagamit ng bomba", + "descriptionFull": "Tapusin ang ${LEVEL} habang hindi gumagamit nang bomba", + "descriptionFullComplete": "Natapos ang ${LEVEL} habang hindi gumagamit nang bomba", "name": "Boksingero" }, "Dual Wielding": { - "descriptionFull": "Ikonekta ang 2 controllers (hardware o app)", - "descriptionFullComplete": "Konektado ang 2 controllers (hardware o app)", - "name": "Dalawang Nangalaro" + "descriptionFull": "Ikonekta ang dalawang mga controllers (hardware o app)", + "descriptionFullComplete": "Nakonektado na ang 2 controllers (hardware o app)", + "name": "Dalawang Hawak" }, "Flawless Victory": { - "description": "Manalo nang hindi natatamaan", - "descriptionComplete": "Nanalo nang hindi natamaan", - "descriptionFull": "Manalo sa ${LEVEL} nang hindi makakakuha ng hit", - "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi nakakakuha ng hit", + "description": "Manalo nang hindi natatamaan ng kalaban", + "descriptionComplete": "Nanalo nang hindi natamaan ng kalaban", + "descriptionFull": "Manalo sa ${LEVEL} nang hindi matatamaan", + "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi natatamaan", "name": "‘Di Mintis Na Pagtagumpay" }, "Free Loader": { @@ -79,11 +83,11 @@ "name": "Manggagamit" }, "Gold Miner": { - "description": "Pumatay Ng 6 na kalaban gamit ang mga land-mine", + "description": "Magpamatay ka ng 6 na kalaban gamit ang mga land-mine", "descriptionComplete": "Pumatay ng 6 na kalaban gamit ang mga land-mine", "descriptionFull": "Pumatay ng 6 na kalaban gamit ang mga land -mine sa ${LEVEL}", "descriptionFullComplete": "Nakapatay ng 6 na kalaban gamit ang mga land-mine sa ${LEVEL}", - "name": "Minahang Lagayan" + "name": "Minahang Ginto" }, "Got the Moves": { "description": "Manalo ng ‘di sumusuntok o gumagamit ng mga bomba", @@ -95,7 +99,7 @@ "In Control": { "descriptionFull": "Magconnect ng controller (hardware o app)", "descriptionFullComplete": "Nagconnect ng controller (hardware o app)", - "name": "Kumokontrol" + "name": "Nasa-kontrol" }, "Last Stand God": { "description": "Maka-iskor ng 1000 na puntos", @@ -189,17 +193,17 @@ "name": "Kampeon ng ${LEVEL}" }, "Pro Onslaught Victory": { - "description": "Matalo lahat ng mga kaway", - "descriptionComplete": "Natalo lahat ng mga kaway", - "descriptionFull": "Matalo lahat ng mga kaway sa ${LEVEL}", - "descriptionFullComplete": "Natalo lahat ng mga kaway sa ${LEVEL}", + "description": "Matalo lahat ng mga yugto", + "descriptionComplete": "Natalo mo ang lahat ng mga lebel", + "descriptionFull": "Matalo lahat ng mga yugto sa ${LEVEL}", + "descriptionFullComplete": "Natalo mo ang lahat ng mga yugto sa ${LEVEL}", "name": "Kampeon ng ${LEVEL}" }, "Pro Runaround Victory": { - "description": "Tapusin lahat ng mga kaway", - "descriptionComplete": "Natapos lahat ng mga kaway", - "descriptionFull": "Tapusin ang lahat ng mg kaway sa ${LEVEL}", - "descriptionFullComplete": "Tinapos lahat ng mga kaway sa ${LEVEL}", + "description": "Tapusin lahat ng mga yugto", + "descriptionComplete": "Natapos lahat ng mga yugto", + "descriptionFull": "Tapusin ang lahat ng mg yugto sa ${LEVEL}", + "descriptionFullComplete": "Tinapos lahat ng mga yugto sa ${LEVEL}", "name": "Kampeon ng ${LEVEL}" }, "Rookie Football Shutout": { @@ -217,10 +221,10 @@ "name": "Nanalo sa ${LEVEL}" }, "Rookie Onslaught Victory": { - "description": "Italo lahat ang mga kaway", - "descriptionComplete": "Natalo lahat ang mga kaway", - "descriptionFull": "Italo lahat ang mga kaway sa ${LEVEL}", - "descriptionFullComplete": "Natalo lahat ng mga kaway sa ${LEVEL}", + "description": "Italo lahat ang mga yugto", + "descriptionComplete": "Natalo mo lahat ang mga yugto", + "descriptionFull": "Italo lahat ang mga yugto sa ${LEVEL}", + "descriptionFullComplete": "Natalo mo lahat ng mga yugto sa ${LEVEL}", "name": "Nanalo sa ${LEVEL}" }, "Runaround God": { @@ -232,7 +236,7 @@ }, "Runaround Master": { "description": "Pumuntos ng 500", - "descriptionComplete": "Nakapuntos ng 500", + "descriptionComplete": "Naka 500 na iskor", "descriptionFull": "Pumuntos ng 500 sa ${LEVEL}", "descriptionFullComplete": "Nakakuha ng 500 puntos sa ${LEVEL}", "name": "Pinuno ng ${LEVEL}" @@ -254,28 +258,28 @@ "descriptionComplete": "Nanalo nang hindi namatay", "descriptionFull": "Nanalo ${LEVEL} nang hindi namatay", "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi namatay", - "name": "Manatiling Buhay" + "name": "Buhay Pa!" }, "Super Mega Punch": { "description": "Magdulot ng 100% damage sa isang suntok", "descriptionComplete": "Nagdulot ng 100% damage sa isang suntok", "descriptionFull": "Magdulot ng 100% damage ng isang suntok sa ${LEVEL}", "descriptionFullComplete": "Nagdulot ng 100% damage sa isang suntok sa ${LEVEL}", - "name": "Sobrang Mega Na Suntok" + "name": "Pinakakirot Na Suntok" }, "Super Punch": { "description": "Magdulot ng 50% damage sa isang suntok", "descriptionComplete": "Nagdulot ng 50% damage sa isang suntok", "descriptionFull": "Magdulot ng 50% damage sa isang suntok sa ${LEVEL}", "descriptionFullComplete": "Nagdulot ng 50% damage sa isang suntok sa ${LEVEL}", - "name": "Sobrang Suntok" + "name": "Masakit Na Suntok" }, "TNT Terror": { "description": "Pumatay ng 6 na kalaban gamit ang TNT", "descriptionComplete": "Pinatay ng 6 na kalaban gamit ang TNT", "descriptionFull": "Pumatay ng 6 na kalaban gamit ang TNT sa ${LEVEL}", "descriptionFullComplete": "Pinatay ng 6 na kalaban gamit ang TNT sa ${LEVEL}", - "name": "Takutan ng TNT" + "name": "Kaguluhan ng TNT" }, "Team Player": { "descriptionFull": "Magsimula ng laro na mayroong 4+ na manlalaro", @@ -283,7 +287,7 @@ "name": "Manlalaro Ng Koponan" }, "The Great Wall": { - "description": "Itigil ang bawat kalaban", + "description": "Patayin ang lahat ng kalaban", "descriptionComplete": "Pinigilan ang bawat kalaban", "descriptionFull": "Itigil ang bawat kalaban sa ${LEVEL}", "descriptionFullComplete": "Pinigilan ang bawat kalaban sa ${LEVEL}", @@ -306,49 +310,54 @@ "Uber Football Victory": { "description": "Ipanalo ang laro", "descriptionComplete": "Nanalo ang laro", - "descriptionFull": "I-panalo ang laro sa ${LEVEL}", + "descriptionFull": "Ipanalo ang laro sa ${LEVEL}", "descriptionFullComplete": "Manalo ang laro sa ${LEVEL}", "name": "${LEVEL} Natagumpay" }, "Uber Onslaught Victory": { - "description": "Talunin ang lahat na mga kaway", - "descriptionComplete": "Natalo ang lahat na mga kaway", - "descriptionFull": "Talunin ang lahat na mga kaway sa ${LEVEL}", - "descriptionFullComplete": "Natalo ang lahat na mga kaway sa ${LEVEL}", + "description": "Talunin ang lahat na mga yugto", + "descriptionComplete": "Natalo ang lahat na mga yugto", + "descriptionFull": "Talunin ang lahat na mga yugto sa ${LEVEL}", + "descriptionFullComplete": "Natalo ang lahat na mga yugto sa ${LEVEL}", "name": "Nanalo sa ${LEVEL}" }, "Uber Runaround Victory": { - "description": "Tapusin ang lahat na kaway", - "descriptionComplete": "Natapos ang lahat na mga kaway", - "descriptionFull": "Tapusin ang lahat na mga kaway sa ${LEVEL}", - "descriptionFullComplete": "Natapos ang lahat na mga kaway sa ${LEVEL}", + "description": "Tapusin ang lahat na yugto", + "descriptionComplete": "Natapos ang lahat na mga yugto", + "descriptionFull": "Tapusin ang lahat na mga yugto sa ${LEVEL}", + "descriptionFullComplete": "Natapos ang lahat na mga yugto sa ${LEVEL}", "name": "${LEVEL} Natagumpay" } }, "achievementsRemainingText": "Ang Mga Natitirang Nakamtan:", - "achievementsText": "Achievements", - "achievementsUnavailableForOldSeasonsText": "Pasensya na, hindi available ang mga detalye ng achievements para sa mga lumang seasons.", + "achievementsText": "Mga Nakamtan", + "achievementsUnavailableForOldSeasonsText": "Pasensya na, hindi maibalik ang mga detalye ng achievements para sa mga lumang seasons.", "activatedText": "Na-aktibo ang ${THING}.", "addGameWindow": { - "getMoreGamesText": "Kukuha ng higit pang mga laro…", + "getMoreGamesText": "Kumuha ng Higit pang mga Laro…", "titleText": "Magdagdag Ng Laro" }, - "allowText": "Payagan", + "addToFavoritesText": "Ilagay sa Mga Paborito", + "addedToFavoritesText": "Nakalagay na ang '${NAME}' sa Mga Paborito.", + "allText": "Lahat", + "allowText": "Payagin", "alreadySignedInText": "Ang iyong account ay naka-sign in mula sa isa pang device;\nMangyaring lumipat ng mga accounts o isara ang laro sa iyong\niba pang mga device at subukan muli.", "apiVersionErrorText": "Hindi ma-load ang module ${NAME}; naka-target ang api-version ${VERSION_USED}; kailangan namin ${VERSION_REQUIRED}", + "applyText": "Gamitin", + "areYouSureText": "Sigurado ka ba?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(Lalabas ang “Auto” ng ito kapag nakasaksak ang headphones)", "headRelativeVRAudioText": "Head-Relative VR Audio", - "musicVolumeText": "Volume ng Musika", + "musicVolumeText": "Lakas ng Musika", "soundVolumeText": "Lakas ng Tunog", "soundtrackButtonText": "Mga Soundtrack", - "soundtrackDescriptionText": "(I-assign ang iyong sariling musika para magtugtug kapag naglalaro)", - "titleText": "Audio" + "soundtrackDescriptionText": "(Maglagay ang iyong sariling musika na maitugtog habang naglalaro)", + "titleText": "Tugtugan" }, "autoText": "Auto", "backText": "Bumalik", - "banThisPlayerText": "I-ban ang Manlalarong Ito", - "bestOfFinalText": "Pinakamahusay-sa-${COUNT} Final", + "banThisPlayerText": "Bawalin ang Manlalarong Ito", + "bestOfFinalText": "Wakas ng Pinakamahusay-sa-${COUNT}", "bestOfSeriesText": "Pinakamahusay sa ${COUNT} series:", "bestOfUseFirstToInstead": 0, "bestRankText": "Ang iyong pinakamahusay ay #${RANK}", @@ -358,15 +367,25 @@ "boostText": "Palakasin", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} naka-configure ito sa mismong app.", "buttonText": "pindutan", - "canWeDebugText": "Gusto mo ba na ang BombSquad ay automatic na mag report ng\nbugs, crashes, at mga basic usage na info na i-sent sa developer?\n\nHindi ito naglalaman ng mga personal information at makatulong ito\npara ang laro ay gumagana at bug-free.", + "canWeDebugText": "Gusto mo ba na ang ${APP_NAME} ay automatic na mag report ng\nbugs, crashes, at mga basic usage na info na i-sent sa developer?\n\nHindi ito naglalaman ng mga personal information at makatulong ito\npara ang laro ay gumagana at bug-free.", "cancelText": "Kanselahin", "cantConfigureDeviceText": "Pasensya na, ang ${DEVICE} na ito ay hindi ma-configure.", "challengeEndedText": "Natapos na ang challenge na ito.", - "chatMuteText": "I-mute ang Chat", + "chatMuteText": "Tahimikin Ang Chat Mo", "chatMutedText": "Na-mute ang Chat", - "chatUnMuteText": "I-unmute ang Chat", + "chatUnMuteText": "Ipaganahin Mo Na ang Chat", + "chests": { + "prizeOddsText": "Premyong Panumbasan", + "reduceWaitText": "Magbawas ng Oras", + "slotDescriptionText": "Ito'y pinaglalaman ng mga baul.\n\nMagtipon ng mga baul sa pamamagitan \nng paglalaro ng kampanya, paligsahan, \nat pagkuha ng mga nakamtan.", + "slotText": "Puwang ng Baul ${NUM}", + "slotsFullWarningText": "BABALA: Lahat ng mga patlang ng baul ay puno na. \nAng mga baul na natanggap sa ngayon ay mawawala.", + "unlocksInText": "Magbubukas sa loob ng" + }, "choosingPlayerText": "", - "completeThisLevelToProceedText": "I complete mo muna\nang level na ito bago ka mag-proceed!", + "claimText": "Ikunin", + "codesExplainText": "Binigay ng isang taong gumagawa ng larong ito ang mga kowd \npara kilalanin at maitama ang mga problema sa account.", + "completeThisLevelToProceedText": "Tapusin mo muna\nang antas na ito bago tumuloy!", "completionBonusText": "Bonus sa Pagkumpleto nito:", "configControllersWindow": { "configureControllersText": "I-configure ang mga Controller", @@ -377,7 +396,7 @@ "ps3Text": "PS3 Controllers", "titleText": "Mga Controller", "wiimotesText": "Wiimotes", - "xbox360Text": "Xbox 360 Controllers" + "xbox360Text": "Controllers ng Xbox 360" }, "configGamepadSelectWindow": { "androidNoteText": "Tandaan: nag-iiba-iba ang suporta sa controller sa mga devices at bersyon ng Andriod.", @@ -385,25 +404,25 @@ "titleText": "I-configure ang mga Controller" }, "configGamepadWindow": { - "advancedText": "Advanced", - "advancedTitleText": "Advanced na Setup ng Controller", + "advancedText": "Mga Iba Pa", + "advancedTitleText": "Iba Pang Setup ng Controller", "analogStickDeadZoneDescriptionText": "(itaas ito kapag ang iyong karakter ay nag ‘d-drift’ kapag binitawan mo ang stick)", "analogStickDeadZoneText": "Analog Stick Dead Zone", "appliesToAllText": "(nalalapat sa lahat ng controller ng ganitong uri)", "autoRecalibrateDescriptionText": "(paganahin ito kung ang iyong karakter ay hindi gumagalaw ng buong bilis)", "autoRecalibrateText": "Auto-Recalibrate Analog Stick", "axisText": "aksis", - "clearText": "alisin", - "dpadText": "dpad", + "clearText": "ibura", + "dpadText": "DPAD", "extraStartButtonText": "Extra na Start Button", "ifNothingHappensTryAnalogText": "Kapag walang gumagana, i-try na i-assign sa analog stick.", "ifNothingHappensTryDpadText": "Kapag hindi gumana, i-try na i-assign sa d-pad.", "ignoreCompletelyDescriptionText": "(pigilan ang controller na ito na maapektuhan ang alinman sa laro o mga menu)", "ignoreCompletelyText": "Huwag Pansinin", - "ignoredButton1Text": "Pindutan Na ‘Di Pansinin 1", - "ignoredButton2Text": "Pindutan Na ‘Di Pansinin 2", - "ignoredButton3Text": "Pindutan Na ‘Di Pansinin 3", - "ignoredButton4Text": "Pindutan Na ‘Di Pansinin 4", + "ignoredButton1Text": "Pindutan Na ‘Di Pinansin 1", + "ignoredButton2Text": "Pindutan Na ‘Di Pinansin 2", + "ignoredButton3Text": "Pindutan Na ‘Di Pinansin 3", + "ignoredButton4Text": "Pindutan Na ‘Di Pinansin 4", "ignoredButtonDescriptionText": "(gamitin ito para ma-prevent ang ‘home’ o ‘sync’ buttons na nakakaapekto sa UI)", "pressAnyAnalogTriggerText": "Pindutin ang anumang analog trigger…", "pressAnyButtonOrDpadText": "Pindutin ang anumang pindutan o dpad…", @@ -419,7 +438,7 @@ "secondaryEnableText": "Paganahin", "secondaryText": "Pangalawang Controller", "startButtonActivatesDefaultDescriptionText": "(i-off ito kung ang iyong start button ay higit pa sa isang ‘menu’ button)", - "startButtonActivatesDefaultText": "Start Button Activates Defualt Widget", + "startButtonActivatesDefaultText": "Ang Pindutang Pagsisimulahin Ay Binubukas Ang Default Widget", "titleText": "Setup ng Controller", "twoInOneSetupText": "2-in-1 na Setup ng Controller", "uiOnlyDescriptionText": "(pigilan ang controller na ito mula sa aktwal na pagsali sa isang laro)", @@ -446,12 +465,14 @@ "swipeText": "mag-swipe", "titleText": "I-configure ang Touchscreen" }, + "configureDeviceInSystemSettingsText": "Ang ${DEVICE} ay pwede ma-configure sa System Settings app.", "configureItNowText": "I-configure ngayon?", "configureText": "Configure", "connectMobileDevicesWindow": { "amazonText": "Amazon Appstore", "appStoreText": "App Store", - "bestResultsText": "Para sa pinakamahusay na mga resulta, kakailanganin mo ng isang lag-free na wifi network. Kaya mo\nbawasan ang wifi lag sa pamamagitan ng pag-off ng iba pang mga wireless na device, sa pamamagitan ng\nnaglalaro malapit sa iyong wifi router, at sa pamamagitan ng pagkonekta sa\ndirektang host ng laro sa network sa pamamagitan ng ethernet.", + "bestResultsScale": 0.6, + "bestResultsText": "Para sa pinakamahusay na mga resulta, kakailanganin mo ng isang lag-free na wifi network. Kaya mo\nbawasan ang wifi lag sa pamamagitan ng pag-off ng iba pang mga wireless na device, sa pamamagitan ng\nnaglalaro malapit sa iyong wifi router, at sa pamamagitan ng pagkonekta sa\ndirektang pinaghanda ng laro sa network sa pamamagitan ng ethernet.", "explanationText": "Para gumamit ng smart-phone o tablet bilang wireless controller,\ni-install ang \"${REMOTE_APP_NAME}\" na app dito. Anumang bilang ng mga device\nmaaaring kumonekta sa isang larong ${APP_NAME} sa Wi-Fi, at libre ito!", "forAndroidText": "para sa Andriod:", "forIOSText": "para sa iOS:", @@ -467,11 +488,11 @@ "activenessInfoText": "Ang multiplier na ito ay tumataas sa mga araw kung kailan ka\nmaglaro at bumaba sa mga araw na hindi mo ginagawa.", "activityText": "Aktibidad", "campaignText": "Kampanya", - "challengesInfoText": "Makakuha ng mga premyo para sa pagkumpleto ng mga mini-game.\n\nAng mga premyo at antas ng kahirapan ay tumataas\nsa bawat oras na ang isang hamon ay nakumpleto at\nbumaba kapag ang isa ay nag-expire o na-forfeit.", + "challengesInfoText": "Makakuha ng mga premyo para sa pagkumpleto ng mga mini-game.\n\nAng mga premyo at antas ng kahirapan ay tumataas\nsa bawat oras na ang isang hamon ay nakumpleto at\nbumaba kapag ang isa ay nawala na o naparusa.", "challengesText": "Mga Challenges", "currentBestText": "Kasalukuyang Pinakamahusay", "customText": "Kustom", - "entryFeeText": "Pasok", + "entryFeeText": "Pumasok", "forfeitConfirmText": "Isuko ang hamon na ito?", "forfeitNotAllowedYetText": "Ang hamon na ito ay hindi pa maaaring mawala.", "forfeitText": "Forfeit", @@ -494,8 +515,8 @@ "skipWaitText": "Lagktawang Paghintay", "timeRemainingText": "Natitirang Oras", "toRankedText": "Sagad Sa Ranggo", - "totalText": "kabuuan", - "tournamentInfoText": "Makipagkumpitensya para sa matataas na marka sa\nibang mga manlalaro sa iyong liga.\n\nAng mga premyo ay iginagawad sa pinakamataas na iskor\nmga manlalaro kapag nag-expire ang oras ng tournament.", + "totalText": "kabuuhan", + "tournamentInfoText": "Makipagkumpitensya para sa matataas na marka sa\nibang mga manlalaro sa iyong liga.\n\nAng mga premyo ay iginagawad sa pinakamataas na iskor\nmga manlalaro kapag natapos ang oras ng tournament.", "welcome1Text": "Maligayang pagdating sa ${LEAGUE}. Maaari mong pagbutihin ang iyong\nranggo ng liga sa pamamagitan ng pagkamit ng mga star rating, pagkumpleto\nmga tagumpay, at panalong tropeo sa mga paligsahan.", "welcome2Text": "Maaari ka ring makakuha ng mga tiket mula sa marami sa parehong mga aktibidad.\nMaaaring gamitin ang mga tiket para i-unlock ang mga bagong character, mapa, at\nmini-games, para makapasok sa mga tournament, at higit pa.", "yourPowerRankingText": "Iyong Power Ranking:" @@ -503,27 +524,27 @@ "copyConfirmText": "Nakopya sa clipboard.", "copyOfText": "Kopya ng ${NAME}", "copyText": "I-kopya", - "createEditPlayerText": "", + "createEditPlayerText": "", "createText": "Gumawa", "creditsWindow": { - "additionalAudioArtIdeasText": "Adisyonal Audio, Agang Artwork, Ideya ni ${NAME}", - "additionalMusicFromText": "Adisyonal musika galing kay ${NAME}", + "additionalAudioArtIdeasText": "Adisyonal na Pagtugtugin, Sining Pang-aga, at Pagharaya ni ${NAME}", + "additionalMusicFromText": "Adisyonal musika galing sa ${NAME}", "allMyFamilyText": "Lahat sa aking kaibigan at pamilya ko na tumulong sa play test", - "codingGraphicsAudioText": "Coding, Graphics, at Audio ni ${NAME}", + "codingGraphicsAudioText": "Pagkukudigo, Paggrapikan, at Pagtugtugin ni ${NAME}", "languageTranslationsText": "Pagsasalin Ng Wika:", "legalText": "Ligal:", "publicDomainMusicViaText": "Public-domain music mula sa ${NAME}", "softwareBasedOnText": "Ang software na ito ay batay sa bahagi ng gawain ng ${NAME}", - "songCreditText": "${TITLE} Ginawa ni ${PERFORMER}\nBinubuo ni ${COMPOSER}, Inayos ni ${ARRANGER}, Na-publish ni ${PUBLISHER},\nSa kagandahang-loob ng ${SOURCE}", + "songCreditText": "${TITLE} Pinagbigkas ng ${PERFORMER}\nBinubuo ni ${COMPOSER}, Inayos ni ${ARRANGER}, Inilathala ng ${PUBLISHER},\nSa kagandahang-loob ng ${SOURCE}", "soundAndMusicText": "Tunog at Musika", "soundsText": "Mga Tunog (${SOURCE}):", "specialThanksText": "Espesyal Na Pasasalamat:", - "thanksEspeciallyToText": "Salamat, lalo na kay ${NAME}", - "titleText": "${APP_NAME} Mga Kredito", + "thanksEspeciallyToText": "Salamat, lalo na ang ${NAME}", + "titleText": "${APP_NAME} Karangalan", "whoeverInventedCoffeeText": "At ang sino man na nag-imbento ng kape" }, "currentStandingText": "Ang kasalukuyang tayo mo ay #${RANK}", - "customizeText": "I-customize...", + "customizeText": "Ayusin...", "deathsTallyText": "${COUNT} pagkamatay", "deathsText": "Pagkamatay", "debugText": "debug", @@ -540,76 +561,82 @@ "stressTestRoundDurationText": "Pagtagal Ng Round", "stressTestTitleText": "Stress Test", "titleText": "Benchmarks at Stress Test", - "totalReloadTimeText": "Kabuuang reload time: ${TIME} (tingnan Ang log para sa mga detalye)" + "totalReloadTimeText": "Kabuuhang reload time: ${TIME} (tingnan Ang log para sa mga detalye)" }, - "defaultGameListNameText": "Default ${PLAYMODE} Playlist", - "defaultNewGameListNameText": "Ang aking ${PLAYMODE} Playlist", + "defaultGameListNameText": "Orihinal Na Laruhang Pang-${PLAYMODE}", + "defaultNewGameListNameText": "Ang Aking Laruhang Pang-${PLAYMODE}", "deleteText": "Tanggalin", "demoText": "Demo", - "denyText": "Tanggihan", + "denyText": "Tanggihin", "deprecatedText": "Hindi Na Uso", + "descriptionText": "Paglalarawan", "desktopResText": "Desktop Res", - "deviceAccountUpgradeText": "Babala:\nNaka-sign in ka gamit ang isang device account (${NAME}).\nMawawala na yan sa kinakabukasang update.\nMag-upgrade sa isang V2 Account kung gusto mong panatilihin ang iyong pag-unlad.", + "deviceAccountUpgradeText": "Babala:\nNaka-sign in ka gamit ang isang device account (${NAME}).\nMawawala na yan sa kinakabukasang pagbabago.\nMag-upgrade sa isang V2 Account kung gusto mong panatilihin ang iyong pag-unlad.", "difficultyEasyText": "Madali", "difficultyHardOnlyText": "Mahirap Na Mode Lang", "difficultyHardText": "Mahirap", - "difficultyHardUnlockOnlyText": "Itong level na ito ay naka-unlock sa Mahirap na mode lang.\nSa tingin mo ba mayroong ano ang kinakailangan!?!?!", + "difficultyHardUnlockOnlyText": "Itong level na ito ay maibukas sa Mahirap na mode lamang.\nSa tingin mo ba mayroong ka nang kinakailangan!?!?!", "directBrowserToURLText": "Mangyaring idirekta Ang isang web-browser sa sumusunod na URL:", - "disableRemoteAppConnectionsText": "I-disable Ang Mga Remote-App Na Konekyson", + "disableRemoteAppConnectionsText": "Itigil Ang Koneksyon Ng Mga Remote-App", "disableXInputDescriptionText": "Pumayag ng higit sa 4 na controllers ngunit maaaring hindi mabuti ang kalagay", "disableXInputText": "Disable XInput", - "doneText": "Tapos", + "disabledText": "Naka-disabled", + "discardText": "Iwaksi", + "discordFriendsText": "Gusto mong may kalaro kang mga tao na gusto mo?\nSumali sa aming Discord server at hanapin mo ang kaibiganin mo!", + "discordJoinText": "Sumali sa Discord", + "doneText": "Tapusin", "drawText": "Patas", - "duplicateText": "I-duplicate", + "duplicateText": "Duplikaduhin", "editGameListWindow": { "addGameText": "Idagdag na\nLaro", "cantOverwriteDefaultText": "Hindi ma-overwrite ang default playlist!", - "cantSaveAlreadyExistsText": "Isang playlist na may ganyang pangalan na!", + "cantSaveAlreadyExistsText": "Mayroon nang isang playlist na may ganyang pangalan!", "cantSaveEmptyListText": "Hindi ma-save ang walang laman na playlist!", - "editGameText": "I-Edit ang\nLaro", + "editGameText": "Ayusin ang\nLaro", "listNameText": "Pangalan Ng Playlist", "nameText": "Pangalan", "removeGameText": "Tanggalin ang\nLaro", "saveText": "I-save Ang Listahan", - "titleText": "Editor Ng Playlist" + "titleText": "Pag-ayusan Ng Playlist" }, "editProfileWindow": { - "accountProfileInfoText": "Itong espesyal na profile ay may\npangalan at icon batay sa iyong account.\n\n${ICONS}\n\nGumawa ng custom na profile para gamitin ng \nmagkaibang pangalan o custom icons.", + "accountProfileInfoText": "Itong espesyal na karakter ay may\npangalan at tatak batay sa iyong account.\n\n\n${ICONS}\n\nGumawa ng sariling karakter para magamit ang iibang pangalan o tatak.", "accountProfileText": "(account profile)", - "availableText": "Ang pangalang \"${NAME}” na ito ay maari mong gamitin pang-icon", + "availableText": "Ang pangalang \"${NAME}” na ito ay maaari mong gamitin pang-tatak", "characterText": "karakter", - "checkingAvailabilityText": "Titignan ko kung maaari mo gamitin ang \"${NAME}\"...", + "checkingAvailabilityText": "Titignan kung maaari mo gamitin ang \"${NAME}\"...", "colorText": "kulay", - "getMoreCharactersText": "Kumuha Ka Pang Mga Karakter...", - "getMoreIconsText": "Kumuha Ka Pang Mga Icons...", - "globalProfileInfoText": "Golbal player profiles ay garantisadong magkaroon ng unique na pangalan worldwide.\nNa-include nila rin ang custom icons.", - "globalProfileText": "(global na profile)", - "highlightText": "highlight", - "iconText": "Mga icon", - "localProfileInfoText": "Ang mga profile Ng lokal na manlalaro ay walang mga icon at ang kanilang mga \npangalan ay hindi garantisadong unique. I-upgrade para maging isang global \nprofile at ma-reserve ng isang unique na pangalan at ma-add ng custom icon.", - "localProfileText": "(lokal na profile)", + "getMoreCharactersText": "Bumili ng Higit pang mga Karakter...", + "getMoreIconsText": "Bumili ng Higit pang Tatak...", + "globalProfileInfoText": "Ang mga karakter ng manlalaro na panglahatan ay garantisadong magkaroon \nng magkaiba na pangalan sa buong mundo. Mayroon din silang ibang tatak.", + "globalProfileText": "(karakter para sa mundo)", + "highlightText": "Pangalawang Kulay", + "iconText": "tatak", + "localProfileInfoText": "Ang mga karakter ng lokal na manlalaro ay wala silang tatak at ang kanilang \nmga pangalan ay hindi garantisadong pambihira. Idakila iyong pinakasikat\n na karakter at ang sariling pambihirang pangalan at tatak para sa buong mundo.", + "localProfileText": "(lokal na karakter)", "nameDescriptionText": "Pangalan Ng Manlalaro", "nameText": "Pangalan", - "randomText": "random", - "titleEditText": "I-Edit Ang Profile", + "profileAlreadyExistsText": "Mayroon nang isang manlalaro na may ganyang pangalan.", + "randomText": "basta-basta", + "titleEditText": "Ayusin Ang Profile", "titleNewText": "Bagong Profile", - "unavailableText": "hindi available ang \"${NAME}\"; sumubok ng ibang pangalan", - "upgradeProfileInfoText": "Irereserba nito ang pangalan ng iyong manlalaro sa buong mundo\nat nagbibigay-daan sa iyong magtalaga ng custom na icon dito.", - "upgradeToGlobalProfileText": "Upgrade sa Global na Profile" + "unavailableText": "Meron na o Hindi wasto ang \"${NAME}\" na ito; subukin ang ibang pangalan.", + "upgradeProfileInfoText": "Irereserba nito ang pangalan ng iyong manlalaro sa buong mundo\nat nagbibigay-daan sa iyong magtalaga ng ibang tatak dito.", + "upgradeToGlobalProfileText": "Taasin sa Global na Profile" }, "editSoundtrackWindow": { "cantDeleteDefaultText": "Hindi mo maitanggal Ang default soundtrack", - "cantEditDefaultText": "Hindi ma-edit ang default soundtrack. I-duplicate mo o gumawa Ng bago", - "cantOverwriteDefaultText": "Hindi ma-overwrite ang default soundtrack", - "cantSaveAlreadyExistsText": "Isang soundtrack na may ganyang pangalan na!", - "defaultGameMusicText": "", - "defaultSoundtrackNameText": "Default na Soundtrack", + "cantEditDefaultText": "Hindi pwede ayusin ang orihinal soundtrack.Kopyahin mo nalang o gumawa ng bago", + "cantOverwriteDefaultText": "Hindi maibahin ang orihinal na soundtrack", + "cantSaveAlreadyExistsText": "May isang soundtrack na may ganyang pangalan na!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Orihinal na Soundtrack", "deleteConfirmText": "Itanggal Ang Soundtrack:\n\n'${NAME}'?", "deleteText": "I-delete Ang\nSoundtrack", - "duplicateText": "I-duplicate Ang\nSoundtrack", - "editSoundtrackText": "Editor Ng Soundtrack", - "editText": "I-edit Ang\nSoundtrack", - "fetchingITunesText": "kumuha ng Music App playlists...", + "duplicateText": "Duplikaduhin Ang\nSoundtrack", + "editSoundtrackText": "Ayusan Ng Soundtrack", + "editText": "Ayusin Ang\nSoundtrack", + "fetchingITunesText": "kumuha ng playlist ng Music App...", "musicVolumeZeroWarning": "Paunawa: Ang volume ng musika ay nakatakda sa 0", "nameText": "Pangalan", "newSoundtrackNameText": "Ang Aking Soundtrack ${COUNT}", @@ -624,11 +651,12 @@ "useMusicFileText": "File Ng Musika (mp3, etc)", "useMusicFolderText": "Folder Ng Mga File Ng Musika" }, - "editText": "I-edit", + "editText": "Ayusin", + "enabledText": "Nakagana", "endText": "Itigil", - "enjoyText": "Ikasiya!", - "epicDescriptionFilterText": "${DESCRIPTION} sa isang epic na slow motion.", - "epicNameFilterText": "Epikong ${NAME}", + "enjoyText": "Ikasaya!", + "epicDescriptionFilterText": "${DESCRIPTION} sa isang dakilang pabagal na galaw.", + "epicNameFilterText": "Dakilang ${NAME}", "errorAccessDeniedText": "walang pahintulot", "errorDeviceTimeIncorrectText": "Ang oras ng iyong device ay di tama nang ${HOURS} na oras.\nIto ay malamang na magdulot ng mga iba’t ibang problema.\nPakisuri ang mga setting ng iyong oras at time-zone.", "errorOutOfDiskSpaceText": "Wala sa puwang ng disk", @@ -636,6 +664,8 @@ "errorText": "Error", "errorUnknownText": "error na ‘di malaman", "exitGameText": "Exit mula sa ${APP_NAME}?", + "expiredAgoText": "Tinapos na noong ${T}", + "expiresInText": "Magtatapos sa ${T}", "exportSuccessText": "Na-export ang '${NAME}'.", "externalStorageText": "External na Storage", "failText": "Bigo", @@ -647,85 +677,88 @@ "useThisFolderButtonText": "Gamitin Ang Folder Na Ito" }, "filterText": "Salain", - "finalScoreText": "Huling Marka", - "finalScoresText": "Huling Mga Marka", - "finalTimeText": "Huling Oras", - "finishingInstallText": "Pagtatapos ng pag-install; sandali lang...", + "finalScoreText": "Wakas Na Marka", + "finalScoresText": "Wakas Ng Mga Marka", + "finalTimeText": "Wakas Na Oras", + "finishingInstallText": "Tumatapos ang paglalagay; sandali lang po...", "fireTVRemoteWarningText": "* Para sa isang mas mahusay na karanasan, gamitin\nGame Controllers o i-install ang\n'${REMOTE_APP_NAME}' app sa iyong\nmga telepono at tablet.", - "firstToFinalText": "Una-sa-${COUNT} Wakas", + "firstToFinalText": "Wakas sa Unang Makakuha ng ${COUNT} Puntos", "firstToSeriesText": "Una-sa-${COUNT} Panunuran", "fiveKillText": "LIMANG PAGPATAY!!!", - "flawlessWaveText": "Walang Kapintasan na Kaway!", + "flawlessWaveText": "Hindi Nasaktan!", "fourKillText": "APAT NA PAGPATAY!!!", - "friendScoresUnavailableText": "Hindi available ang marka ng kaibigan", + "friendScoresUnavailableText": "Walang maipakita ang marka ng kaibigan", "gameCenterText": "GameCenter", "gameCircleText": "GameCircle", "gameLeadersText": "Mga Pinuno Ng Pang-${COUNT} na Laro", "gameListWindow": { "cantDeleteDefaultText": "Hindi pwedeng itanggal ang default na playlist.", - "cantEditDefaultText": "Hindi ma-edit ang default playlist! I-duplicate mo o gumawa ng bago.", + "cantEditDefaultText": "Hindi pwede ayusin ang orihinal na playlist! Ipakopya mo o gumawa ng bago.", "cantShareDefaultText": "Hindi pwede ma-share ang default na playlist.", "deleteConfirmText": "Tanggalin ang \"${LIST}\"?", "deleteText": "Tanggalin ang\nPlaylist", - "duplicateText": "I-duplicate ang\nPlaylist", - "editText": "I-edit ang\nPlaylist", + "duplicateText": "Dalawahin ang\nPlaylist", + "editText": "Ayusin ang\nPlaylist", "newText": "Gumawa ng\nPlaylist", + "pointsToWinText": "Puntos Upang Maitupad", + "seriesLengthText": "Haba ng Serye", "showTutorialText": "Ipakita Ang Tutorial", - "shuffleGameOrderText": "I-shuffle Ang Kaayusan Ng Laro", - "titleText": "I-customize Ang ${TYPE} Playlists" + "shuffleGameOrderText": "Paghalu-haluin Ang Kaayusan Ng Laro", + "titleText": "Ayusin Ang Playlist ng ${TYPE}" }, "gameSettingsWindow": { - "addGameText": "Maglagay ng Laro" + "addGameText": "Magdagdag ng Laro" }, - "gamesToText": "${WINCOUNT} na laro sa ${LOSECOUNT}", + "gamesToText": "${WINCOUNT} na laro kontra sa ${LOSECOUNT}", "gatherWindow": { - "aboutDescriptionLocalMultiplayerExtraText": "Tandaan: anumang device sa isang party ay maaaring magkaroon ng higit pa\nkaysa sa isang manlalaro kung mayroon kang sapat na mga controller.", + "aboutDescriptionLocalMultiplayerExtraText": "Tandaan: anumang device sa isang partido ay maaaring magkaroon ng higit pa\nkaysa sa isang manlalaro kung mayroon kang sapat na mga controller.", "aboutDescriptionText": "Gamitin ang mga tab na ito para mag-assemble ng party.\n\nPwede kang maglaro at mag paligsahan kasama ang iyong mga kaibigan sa \niba't ibang device sa pamamagitan ng “Party”.\n\nGamitin ang pindutin na ${PARTY} sa kanang tuktok upang\nmakipag-chat at makipag-ugnayan sa iyong partido.\n(sa isang controller, pindutin ang ${BUTTON} habang nasa isang menu)", "aboutText": "Tungkulin", - "addressFetchErrorText": "", + "addressFetchErrorText": "", "appInviteMessageText": "Pinadalhan ka ni ${NAME} ng ${COUNT} ticket sa ${APP_NAME}", - "appInviteSendACodeText": "Mag-send ka sa Kanila ng Code", - "appInviteTitleText": "${APP_NAME} App Invite", + "appInviteSendACodeText": "Padalhan Ng Kowd", + "appInviteTitleText": "Paanyaya sa ${APP_NAME}", "bluetoothAndroidSupportText": "(gumagana sa anumang Android device na mayroong Bluetooth)", - "bluetoothDescriptionText": "Mag-host/sumali sa isang party sa pamamagitan ng Bluetooth:", - "bluetoothHostText": "Mag-host gamit ang Bluetooth", + "bluetoothDescriptionText": "Maghanda/sumali sa isang partido sa pamamagitan ng Bluetooth:", + "bluetoothHostText": "Maghanda gamit ang Bluetooth", "bluetoothJoinText": "Sumali gamit ang Bluetooth", "bluetoothText": "Bluetooth", - "checkingText": "nag-checking…", - "copyCodeConfirmText": "Nakopya ang code sa clipboard.", - "copyCodeText": "I-kopya ang Code", + "checkingText": "sinusuri...", + "copyCodeConfirmText": "Nakopya na ang kowd sa clipboard.", + "copyCodeText": "Kopyahin ang kowd", "dedicatedServerInfoText": "Para sa pinakamahusay na mga resulta, mag-set up ng nakalaang server. Tingnan ang bombsquadgame.com/server para malaman kung paano.", - "disconnectClientsText": "Ididiskonekta nito ang ${COUNT} (mga) manlalaro\nsa iyong party. Sigurado ka ba?", + "descriptionShortText": "Ipamahala ang panig \"Sumama\" upang magtipun-tipon ng isang partido.", + "disconnectClientsText": "Ididiskonekta nito ang ${COUNT} (mga) manlalaro\nsa iyong partido. Sigurado ka ba?", "earnTicketsForRecommendingAmountText": "Makakatanggap ang mga kaibigan ng ${COUNT} na tiket kung susubukan nila ang laro\n(at makakatanggap ka ng ${YOU_COUNT} para sa bawat gagawa)", - "earnTicketsForRecommendingText": "I-share ang laro\npara makatanggap ng libreng tickets…", + "earnTicketsForRecommendingText": "Ibahagi ang laro\npara makatanggap ng mga libreng tiket…", "emailItText": "I-email", - "favoritesSaveText": "I-save bilang paborito", + "favoritesSaveText": "Ipunin Bilang Paborito", "favoritesText": "Mga Paborito", - "freeCloudServerAvailableMinutesText": "Available ang susunod na libreng cloud server sa loob ng ${MINUTES} (na) minuto.", + "freeCloudServerAvailableMinutesText": "Mayroon ang susunod na libreng cloud server sa loob ng ${MINUTES} (na) minuto.", "freeCloudServerAvailableNowText": "Mayroong libreng cloud server!", - "freeCloudServerNotAvailableText": "Walang available na libreng cloud server.", + "freeCloudServerNotAvailableText": "Walang libreng cloud server sa ngayon.", "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} na mga tiket mula sa ${NAME}", "friendPromoCodeAwardText": "Makakatanggap ka ng ${COUNT} na tiket sa tuwing ito ay gagamitin.", - "friendPromoCodeExpireText": "Mag-e-expire ang code sa loob ng ${EXPIRE_HOURS} na oras at gagana lang para sa mga bagong manlalaro.", - "friendPromoCodeInstructionsText": "Upang gamitin ito, buksan ang ${APP_NAME} at pumunta sa \"Mga Setting->Advanced->Ilagay ang Code\".\nTingnan ang bombsquadgame.com para sa mga link sa pag-download para sa lahat ng sinusuportahang platform.", + "friendPromoCodeExpireText": "Mawawalan-bisa ang kowd sa loob ng ${EXPIRE_HOURS} na oras at gagana lang para sa mga bagong manlalaro.", + "friendPromoCodeInstructionsText": "Upang gamitin ito, buksan ang ${APP_NAME} at pumunta sa \"Mga Setting->Mga Iba Pa->Ilagay ang Impormasyon\".\nTingnan ang bombsquadgame.com para sa mga link sa pag-download para sa lahat ng sinusuportahang platform.", "friendPromoCodeRedeemLongText": "Maaari itong ma-redem ng ${COUNT} na libreng tiket ng hanggang ${MAX_USES} na tao.", "friendPromoCodeRedeemShortText": "Maaari itong ma-redem ng ${COUNT} na tiket sa larong ito.", - "friendPromoCodeWhereToEnterText": "(sa \"Settings->Advanced->Ilagay Ang Code\")", - "getFriendInviteCodeText": "Kumuha ng imbitasyon ng code ng kaibigan", + "friendPromoCodeWhereToEnterText": "(sa \"Settings->Mga Iba Pa->Ilagay Ang Impormasyon\")", + "getFriendInviteCodeText": "Kumuha ng imbitasyon ng kowd ng kaibigan", "googlePlayDescriptionText": "Mag-imbita ng mga manlalaro ng Google Play sa iyong party:", "googlePlayInviteText": "Mag-imbita", "googlePlayReInviteText": "Mayroong ${COUNT} (mga) Google Play na manlalaro sa iyong party \nna madidiskonekta kung magsisimula ka ng bagong imbitasyon.\nIsama sila sa bagong imbitasyon para maibalik mo sila.", "googlePlaySeeInvitesText": "Ipakita Ang Mga Imbitasyon", "googlePlayText": "Google Play", "googlePlayVersionOnlyText": "(Bersyon ng Android / Google Play)", - "hostPublicPartyDescriptionText": "Mag-host ng Pampublikong Party", - "hostingUnavailableText": "Hindi Available Ang Pagho-host", + "hostPublicPartyDescriptionText": "Maghanda ng Pampublikong Party", + "hostingUnavailableText": "Bawal Muna Ang Paghandahin", "inDevelopmentWarningText": "Note:\n\nAng Network Play ay bago at patuloy na umuunlad na feature.\nSa ngayon, Ito'y lubos na inirerekomenda na ang lahat ng \nmga manlalaro ay nasa parehong Wi-Fi network.", "internetText": "Internet", "inviteAFriendText": "Walang laro ang mga kaibigan mo nito? Mag-imbita mo sila \npara sila'y subukan maglaro ito at makakatanggap sila ng ${COUNT} libreng tiket.", "inviteFriendsText": "Mag-imbita ng mga kaibigan", "joinPublicPartyDescriptionText": "Sumali sa isang Pampublikong Party", - "localNetworkDescriptionText": "Sumali sa malapit na party (LAN, Bluetooth, etc.)", + "localNetworkDescriptionText": "Sumali sa Partidong Malapit Sa'yo! (LAN, Bluetooth, atbp.)", "localNetworkText": "Lokal na Network", "makePartyPrivateText": "Gawing Pribado Ang Party Ko", "makePartyPublicText": "Gawing Publiko Ang Party Ko", @@ -742,12 +775,13 @@ "manualYourLocalAddressText": "Iyong lokal na address:", "nearbyText": "Malapit", "noConnectionText": "", + "noPartiesAddedText": "Walang Nadagdag na mga Partido", "otherVersionsText": "", - "partyCodeText": "Code ng Partido", + "partyCodeText": "Kowd ng Partido", "partyInviteAcceptText": "Tanggapin", "partyInviteDeclineText": "Tanggihan", "partyInviteGooglePlayExtraText": "(tingnan ang 'Google Play' tab sa 'Sumama' window)", - "partyInviteIgnoreText": "Ignorahin", + "partyInviteIgnoreText": "Pabayaan", "partyInviteText": "Inimbitahan ka ni ${NAME} \nna sumali sa kanilang party", "partyNameText": "Pangalan Ng Partido", "partyServerRunningText": "Tumatakbo ang iyong party server.", @@ -765,9 +799,9 @@ "privateText": "Pribado", "publicHostRouterConfigText": "Maaaring mangailangan nito ng pag-configure ng port-forwarding sa iyong router. Para sa mas madaling opsyon, mag-host ng pribadong party.", "publicText": "Publiko", - "requestingAPromoCodeText": "Humihiling ng code...", + "requestingAPromoCodeText": "Humihiling ng kowd...", "sendDirectInvitesText": "I-send ng direktang imbitasyon", - "shareThisCodeWithFriendsText": "Ibahagi ang code na ito sa iyong mga kaibigan:", + "shareThisCodeWithFriendsText": "Ibahagi ang kowd nito sa iyong mga kaibigan:", "showMyAddressText": "Ipakita Ang Address Ko", "startHostingPaidText": "Mag-host ngayon ng ${COST}", "startHostingText": "Host", @@ -780,7 +814,7 @@ "wifiDirectText": "Wi-Fi Direct", "worksBetweenAllPlatformsText": "(ito’y gumagana sa pagitan ng lahat ng mga platform)", "worksWithGooglePlayDevicesText": "(ito’y gumagana sa mga devices na tumatakbo ang bersyon ng Google Play (android) ng larong ito)", - "youHaveBeenSentAPromoCodeText": "Pinadalhan ka ng promo code na ${APP_NAME}:" + "youHaveBeenSentAPromoCodeText": "Pinadalhan ka ng promo kowd ng ${APP_NAME}:" }, "getTicketsWindow": { "freeText": "LIBRE!", @@ -798,25 +832,33 @@ "ticketsFromASponsorText": "Manood ng Ad\npara makuha ang ${COUNT} na tiket", "ticketsText": "${COUNT} Tiket", "titleText": "Kumuha Ng Tiket", - "unavailableLinkAccountText": "Pasensya na, hindi available ang pagbili sa platform na ito.\nBilang isang solusyon, maaari mong i-link ang account na ito sa isang account na nasa\nisa pang platform at bumili doon.", - "unavailableTemporarilyText": "Hindi available ito. Subukang muli mamaya.", + "unavailableLinkAccountText": "Pasensya na, bawal ang pagbili sa platform na ito.\nBilang isang solusyon, maaari mong i-link ang account na ito sa isang account na nasa\nisa pang platform at bumili doon.", + "unavailableTemporarilyText": "Bawal muna ito; subukang muli mamaya.", "unavailableText": "Pasensya na, hindi ito available.", - "versionTooOldText": "Pasensya na, ang bersyon ng laro na ito ay masyadong luma; mangyaring mag-update sa isang mas bagong bersyon.", + "versionTooOldText": "Pasensya na, ang bersyon ng laro na ito ay masyadong luma; mangyaring ibaguhin sa isang pang mas mabagong bersyon.", "youHaveShortText": "mayroon kang ${COUNT}", "youHaveText": "mayroon kang ${COUNT} na tiket" }, + "goldPass": { + "desc1InfTokensText": "Walang hanggang Sagisag", + "desc2NoAdsText": "Walang mga ad.", + "desc3ForeverText": "Magpakailanman.", + "goldPassText": "Gintong Pahintulot" + }, "googleMultiplayerDiscontinuedText": "Pasensya na, hindi na available ang multiplayer na serbisyo ng Google.\nGumagawa ako ng kapalit sa lalong madaling panahon.\nHanggang doon, mangyaring sumubok ng ibang paraan ng koneksyon.\n-Eric", - "googlePlayPurchasesNotAvailableText": "Hindi puwede ang mga pagbili sa Google Play nito.\nMaaaring kailanganin mong i-update ang iyong store app.", - "googlePlayServicesNotAvailableText": "Hindi available ang Google Play Services sa ngayon.\n‘Di magagana ang takbo ng ilang mga app.", + "googlePlayPurchasesNotAvailableText": "Hindi puwede ang mga pagbili sa Google Play nito.\nMaaaring kailanganin mong ibaguhin ang iyong store app.", + "googlePlayServicesNotAvailableText": "Hindi pwede ang Google Play Services sa ngayon.\n‘Di magagana ang takbo ng ilang mga app.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Palagi", "fullScreenCmdText": "Fullscreen (Cmd-F)", "fullScreenCtrlText": "Fullscreen (Ctrl-F)", + "fullScreenText": "Fullscreen", "gammaText": "Gama", "highText": "Mataas", "higherText": "Napakataas", "lowText": "Mababa", + "maxFPSText": "Pinakamataas na FPS", "mediumText": "Katamtaman", "neverText": "Wala", "resolutionText": "Resolusyon", @@ -828,9 +870,9 @@ "visualsText": "Biswal" }, "helpWindow": { - "bombInfoText": "- Bomba -\nMas malakas pa sa suntok, pero\nmaaaring magresulta sa matinding pananakit sa sarili.\nPara sa pinakamahusay na mga resulta, itapon patungo\nkalaban bago maubos ang fuse.", + "bombInfoText": "- Bomba -\nMas malakas pa sa suntok, ngunit\nmaaaring magresulta sa matinding pananakit sa sarili.\nPara sa pinakamahusay na mga resulta, ihagis mo patungo sa\nkalaban bago ito'y sumabog.", "bombInfoTextScale": 0.5, - "canHelpText": "Makakatulong ang ${APP_NAME}.", + "canHelpText": "Makakatulong ang ${APP_NAME} para sa iyo.", "controllersInfoText": "Maaari mong laruin ang ${APP_NAME} kasama ng mga kaibigan sa isang network, o ikaw\nlahat ay maaaring maglaro sa parehong device kung mayroon kang sapat na mga controller.\nSinusuportahan ng ${APP_NAME} ang iba't ibang mga ito; maaari ka ring gumamit ng mga telepono\nbilang mga controller sa pamamagitan ng libreng '${REMOTE_APP_NAME}' app.\nTingnan ang Mga Setting->Controller para sa higit pang impormasyon.", "controllersInfoTextRemoteOnly": "Maaari mong laruin ang ${APP_NAME} kasama ng mga kaibigan sa isang network, o ikaw\nlahat ay maaaring maglaro sa parehong device sa pamamagitan ng paggamit ng mga phones bilang\nmga controller sa pamamagitan ng libreng '${REMOTE_APP_NAME}' app.", "controllersText": "Mga Controllers", @@ -842,44 +884,46 @@ "friendsText": "Mga Kaibigan", "jumpInfoText": "-Tumalon-\nTumalon upang tumawid sa maliliit na puwang,\nupang ihagis ang mga bagay na mas mataas, at\nupang ipahayag ang damdamin ng kagalakan.", "jumpInfoTextScale": 0.5, - "orPunchingSomethingText": "O sumuntok ng isang bagay, itinapon ito sa isang bangin, at pinasabog ito habang pababa gamit ang isang malagkit na bomba.", + "orPunchingSomethingText": "O sumuntok ng isang bagay, maghagis sa isang bangin, at pinasabog habang pababa gamit ang isang malagkit na bomba.", "pickUpInfoText": "- Pulutin -\nKunin ang mga flag, mga kaaway, o anumang bagay\nkung hindi ay hindi naka-bold sa lupa.\nPindutin muli upang ihagis.", "pickUpInfoTextScale": 0.5, "powerupBombDescriptionText": "Payagan kang maglabas ng tatlong bomba\nsa isang hilera sa halip na isa lamang.", "powerupBombNameText": "Tatlong-Bomba", "powerupCurseDescriptionText": "Malamang na gusto mong iwasan ang mga ganito.\n ...o sige lang?", "powerupCurseNameText": "Sumpa", - "powerupHealthDescriptionText": "Ibangon ka sa buong kalusugan.\nHindi mo naisip nito.", - "powerupHealthNameText": "Medikal-Pakete", - "powerupIceBombsDescriptionText": "Mas mahina kaysa sa mga normal na bomba\nngunit nagyelo ang iyong mga kalaban\nat partikular na mabasag.", + "powerupHealthDescriptionText": "Ibangon ka sa mapunong kalusugan.\nNaasahan mo naman.", + "powerupHealthNameText": "Pakete-Medikal", + "powerupIceBombsDescriptionText": "Mas mahina kaysa sa mga bombang karaniwan\nngunit nagyelo ang iyong mga kalaban\nat partikular na mabasag sila.", "powerupIceBombsNameText": "Bombang-Yelo", "powerupImpactBombsDescriptionText": "Medyo mahina kaysa sa regular\nbomba, ngunit sumasabog ito kapag nabagsak.", - "powerupImpactBombsNameText": "Gatilyong-Bomba", - "powerupLandMinesDescriptionText": "Ang mga ito ay dumating sa mga pakete ng 3;\nKapaki-pakinabang para sa base defense o\npaghinto ng mabilis na mga kalaban.", + "powerupImpactBombsNameText": "Bombang-Gatilyo", + "powerupLandMinesDescriptionText": "Ito ay naglalaman sa dami ng 3;\nKapaki-pakinabang para sa pagdepensa o\npaghinto ng mga mabibilis na kalaban.", "powerupLandMinesNameText": "Mina", "powerupPunchDescriptionText": "Ang iyong mga suntok ay mas mahirap,\nmas mabilis, mas mahusay, at mas malakas.", - "powerupPunchNameText": "Boxing-Gloves", - "powerupShieldDescriptionText": "Pumigil na pagsakit\nkaya hindi mo kailangan.", + "powerupPunchNameText": "Guwantes", + "powerupShieldDescriptionText": "Pumigil na pagsakit\nPara mas guminhawa.", "powerupShieldNameText": "Enrhiyang-Kalasag", "powerupStickyBombsDescriptionText": "Dumikit sa anumang matamaan nila.\nIto’y naging pagtawanan.", - "powerupStickyBombsNameText": "Malagkit-Bomba", - "powerupsSubtitleText": "Siyempre, walang larong kumpleto pag walang powerups:", + "powerupStickyBombsNameText": "Bombang-Malagkit", + "powerupsSubtitleText": "Siyempre, 'di kumpleto ang laro kapag walang mga powerups:", "powerupsText": "Powerups", "punchInfoText": "- Suntok -\nAng mga suntok ay mas nakakasakit\nmas mabilis ang paggalaw ng iyong mga kamay, kaya\ntumakbo at umiikot na parang baliw.", - "runInfoText": "- Takbo -\nPindutin ang ANY button para tumakbo. Ang mga trigger o mga button sa balikat ay gumagana nang maayos kung mayroon ka ng mga ito.\nAng pagtakbo ay nagpapabilis sa iyo ng mga lugar ngunit nahihirapan kang lumiko, kaya mag-ingat sa mga bangin.", + "punchInfoTextScale": 0.4, + "runInfoText": "- Takbo -\nPindutin ang KAHIT ANUMANG button para tumakbo. Ang mga trigger o mga gilid na button ay gumagana nang maayos kung mayroon ka ng mga ito.\nAng pagtakbo ay nagpapabilis sa iyo ng mga lugar ngunit nahihirapan kang lumiko, kaya mag-ingat sa mga bangin.", "someDaysText": "May mga araw na parang gusto mong sumuntok ng kung ano. O nagpapasabog ng isang bagay.", "titleText": "Tulong ng ${APP_NAME}", - "toGetTheMostText": "Upang masulit ang larong ito, kakailanganin mo:", + "toGetTheMostText": "Upang masulit ang larong ito, kakailanganin mo ng:", "welcomeText": "Maligayang Pagdating sa ${APP_NAME}" }, "holdAnyButtonText": "", "holdAnyKeyText": "", "hostIsNavigatingMenusText": "- Ang ${HOST} ay nagna-navigate sa mga menu tulad ng isang boss -", - "importPlaylistCodeInstructionsText": "Gamitin ang sumusunod na code upang i-import ang playlist na ito sa ibang lugar:", + "importPlaylistCodeInstructionsText": "Gamitin ang sumusunod na kowd upang i-import ang playlist na ito sa ibang lugar:", "importPlaylistSuccessText": "Na-import na ${TYPE} na playlist '${NAME}'", "importText": "I-Import", "importingText": "Nag-Iimport…", "inGameClippedNameText": "Sa in-game ay naging\n\"${NAME}\"", + "inboxText": "Inbaks", "installDiskSpaceErrorText": "ERROR: Hindi makumpleto ang pag-install.\nMaaaring wala ka nang espasyo sa iyong device.\nMag-clear ng ilang espasyo at subukang muli.", "internal": { "arrowsToExitListText": "pindutin ang ${LEFT} o ${RIGHT} upang mawala sa listahan", @@ -890,7 +934,7 @@ "connectedToPartyText": "Sumali sa party ni ${NAME}!", "connectingToPartyText": "Nagdudugtong….", "connectionFailedHostAlreadyInPartyText": "Nabigo ang koneksyon; nasa ibang party ang host.", - "connectionFailedPartyFullText": "Nabigo ang koneksyon; puno na ang party.", + "connectionFailedPartyFullText": "Nabigo ang koneksyon; puno na po.", "connectionFailedText": "Nabigo ang koneksyon.", "connectionFailedVersionMismatchText": "Nabigo ang koneksyon; nagpapatakbo ang host ng ibang bersyon ng laro.\nTiyaking pareho kayong napapanahon at subukang muli sumali.", "connectionRejectedText": "Tinanggihan ang koneksyon.", @@ -907,7 +951,7 @@ "errorPlayingMusicText": "Error sa paglalaro ng musika: ${MUSIC}", "errorResettingAchievementsText": "Hindi ma-reset ang mga online na achievements; Subukang muli mamaya.", "hasMenuControlText": "Si ${NAME} lang ay may kontrol sa menu.", - "incompatibleNewerVersionHostText": "Ang host ay nagpapatakbo ng mas bagong bersyon ng laro.\nMag-update sa pinakabagong bersyon at subukang muli.", + "incompatibleNewerVersionHostText": "Ang punong-abala ay nagpapatakbo ng mas mabagong bersyon ng laro.\nMagbago sa pinakabagong bersyon at subukang muli.", "incompatibleVersionHostText": "Ang host ay nagpapatakbo ng ibang bersyon ng laro.\nTiyaking pareho kayong napapanahong bersyon at subukang muli.", "incompatibleVersionPlayerText": "Ang ${NAME} ay nagpapatakbo ng ibang bersyon ng laro.\nTiyaking pareho kayong napapanahong bersyon at subukang muli.", "invalidAddressErrorText": "Error: di-wastong address.", @@ -917,29 +961,31 @@ "invitationsSentText": "${COUNT} (na) imbitasyon ang napadala.", "joinedPartyInstructionsText": "May sumali sa iyong partido.\nPumunta sa 'Maglaro' para magsimula ng laro.", "keyboardText": "Keyboard", - "kickIdlePlayersKickedText": "na-kicked si ${NAME} dahil sa pagiging idle.", - "kickIdlePlayersWarning1Text": "I-kikick si ${NAME} sa loob ng ${COUNT} (na) segundo kung idle pa rin.", - "kickIdlePlayersWarning2Text": "(maaari mong i-off ito sa Mga Setting -> Advanced)", + "kickIdlePlayersKickedText": "nalayas si ${NAME} dahil hindi gumagalaw.", + "kickIdlePlayersWarning1Text": "Lalayas si ${NAME} sa loob ng ${COUNT} (na) segundo kung hindi pa rin gumagalaw.", + "kickIdlePlayersWarning2Text": "(maaari mong isara ito sa \"Mga Setting\" -> \"Mga Iba Pa\")", "leftGameText": "Umalis ka sa '${NAME}'.", "leftPartyText": "Umalis ka sa party ni ${NAME}.", "noMusicFilesInFolderText": "Walang mga file ng musika ang folder.", "playerJoinedPartyText": "Sumali si ${NAME} sa party mo!", "playerLeftPartyText": "Umalis si ${NAME} sa party mo.", - "rejectingInviteAlreadyInPartyText": "Pagtanggi sa imbitasyon (nasa isang party na).", - "serverRestartingText": "Nagre-restart ang server. Mangyaring sumali muli sa isang saglit…", + "rejectingInviteAlreadyInPartyText": "Natanggi ang imbitasyon (nasa isang party ka na).", + "serverRestartingText": "Umuulit ang server. Mangyaring sumali muli sa isang saglit…", "serverShuttingDownText": "Nagsasara ang server...", - "signInErrorText": "Error sa pag-sign in.", + "signInErrorText": "May problema sa pagpasok sa account.", "signInNoConnectionText": "Hindi makapag-sign in. (walang koneksyon ang Wi-Fi mo?)", "telnetAccessDeniedText": "ERROR: ang user ay hindi nagbigay ng access sa telnet.", "timeOutText": "(time out sa ${TIME} segundo)", "touchScreenJoinWarningText": "Sumali ka gamit ang touchscreen.\nKung ito ay isang pagkakamali, i-tap ang 'Menu->Umalis sa Laro' kasama nito.", "touchScreenText": "TouchScreen", + "unableToCompleteTryAgainText": "Hindi maaaring maitapos ito sa ngayon.\nMaaaring mo ulitin.", "unableToResolveHostText": "Error: hindi malutas ang host.", "unavailableNoConnectionText": "Ito’y kasalukuyang hindi magagamit (walang koneksyon sa internet?)", "vrOrientationResetCardboardText": "Gamitin ito upang i-reset ang oryentasyon ng VR.\nUpang maglaro ng laro kakailanganin mo ng isang panlabas na controller.", "vrOrientationResetText": "Pag-reset ng oryentasyon ng VR.", "willTimeOutText": "(magta-time out kung idle)" }, + "inventoryText": "Imbentaryo", "jumpBoldText": "TALON", "jumpText": "Talon", "keepText": "Panatilihin", @@ -947,22 +993,22 @@ "keyboardChangeInstructionsText": "I-double press space para mapalitan ang mga keyboard.", "keyboardNoOthersAvailableText": "Walang ibang mga keyboard na magagamit.", "keyboardSwitchText": "Nagpapalit ng keyboard sa \"${NAME}\".", - "kickOccurredText": "na-kicked si ${NAME}", - "kickQuestionText": "I-Kick si ${NAME}?", - "kickText": "I-Kick", - "kickVoteCantKickAdminsText": "Hindi ma-kick ang mga admin.", - "kickVoteCantKickSelfText": "Hindi mo ma-kick ng sarili mo.", - "kickVoteFailedNotEnoughVotersText": "Hindi marami ang mga manlalaro para sa isang boto.", - "kickVoteFailedText": "Nabigo ang kick-vote.", - "kickVoteStartedText": "Sinimulan na ang isang kick vote para kay ${NAME}.", - "kickVoteText": "Bumoto sa Pagki-kick", + "kickOccurredText": "Napalayas si ${NAME} dito.", + "kickQuestionText": "Palayasin si ${NAME}?", + "kickText": "Palayasin", + "kickVoteCantKickAdminsText": "Hindi pwedeng palayasin ang Mga Ninuno dito.", + "kickVoteCantKickSelfText": "Hindi mo mailayas ang iyong sarili.", + "kickVoteFailedNotEnoughVotersText": "Konti ang mga naglalaro upang magbutuhan.", + "kickVoteFailedText": "Hindi maipalayas mula sa pagbutuhan.", + "kickVoteStartedText": "Sinimulan ang butuhan upang palayasin dito si ${NAME}.", + "kickVoteText": "Bumoto para Ipalayas", "kickVotingDisabledText": "Naka-disable ang kick voting.", - "kickWithChatText": "I-type ang ${YES} sa chat para sa oo at ${NO} para sa hindi.", - "killsTallyText": "${COUNT} ang pinatay", + "kickWithChatText": "Pindutin ang ${YES} sa iyong puwang salitahan kung oo at ${NO} kung hindi.", + "killsTallyText": "${COUNT} pinatay", "killsText": "Pinatay", "kioskWindow": { "easyText": "Madali", - "epicModeText": "Mode na Epic", + "epicModeText": "Dakilang Paraan", "fullMenuText": "Buong Menu", "hardText": "Mahirap", "mediumText": "Katamtaman", @@ -971,8 +1017,8 @@ }, "languageSetText": "Ang wika ay \"${LANGUAGE}\" sa ngayon.", "lapNumberText": "Ikot ${CURRENT}/${TOTAL}", - "lastGamesText": "(huling ${COUNT} na laro)", - "leaderboardsText": "Mga Leaderboard", + "lastGamesText": "(sa huling ${COUNT} na laro)", + "leaderboardsText": "Ranggo Ng Mga Pasimuno", "league": { "allTimeText": "Lahat Ng Oras", "currentSeasonText": "Kasalukuyang Season (${NUMBER})", @@ -980,14 +1026,17 @@ "leagueRankText": "Ranggo ng Liga", "leagueText": "Liga", "rankInLeagueText": "#${RANK}, ${NAME} ${SUFFIX} na Liga", - "seasonEndedDaysAgoText": "Natapos ang season noing ${NUMBER} na araw.", + "seasonEndedDaysAgoText": "Tumapos na ang season noong ${NUMBER} na araw.", "seasonEndsDaysText": "Matatapos ang season sa ${NUMBER} (na) araw.", - "seasonEndsHoursText": "Matatapos ang season sa ${NUMBER} (na) oras.", + "seasonEndsHoursText": "Matatapos ang season na ito sa ${NUMBER} (na) oras.", "seasonEndsMinutesText": "Matatapos ang season sa ${NUMBER} (na) minuto.", "seasonText": "Ika-${NUMBER} na season", "tournamentLeagueText": "Dapat mong maabot ang liga ng ${NAME} upang makapasok sa paligsahan na ito.", - "trophyCountsResetText": "Ire-reset ang mga bilang ng tropeo sa susunod na season." + "trophyCountsResetText": "Ire-reset ang mga bilang ng tropeo sa susunod na season.", + "upToDateBonusDescriptionText": "Ang mga naglalaro ng mas bagong bersyon ng laro \nna ito ay tatanggap ng ${PERCENT}% na abono rito.", + "upToDateBonusText": "Abono sa Makabago" }, + "learnMoreText": "Alamin", "levelBestScoresText": "Pinakamahusay na mga iskor sa ${LEVEL}", "levelBestTimesText": "Pinakamahusay na lahat sa ${LEVEL}", "levelIsLockedText": "Naka-lock ang ${LEVEL}.", @@ -1004,7 +1053,7 @@ "macControllerSubsystemMFiText": "Made-for-iOS/Mac", "macControllerSubsystemTitleText": "Suporta sa Controller", "mainMenu": { - "creditsText": "Mga Kredito", + "creditsText": "Karangalan", "demoMenuText": "Demo na Menu", "endGameText": "Itigil ang Laro", "endTestText": "Itigil ang Test", @@ -1019,7 +1068,7 @@ "resumeText": "Ipatuloy", "settingsText": "Mga Setting" }, - "makeItSoText": "Gawin itong Kaya", + "makeItSoText": "Gawin mo syang parag ganyan", "mapSelectGetMoreMapsText": "Kumuha ng Higit pang Mapa...", "mapSelectText": "Pumili…", "mapSelectTitleText": "Mapa ng ${GAME}", @@ -1031,6 +1080,8 @@ "modeArcadeText": "Arcade na Mode", "modeClassicText": "Klasikong Mode", "modeDemoText": "Mode na Demo", + "moreSoonText": "Marami pang darating...", + "mostDestroyedPlayerText": "Pinakanapinsalang Manlalaro", "mostValuablePlayerText": "Pinakamalupit sa lahat", "mostViolatedPlayerText": "Pinakanakawawa sa lahat", "mostViolentPlayerText": "Pinakamadugo sa lahat", @@ -1038,31 +1089,36 @@ "multiKillText": "${COUNT}-PAGPATAY!!!", "multiPlayerCountText": "${COUNT} na manlalaro", "mustInviteFriendsText": "Tandaan: dapat kang mag-imbita ng mga kaibigan\nang panel na \"${GATHER}\" o i-attach\nmga controller para maglaro ng multiplayer.", - "nameBetrayedText": "${VICTIM} ay pinagtaksilan ni ${NAME}.", + "nameBetrayedText": "Pinagtaksilan ni ${NAME} si ${VICTIM}", "nameDiedText": "${NAME} ay namatay.", - "nameKilledText": "${VICTIM} ay pinatay ni ${NAME}.", + "nameKilledText": "Pinatay ni ${NAME} si ${VICTIM}", "nameNotEmptyText": "Hindi pwede ang walang pangalan!", - "nameScoresText": "${NAME} Naka-score!", + "nameScoresText": "Nakaiskor si ${NAME}!", "nameSuicideKidFriendlyText": "Hindi sinasadyang namatay si ${NAME}.", "nameSuicideText": "Nagpakamatay si ${NAME}.", "nameText": "Pangalan", "nativeText": "Natural", + "newExclaimText": "Bagong-bago!", "newPersonalBestText": "Bagong personal na pinakamahusay!", "newTestBuildAvailableText": "Available ang isang mas bagong pagsubok na build! (${VERSION} build ${BUILD}).\nKunin ito sa ${ADDRESS}", - "newText": "Bago", + "newText": "Gumawa ng Bago", "newVersionAvailableText": "Available ang isang mas bagong bersyon ng ${APP_NAME}! (${VERSION})", "nextAchievementsText": "Mga Susunod na Nakamit:", - "nextLevelText": "Mga Susunod na Level", + "nextLevelText": "Susunod na Antas", "noAchievementsRemainingText": "- wala", - "noContinuesText": "(hindi i-continue)", + "noContinuesText": "(walang tuluyan)", "noExternalStorageErrorText": "Walang nakitang external na storage sa device na ito", "noGameCircleText": "Error: hindi naka-log in sa GameCircle", + "noMessagesText": "Walang mga message.", + "noPluginsInstalledText": "Hindi Nakabit ang mga Plugin", "noScoresYetText": "Wala pang score.", + "noServersFoundText": "Walang nahanap na servers.", "noThanksText": "Salamat Nalang", "noTournamentsInTestBuildText": "BABALA: Babalewalain ang mga score sa tournament mula sa test build na ito.", "noValidMapsErrorText": "Walang nakitang valid na mapa para sa ganitong uri ng laro.", "notEnoughPlayersRemainingText": "Hindi marami na manlalaro ang natitira; umalis at magsimula ng bagong laro.", "notEnoughPlayersText": "Kailangan mo ng atleast ${COUNT} na manlalaro upang simulan ang larong ito!", + "notEnoughTicketsText": "Kulang ang iyong bilang ng tiket!", "notNowText": "Hindi muna ngayon", "notSignedInErrorText": "Dapat kang mag-sign in para magawa ito.", "notSignedInGooglePlayErrorText": "Dapat kang mag-sign in gamit ang Google Play para magawa ito.", @@ -1070,15 +1126,18 @@ "notUsingAccountText": "Note: hindi pinapansin ang account ng ${SERVICE}.\nPumunta sa 'Account -> Mag-sign in gamit ang ‘${SERVICE}' kung gusto mo itong gamitin.", "nothingIsSelectedErrorText": "Walang napili!", "numberText": "#${NUMBER}", - "offText": "Naka-Off", + "offText": "Nakasara", "okText": "Ok lang", - "onText": "Naka-On", + "onText": "Nakabuksan", "oneMomentText": "Saglit lang…", - "onslaughtRespawnText": "Ang ${PLAYER} ay respawn sa wave na ${WAVE}", + "onslaughtRespawnText": "Ang ${PLAYER} ay respawn sa ika-${WAVE} na yugto", + "openMeText": "Buksan Mo 'Ko!", + "openNowText": "Ibuksan Ngayon", + "openText": "Ibuksan", "orText": "${A} o ${B}", "otherText": "Iba Pa…", "outOfText": "(#${RANK} sa ${ALL})", - "ownFlagAtYourBaseWarning": "Ang iyong sariling watawat ay dapat na\nsa iyong base upang makapuntos!", + "ownFlagAtYourBaseWarning": "Ang iyong sariling watawat ay dapat na\nsa lagayan nito upang makapuntos!", "packageModsEnabledErrorText": "Ang network-play ay hindi pinapayagan habang ang local-package-mods ay pinagana (tingnan ang Mga Setting->Advanced)", "partyWindow": { "chatMessageText": "Mensahe", @@ -1088,14 +1147,14 @@ "titleText": "Iyong Party" }, "pausedByHostText": "(naka-pause ng host)", - "perfectWaveText": "Perpekto na Kaway!", + "perfectWaveText": "Perpekto!", "pickUpText": "Pulutin", "playModes": { "coopText": "Kooperatiba", "freeForAllText": "Awayang Rambulan", "multiTeamText": "Maraming Team", "singlePlayerCoopText": "Nag-iisa / Kooperatiba", - "teamsText": "Mga Teams" + "teamsText": "Kampihan" }, "playText": "Maglaro", "playWindow": { @@ -1104,48 +1163,52 @@ "twoToEightPlayersText": "2-8 na manlalaro" }, "playerCountAbbreviatedText": "${COUNT}p", - "playerDelayedJoinText": "Papasok si ${PLAYER} sa simula ng susunod na round.", + "playerDelayedJoinText": "Papasok si ${PLAYER} sa simula ng susunod na laro.", "playerInfoText": "Impormasyon ng Manlalaro", "playerLeftText": "Umalis si ${PLAYER} sa laro.", - "playerLimitReachedText": "Naabot na ang limitasyon ng manlalaro na ${COUNT}; hindi pinapayagan ang mga ibang sumali.", + "playerLimitReachedText": "Naabot na ang limitasyon ng manlalaro na ${COUNT}; hindi pinapayagan ang mga ibang manlalaro sumali.", "playerProfilesWindow": { - "cantDeleteAccountProfileText": "Hindi mo matatanggal ang profile ng iyong account.", + "cantDeleteAccountProfileText": "Hindi mo matatanggal ang karakter ng iyong account.", "deleteButtonText": "Itangal ang\nProfile", "deleteConfirmText": "Itangal si ‘${PROFILE}’?", - "editButtonText": "I-edit ang\nProfile", + "editButtonText": "Ayusin ang\nProfile", "explanationText": "(mga pangalan at hitsura ng custom na manlalaro para sa account na ito)", "newButtonText": "Gumawa ng\nProfile", - "titleText": "Profile ng Manlalaro" + "titleText": "Karakter ng Manlalaro" }, "playerText": "Manlalaro", - "playlistNoValidGamesErrorText": "Ang playlist na ito ay hindi naglalaman ng mga wastong naka-unlock na laro.", + "playlistNoValidGamesErrorText": "Ang playlist na ito ay hindi naglalaman ng mga wastong 'di maibukas na laro.", "playlistNotFoundText": "hindi nahanap ang playlist", "playlistText": "Playlist", "playlistsText": "Mga Playlist", - "pleaseRateText": "Kung nae-enjoy mo ang ${APP_NAME}, mangyaring isaalang-alang ang \npagkuha na sandali lang at i-rate ito o pagsulat ng isang pagsusuri. Nagbibigay ito ngkapaki-pakinabang na feedback at \ntumutulong sa pagsuporta sa pag-unlad sa hinaharap.\n\nsalamat!\n-eric", + "pleaseRateText": "Kung nasasaya ka sa larong ${APP_NAME} na ito, mangyaring isaalang-alang\numisip sa isang sandali at i-grado ito o sumulat ng isang pagsusuri. Nagbibigay ito ng kapaki-pakinabang na puna at\ntumutulong ito sa pagsuporta sa aming pag-uunlad sa hinaharap.\n\nsalamat po!\n-eric", "pleaseWaitText": "Hintay lang…", "pluginClassLoadErrorText": "Error sa paglo-load ang '${PLUGIN}' na klaseng plugin : ${ERROR}", "pluginInitErrorText": "Error sa pagsisimula ang '${PLUGIN}' na plugin: ${ERROR}", + "pluginSettingsText": "Settings ng mga Plugin", + "pluginsAutoEnableNewText": "Paganahin ang Bagong Plugins", "pluginsDetectedText": "May nakitang bagong (mga) plugin. I-restart para i-activate ang mga ito, o i-configure ang mga ito sa mga setting.", + "pluginsDisableAllText": "Salantahin ang mga Plugin", + "pluginsEnableAllText": "Paganahin Lahat ng mga Plugin", "pluginsRemovedText": "Hindi na nahanapan ang ${NUM} ng (mga) plugin.", "pluginsText": "Mga Plugin", - "practiceText": "Pagsasagawa", + "practiceText": "Sanayan", "pressAnyButtonPlayAgainText": "Pindutin ang anumang button para maglaro muli...", "pressAnyButtonText": "Pindutin ang anumang button para magpatuloy...", "pressAnyButtonToJoinText": "pindutin ang anumang button para sumali...", "pressAnyKeyButtonPlayAgainText": "Pindutin ang anumang key/button para maglaro muli...", "pressAnyKeyButtonText": "Pindutin ang anumang key/button para magpatuloy...", "pressAnyKeyText": "Pindutin ang anumang key…", - "pressJumpToFlyText": "** Pindutin ang tumalon nang paulit-ulit upang lumipad **", + "pressJumpToFlyText": "** Pindutin ang pindutang \"tumalon\" nang paulit-ulit upang lumipad **", "pressPunchToJoinText": "Pindutin ang SUNTOK para sumali...", - "pressToOverrideCharacterText": "pindutin ang ${BUTTONS} upang i-override ang iyong karakter", + "pressToOverrideCharacterText": "pindutin ang ${BUTTONS} upang mapalitan ang iyong itsura ng karakter", "pressToSelectProfileText": "pindutin ang ${BUTTONS} upang pumili ng manlalaro", "pressToSelectTeamText": "pindutin ang ${BUTTONS} para pumili ng team", "promoCodeWindow": { - "codeText": "Code", + "codeText": "Kowd", "enterText": "I-enter" }, - "promoSubmitErrorText": "Error sa pagsusumite ng code; suriin ang iyong koneksyon ng internet", + "promoSubmitErrorText": "Error sa pagsusumite ng kowd; suriin ang iyong koneksyon sa internet", "ps3ControllersWindow": { "macInstructionsText": "I-off ang power sa likod ng iyong PS3, siguraduhin\nNaka-enable ang Bluetooth sa iyong Mac, pagkatapos ay ikonekta ang iyong controller\nsa iyong Mac sa pamamagitan ng USB cable upang ipares ang dalawa. Mula noon, ikaw\nmaaaring gamitin ang home button ng controller para ikonekta ito sa iyong Mac\nsa alinman sa wired (USB) o wireless (Bluetooth) mode.\n\nSa ilang mga Mac maaari kang ma-prompt para sa isang passcode kapag nagpapares.\nKung mangyari ito, tingnan ang sumusunod na tutorial o google para sa tulong.\n\n\n\n\nDapat lumabas sa device ang mga PS3 controller na nakakonekta nang wireless\nlistahan sa System Preferences->Bluetooth. Maaaring kailanganin mong alisin ang mga ito\nmula sa listahang iyon kapag gusto mong gamitin muli ang mga ito sa iyong PS3.\n\nTiyakin din na idiskonekta ang mga ito sa Bluetooth kapag hindi naka-in\ngamitin o ang kanilang mga baterya ay patuloy na mauubos.\n\nDapat hawakan ng Bluetooth ang hanggang 7 konektadong device,\nkahit na ang iyong mileage ay maaaring mag-iba.", "ouyaInstructionsText": "Para gumamit ng PS3 controller sa iyong OUYA, ikonekta lang ito gamit ang USB cable\nisang beses upang ipares ito. Ang paggawa nito ay maaaring madiskonekta ang iyong iba pang mga controller, kaya\ndapat mong i-restart ang iyong OUYA at i-unplug ang USB cable.\n\nMula noon, magagamit mo na ang HOME button ng controller para\nikonekta ito nang wireless. Kapag tapos ka nang maglaro, pindutin nang matagal ang HOME button\npara sa 10 segundo upang i-off ang controller; kung hindi, maaari itong manatili sa\nat mga basurang baterya.", @@ -1154,8 +1217,10 @@ }, "punchBoldText": "SUNTOK", "punchText": "Suntok", - "purchaseForText": "Ibili para sa ${PRICE}", + "purchaseForText": "Ipagbili ng ${PRICE}", "purchaseGameText": "Ibili ang laro", + "purchaseNeverAvailableText": "Pasensya na, ang pagbibili rito ay ipinagbawal sa pangangatawan na ito.\nSubukang pumasok sa iyong account sa ibang plataporma at bumili doon", + "purchaseNotAvailableText": "Hindi mo maaaring bumili ito.", "purchasingText": "Nagbabayad...", "quitGameText": "Ihinto ang ${APP_NAME}?", "quittingIn5SecondsText": "Humihinto sa loob ng 5 segundo...", @@ -1163,7 +1228,7 @@ "randomText": "Random", "rankText": "Ranggo", "ratingText": "Marka", - "reachWave2Text": "Abutin ang kaway 2 para ma-ranggo.", + "reachWave2Text": "Abutin ang ika-2 yugto para ma-ranggo.", "readyText": "nakahanda", "recentText": "Makabago", "remoteAppInfoShortText": "Ang ${APP_NAME} ay pinakanakakatuwa kapag nilalaro kasama ng pamilya at mga kaibigan.\nIkonekta ang isa o higit pang mga controller ng hardware o i-install ang\n${REMOTE_APP_NAME} app sa mga phone o tablet upang magamit ang mga ito\nbilang mga controllers.", @@ -1174,8 +1239,8 @@ "button_size": "Laki ng Pindutan", "cant_resolve_host": "Hindi malutas ang host.", "capturing": "Kumukuha…", - "connected": "Konektdo.", - "description": "Gamitin ang iyong mga phone o tablet bilang controller sa BombSquad.\nHanggang 8 device ang maaaring kumonekta nang sabay-sabay para sa epic na lokal na multiplayer na kabaliwan sa isang TV o tablet", + "connected": "Nakakonek.", + "description": "Gamitin ang iyong mga phone o tablet bilang controller sa BombSquad.\nHanggang 8 device ang maaaring kumonekta nang sabay-sabay para sa maringal na lokal na multiplayer na kabaliwan sa isang TV o tablet", "disconnected": "Nadiskonekta ng server.", "dpad_fixed": "nakapirmi", "dpad_floating": "lumulutang", @@ -1183,12 +1248,12 @@ "dpad_size": "Laki ng D-Pad", "dpad_type": "Uri ng D-Pad", "enter_an_address": "Maglagay ng Address", - "game_full": "Ang laro ay puno na o hindi tumatanggap ng mga koneksyon.", + "game_full": "Ang laro ay alinman puno na o hindi tumatanggap ng mga koneksyon.", "game_shut_down": "Nagsara ang laro.", "hardware_buttons": "Mga Pindutan ng Hardware", "join_by_address": "Sumali sa pamamagitan ng Address...", "lag": "Lag: ${SECONDS} na segundo", - "reset": "I-reset sa default", + "reset": "Ibalik sa Orihinal", "run1": "Takbo 1", "run2": "Takbo 2", "searching": "Naghahanap ng mga laro sa BombSquad...", @@ -1197,114 +1262,131 @@ "version_mismatch": "Hindi tugma ang bersyon.\nTiyaking BombSquad at BombSquad Remote\nay ang mga pinakabagong bersyon at subukang muli." }, "removeInGameAdsText": "I-unlock ang \"${PRO}\" sa tindahan upang alisin ang mga in-game na ad.", + "removeInGameAdsTokenPurchaseText": "TAKDANG PAGHAHANDOG:Bumili ng KAHIT ANONG paketeng sagisag para mawala ang mga in-game ads.", "renameText": "I-palitan", "replayEndText": "Itigil Ang Replay", "replayNameDefaultText": "Replay ng Huling Laro", - "replayReadErrorText": "Error sa pagbabasa ng replay file.", + "replayReadErrorText": "May kamalian sa pagbabasa ng replay file.", "replayRenameWarningText": "Palitan ang pangalan ng \"${REPLAY}\" pagkatapos ng isang laro kung gusto mong panatilihin ito; kung hindi, ito ay mapapatungan.", "replayVersionErrorText": "Pasensya na, ginawa ang replay na ito sa ibang paraang\nbersyon ng laro at hindi magagamit.", "replayWatchText": "Panoorin ang replay", - "replayWriteErrorText": "Error sa pagsulat ng replay file.", + "replayWriteErrorText": "May kamalian sa pagsulat ng replay file.", "replaysText": "Mga Replay", "reportPlayerExplanationText": "Gamitin ang email na ito upang mag-ulat ng pagdaya, hindi naaangkop na pananalita, o iba pang masamang gawin.\nPakilarawan sa ibaba:", - "reportThisPlayerCheatingText": "Pagdaya", + "reportThisPlayerCheatingText": "Dumadaya", "reportThisPlayerLanguageText": "Hindi Angkop na Salita", - "reportThisPlayerReasonText": "Ano ang gusto mong iulat?", - "reportThisPlayerText": "Iulat ang Manlalaro na Ito", - "requestingText": "Humihiling", - "restartText": "I-restart", - "retryText": "I-retry", + "reportThisPlayerReasonText": "Anong dahilan upang sumumbong?", + "reportThisPlayerText": "Isumbong ang Manlalaro na Ito", + "requestingText": "Humihiling...", + "restartText": "Umulit", + "retryText": "Ulitin", "revertText": "Ibalik", - "runText": "Takbo", - "saveText": "I-save", - "scanScriptsErrorText": "(Mga) error sa pag-scan ng mga script; tingnan ang log para sa mga detalye.", - "scoreChallengesText": "Mga Hamon sa Iskor", - "scoreListUnavailableText": "Hindi available ang listahan ng iskor", + "runText": "Tumakbo", + "saveText": "Panatilihin", + "scanScriptsErrorText": "(Mga) kamalian sa pag-scan ng mga script; Tignan ang log para sa mga detalye.", + "scanScriptsMultipleModulesNeedUpdatesText": "Kailangan maibago para sa API ${API} ang ${PATH} at mga ${NUM} na iba pang modules.", + "scanScriptsSingleModuleNeedsUpdatesText": "Kailangan maibago para sa api ${API} ang ${PATH}.", + "scoreChallengesText": "Mga Hamon Para sa Iskor", + "scoreListUnavailableText": "Hindi maipakita ang listahan ng iskor", "scoreText": "Iskor", "scoreUnits": { "millisecondsText": "Milisegundo", "pointsText": "Puntos", "secondsText": "Segundo" }, - "scoreWasText": "(ay nasa ${COUNT})", - "selectText": "Piliin", + "scoreWasText": "(nagmula sa ${COUNT})", + "selectText": "Pilihin", + "sendInfoDescriptionText": "Napapadala ang iyong account at impormasyon sa lagay ng app sa mga gumagawa ng larong ito.\nPakiusap na ilagay ang iyong pangalan o ang dahilan ng pagpapadala nito.", "seriesWinLine1PlayerText": "ANG NANALO SA", "seriesWinLine1TeamText": "ANG NANALO SA", "seriesWinLine1Text": "ANG NANALO SA", - "seriesWinLine2Text": "SERYE!", + "seriesWinLine2Text": "SERYE NITO!", "settingsWindow": { "accountText": "Account", - "advancedText": "Advanced", - "audioText": "Audio", + "advancedText": "Mga Iba Pa", + "audioText": "Tugtugan", "controllersText": "Mga Controller", "graphicsText": "Grapika", - "playerProfilesMovedText": "Tandaan: Ang mga Profile ng Manlalaro ay inilipat sa Account window sa pangunahing menu.", + "playerProfilesMovedText": "Paunawa: Ang mga Karakter ng Manlalaro ay inilipat na sa salaan ng mga account sa pangunahing menu.", "titleText": "Mga Setting" }, "settingsWindowAdvanced": { - "alwaysUseInternalKeyboardDescriptionText": "(isang simpleng, controller-friendly na on-screen na keyboard para sa pag-edit ng teksto)", - "alwaysUseInternalKeyboardText": "Laging Gumamit ng Panloob na Keyboard", - "benchmarksText": "Mga Benchmark at Stress-Test", - "disableCameraGyroscopeMotionText": "I-disable ang Camera Gyroscope Motion", - "disableCameraShakeText": "Huwag paganahin ang Camera Shake", - "disableThisNotice": "(maaari mong i-disable ang notice na ito sa mga advanced na setting)", + "alwaysUseInternalKeyboardDescriptionText": "(isang simpleng keyboard na nasa loob lamang ng larong ito para sa pagasasaayos ng teksto)", + "alwaysUseInternalKeyboardText": "Laging gumamit ang keyboard na panloob", + "benchmarksText": "Mga Benchmark at Pagsusuri sa Pagdiin", + "devToolsText": "Kagamitan sa Paggawa", + "disableCameraGyroscopeMotionText": "Itigil ang mosyong dyayroskop ng larawan", + "disableCameraShakeText": "Huwag paganahin ang alog ng larawan", + "disableThisNotice": "(maaari mong ipatigil ang paunawa na ito sa setting \"Mga Iba Pa\")", "enablePackageModsDescriptionText": "(nagpapagana ng mga karagdagang kakayahan sa pag-modding ngunit hindi pinapagana ang net-play)", "enablePackageModsText": "Paganahin ang Lokal na Package Mods", - "enterPromoCodeText": "Ilagay ang Code", - "forTestingText": "Tandaan: ang mga value na ito ay para lamang sa pagsubok at mawawala kapag lumabas ang app.", - "helpTranslateText": "Ang mga pagsasalin na hindi Ingles ng ${APP_NAME} ay isang komunidad\nsuportadong pagsisikap. Kung gusto mong mag-ambag o magtama\nisang pagsasalin, sundan ang link sa ibaba. Salamat!", - "kickIdlePlayersText": "I-kick Ang Mga Idle na Manlalaro", - "kidFriendlyModeText": "Kid-Friendly Mode (binawasan ang karahasan, atbp)", + "enterPromoCodeText": "Ilagay ang Kowd", + "forTestingText": "Tandaan: ang mga value na ito ay para lamang sa pagsusuri at mawawala ito kapag umalis ka sa larong ito.", + "helpTranslateText": "Ang mga pagsasalin na bukod sa Ingles ng ${APP_NAME} ay isang pagsisikap na \nsuporta ng komunidad dito sa larong ito. Kung gusto mong mag-ambag o magtama \nng isa o higit pang pagsasalin, sundan ang link sa ibaba. Salamat po muli!", + "insecureConnectionsDescriptionText": "Hindi ito irerekomenda, ngunit pwede maglaro nang online \nmula sa ibang bansa o network na limitado.", + "insecureConnectionsText": "Gumamit ng koneksyong walang seguridad", + "kickIdlePlayersText": "Ipalayas ang mga manlalarong hindi gumagalaw", + "kidFriendlyModeText": "Pamamaraang Pambata (walang tinding karahasan, atbp)", "languageText": "Wika", - "moddingGuideText": "Gabay sa Modding", - "mustRestartText": "Dapat mong i-restart ang laro para magka-epekto ito.", + "moddingGuideText": "Gabay sa Pagbabago (Mod)", + "moddingToolsText": "Kagamitan sa Pag-mod", + "mustRestartText": "Ulitin mo ang larong ito upang gumana ang kalalabasan nito.", "netTestingText": "Pagsusuri ng Network", - "resetText": "I-reset", - "showBombTrajectoriesText": "Ipakita ang Mga Trajectory ng Bomba", - "showPlayerNamesText": "Ipakita ang Mga Pangalan ng Manlalaro", - "showUserModsText": "Ipakita ang Mods Folder", + "resetText": "Ulitin", + "sendInfoText": "Ipadala ang Impormasyon", + "showBombTrajectoriesText": "Ipakita Kung Saan Lalapag ang Bomba", + "showDemosWhenIdleText": "Ipakita ang demo habang nakatigil", + "showDeprecatedLoginTypesText": "Ipakita ang mga natakwil na uri ng pagpasok sa account", + "showDevConsoleButtonText": "Ipakita ang pindutan ng dev console", + "showInGamePingText": "Ipakita ang leytensi habang naglalaro", + "showPlayerNamesText": "Ipakita ang Pangalan ng Mga Manlalaro", + "showUserModsText": "Ipakita ang Paniklop ng Mga Mod", "titleText": "Advanced", - "translationEditorButtonText": "Editor ng Wika ng ${APP_NAME}.", - "translationFetchErrorText": "hindi available ang katayuan ng wika", - "translationFetchingStatusText": "sinusuri ang status ng lengguwahe…", - "translationInformMe": "Ipaalam sa akin kapag ang aking wika ay nangangailangan ng mga update", - "translationNoUpdateNeededText": "ang kasalukuyang wika ay makabago; woohoo!", - "translationUpdateNeededText": "** ang kasalukuyang wika ay nangangailangan ng mga update!! **", + "translationEditorButtonText": "Pag-ayusan ng Wika sa ${APP_NAME}.", + "translationFetchErrorText": "Hindi maipakita ang kalagayan ng wikang ito.", + "translationFetchingStatusText": "sinusuri ang kalagayan ng lengguwahe…", + "translationInformMe": "Ipaalam sa akin kapag ang aking wika ay nangangailangan ng pagbabago", + "translationNoUpdateNeededText": "Ang kasalukuyang wika ay makabago na muli; yehey!", + "translationUpdateNeededText": "** Ang kasalukuyang wika ay nangangailangan ng pagbabago!! **", "vrTestingText": "Testing ng VR" }, "shareText": "I-share", "sharingText": "Nagbabahagi….", "showText": "Ipakita", - "signInForPromoCodeText": "Dapat kang mag-sign in sa isang account para magkabisa ang mga code.", + "signInForPromoCodeText": "Dapat kang mag-sign in sa isang account para magkabisa ang mga kowd.", "signInWithGameCenterText": "Para gumamit ng Game Center account,\nmag-sign in gamit ang Game Center app.", "singleGamePlaylistNameText": "${GAME} lang", "singlePlayerCountText": "1 manlalaro", - "soloNameFilterText": "Solo na ${NAME}", + "sizeLargeText": "Malaki", + "sizeMediumText": "Sakto lang", + "sizeSmallText": "Maliit", + "soloNameFilterText": "Pinag-iisang ${NAME}", "soundtrackTypeNames": { "CharSelect": "Pagpili ng Karakter", - "Chosen One": "Napili ng Isa", - "Epic": "Larong Epic na Mode", - "Epic Race": "Epic na Takbuan", - "FlagCatcher": "Kunin ang Bandila", - "Flying": "Masayang Isip", + "Chosen One": "Ang Piniling Isa", + "Epic": "Larong Madakila", + "Epic Race": "Dakilang Takbuhan", + "FlagCatcher": "Agawang Bandila", + "Flying": "Isipang Masaya", "Football": "Rugbi", - "ForwardMarch": "Pag-atake", + "ForwardMarch": "Dadaluhungin", "GrandRomp": "Pagsakop", - "Hockey": "Hockey", - "Keep Away": "Layuan Mo", + "Hockey": "Haki", + "Keep Away": "Hawakang Bandila", "Marching": "Bantayan", "Menu": "Pangunahing Menu", "Onslaught": "Pagsalakay", - "Race": "Takbuan", + "Race": "Takbuhan", "Scary": "Hari Ng Burol", - "Scores": "Screen Ng Iskor", - "Survival": "Kaligtasan", + "Scores": "Salaan Ng Iskor", + "Survival": "Pagbabawasan", "ToTheDeath": "Laban Ng Kamatayan", - "Victory": "Final Na Screen Ng Iskor" + "Victory": "Wakas Na Salaan Ng Iskor" }, "spaceKeyText": "space", "statsText": "Katayuan", - "storagePermissionAccessText": "Nangangailangan ito ng access sa storage", + "stopRemindingMeText": "Itigil ang paalala", + "storagePermissionAccessText": "Nangangailangan ito ng pagpasok sa storage", "store": { "alreadyOwnText": "Nabili mo na ang ${NAME}!", "bombSquadProNameText": "${APP_NAME} Pro", @@ -1314,21 +1396,21 @@ "comingSoonText": "Abangan...", "extrasText": "Padagdag", "freeBombSquadProText": "Ang BombSquad ay libre na ngayon, ngunit dahil ikaw ang orihinal na bumili nito, ikaw na\npagtanggap ng BombSquad Pro upgrade at ${COUNT} na mga tiket bilang pasasalamat.\nTangkilikin ang mga bagong feature, at salamat sa iyong suporta!\n-Eric", - "holidaySpecialText": "Espesyal Na Holiday", - "howToSwitchCharactersText": "(pumunta sa \"${SETTINGS} -> ${PLAYER_PROFILES}\" para magtalaga at mag-customize ng mga character)", - "howToUseIconsText": "(gumawa ng mga global profile ng manlalaro (sa window ng account) para magamit ang mga ito)", + "holidaySpecialText": "Espesyal Ng Holiday", + "howToSwitchCharactersText": "(pumunta sa \"${SETTINGS} -> ${PLAYER_PROFILES}\" para magtalaga at maiba ng mga karakter)", + "howToUseIconsText": "(gumawa ng karakter ng mga manlalaro (sa salaan ng mga account) para magamit ang mga ito)", "howToUseMapsText": "(gamitin ang mga mapa na ito sa sarili mong Mga Team/Rambulan na mga playlist)", - "iconsText": "Mga Icon", + "iconsText": "Mga Tatak", "loadErrorText": "Hindi ma-load ang page.\nSuriin ang iyong koneksyon sa internet.", "loadingText": "Saglit lang…", "mapsText": "Mga Mapa", - "miniGamesText": "Mga MiniGames", - "oneTimeOnlyText": "(isang beses lamang)", + "miniGamesText": "Mga Lalaruhin", + "oneTimeOnlyText": "(isang beses lang)", "purchaseAlreadyInProgressText": "Ang isang nabilhin ng item na ito ay isinasagawa na.", - "purchaseConfirmText": "Ibili ang ${ITEM}?", + "purchaseConfirmText": "Bilhin ang ${ITEM} na ito?", "purchaseNotValidError": "Hindi wasto ang nabilhin.\nMakipag-ugnayan kay ${EMAIL} kung ito ay isang error.", "purchaseText": "Bilhin", - "saleBundleText": "Diskwento ng Bundle!", + "saleBundleText": "Diskwento ng Balutan!", "saleExclaimText": "Diskwento!", "salePercentText": "(${PERCENT}% diskwento)", "saleText": "BAWAS", @@ -1346,49 +1428,66 @@ "customize2Text": "I-customize ang mga character, mini-game, at maging ang mga soundtrack.", "customizeText": "I-customize ang mga character at gumawa ng sarili mong mga mini-game playlist.", "sportsMoreFunText": "Mas masaya ang sports na may pampasabog.", - "teamUpAgainstComputerText": "Makipagtulungan laban sa computer." + "teamUpAgainstComputerText": "Makipagtulungan laban sa kumukusa." }, "storeText": "Tindahan", "submitText": "Ipasa", - "submittingPromoCodeText": "Nagsusumite ng Code...", - "teamNamesColorText": "Mga Pangalan/Kulay ng Team…", + "submittingPromoCodeText": "Pinapasa ang Kowd...", + "successText": "Matagumpay!", + "supportEmailText": "Pag may problema sa app, \npaki-email ang ${EMAIL}.", + "teamNamesColorText": "Mga Pangalan/Kulay ng Kampihan…", "telnetAccessGrantedText": "Pinagana ang pag-access sa Telnet..", "telnetAccessText": "Natuklasan ang pag-access sa Telnet; payagan?", "testBuildErrorText": "Ang test build na ito ay hindi na aktibo; mangyaring suriin para sa isang bagong bersyon.", "testBuildText": "Test Build", - "testBuildValidateErrorText": "Hindi ma-validate ang test build. (walang koneksyon sa internet?)", - "testBuildValidatedText": "Na-validate ang Test Build; Tamasahin!", - "thankYouText": "Salamat sa iyong suporta! Tangkilikin ang laro!!", + "testBuildValidateErrorText": "Hindi nawasto ang test build. (walang koneksyon sa internet?)", + "testBuildValidatedText": "Napawasto ang Test Build; Tamasahin!", + "thankYouText": "Salamat po sa iyong pagsuporta! Tangkilikin ang laro na ito!!", "threeKillText": "TRIPLENG PAGPATAY!!", - "timeBonusText": "Bonus Ng Oras", + "ticketsDescriptionText": "Ang tiket ay magagamit upang magamit ang mga karakter, \nmapa, lalaruhin, at iba pa sa tindahan.\n\nAng tiket ay maaaring mahanap sa mga baul mula sa pagtagumpay \nsa kampanya, paligsahan, at mga makamtan.", + "timeBonusText": "Sigla sa Oras", "timeElapsedText": "Oras Na Lumipas", - "timeExpiredText": "Nag-expire Na Ang Oras!", + "timeExpiredText": "Lagpas Na!", "timeSuffixDaysText": "${COUNT}d", "timeSuffixHoursText": "${COUNT}h", "timeSuffixMinutesText": "${COUNT}m", "timeSuffixSecondsText": "${COUNT}s", - "tipText": "Tip", + "tipText": "Isang Payo", "titleText": "BombSquad", "titleVRText": "BombSquad VR", - "topFriendsText": "Pangunahing Kaibigan", + "tokens": { + "getTokensText": "Bumili Ng Mga Sagisag", + "notEnoughTokensText": "Hindi sapat ang iyong mga sagisag para rito!", + "numTokensText": "${COUNT} Mga Sagisag", + "openNowDescriptionText": "May sapat kang token para \nmabuksan mo na ito ngayon – \nhindi mo na kailangang maghintay.", + "shinyNewCurrencyText": "Isang makintab na bagong pera ng BombSquad.", + "tokenPack1Text": "Maliit-Paketeng Sagisag", + "tokenPack2Text": "Katamtamang Paketeng Sagisag", + "tokenPack3Text": "Malaking Paketeng Sagisag", + "tokenPack4Text": "Pinakamalaking Paketeng Sagisag", + "tokensDescriptionText": "Ang Sagisag ay ginagamit upang bumilis ang pagbuksan ng \nmga baul at para sa ibang katangiang ng account at larong ito.\n\nMaaari kang manalo ng mga sagisag \nsa mga laruhin o bumili ang mga pakete nito. \nO kaya bumili ng \"Gintong Pahintulot\" upang mawalang-hanggan", + "youHaveGoldPassText": "Mayroon ka nang Gintong Pahintulot.\nLahat ng mga pagbili ng mga Sagisag ay libre na.\nIkasaya mo na!" + }, + "topFriendsText": "Pinakamataas sa mga Kaibigan", "tournamentCheckingStateText": "Sinusuri ang estado ng paligsahan; pakihintay...", "tournamentEndedText": "Natapos na ang paligsahan na ito. Magsisimula ng bago mamaya.", "tournamentEntryText": "Pagpasok sa Paligsahan", + "tournamentFinalStandingsText": "Pinaka-tapos na Standing", "tournamentResultsRecentText": "Mga Resulta ng Kamakailang Paligsahan", - "tournamentStandingsText": "Mga Paninindigan sa Paligsahan", + "tournamentStandingsText": "Mga Puwesto sa Paligsahan", "tournamentText": "Paligsahan", - "tournamentTimeExpiredText": "Na-expire Na Ang Oras Ng Paligsahan", - "tournamentsDisabledWorkspaceText": "Naka-disable ang mga paligsahan kapag aktibo ang mga workspace. \nHuwag munang paganahin muli ang iyong workspace at i-restart upang makipaglaro sa paligsahan.", + "tournamentTimeExpiredText": "Natapos Na Ang Oras Ng Paligsahan Na Ito", + "tournamentsDisabledWorkspaceText": "Hindi ka pwede maglaro ng mga paligsahan kapag aktibo ang mga workspace. \nIsara muna ang iyong workspace at ulitin ang larong ito upang makipaglaro sa paligsahan.", "tournamentsText": "Mga Paligsahan", "translations": { "characterNames": { "Agent Johnson": "Ahente Johnson", - "B-9000": "B-9000", + "B-9000": "Makina-9000", "Bernard": "Oso", - "Bones": "Buto", + "Bones": "Kalansay", "Butch": "Bakero", "Easter Bunny": "Kuneho", - "Flopsy": "Malambot", + "Flopsy": "Magalaw", "Frosty": "Taong Niyebe", "Gretel": "Mag-aawit Na Manananggal", "Grumbledorf": "Manggagaway", @@ -1404,7 +1503,7 @@ "Sammy Slam": "Mambubuno", "Santa Claus": "Santa Klaus", "Snake Shadow": "Aninong Balatkayo", - "Spaz": "Kawal", + "Spaz": "Mandirigma", "Taobao Mascot": "Taobao Maskot", "Todd McBurton": "Todd McBurton", "Zoe": "Dalagang Bombero", @@ -1420,7 +1519,7 @@ "Pro Football": "Batidong Rugbi", "Pro Onslaught": "Batidong Pagsalakay", "Pro Runaround": "Batidong Bantayan", - "Rookie ${GAME}": "Bagitong ${GAME}", + "Rookie ${GAME}": "Pang bago na ${GAME}", "Rookie Football": "Bagitong Rugbi", "Rookie Onslaught": "Bagitog Pagsalakay", "The Last Stand": "Ang Huling Labanan", @@ -1429,29 +1528,41 @@ "Uber Onslaught": "Kasukdulang Pagsalakay", "Uber Runaround": "Kasukdulang Bantayan" }, + "displayItemNames": { + "${C} Tickets": "${C} Tickets", + "${C} Tokens": "${C} Tokens", + "Chest": "Chest", + "L1 Chest": "L1 Chest", + "L2 Chest": "L2 Chest", + "L3 Chest": "L3 Chest", + "L4 Chest": "L4 Chest", + "L5 Chest": "L5 Chest", + "L6 Chest": "L6 Chest", + "Unknown Chest": "Hindi kilala na chest" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Maging ang napili ng tiyak na oras para manalo.\nPatayin ang napili para maging isa nito.", - "Bomb as many targets as you can.": "Bomba ng maraming target hangga't maaari mo.", + "Bomb as many targets as you can.": "Bombahin ang maraming patamaan hangga't maaari mo.", "Carry the flag for ${ARG1} seconds.": "Hawakan ang bandila sa loob ng ${ARG1} segundo.", "Carry the flag for a set length of time.": "Hawakan ang bandila para sa isang nakatakdang haba ng oras.", "Crush ${ARG1} of your enemies.": "Patayin ang ${ARG1} ng iyong mga kalaban", - "Defeat all enemies.": "Talunin ang lahat ng iyong mga kalaban", - "Dodge the falling bombs.": "Umiwas sa mga bumabagsak na bomba.", - "Final glorious epic slow motion battle to the death.": "Huling maluwalhating epic slow motion na labanan hanggang kamatayan.", + "Defeat all enemies.": "Talunin ang lahat ng mga kalaban.", + "Dodge the falling bombs.": "Iwasan ang bumabagsak na bomba.", + "Final glorious epic slow motion battle to the death.": "Ito na ang huling maluwalhating na labanan sa isang dakilang pabagalang galaw hanggang sa kamatayan.", "Gather eggs!": "Ipunin ng mga itlog!", - "Get the flag to the enemy end zone.": "Kunin ang bandila sa end zone ng kalaban.", + "Get the flag to the enemy end zone.": "Hawakin ang bandila patungo sa dulong lugar ng kalaban.", "How fast can you defeat the ninjas?": "Gaano kabilis mo matatalo ang mga ninja?", "Kill a set number of enemies to win.": "Pumatay ng isang set na bilang ng mga kalaban upang manalo.", - "Last one standing wins.": "Kung sino ang huling nakatayo ang siyang mananalo.", + "Last one standing wins.": "Kung sino ang huling nabuhay ang siyang mananalo.", "Last remaining alive wins.": "Kung sino ang huling natitirang buhay ang siyang mananalo.", "Last team standing wins.": "Kung sino ang huling katayuan ng koponan ang siyang mananalo", "Prevent enemies from reaching the exit.": "Pigilan ang mga kalaban na makarating at makalabas sa labasan.", - "Reach the enemy flag to score.": "Abutin ang bandila ng kalaban upang maka-iskor.", + "Reach the enemy flag to score.": "Ihawak ang bandila ng kalaban upang maka-iskor.", "Return the enemy flag to score.": "Ibalik ang watawat ng kalaban upang maka-iskor.", "Run ${ARG1} laps.": "Tumakbo ng ${ARG1} ikot", "Run ${ARG1} laps. Your entire team has to finish.": "Tumakbo ng {ARG1} ikot. Kailangang matapos ang iyong buong team na ito.", "Run 1 lap.": "Tumakbo ng 1 ikot.", - "Run 1 lap. Your entire team has to finish.": "Tumakbo ng 1 ikot. Kailangang matapos ang iyong buong team na ito.", + "Run 1 lap. Your entire team has to finish.": "Tumakbo ng 1 ikot. Kailangang matapos ang iyong buong grupo.", "Run real fast!": "Tumakbo ng mabilis!", "Score ${ARG1} goals.": "Makaiskor ng ${ARG1} gol.", "Score ${ARG1} touchdowns.": "Makaiskor ng ${ARG1} touchdowns.", @@ -1469,8 +1580,8 @@ "Touch the enemy flag.": "Humawak sa bandera ng iyong kalaban.", "carry the flag for ${ARG1} seconds": "Hawakan ang bandila ng ${ARG1} segundo", "kill ${ARG1} enemies": "patayin ang ${ARG1} na mga kalaban.", - "last one standing wins": "kung sino ang huling nakatayo ang siyang mananalo", - "last team standing wins": "kung sino ang huling katayuan ng team ang siyang mananalo", + "last one standing wins": "kung sino ang huling nabuhay ang siyang mananalo", + "last team standing wins": "ang huling grupong buhay ay mananalo", "return ${ARG1} flags": "Magnakaw ng ${ARG1} na mga bandera", "return 1 flag": "ibalik ang 1 bandila", "run ${ARG1} laps": "Tumakbo ng ${ARG1} ikot", @@ -1485,68 +1596,74 @@ "touch 1 flag": "humawak ng 1 bandila" }, "gameNames": { - "Assault": "Pag-atake", - "Capture the Flag": "Kunin ang Bandila", - "Chosen One": "Napili ang Isa", + "Assault": "Dadaluhungin", + "Capture the Flag": "Agawang Bandila", + "Chosen One": "Ang Piniling Isa", "Conquest": "Pagsakop", "Death Match": "Laban ng Kamatayan", "Easter Egg Hunt": "Paghahanap ng mga Easter Egg", - "Elimination": "Kaligtasan", - "Football": "Rugbi", + "Elimination": "Pagbabawasan", + "Football": "Putbol", "Hockey": "Hockey", - "Keep Away": "Layuan Mo", + "Keep Away": "Hawakang Bandila", "King of the Hill": "Hari ng Burol", "Meteor Shower": "Ulan ng mga Bulalakaw", "Ninja Fight": "Labanan ng mga Ninja", "Onslaught": "Pagsalakay", - "Race": "Takbuan", + "Race": "Takbuhan", "Runaround": "Bantayan", "Target Practice": "Pagsasanay ng Patamaan", "The Last Stand": "Ang Huling Labanan" }, "inputDeviceNames": { "Keyboard": "Keyboard", - "Keyboard P2": "Keyboard F2" + "Keyboard P2": "Keyboard P2" }, "languages": { - "Arabic": "Arabe", - "Belarussian": "Belaruso", - "Chinese": "Tsino", - "ChineseTraditional": "Tsinong Tradisyonal", - "Croatian": "Kroatyano", - "Czech": "Tsek", - "Danish": "Makadenmark", - "Dutch": "Olandes", - "English": "Ingles", - "Esperanto": "Esperanto", - "Filipino": "Tagalog", - "Finnish": "Finnish", - "French": "Pranses", - "German": "Aleman", - "Gibberish": "Walang Kwentang Linguahe", - "Greek": "Griyego", - "Hindi": "Indiyano", - "Hungarian": "Hanggaryan", - "Indonesian": "Indonesiyo", - "Italian": "Italiyano", - "Japanese": "Nippongo", - "Korean": "Koreano", - "Malay": "Malay", - "Persian": "Persyano", - "Polish": "Polish", - "Portuguese": "Portuges", - "Romanian": "Rumano", - "Russian": "Ruso", - "Serbian": "Serbyan", - "Slovak": "Eslobako", - "Spanish": "Espanyol", - "Swedish": "Suweko", - "Tamil": "Tamil", - "Thai": "Siyam", - "Turkish": "Turko", - "Ukrainian": "Ukranyo", - "Venetian": "Benesiya", - "Vietnamese": "Byetnam" + "Arabic": "Wikang Arabik", + "Belarussian": "Wikang Belaruso", + "Chinese": "Wikang Tsino ", + "ChineseSimplified": "Wikang Tsino - Pangkaraniwan", + "ChineseTraditional": "Wikang Tsino - Tradisyonal", + "Croatian": "Wikang Kroatyano", + "Czech": "Wikang Tsek", + "Danish": "Wikang Denmark", + "Dutch": "Wikang Olandes", + "English": "Wikang Ingles", + "Esperanto": "Wikang Esperanto", + "Filipino": "Wikang Pilipino", + "Finnish": "Wikang Finnish", + "French": "Wikang Pranses", + "German": "Wikang Alemanya", + "Gibberish": "Pagyayapyap", + "Greek": "Wikang Griyego", + "Hindi": "Wikang Indiyano", + "Hungarian": "Wikang Hanggaryan", + "Indonesian": "Wikang Indonesiyo", + "Italian": "Wikang Italiyano", + "Japanese": "Wikang Hapon", + "Korean": "Wikang Koreano", + "Malay": "Wikang Malay", + "Persian": "Wikang Persyano", + "PirateSpeak": "Salitang Pirata", + "Polish": "Wikang Polish", + "Portuguese": "Wikang Portuges", + "PortugueseBrazil": "Wikang Portuges - Brasil", + "PortuguesePortugal": "Wikang Portuges - Portugal", + "Romanian": "Wikang Rumano", + "Russian": "Wikang Ruso", + "Serbian": "Wikang Serbyan", + "Slovak": "Wikang Eslobako", + "Spanish": "Wikang Espanyol", + "SpanishLatinAmerica": "Wikang Espanyol - Amerikanong Latino", + "SpanishSpain": "Wikang Espanyol - Espanya", + "Swedish": "Wikang Suweko", + "Tamil": "Wikang Tamil", + "Thai": "Wikang Thai", + "Turkish": "Wikang Turko", + "Ukrainian": "Wikang Ukranyo", + "Venetian": "Wikang Benesiya", + "Vietnamese": "Wikang Byetnam" }, "leagueNames": { "Bronze": "Tanso", @@ -1557,15 +1674,15 @@ "mapsNames": { "Big G": "Malaking G", "Bridgit": "Tawiring Tulay", - "Courtyard": "Looban Patyo", + "Courtyard": "Loobang Patyo", "Crag Castle": "Kastilyong Bangin", "Doom Shroom": "Itim na Kabute", "Football Stadium": "Istadyum", - "Happy Thoughts": "Masayang Isip", + "Happy Thoughts": "Isipang Masaya", "Hockey Stadium": "Istadyum ng Hockey", - "Lake Frigid": "Yelong Lawa", + "Lake Frigid": "Lawang Yelo", "Monkey Face": "Mukha ng Unggoy", - "Rampage": "Mandaluhong", + "Rampage": "Dalawang Dahilig", "Roundabout": "Paliguy-ligoy", "Step Right Up": "Hakbang Pataas", "The Pad": "Ang Pad", @@ -1574,8 +1691,8 @@ "Zigzag": "Sigsag" }, "playlistNames": { - "Just Epic": "Epic Lang", - "Just Sports": "Shorts Lang" + "Just Epic": "Mga Madakila", + "Just Sports": "Sports Lang" }, "scoreNames": { "Flags": "Watawat", @@ -1586,7 +1703,7 @@ "Time Held": "Oras na Gaganapin" }, "serverResponses": { - "A code has already been used on this account.": "Nagamit na ang isang code sa account na ito.", + "A code has already been used on this account.": "Nagamit na ang isang kowd sa account na ito.", "A reward has already been given for that address.": "Naibigay na ang reward para sa address na iyon.", "Account linking successful!": "Matagumpay ang pag-link ng account!", "Account unlinking successful!": "Matagumpay ang pag-unlink ng account!", @@ -1604,30 +1721,36 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Natukoy ang pagdadaya; nasuspinde ang mga iskor at premyo sa loob ng ${COUNT} (na) araw.", "Could not establish a secure connection.": "Hindi makapagtatag ng secure na koneksyon.", "Daily maximum reached.": "Naabot na ang pang-araw-araw ng request.", + "Daily sign-in reward": "Pangaraw-araw na gantimpala", "Entering tournament...": "Papasok sa paligsahan…", - "Invalid code.": "Di-wastong code.", + "Invalid code.": "Di-wasto ang kowd.", "Invalid payment; purchase canceled.": "Di-wastong pagbabayad; kinansela ang pagbili.", - "Invalid promo code.": "Di-wastong promo code.", + "Invalid promo code.": "Di-wasto ang promo kowd.", "Invalid purchase.": "Di-wastong bilihin", "Invalid tournament entry; score will be ignored.": "Di-wastong entry sa paligsahan; hindi papansinin ang mga iskor.", "Item unlocked!": "Na-unlock ang aytem!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "TINANGGI ANG PAG-LINK. ang ${ACCOUNT} na ito\nay may makabuluhang data na maaaring MAWAWALA LAHAT.\nMaaari kang mag-link sa kabaligtaran na pagkakasunud-sunod kung gusto mo\n(at sa halip ay mawala ang data ng account na ITO)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "I-link ang account na ${ACCOUNT} sa account na ito?\nMawawala ang lahat ng umiiral na data sa ${ACCOUNT}.\nHindi na ito maaaring bawiin. Sigurado ka ba?", + "Longer streaks lead to better rewards.": "sunod-sunod mong buksan ang larong ito, mas malaking gantimpala.", "Max number of playlists reached.": "Naabot na ang maximum na bilang ng mga playlist.", "Max number of profiles reached.": "Naabot na ang maximum na bilang ng mga profile.", - "Maximum friend code rewards reached.": "Naabot ang maximum na mga reward sa code ng kaibigan.", + "Maximum friend code rewards reached.": "Naabot ang maximum na mga reward sa kowd ng kaibigan.", "Message is too long.": "Ang mensahe ay napakahaba.", + "New tournament result!": "Mga bagong resulta ng tournament!", "No servers are available. Please try again soon.": "Walang makakuha na mga server. Pakisubukang muli sa lalong madaling oras.", + "No slots available. Free a slot and try again.": "Walang magagamit na mga puwang. Magbakante ng slot at subukang muli.", "Profile \"${NAME}\" upgraded successfully.": "Matagumpay na na-upgrade ang profile na \"${NAME}\".", "Profile could not be upgraded.": "Hindi ma-upgrade ang profile.", "Purchase successful!": "Matagumpay ang pagbili!", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Nakatanggap ng ${COUNT} na tiket para sa pag-sign in.\nBumalik bukas para makatanggap ng ${TOMORROW_COUNT}.", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Hindi na sinusuportahan ang functionality ng server sa bersyong ito ng laro;\nMangyaring mag-update sa isang mas bagong bersyon.", - "Sorry, there are no uses remaining on this code.": "Pasensya na, wala nang natitirang gamit sa code na ito.", - "Sorry, this code has already been used.": "Pasensya na, nagamit na ang code na ito.", - "Sorry, this code has expired.": "Pasensya na, nag-expire na ang code na ito.", - "Sorry, this code only works for new accounts.": "Pasensya na, gumagana lang ang code na ito para sa mga bagong account.", + "Sorry, there are no uses remaining on this code.": "Pasensya na, hindi na magagamit ang kowd na ito.", + "Sorry, this code has already been used.": "Pasensya na, nagamit na ang kowd na ito.", + "Sorry, this code has expired.": "Pasensya na, nag-expire na ang kowd na ito.", + "Sorry, this code only works for new accounts.": "Pasensya na, gumagana lang ang kowd na ito para sa mga bagong account.", + "Sorry, this has expired.": "Pasensya na, ito ay na-expire.", "Still searching for nearby servers; please try again soon.": "Naghahanap pa rin ng mga kalapit na server; mangyaring subukan muli sa lalong madaling oras.", + "Streak: ${NUM} days": "Pagsunod-sunod: ${NUM} na araw", "Temporarily unavailable; please try again later.": "Pansamantalang hindi magagamit; Subukang muli mamaya.", "The tournament ended before you finished.": "Natapos ang tournament bago ka natapos.", "This account cannot be unlinked for ${NUM} days.": "Ang account na ito ay hindi maaaring i-unlink sa loob ng ${NUM} (na) araw.", @@ -1638,19 +1761,28 @@ "Tournaments require ${VERSION} or newer": "Ang mga paligsahan ay nangangailangan ng ${VERSION} o mas bago", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "I-unlink ang ${ACCOUNT} mula sa account na ito?\nIre-reset ang lahat ng data sa ${ACCOUNT}.\n(maliban sa mga nakamit sa ilang pagkakataon)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "BABALA: ang mga reklamo ng pag-hack ay inilabas laban sa iyong account.\nIpagbabawal ang mga account na makikitang nagha-hack. Mangyaring maglaro ng patas.", + "Wait reduced!": "Nabawasan ang hintay!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Babala: Ang bersyon ng larong ito ay nakatakda sa lumang data; mayroong pagkawala o kupas ang nasa larawan.\nPakiusap na mapalitan ng bagong bersyon ang laro na ito upang matanawin ang kasalukuyang data.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Gusto mo bang i-link ang iyong device account sa isang ito?\n\nAng iyong device account ay ${ACCOUNT1}\nAng account na ito ay ${ACCOUNT2}\n\nPapayagan ka nitong panatilihin ang iyong progress.\nBabala: hindi na ito maaaring bawiin!", "You already own this!": "Nabili mo na ito!", "You can join in ${COUNT} seconds.": "Makakasali ka sa loob ng ${COUNT} segundo.", "You don't have enough tickets for this!": "Hindi sapat ang tickets mo para dito!", "You don't own that.": "Hindi sayo iyan.", "You got ${COUNT} tickets!": "Nakakuha ka ng ${COUNT} tickets!", + "You got ${COUNT} tokens!": "May nakuha ka na ${COUNT} tokens!", "You got a ${ITEM}!": "Nakakuha ka ng ${ITEM}!", + "You got a chest!": "Mayroon na ka chest!", + "You got an achievement reward!": "May bago kang gantimpala sa tagumpay!", "You have been promoted to a new league; congratulations!": "Na-promote ka sa isang bagong liga; congrats!", - "You must update to a newer version of the app to do this.": "Dapat kang mag-update sa mas bagong bersyon ng app para magawa ito.", - "You must update to the newest version of the game to do this.": "Dapat kang mag-update sa pinakabagong bersyon ng laro upang magawa ito.", + "You lost a chest! (All your chest slots were full)": "May nawalan ka na chest! (Lahat ng chest slot mo ay puno)", + "You must update the app to view this.": "Kailangan mong baguhin muna ang bersyon ng app na ito upang maitignan ito.", + "You must update to a newer version of the app to do this.": "Kailangang magbago sa mas mabagong bersyon ng app para magawa ito.", + "You must update to the newest version of the game to do this.": "Kailangang magbago sa pinakabagong bersyon ng laro upang magawa ito.", "You must wait a few seconds before entering a new code.": "Dapat kang maghintay ng ilang segundo bago maglagay ng bagong code.", - "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ikaw ay niraranggo ng #${RANK} sa huling paligsahan. Salamat sa paglalaro!", + "You placed #${RANK} in a tournament!": "Nag place ka ng #${RANK} sa paligsahan!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ikaw ay niraranggo ng #${RANK} sa huling paligsahan. Salamat po sa paglalaro!", "Your account was rejected. Are you signed in?": "Tinanggihan ang iyong account. Naka-sign in ka ba?", + "Your ad views are not registering. Ad options will be limited for a while.": "Ang bilang ng iyong pagnood ng adbertismo ay hindi napaoarehistro. Ang iyong opsyon sa pagnood ay saglit na limitado.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ang iyong kopya ng laro ay na-modified.\nMangyaring ibalik ang anumang mga pagbabago at subukang muli.", "Your friend code was used by ${ACCOUNT}": "Ang code ng iyong kaibigan ay ginamit ng ${ACCOUNT}" }, @@ -1665,9 +1797,9 @@ "5 Minutes": "5 minuto", "8 Seconds": "8 segundo", "Allow Negative Scores": "Payagan ang Mga Negatibong Iskor", - "Balance Total Lives": "Balansehin ang Kabuuang Buhay", + "Balance Total Lives": "Balansehin ang Kabuuhang Buhay", "Bomb Spawning": "Paglitaw ng Bomba", - "Chosen One Gets Gloves": "Ang Isa Sa Napili Ay Makukuha Ng Gloves", + "Chosen One Gets Gloves": "Ang Isa Sa Napili Ay Makukuha Mga Guwantes", "Chosen One Gets Shield": "Ang Isa Sa Napili Ay Makukuha Ng Kalasag", "Chosen One Time": "Oras Ng Isa Sa Napili", "Enable Impact Bombs": "I-enable Ang Mga Gatilyong Bomba", @@ -1707,51 +1839,51 @@ "Red": "Pula" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Ang isang perpektong naka-time na takbo-talon-ikot-suntok ay maaaring makapatay sa isang hit\nat magkaroon ka ng panghabambuhay na paggalang mula sa iyong mga kaibigan.", - "Always remember to floss.": "Laging tandaan na mag-floss.", - "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Gumawa ng mga profile ng player para sa iyong sarili at sa iyong mga kaibigan\nang iyong mga gustong pangalan at hitsura sa halip na gumamit ng mga random.", - "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Ginagawa ka ng sumpa sa isang ticking time na bomba.\nAng tanging lunas ay ang mabilisang kumuha ng health-pack.", - "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Sa kabila ng kanilang hitsura, lahat ng kakayahan ng mga karakter ay magkapareho,\nkaya pumili lang kung alin ang pinakahawig mo.", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Huwag masyadong maangas sa enerhiya na kalasag na iyon; ihahagis ka nila sa isang platform", - "Don't run all the time. Really. You will fall off cliffs.": "Huwag tumakbo sa lahat ng oras. Talaga. Mahuhulog ka sa platform", - "Don't spin for too long; you'll become dizzy and fall.": "Huwag paikutin nang masyadong mahaba; mahihilo ka at mahulog.", - "Hold any button to run. (Trigger buttons work well if you have them)": "Pindutin ang anumang pindutan upang tumakbo. (Mahusay na gumagana ang mga pindutan ng pag-trigger kung mayroon ka nito)", - "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Pindutin nang matagal ang anumang button para tumakbo. Mas mabilis kang makakakuha ng mga lugar\nngunit hindi lumiko nang mahusay, kaya mag-ingat sa matalim na mga gilid", - "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ang mga bomba ng yelo ay hindi masyadong malakas, ngunit nagyeyelo\nkung sino man ang kanilang natamaan, na nag-yelo sa kanila na madaling masira.", - "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Kung may napulot sa iyo, suntukin mo siya at bibitaw siya.\nGumagana rin ito sa totoong buhay.", - "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Kung kulang ka sa mga controller, i-install ang '${REMOTE_APP_NAME}' app\nsa iyong mga mobile device upang gamitin ang mga ito bilang mga controller.", - "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Kung nakadikit sa iyo ang isang malagkit na bomba, tumalon at paikutin. Baka \ni-alis mo ang bomba, o kung wala na ang iyong mga huling sandali ay nakakaaliw.", - "If you kill an enemy in one hit you get double points for it.": "Kung pumatay ka ng isang kalaban sa isang hit makakakuha ka ng dobleng puntos para dito.", - "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Kung nakatanggap ka ng sumpa, ang tanging pag-asa mo para mabuhay ay\nmaghanap ng health powerup sa susunod na ilang segundo.", - "If you stay in one place, you're toast. Run and dodge to survive..": "Kung manatili ka sa isang lugar, toasted ka. Tumakbo at umigtad para mabuhay..", - "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Kung marami kang manlalaro na dumarating at pupunta, i-on ang 'auto-kick-ng-idle-na-manlalaro’\nsa ilalim ng mga setting kung sakaling may makakalimutang umalis sa laro.", - "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Kung masyadong mainit ang iyong device o gusto mong makatipid ng baterya,\ni-down ang \"Biswal” o \"Resolusyon\" sa Mga Setting->Grapika", - "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Kung hindi mabuti ang iyong framerate, subukang ibaba ang resolusyon\no mga biswal sa mga setting ng grapika ng laro.", - "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Sa Kunin-ang-Bandila, ang iyong sariling bandila ay dapat nasa iyong base para makaiskor, Kung ang isa\nang team ay malapit nang makapuntos, ang pagnanakaw ng kanilang bandila ay maaaring maging isang magandang paraan upang pigilan sila.", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Ang isang perpektong oras na takbo-talon-ikot-suntok ay maaaring makapatay sa isang tama\nat magkaroon ka ng panghabambuhay na paggalang mula sa iyong mga kaibigan.", + "Always remember to floss.": "Laban-laban lang!", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Gumawa ng mga karakter para sa iyong sarili at sa mga kaibigan mo na\nmayroong kanyang-kanyang pangalan at itsura kaysa ano-ano ang pinagpilian mo.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Ang \"Sumpa\" ay ginagawa kang isang masasaboh na bomba.\nAng tanging lunas ay ang mabilisang kumuha ng health-pack.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Sa kabila ng kanilang hitsura, lahat ng kakayahan ng mga karakter ay magkaparehas lamang,\nkaya pumili lang kung alin ang pinakahawig mo.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Huwag masyadong maangas sa paggalaw na mayroon kang enerhiyang kalasag; pwede ka pa rin nilang ihagis mula sa isang plataporma.", + "Don't run all the time. Really. You will fall off cliffs.": "Talagang huwag tumakbo sa lahat ng oras. Mahuhulog ka.", + "Don't spin for too long; you'll become dizzy and fall.": "Huwag paikutin Ang iyong sarili nang masyadong matagal; mahihilo at matumba ka.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pindutin ang anumang pindutan upang tumakbo. (Mahusay na gumagana gamit ang mga pindutang kalabitan kung mayroon ka nito)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Pindutin nang matagal ang anumang pindutan para tumakbo. Mas mabilis kang makarating\nngunit hindi lumiko nang mahusay, kaya mag-ingat sa matalim na mga gilid", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ang mga Bombang Yelo ay hindi masyadong malakas, ngunit makatigil at magyeyelo\nkung sino man ang kanilang natamaan na madaling maisira.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Kung ikaw ay nahawak, suntukin mo at bibitaw siya.\nNatunay ito sa totoong buhay.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Kung kulang ka sa mga controller, gamitin ang '${REMOTE_APP_NAME}'\nsa iyong mga gadyet upang gamitin ang mga ito bilang mga controller.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Kung nakadikit sa iyo ang isang Bombang Malagkit, tumalon at umikot ka. Baka\nmaialis mo ang bomba mula sa iyong sarili, dili kaya'y nakakaaliw Ang iyong huling sandali.", + "If you kill an enemy in one hit you get double points for it.": "Kapag pumatay ka ng isang kalaban sa isang tama lamang, makakakuha ka ng dobleng puntos.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Kung 'di mo sinadyang nakuha ng Sumpa, ang tanging pag-asa mo para mabuhay ay\nmaghanap ng Medikal-Pakete sa susunod na 5 segundo.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Kung manatili ka sa isang lugar, wala ka na. Tumakbo at umigtad para mabuhay..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Kung marami kang manlalaro na dumarating at pupunta, buksan ang 'Ipalayas ang manlalarong hindi gumagalaw’\nsa ilalim ng mga setting kung sakaling may makakalimutang umalis sa laro.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Kung masyadong mainit ang iyong device o gusto mong makatipid ng baterya,\nhanggahan ang \"Biswal” o \"Resolusyon\" sa Mga Setting->Grapika", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Kung hindi mabuti ang iyong framerate, subukang ibaba ang resolusyon\no mga biswal sa grapika, mga setting.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Sa Kunin-ang-Bandila, ang iyong sariling bandila ay dapat nasa iyong istasyon para makaiskor, Kung ang isa\nang team ay malapit nang makapuntos, ang pagnanakaw ng kanilang bandila ay maaaring maging isang paraan upang pigilan ang iyon.", "In hockey, you'll maintain more speed if you turn gradually.": "Sa hockey, mapapanatili mo ang higit na bilis kung unti-unti kang lumiko.", "It's easier to win with a friend or two helping.": "mas madaling manalo sa tulong ng isa o dalawang kaibigan.", - "Jump just as you're throwing to get bombs up to the highest levels.": "Tumalon habang humagis upang makakuha ng mga bomba hanggang sa pinakamataas na antas.", - "Land-mines are a good way to stop speedy enemies.": "Ang mga mina ay isang mahusay na paraan upang pigilan ang mabilis na mga kalaban.", - "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Maraming bagay ang maaaring kunin at ihagis, kabilang ang iba pang mga manlalaro. Paghahagis\nang iyong mga kalaban mula sa mga gilid ay maaaring maging isang epektibo at emosyonal na diskarte.", - "No, you can't get up on the ledge. You have to throw bombs.": "Hindi, hindi ka makakabangon sa pag-ungos. Kailangan mong maghagis ng bomba.", - "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Maaaring sumali at umalis ang mga manlalaro sa gitna ng karamihan ng mga laro,\nat maaari mo ring isaksak at i-unplug ang mga controller nang mabilis.", - "Practice using your momentum to throw bombs more accurately.": "Magsanay gamit ang iyong momentum para maghagis ng mga bomba nang mas tumpak.", - "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ang mga suntok ay mas nagdudulot ng saktan sa mas mabilis na paggalaw ng iyong mga kamay,\nkaya subukang tumakbo, tumalon, at umiikot na parang baliw.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Tumalon habang humagis ng mga bomba upang makarating ito sa pinakamataas na antas.", + "Land-mines are a good way to stop speedy enemies.": "Ang mga mina ay isang mahusay na paraan upang pigilan ang mabilis na mga kalaban.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Maraming bagay ang maaaring kunin at ihagis, kabilang ang iba pang mga manlalaro. Paghahagis\nang iyong mga kalaban mula sa talampas ay maaaring maging isang epektibo at emosyonal na pagdiskarte.", + "No, you can't get up on the ledge. You have to throw bombs.": "Hindi ka makakahawak sa ungos. Kailangan mong maghagis ng bomba.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Maaaring sumali at umalis ang mga manlalaro sa gitna ng karamihan ng mga laro,\nat maaari mo ring isaksak at magpatanggal ang mga controller nang mabilis.", + "Practice using your momentum to throw bombs more accurately.": "Magsanay gamit ang iyong pag-udyok para maghagis ng mga bomba nang mas wasto.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ang mga suntok ay mas nagdudulot ng pagsaktan sa mas mabilis na paggalaw ng iyong mga kamay,\nkaya subukang tumakbo, tumalon, at umiikot na parang baliw.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Patakbong pabalik-balik bago maghagis ng bomba\nupang ‘ma-ikot’ ito at ihagis ito nang mas malayo.", - "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Ilabas ang isang grupo ng mga kalaban sa pamamagitan ng\nnaglalagay ng bomba malapit sa isang TNT box.", - "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Ang ulo ay ang pinaka-mahina na lugar, kaya isang malagkit-bomba \nna lumapag sa ulo mo ay game-over na.", - "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ang level na ito ay hindi kailanman nagtatapos, ngunit isang mataas na iskor dito\nbibigyan ka ng walang hanggang paggalang sa buong mundo.", - "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Ang lakas ng paghagis ay batay sa direksyon na iyong hinahawakan.\nUpang ihagis ang isang bagay nang malumanay sa harap mo, huwag humawak sa anumang direksyon.", - "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Pagod na sa mga soundtrack? Palitan nito ng iyong sarili!\nTingnan ang Mga Setting->Audio->Soundtrack", - "Try 'Cooking off' bombs for a second or two before throwing them.": "Try mo ‘I-timing” ang mga bomba sa isang segundo o dalawa bag mo ihagis.", - "Try tricking enemies into killing eachother or running off cliffs.": "Subukang linlangin ang mga kalaban sa pagpatay sa isa't isa o pahulog sa mga gilid.", - "Use the pick-up button to grab the flag < ${PICKUP} >": "Gamitin ang pick-up button para kunin ang bandera < ${PICKUP} >", - "Whip back and forth to get more distance on your throws..": "Paikut-ikot upang makakuha ng higit na distansya sa iyong mga paghagis..", - "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Maaari mong 'itutok' ang iyong mga suntok sa pamamagitan ng pag-ikot pakaliwa o pakanan.\nIto ay kapaki-pakinabang para sa pagtanggal ng mga kalaban sa mga gilid o pag-iskor sa hockey.", - "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Maaari mong hatulan kung kailan sasabog ang isang bomba batay sa\nkulay ng sparks mula sa fuse nito: Dilaw..Kahel..Pula..SABOG.", - "You can throw bombs higher if you jump just before throwing.": "Maaari kang maghagis ng mga bomba nang mas mataas kung tumalon ka bago ihagis.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Pwede kang masaktan kapag natamaan mo ang iyong ulo sa mga bagay,\nkaya't subukang huwag ipilit ang iyong ulo sa iyan.", - "Your punches do much more damage if you are running or spinning.": "Ang iyong mga suntok ay nagdudulot ng higit na damage kung ikaw ay tumatakbo o umiikot." + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Magpatay ang isang grupo ng mga kalaban sa pamamagitan ng\npagsabog ng bomba malapit sa isang kahong TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Ang ulo ay ang pinakamatalban na parte, kaya isang Bombang Malagkit \nna lumapag sa ulo mo ay dedma ka na.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ang anyas na ito ay hindi kailanman nagtatapos, ngunit isang mataas na iskor dito\nbibigyan ka ng walang hanggang paggalang mula sa buong mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Ang lakas ng paghagis ay batay sa direksyon na iyong hinahawakan.\nUpang ihagis ang isang bagay nang malumanay sa harap mo, huwag maitungo sa anumang direksyon.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Pagod na sa mga soundtrack? Palitan nito ng iyong sarili!\nTignan ang Mga Setting->Tugtugan->Mga Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Try mo \"Itiisin” ang mga bomba sa isang segundo o dalawa bago mo ihagis.", + "Try tricking enemies into killing eachother or running off cliffs.": "Subukang linlangin ang mga kalaban sa pagsuntok sa isa't isa o pahulog sa mga gilid.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Gamitin ang pindutang \"Pulutin\" para makunin ang bandera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Paikut-ikot upang makakuha ng higit pang distansya sa iyong mga paghagis..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Maaari mong 'itutok' ang iyong mga suntok sa pamamagitan ng pagtungo pakaliwa o pakanan.\nIto ay kapaki-pakinabang para sa pagtama sa mga kalaban sa mga gilid o pag-iskor sa hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Maaari mong hatulan kung kailan sasabog ang isang bomba batay sa\nkulay ng tilamsik mula sa bungad nito: Dilaw..Kahel..Pula..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Maaari kang maihagis ng mga bomba nang mas mataas kung tumalon ka bago ihagis.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Pwede kang masaktan kapag natamaan mo ang iyong ulo sa mga bagay,\nkaya't subukang huwag matama ang iyong ulo sa iyan.", + "Your punches do much more damage if you are running or spinning.": "Ang iyong mga suntok ay nagdudulot ng higit pang saktan kung ikaw ay tumatakbo o umiikot." } }, "trophiesRequiredText": "Nangangailangan ito ng ${NUMBER} na trophies.", @@ -1759,32 +1891,32 @@ "trophiesThisSeasonText": "Mga Tropeo Ngayong Season", "tutorial": { "cpuBenchmarkText": "Pagpapatakbo ng tutorial sa nakakatawang bilis (pangunahing test sa bilis ng CPU)", - "phrase01Text": "Kamusta!", + "phrase01Text": "Kumusta!", "phrase02Text": "Maligayang pagdating sa ${APP_NAME}!", - "phrase03Text": "Narito ang ilang mga tip para sa pagkontrol ng iyong karakter:", + "phrase03Text": "Narito ang ilang mga paunawa para sa pagkontrol ng iyong karakter:", "phrase04Text": "Maraming bagay sa ${APP_NAME} ang nakabatay sa PISIKA", "phrase05Text": "Halimbawa, kapag sumuntok ka,..", - "phrase06Text": "..binase ang damage sa bilis ng mga kamay mo.", + "phrase06Text": "..nakabatay ang sakit sa bilis ng mga kamay mo.", "phrase07Text": "Kita mo? Hindi kami gumagalaw, kaya halos hindi nasaktan si ${NAME}", "phrase08Text": "Ngayon, tumalon at umikot tayo upang makakuha ng higit na bilis.", - "phrase09Text": "Ayan, mas maganda", + "phrase09Text": "Ayan, mas maayos.", "phrase10Text": "Ang pagtakbo ay nakakatulong din.", "phrase11Text": "Pindutin nang matagal ang KAHIT ANONG pindutan para tumakbo.", - "phrase12Text": "Para sa sobrang kahanga-hangang mga suntok, subukang tumakbo AT umikot.", - "phrase13Text": "Oops; pasensya na ${NAME}.", - "phrase14Text": "Maaari mong kunin at ihagis ang mga bagay tulad ng mga bandera.. o si ${NAME}.", - "phrase15Text": "Sa huli, meron pampasabog", - "phrase16Text": "Ang paghagis ng bomba ay kailangan may practice", - "phrase17Text": "Aray! Hindi napakahusay na hagis.", - "phrase18Text": "Ang paggalaw ay nakakatulong sa iyo na ihagis ng mas malayo.", - "phrase19Text": "Ang pagtalon tumutulong para matapon mo na masmataas", - "phrase20Text": "Ikot at ihagis ang iyong mga bomba para sa mas mahabang paghagis.", - "phrase21Text": "Ang pagtiming sa bomba ay pwedeng tricky", + "phrase12Text": "Para sa sobrang kumikirot na mga suntok, subukang tumakbo AT umikot.", + "phrase13Text": "Pasensya na pala, ${NAME}.", + "phrase14Text": "Maaari mong kunin at ihagis ang mga bagay tulad ng mga bandila.. o si ${NAME}.", + "phrase15Text": "Sa huli, meron pampasabog o bomba.", + "phrase16Text": "Nangangailangang sanayin ang paghagis ng bomba.", + "phrase17Text": "Aray! Hindi maayos na hagis.", + "phrase18Text": "Ang paggalaw ay nakakatulong maihagis ng mas malayo.", + "phrase19Text": "Ang pagtalon ay tumutulong para maihagis mo na masmataas", + "phrase20Text": "Umikot at ihagis ang iyong mga bomba para sa mas mahabang paghagis.", + "phrase21Text": "Pwede kang malito sa pagtiyempo ng iyong bomba.", "phrase22Text": "Aba.", - "phrase23Text": "Subukang “i-timing” fuse para sa isang segundo o dalawa.", - "phrase24Text": "Yay! Magaling na gawa.", + "phrase23Text": "Subukang “ipagtiyempo” ang bomba sa isang segundo o dalawa.", + "phrase24Text": "Yay! Lutong-luto!", "phrase25Text": "Well, hanggang doon lang.", - "phrase26Text": "Ngayon kunin mo sila, tigre!", + "phrase26Text": "Ngayon,talunin mo na sila!", "phrase27Text": "Alalahanin ang iyong pagsasanay, at babalik KANG buhay!", "phrase28Text": "...siguro...", "phrase29Text": "Paalam!", @@ -1793,28 +1925,35 @@ "randomName3Text": "Stephen", "randomName4Text": "Joshua", "randomName5Text": "Villar", - "skipConfirmText": "Sure ka ba na i-skip ang tutorial? Tap o pindutin para ma i-confirm.", + "skipConfirmText": "Sigurado ka ba na laktawin ang tutorial? I-tap o pindutin para sigurado ka.", "skipVoteCountText": "${COUNT}/${TOTAL} boto na gustong laktawan", - "skippingText": "Nilalaktawan ang tutorial", + "skippingText": "Nilalaktawan ang tutorial...", "toSkipPressAnythingText": "(i-tap o pindutin ang anuman para laktawan ang tutorial)" }, "twoKillText": "DOBLENG PAGPATAY!!", - "unavailableText": "hindi available", + "uiScaleText": "Sukat Ng UI", + "unavailableText": "hindi pwede", + "unclaimedPrizesText": "May mga premyo ka pang hindi nakukuha!", "unconfiguredControllerDetectedText": "Naktuklas ang hindi naka-configure na controller:", "unlockThisInTheStoreText": "Ito ay dapat na naka-unlock sa tindahan.", "unlockThisProfilesText": "Upang lumikha ng higit sa ${NUM} na mga profile, kailangan mo:", "unlockThisText": "Upang i-unlock ito, kailangan mo ng:", + "unsupportedControllerText": "Pasensya na, ang pangalan na \"${NAME}\" ay hindi naipataguyod.", "unsupportedHardwareText": "Pasensya na, ang hardware na ito ay hindi suportado ng build na ito ng laro.", "upFirstText": "Bumangon muna:", "upNextText": "Susunod sa larong ${COUNT}:", - "updatingAccountText": "Ina-update ang iyong account...", + "updatingAccountText": "Pinababago ang iyong account...", "upgradeText": "I-upgrade", "upgradeToPlayText": "I-unlock ang \"${PRO}\" sa in-game store upang i-play ito.", "useDefaultText": "Gamitin ang default", + "userSystemScriptsCreateText": "lumikha ng mga script ng system ng gumagamit", + "userSystemScriptsDeleteText": "tanggalin ang mga script ng system ng gumagamit", "usesExternalControllerText": "Gumagamit ang larong ito ng external na controller para sa input.", "usingItunesText": "Paggamit ng Music App para sa soundtrack...", "v2AccountLinkingInfoText": "Upang ma-link ang mga V2 account mo, dumeretso ka sa “I-Manage ang Account“.", + "v2AccountRequiredText": "Kailangan Ang iyong V2 account para rito. Itaas ang grado ng iyong account at ulitin.", "validatingTestBuildText": "Pinapatunayan ang Test Build...", + "viaText": "via", "victoryText": "Panalo!", "voteDelayText": "Hindi ka makapagsimula ng bagong botohan sa ${NUMBER} segundo", "voteInProgressText": "Ang pagboboto ay isinasagawa na.", @@ -1844,11 +1983,11 @@ "titleText": "Manood", "watchReplayButtonText": "Ipanood ang\nReplay" }, - "waveText": "Kaway", + "waveText": "Yugtong", "wellSureText": "Oo Syempre!", "whatIsThisText": "Ano ito?", "wiimoteLicenseWindow": { - "titleText": "Copyright ni DarwiinRemote" + "titleText": "Copyright ng DarwiinRemote" }, "wiimoteListenWindow": { "listeningText": "Nakikinig sa Wiimote...", @@ -1856,20 +1995,20 @@ "pressText2": "Sa mas bagong Wiimotes na may built in na Motion Plus, pindutin na lang ang pulang 'sync' na button sa likod." }, "wiimoteSetupWindow": { - "copyrightText": "Copyright ni DarwinRemote", + "copyrightText": "Copyright ni DarwinRemote ", "listenText": "Makinig", "macInstructionsText": "Tiyaking naka-off ang iyong Wii at naka-enable ang Bluetooth\nsa iyong Mac, pagkatapos ay pindutin ang 'Makinig'. Maaari ang suporta ng Wiimote\nmaging medyo patumpik-tumpik, kaya maaaring kailanganin mong subukan ng ilang beses\nbago ka magkaroon ng koneksyon.\n\nDapat hawakan ng Bluetooth ang hanggang 7 konektadong device,\nkahit na ang iyong mileage ay maaaring mag-iba.\n\nSinusuportahan ng BombSquad ang orihinal na Wiimotes, Nunchuks,\nat ang Klasikong Controller.\nGumagana na rin ang mas bagong Wii Remote Plus\nngunit hindi sa mga kalakip.", "thanksText": "Salamat sa DarwiinRemote team\nPara maging posible ito.", - "titleText": "Pag-setup ng Wiimote" + "titleText": "Pag-setup ng Wiimote " }, "winsPlayerText": "Nanalo si ${NAME}!", "winsTeamText": "Nanalo ang ${NAME}!", "winsText": "${NAME} Nanalo!", "workspaceSyncErrorText": "Error sa pag-sync ng ${WORKSPACE}. Tingnan ang log para sa mga detalye.", "workspaceSyncReuseText": "Hindi ma-sync ang ${WORKSPACE}. Muling paggamit ng nakaraang naka-sync na bersyon.", - "worldScoresUnavailableText": "Ang scores sa buong mundo ay hindi pa handa", - "worldsBestScoresText": "Pinakamahusay na Iskor ng Mundo", - "worldsBestTimesText": "Oras ng Pinakamahusay sa Mundo", + "worldScoresUnavailableText": "Hindi makuha ang mga pandaigdigang iskor.", + "worldsBestScoresText": "Pinakamahusay na Iskor sa Mundo", + "worldsBestTimesText": "Oras ng Pinakamabilis sa Mundo", "xbox360ControllersWindow": { "getDriverText": "Kunin ang Driver", "macInstructions2Text": "Upang gumamit ng mga controller nang wireless, kakailanganin mo rin ang receiver na iyon\nay kasama ang 'Xbox 360 Wireless Controller para sa Windows'.\nPinapayagan ka ng isang receiver na kumonekta hanggang sa 4 na controllers.\n\nMahalaga: Ang mga 3rd-party na receiver ay hindi gagana sa driver na ito;\ntiyaking 'Microsoft' ang nakasulat dito sa iyong receiver, hindi 'XBOX 360'.\nHindi na ibinebenta ng Microsoft ang mga ito nang hiwalay, kaya kakailanganin mong makuha\nyung naka-bundle sa controller or else search ebay.\n\nKung sa tingin mo ay kapaki-pakinabang ito, mangyaring isaalang-alang ang isang donasyon sa\ndeveloper ng driver sa kanilang site.", @@ -1879,5 +2018,6 @@ }, "yesAllowText": "Sige!", "yourBestScoresText": "Pinakamataas Mong Iskor", - "yourBestTimesText": "Pinakamabilis Mong Oras" + "yourBestTimesText": "Pinakamabilis Mong Oras", + "yourPrizeText": "Premyo mo:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/french.json b/dist/ba_data/data/languages/french.json index 873fadfb..4e10f0f5 100644 --- a/dist/ba_data/data/languages/french.json +++ b/dist/ba_data/data/languages/french.json @@ -7,7 +7,9 @@ "campaignProgressText": "Progression de la campagne [Difficile]: ${PROGRESS}", "changeOncePerSeason": "Vous ne pouvez changer cela qu'une fois par saison.", "changeOncePerSeasonError": "Vous devez attendre la prochaine saison pour le modifier à nouveau (${NUM} jours)", + "createAnAccountText": "Créer un compte", "customName": "Nom personnalisé", + "deleteAccountText": "Supprimer le compte", "googlePlayGamesAccountSwitchText": "Si vous voulez utiliser un autre compte Google, \nutilisez l'application Google Play Games pour le changer.", "linkAccountsEnterCodeText": "Entrer code", "linkAccountsGenerateCodeText": "Générez votre code", @@ -26,14 +28,16 @@ "setAccountNameDesc": "Sélectionnez le nom à afficher pour votre compte.\nVous pouvez utiliser le nom d'un de vos comptes\n associés ou créer un nom personnalisé unique.", "signInInfoText": "Connectez-vous pour gagner des tickets, participer aux tournois en ligne,\net partager votre progression entre plusieurs appareils.", "signInText": "Connexion", + "signInWithAnEmailAddressText": "Connectez-vous avec une adresse e-mail", "signInWithDeviceInfoText": "(un compte généré automatiquement utilisable seulement sur cet appareil)", "signInWithDeviceText": "Connectez-vous avec le compte de cet appareil", "signInWithGameCircleText": "Connectez-vous avec Game Circle", "signInWithGooglePlayText": "Connectez-vous avec Google Play", "signInWithTestAccountInfoText": "(ancien compte; utilisez les comptes de cet appareil pour les prochaines fois)", "signInWithTestAccountText": "Connectez-vous avec un compte test", + "signInWithText": "Connectez-vous avec ${SERVICE}", "signInWithV2InfoText": "(un compte qui fonctionne sur toutes les plateformes)", - "signInWithV2Text": "Connectez-vous avec un compte Bombsquad", + "signInWithV2Text": "Connectez-vous avec un compte ${APP_NAME}", "signOutText": "Se déconnecter", "signingInText": "Connexion...", "signingOutText": "Déconnexion...", @@ -339,9 +343,14 @@ "getMoreGamesText": "Obtenir plus de jeux...", "titleText": "Ajouter un Jeu" }, + "addToFavoritesText": "Ajouter aux favoris", + "addedToFavoritesText": "'${NAME}' a été ajouté aux favoris.", + "allText": "Tous", "allowText": "Autoriser", "alreadySignedInText": "Votre compte est connecté sur un autre appareil;\nveuillez changer de compte ou fermez le jeu sur \nles autres appareils et réessayez.", "apiVersionErrorText": "Impossible de charger le jeu ${NAME}; sa version api est ${VERSION_USED}; nous demandons la version ${VERSION_REQUIRED}.", + "applyText": "Appliquer", + "areYouSureText": "Êtes-vous sûr ?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" s'active seulement quand un casque est branché)", "headRelativeVRAudioText": "Son à position relative (RV)", @@ -367,14 +376,24 @@ "boostText": "Accroître", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} est configuré dans sa propre application.", "buttonText": "bouton", - "canWeDebugText": "Voulez-vous que BombSquad envoie automatiquement un rapport des bugs, \ncrashs et certaines informations relatives au jeu au développeur?\n\nCes rapports ne contiendront aucune information personnelle \net aideront à maintenir un jeu sans bugs ni ralentissements.", + "canWeDebugText": "Voulez-vous que ${APP_NAME} envoie automatiquement un rapport des bugs, \ncrashs et certaines informations relatives au jeu au développeur?\n\nCes rapports ne contiendront aucune information personnelle \net aideront à maintenir un jeu sans bugs ni ralentissements.", "cancelText": "Annuler", "cantConfigureDeviceText": "Désolé, ${DEVICE} ne peut pas être configuré.", "challengeEndedText": "Ce défi est terminé.", "chatMuteText": "Tchat muet", "chatMutedText": "Tchat muet", "chatUnMuteText": "Réactiver tchat", + "chests": { + "prizeOddsText": "Chances de prix", + "reduceWaitText": "Réduire l'attente", + "slotDescriptionText": "Cet emplacement peut contenir un coffre.\n\nGagnez des coffres en jouant à des niveaux\nde campagne, en participant à des tournois\net en terminant les succès.", + "slotText": "Coffre n° ${NUM}", + "slotsFullWarningText": "ATTENTION: tous vos coffres sont pleins.\nLes coffres gagnés dans ce jeu seront perdus.", + "unlocksInText": "Se débloque dans" + }, "choosingPlayerText": "", + "claimText": "Réclamer", + "codesExplainText": "Les codes sont fournis par le développeur pour \ndiagnostiquer et corriger les problèmes de compte.", "completeThisLevelToProceedText": "Vous devez compléter ce \nniveau pour continuer!", "completionBonusText": "Bonus de fin", "configControllersWindow": { @@ -458,6 +477,7 @@ "titleText": "Configurer l'Écran Tactile", "touchControlsScaleText": "Taille des boutons tactiles" }, + "configureDeviceInSystemSettingsText": "${DEVICE} peut être configuré dans Paramètres Système.", "configureItNowText": "Configurer maintenant?", "configureText": "Configurer", "connectMobileDevicesWindow": { @@ -568,6 +588,7 @@ "demoText": "Démo", "denyText": "Refuser", "deprecatedText": "Obsolète", + "descriptionText": "Description", "desktopResText": "Résolution de l'Ordinateur", "deviceAccountUpgradeText": "Avertissement:\nVous etes connecté avec un compte d'appareil (${NAME}).\nLes comptes d'appareils seront enlevés dans une future mise à jour.\nMettez à jour vers un compte V2 si vous voulez garder votre progression.", "difficultyEasyText": "Facile", @@ -578,6 +599,10 @@ "disableRemoteAppConnectionsText": "Désactiver les connexions d'applications-manettes", "disableXInputDescriptionText": "Permet plus que 4 manettes mais risque de malfonctionner.", "disableXInputText": "Désactiver XInput", + "disabledText": "Désactivé", + "discardText": "Rejeter", + "discordFriendsText": "Vous voulez chercher de nouvelles personnes avec qui jouer ? \nRejoignez notre Discord et trouvez de nouveaux amis !", + "discordJoinText": "Rejoignez le Discord", "doneText": "Terminé", "drawText": "Égalité", "duplicateText": "Dupliquer", @@ -612,6 +637,7 @@ "localProfileText": "(profil local)", "nameDescriptionText": "Nom du Joueur", "nameText": "Nom", + "profileAlreadyExistsText": "Un profile avec ce nom existe deja", "randomText": "aléatoire", "titleEditText": "Éditer ce Profil", "titleNewText": "Nouveau Profil", @@ -651,6 +677,7 @@ "useMusicFolderText": "Dossier de Fichiers Musicaux" }, "editText": "Éditer", + "enabledText": "Activé", "endText": "Terminé", "enjoyText": "Amusez-vous Bien!", "epicDescriptionFilterText": "${DESCRIPTION} Dans un \"slow-motion\" épique.", @@ -662,6 +689,8 @@ "errorText": "Erreur", "errorUnknownText": "erreur inconnue", "exitGameText": "Quitter ${APP_NAME}?", + "expiredAgoText": "Expiré il y a ${T}", + "expiresInText": "Expire dans ${T}", "exportSuccessText": "'${NAME}' exporté.", "externalStorageText": "Stockage Externe", "failText": "Échec", @@ -698,6 +727,8 @@ "editText": "Modifier\nLa Playlist", "gameListText": "Liste de jeu", "newText": "Nouvelle\nPlaylist", + "pointsToWinText": "Point pour gagner", + "seriesLengthText": "Longueur de la série", "showTutorialText": "Voir le Tutoriel", "shuffleGameOrderText": "Mélanger l'ordre des jeux", "titleText": "Personnaliser les Playlists ${TYPE}" @@ -726,6 +757,7 @@ "copyCodeConfirmText": "Le code a bien été copié dans le presse-papier.", "copyCodeText": "Copier le code", "dedicatedServerInfoText": "Pour un meilleur résultat, créez un server dédié. Voir bombsquadgame.com/server pour plus d'infos.", + "descriptionShortText": "Utilisez la fenêtre de regroupement pour constituer un groupe.", "disconnectClientsText": "Ceci déconnectera le(s) ${COUNT} joueur(s)\nde votre partie. Êtes-vous sûr?", "earnTicketsForRecommendingAmountText": "Vos amis recevront ${COUNT} tickets si ils essayent le jeu\n(et vous recevrez ${YOU_COUNT} pour chacun d'entre eux qui le feront)", "earnTicketsForRecommendingText": "Partagez le jeu pour \ndes tickets gratuits...", @@ -738,10 +770,10 @@ "friendHasSentPromoCodeText": "${COUNT} tickets ${APP_NAME} de la part de ${NAME}", "friendPromoCodeAwardText": "Vous recevrez ${COUNT} tickets à chaque fois qu'il sera utilisé.", "friendPromoCodeExpireText": "Ce code expirera dans ${EXPIRE_HOURS} heures et ne fonctionne que pour les nouveaux joueurs.", - "friendPromoCodeInstructionsText": "Pour l'utiliser, ouvrez ${APP_NAME} puis aller dans \"Paramètres->Avancé->Entrer code\".\nAllez sur bombsquadgame.com pour les liens de téléchargement pour toutes les plateformes supportées.", + "friendPromoCodeInstructionsText": "Pour l'utiliser, ouvrez ${APP_NAME} puis allez dans \"Paramètres -> Avancé -> Entrer code\".\nAllez sur bombsquadgame.com pour les liens de téléchargement pour toutes les plateformes supportées.", "friendPromoCodeRedeemLongText": "Peut être utilisé pour ${COUNT} tickets gratuits jusqu'à ${MAX_USES} personnes maximum.", "friendPromoCodeRedeemShortText": "Il peut-être utilisé pour ${COUNT} tickets dans le jeu.", - "friendPromoCodeWhereToEnterText": "(dans \"Paramètres->Avancé->Entrer code\")", + "friendPromoCodeWhereToEnterText": "(dans \"Paramètres -> Avancé -> Envoyer information\")", "getFriendInviteCodeText": "Obtenir un Code pour Inviter mes Amis", "googlePlayDescriptionText": "Invitez des joueurs Google Play à votre partie:", "googlePlayInviteText": "Inviter", @@ -773,6 +805,7 @@ "manualYourLocalAddressText": "Votre adresse locale:", "nearbyText": "Proche", "noConnectionText": "", + "noPartiesAddedText": "Aucune partie ajoutée", "otherVersionsText": "(autres versions)", "partyCodeText": "Code de la partie", "partyInviteAcceptText": "Accepter", @@ -846,6 +879,12 @@ "youHaveShortText": "vous avez ${COUNT}", "youHaveText": "vous avez ${COUNT} tickets" }, + "goldPass": { + "desc1InfTokensText": "Jetons infini.", + "desc2NoAdsText": "Aucune publicités.", + "desc3ForeverText": "Pour toujours.", + "goldPassText": "Pass d'or" + }, "googleMultiplayerDiscontinuedText": "Désolé, le service multijoueur de Google n'est plus disponible.\nJe travaille sur un moyen de le remplacer aussi vite que possible.\nEn attendant, veuillez essayer une nouvelle méthode de connexion.\n-Eric", "googlePlayPurchasesNotAvailableText": "Les achats Google Play ne sont pas disponibles.\nVous avez peut-être besoin de mettre à jour votre Google play", "googlePlayServicesNotAvailableText": "Les services Google Play sont indisponibles.\nCertaines fonctions de l'application peuvent être désactivées.", @@ -854,10 +893,12 @@ "alwaysText": "Toujours", "fullScreenCmdText": "Plein Écran (Cmd-F)", "fullScreenCtrlText": "Plein Écran (Ctrl-F)", + "fullScreenText": "plein écran", "gammaText": "Gamma", "highText": "Élevé", "higherText": "Très élevé", "lowText": "Bas", + "maxFPSText": "FPS maximum", "mediumText": "Moyen", "neverText": "Jamais", "resolutionText": "Résolution", @@ -931,6 +972,7 @@ "importText": "Importer", "importingText": "Importation...", "inGameClippedNameText": "dans le jeu sera\n\"${NAME}\"", + "inboxText": "Messages", "installDiskSpaceErrorText": "ERREUR: Incapable de compléter l'installation.\nL'appareil manque paut-être d'espace.\nLibérez de l'espace et ressayez.", "internal": { "arrowsToExitListText": "appuyez sur ${LEFT} ou ${RIGHT} pour quitter la liste", @@ -987,12 +1029,14 @@ "touchScreenJoinWarningText": "Vous avez joint avec l'écran tactile.\nSi c'était une erreur, touchez 'Menu->Quitter le Jeu'.", "touchScreenText": "Écran Tactile", "trialText": "test", + "unableToCompleteTryAgainText": "Impossible de terminer l'opération.\nRéessayez plus tard.", "unableToResolveHostText": "Erreur: impossible de résoudre l'hôte.", "unavailableNoConnectionText": "Pas disponible à l'instant (pas de connexion internet?)", "vrOrientationResetCardboardText": "Utilisez ceci pour réinitialiser l'orientation RV.\nPour jouer au jeu vous aurez besoin d'un contrôleur externe.", "vrOrientationResetText": "Réinitialiser l'orientation RV.", "willTimeOutText": "(expirera si inactive)" }, + "inventoryText": "Inventaire", "jumpBoldText": "SAUT", "jumpText": "Saut", "keepText": "Garder", @@ -1039,8 +1083,11 @@ "seasonEndsMinutesText": "La saison se termine dans ${NUMBER} minutes.", "seasonText": "Saison ${NUMBER}", "tournamentLeagueText": "Vous devez atteindre la ligue ${NAME} pour participer à ce tournoi.", - "trophyCountsResetText": "Les trophées seront remis à zéro la saison suivante." + "trophyCountsResetText": "Les trophées seront remis à zéro la saison suivante.", + "upToDateBonusDescriptionText": "Les joueurs qui utilisent une version récente\ndu jeu reçoivent un bonus de ${PERCENT}%.", + "upToDateBonusText": "à jour = bonus" }, + "learnMoreText": "En savoir plus", "levelBestScoresText": "Meilleurs scores dans ${LEVEL}", "levelBestTimesText": "Meilleurs temps dans ${LEVEL}", "levelFastestTimesText": "Meilleurs temps en ${LEVEL}", @@ -1087,6 +1134,8 @@ "modeArcadeText": "Mode Arcade", "modeClassicText": "Mode classique", "modeDemoText": "Mode Demo", + "moreSoonText": "Plus à venir bientôt...", + "mostDestroyedPlayerText": "Joueur le plus détruit", "mostValuablePlayerText": "Meilleur joueur", "mostViolatedPlayerText": "Joueur le plus violenté", "mostViolentPlayerText": "Joueur le plus violent", @@ -1103,6 +1152,7 @@ "nameSuicideText": "${NAME} s'est suicidé.", "nameText": "Nom", "nativeText": "Native", + "newExclaimText": "Nouveau !", "newPersonalBestText": "Nouveau record personnel!", "newTestBuildAvailableText": "Une nouvelle version test est disponible ! (${VERSION} ${BUILD}).\nObtenez à ${ADDRESS}", "newText": "Nouveau", @@ -1114,13 +1164,17 @@ "noExternalStorageErrorText": "Aucun stockage externe a été trouvé pour cet appareil", "noGameCircleText": "Erreur: vous n'êtes pas connecté au GameCircle", "noJoinCoopMidwayText": "Vous ne pouvez pas rejoindre une partie co-cop en plein milieu.", + "noMessagesText": "Aucun message.", + "noPluginsInstalledText": "Aucun Plug-in installé", "noProfilesErrorText": "Vous avez aucun profil de joueur, vous êtes donc coincés avec '${NAME}'.\nAllez à Paramètres->Profils des Joueurs pour vous créer un profil.", "noScoresYetText": "Aucun score pour le moment.", + "noServersFoundText": "Aucun serveur trouvé.", "noThanksText": "Non Merci", "noTournamentsInTestBuildText": "AVERTISSEMENT: les scores de tournoi de cette version de test seront ignorés.", "noValidMapsErrorText": "Aucune carte valide a été trouvée pour ce type de jeu.", "notEnoughPlayersRemainingText": "Pas assez de joueurs restant; quittez et commencez un nouveau jeu.", "notEnoughPlayersText": "Vous avez besoin d'au moins ${COUNT} joueurs pour commencer ce jeu!", + "notEnoughTicketsText": "Pas assez de tickets!", "notNowText": "Pas maintenant", "notSignedInErrorText": "Vous devez vous connecter pour faire ceci.", "notSignedInGooglePlayErrorText": "Vous devez vous connecter avec Google Play pour faire ceci.", @@ -1133,6 +1187,9 @@ "onText": "Activé", "oneMomentText": "Juste un moment...", "onslaughtRespawnText": "${PLAYER} réapparaîtra à la vague ${WAVE}", + "openMeText": "Ouvrez-moi !", + "openNowText": "Ouvrir mnt", + "openText": "Ouvrir", "orText": "${A} ou ${B}", "otherText": "Autre...", "outOfText": "(#${RANK} sur ${ALL})", @@ -1189,7 +1246,11 @@ "pleaseWaitText": "Veuillez patienter...", "pluginClassLoadErrorText": "Une erreur est survenue en chargeant la classe de plugins '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Une erreur est survenue en démarrant le plugin '${PLUGIN}' : ${ERROR}", + "pluginSettingsText": "Paramètres Des Plugins", + "pluginsAutoEnableNewText": "Activer Automatiquement Les Nouveaux Plugins", "pluginsDetectedText": "Nouveaux plugins détectés. Redémarrez l'application pour les activer, ou configurez-les dans les paramètres.", + "pluginsDisableAllText": "Désactiver Tous Les Plugins", + "pluginsEnableAllText": "Activer Tous Les Plugins", "pluginsRemovedText": "${NUM} plugin(s) ne sont plus disponibles.", "pluginsText": "Plugins", "practiceText": "Entraînement", @@ -1222,6 +1283,8 @@ "punchText": "Frapper", "purchaseForText": "Achetez pour ${PRICE}", "purchaseGameText": "Acheter le Jeu", + "purchaseNeverAvailableText": "Désolé, les achats son indisponible sur cette version.\nEssayez de vous connecter à votre compte sur un autre appareil et effectuer un achat depuis ce dernier.", + "purchaseNotAvailableText": "Cet achat est indisponible.", "purchasingText": "Achat en cours...", "quitGameText": "Quitter ${APP_NAME}?", "quittingIn5SecondsText": "Le jeu fermera dans 5 secondes...", @@ -1264,6 +1327,7 @@ "version_mismatch": "Mauvaise version.\nVérifiez que BombSquad et BombSquad Remote \nsont mis à jour et réessayez." }, "removeInGameAdsText": "Débloquez \"${PRO}\" dans le magasin pour enlever les annonces.", + "removeInGameAdsTokenPurchaseText": "OFFRE À DURÉE LIMITÉE: achetez UN pack de jetons pour retirer les pubs.", "renameText": "Renommer", "replayEndText": "Terminer la Reprise", "replayNameDefaultText": "Reprise du Match Précédent", @@ -1285,7 +1349,9 @@ "runBoldText": "COURIR", "runText": "Courir", "saveText": "Sauvegarder", - "scanScriptsErrorText": "Erreur(s) dans les scripts; voir journal pour détails.", + "scanScriptsErrorText": "Erreur(s) dans les scripts. Consulter le journal pour plus de détails.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} et ${NUM} autre(s) module(s) doivent être mis à jour pour l'API ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} doit être mis à jour pour l'API ${API}.", "scoreChallengesText": "Défis de Score", "scoreListUnavailableText": "Liste des scores indisponible.", "scoreText": "Score", @@ -1296,6 +1362,7 @@ }, "scoreWasText": "(A été ${COUNT})", "selectText": "Sélectionner", + "sendInfoDescriptionText": "Envoyez des informations sur l'état du compte et de l'application au développeur.\nVeuillez inclure votre nom ou la raison de l'envoi.", "seriesWinLine1PlayerText": "A GAGNÉ LA", "seriesWinLine1TeamText": "A GAGNÉ LA", "seriesWinLine1Text": "A GAGNÉ", @@ -1315,22 +1382,31 @@ "alwaysUseInternalKeyboardDescriptionText": "(un simple clavier sur l'écran pour taper du texte)", "alwaysUseInternalKeyboardText": "Toujours utiliser le clavier interne", "benchmarksText": "Benchmarks et Tests de Stress", + "devToolsText": "Outils de développeur", "disableCameraGyroscopeMotionText": "Désactiver le mouvement de gyroscope de la caméra", - "disableCameraShakeText": "Désactiver le tremblement de la camera", + "disableCameraShakeText": "Désactiver le tremblement de la caméra", "disableThisNotice": "(vous pouvez désactiver cette notification dans les paramètres avancés)", "enablePackageModsDescriptionText": "(activer plusieurs capabilités des mods mais désactiver le jeu en réseau)", "enablePackageModsText": "Activer les Packages Mods Locaux", "enterPromoCodeText": "Entrez code", "forTestingText": "Note: ces valeurs sont exclusivement pour les tests et seront perdus à la fermeture de l'application.", "helpTranslateText": "Les traductions de ${APP_NAME} proviennent des efforts de \nla communauté. Si vous voulez contribuer ou corriger une \ntraduction, suivez le lien ci-dessous. Merci d'avance!", + "insecureConnectionsDescriptionText": "Non recommandé, mais peut permettre le jeu en ligne \ndepuis des pays ou des réseaux restreints.", + "insecureConnectionsText": "Utilisez des connexions non sécurisées", "kickIdlePlayersText": "Déconnecter les joueurs inactifs", "kidFriendlyModeText": "Mode Enfant-Gentil (moins de violence, etc)", - "languageText": "Langage", + "languageText": "Langue", "moddingGuideText": "Guide pour Modder", + "moddingToolsText": "Outils de mod", "mustRestartText": "Vous devez redémarrer le jeu pour que les changements prennent effet.", "netTestingText": "Tester Votre Réseau", "resetText": "Réinitialiser", + "sendInfoText": "Envoyer des informations", "showBombTrajectoriesText": "Montrer les trajectoires de bombe", + "showDemosWhenIdleText": "Afficher les démonstrations en cas d'inactivité", + "showDeprecatedLoginTypesText": "Afficher les types de connexions obsolètes", + "showDevConsoleButtonText": "Afficher le bouton de la console de développeur", + "showInGamePingText": "Afficher la latence en jeu", "showPlayerNamesText": "Montrer les Noms des Joueurs", "showUserModsText": "Montrer le Dossier des Mods", "titleText": "Avancé", @@ -1338,8 +1414,8 @@ "translationFetchErrorText": "statut de la traduction indisponible", "translationFetchingStatusText": "vérification du statut de la traduction...", "translationInformMe": "M'avertir quand ma langue a besoin de mises à jour", - "translationNoUpdateNeededText": "ce langage est à jour; woohoo!", - "translationUpdateNeededText": "** ce langage à besoin des modifications!! **", + "translationNoUpdateNeededText": "Cette langue est à jour; youpi !", + "translationUpdateNeededText": "** Cette langue a besoin de modification ! **", "vrTestingText": "Test de la RV" }, "shareText": "Partager", @@ -1349,6 +1425,9 @@ "signInWithGameCenterText": "Pour l'utilisation d'un compte Game \nCenter, connectez-vous avec l'application Game Center.", "singleGamePlaylistNameText": "Seulement ${GAME}", "singlePlayerCountText": "1 joueur", + "sizeLargeText": "Large", + "sizeMediumText": "Moyen", + "sizeSmallText": "Petit", "soloNameFilterText": "${NAME} Solo", "soundtrackTypeNames": { "CharSelect": "Sélection du Personnage", @@ -1374,6 +1453,7 @@ }, "spaceKeyText": "espace", "statsText": "Stats", + "stopRemindingMeText": "Ne plus me le rappeler", "storagePermissionAccessText": "Cette action a besoin de l'accès au stockage", "store": { "alreadyOwnText": "Vous avez déja acheté ${NAME}!", @@ -1425,6 +1505,8 @@ "storeText": "Magasin", "submitText": "Soumettre", "submittingPromoCodeText": "Envoi du code...", + "successText": "Succès!", + "supportEmailText": "Si vous rencontrez des problèmes avec \nl'application, veuillez envoyer un e-mail à ${EMAIL}.", "teamNamesColorText": "Noms d'équipe/Couleurs...", "teamsText": "Équipes", "telnetAccessGrantedText": "L'accès Telnet est activé.", @@ -1435,6 +1517,7 @@ "testBuildValidatedText": "Version Test Validée; Amusez-Vous!", "thankYouText": "Merci pour votre soutien! Amusez-vous!!", "threeKillText": "TRIPLE MEURTRE!!!", + "ticketsDescriptionText": "Utilisez les tickets pour débloquer des personnages,\ncartes, mini-jeux, et d'autres dans la boutique.\n\nTrouvez les tickets dans des coffres gagnés grâce aux\ncampagnes, tournois et succès.", "timeBonusText": "Bonus de Temps", "timeElapsedText": "Temps Passé", "timeExpiredText": "Temps Expiré", @@ -1445,10 +1528,24 @@ "tipText": "Conseil", "titleText": "BombSquad", "titleVRText": "RV BombSquad", + "tokens": { + "getTokensText": "Obtenir des jetons", + "notEnoughTokensText": "Vous n'avez pas assez de jetons !", + "numTokensText": "${COUNT} Jetons", + "openNowDescriptionText": "Vous avez assez de jetons pour\nouvrir ceci maintenant - vous n’avez\npas besoin d’attendre.", + "shinyNewCurrencyText": "La nouvelle monnaie brillante de BombSquad.", + "tokenPack1Text": "Petit paquet de jeton", + "tokenPack2Text": "Paquet de jeton moyen", + "tokenPack3Text": "Grand paquet de jeton", + "tokenPack4Text": "Paquet géant de jeton", + "tokensDescriptionText": "Les jetons permettent d'accélérer le déblocage des coffres\net pour d'autres fonctionnalités du jeu et du compte.\n\nVous pouvez gagner des jetons dans le jeu ou les acheter\nen packs. Ou achetez un Pass Or pour des jetons infinis\net n'en entendez plus jamais parler.", + "youHaveGoldPassText": "Vous avez un pass d'or.\nTout les achats de jeton sont gratuit.\nProfitez-en !" + }, "topFriendsText": "Les amis les mieux classés", "tournamentCheckingStateText": "Vérification de l'état du tournoi; attendez SVP...", "tournamentEndedText": "Ce tournoi est terminé. Un nouveau commencera bientôt.", "tournamentEntryText": "Inscription au Tournoi", + "tournamentFinalStandingsText": "Classement final", "tournamentResultsRecentText": "Résultats des Tournois Récents", "tournamentStandingsText": "Classements du Tournoi", "tournamentText": "Tournoi", @@ -1522,6 +1619,18 @@ "Uber Onslaught": "Bousculade Uber", "Uber Runaround": "Défense du portail Uber" }, + "displayItemNames": { + "${C} Tickets": "${C} Tickets", + "${C} Tokens": "${C} Jetons", + "Chest": "Coffre", + "L1 Chest": "Coffre N1", + "L2 Chest": "Coffre N2", + "L3 Chest": "Coffre N3", + "L4 Chest": "Coffre N4", + "L5 Chest": "Coffre N5", + "L6 Chest": "Coffre N6", + "Unknown Chest": "Coffre inconnu" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Restez l'élu pendant un certain temps pour gagner.\nTuez l'élu pour devenir l'élu.", "Bomb as many targets as you can.": "Bombardez autant de cibles que vous pouvez.", @@ -1627,6 +1736,7 @@ "Korean": "Coréen", "Malay": "Malais", "Persian": "Persan", + "PirateSpeak": "Parole de pirate", "Polish": "Polonais", "Portuguese": "Portugais", "Romanian": "Roumain", @@ -1701,6 +1811,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Tricherie détectée, scores et prix suspendus pour ${COUNT} jours.", "Could not establish a secure connection.": "Impossible d'établir une connexion sécurisé.", "Daily maximum reached.": "Limite quotidienne atteinte.", + "Daily sign-in reward": "Décompense de connexion quotidienne", "Entering tournament...": "Accès au tournoi...", "Invalid code.": "Code invalide.", "Invalid payment; purchase canceled.": "Payement invalide. Achat annulé.", @@ -1710,11 +1821,14 @@ "Item unlocked!": "Article débloqué!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LIEN REFUSÉ. ${ACCOUNT} contient des\ndonnées importantes qui seraient perdus.\nVous pouvez lier dans l'ordre inverse si vous le souhaitez\n(et perdre les données de CE compte à la place)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Lier le compte ${ACCOUNT} à ce compte?\nToutes les données existantes sur ${ACCOUNT} seront perdues.\nCela ne peut pas être annulé. Vous en êtes sûr", + "Longer streaks lead to better rewards.": "Des séquences plus longues mènent à de meilleures récompenses.", "Max number of playlists reached.": "Nombre maximum de playlists atteint.", "Max number of profiles reached.": "Nombre maximum de profils atteint.", "Maximum friend code rewards reached.": "Maximum récompenses de code ami atteint.", "Message is too long.": "Message trop long.", + "New tournament result!": "Nouveau résultat du tournoi!", "No servers are available. Please try again soon.": "Aucun serveur disponible. S'il vous plaît réessayez plus tard.", + "No slots available. Free a slot and try again.": "Aucun emplacement libre. Libérez-en un et réessayez.", "Profile \"${NAME}\" upgraded successfully.": "Le profil \"${NAME}\" à été mis à jour.", "Profile could not be upgraded.": "Le profil ne peut pas être mis à jour.", "Purchase successful!": "Achat réussi!", @@ -1724,7 +1838,9 @@ "Sorry, this code has already been used.": "Désolé, ce code a déjà été utilisé.", "Sorry, this code has expired.": "Désolé, ce code a expiré.", "Sorry, this code only works for new accounts.": "Désolé, ce code fonctionne seulement pour les nouveaux comptes.", + "Sorry, this has expired.": "Désolé, il a expiré.", "Still searching for nearby servers; please try again soon.": "Recherche de serveurs à proximité en cours; s'il vous plaît réessayez plus tard.", + "Streak: ${NUM} days": "Série : ${NUM} jours", "Temporarily unavailable; please try again later.": "Temporairement indisponible; veuillez réessayer plus tard.", "The tournament ended before you finished.": "Le tournoi s'est terminé avant que vous finissiez.", "This account cannot be unlinked for ${NUM} days.": "Ce compte ne peux pas être dissocié pendant ${NUM} jours.", @@ -1735,19 +1851,28 @@ "Tournaments require ${VERSION} or newer": "Les tournois nécessitent ${VERSION} ou plus récent", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Dissocier ${ACCOUNT} de ce compte?\nToutes les données sur ${ACCOUNT} seront réinitialisées.\n(à l'exception des achèvements dans certains cas)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATTENTION: des plaintes de piratage/tricherie ont été émises contre votre compte.\nLes comptes piratés sont interdits et bannis. S'il vous plaît, jouez fair play", + "Wait reduced!": "Attente réduite!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Attention : Cette version du jeu est limitée aux anciennes données de compte ; des éléments pourraient manquer ou être obsolètes.\nVeuillez mettre le jeu à jour dans une version plus récente pour voir vos dernières données de compte.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Voulez-vous lier votre compte d'appareil à celui-ci?\n\nVotre compte d'appareil est ${ACCOUNT1}\nCe compte est ${ACCOUNT2}\n\nCeci vous permet de garder votre progression.\nAttention: ceci est permanent!", "You already own this!": "Vous possédez déjà ceci!", "You can join in ${COUNT} seconds.": "Vous pouvez rejoindre dans ${COUNT} secondes.", "You don't have enough tickets for this!": "Vous n'avez pas assez de tickets pour ça!", "You don't own that.": "Cela ne vous appartient pas!", "You got ${COUNT} tickets!": "Vous avez reçu ${COUNT} tickets!", + "You got ${COUNT} tokens!": "Vous obtenez ${COUNT} jetons!", "You got a ${ITEM}!": "Vous avez reçu un ${ITEM}!", + "You got a chest!": "Tu as un coffre!", + "You got an achievement reward!": "Vous recevez une récompense de succès!", "You have been promoted to a new league; congratulations!": "Vous avez été promu à une ligue supérieure; félicitations!", + "You lost a chest! (All your chest slots were full)": "Vous perdez un coffre! (Tous vos coffres étaient pleins)", + "You must update the app to view this.": "Mettez à jour l'app pour voir ceci.", "You must update to a newer version of the app to do this.": "L'app doit être mise à jour pour faire ceci.", "You must update to the newest version of the game to do this.": "Vous devez mettre à jour vers une version plus récente pour faire ça.", "You must wait a few seconds before entering a new code.": "Vous devez attendre quelques secondes avant d'entrer un nouveau code.", + "You placed #${RANK} in a tournament!": "Vous avez placé #${RANK} dans un tournoi!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Vous avez été classé #${RANK} au dernier tournoi. Merci d'avoir participé!", "Your account was rejected. Are you signed in?": "Votre compte a été rejeté. Êtes-vous connecté?", + "Your ad views are not registering. Ad options will be limited for a while.": "Vos vues pubs ne sont pas enregistrées. Les options pubs seront limitées pendant un temps.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Votre copie du jeu a été modifié.\nRéinitialisez tous changements et réessayez.", "Your friend code was used by ${ACCOUNT}": "Votre code d'ami a été utilisé par ${ACCOUNT}" }, @@ -1901,11 +2026,14 @@ "toSkipPressAnythingText": "(appuyez n'importe où pour passer le tutoriel)" }, "twoKillText": "DOUBLE MEURTRE!", + "uiScaleText": "Échelle UI", "unavailableText": "indisponible", + "unclaimedPrizesText": "Vous avez des prix non réclamés !", "unconfiguredControllerDetectedText": "Contrôleur non-configuré détecté:", "unlockThisInTheStoreText": "Cela doit être débloqué dans le magasin.", "unlockThisProfilesText": "Pour créer plus de ${NUM} profiles, vous avez besoin de:", "unlockThisText": "Pour débloquer ceci, vous avez besoin:", + "unsupportedControllerText": "Désolé, contrôleur \"${NAME}\" pas pris en charge.", "unsupportedHardwareText": "Désolé, ce hardware n'est pas supporté par cette version du jeu.", "upFirstText": "En premier:", "upNextText": "Le jeu ${COUNT} sera:", @@ -1913,12 +2041,16 @@ "upgradeText": "Mise à jour", "upgradeToPlayText": "Débloquez \"${PRO}\" dans le magasin pour jouer ceci.", "useDefaultText": "Utilisez le Défaut", + "userSystemScriptsCreateText": "Créer un script système d'utilisateur", + "userSystemScriptsDeleteText": "Script système de suppression d'utilisateur", "usesExternalControllerText": "Ce jeu utilise un contrôleur externe pour l'input.", "usingItunesText": "Utilisez Music App pour la bande-son...", "usingItunesTurnRepeatAndShuffleOnText": "Vérifiez que 'Lecture Aléatoire'='ACTIF' et 'Reprise'='TOUT' dans iTunes.", "v2AccountLinkingInfoText": "Pour lier des comptes V2, utilisez le bouton 'Gérer compte'.", + "v2AccountRequiredText": "Ceci requière un compte V2. Veuillez mettre à jour votre compte et essayez à nouveau.", "validatingBetaText": "Validation de la beta...", "validatingTestBuildText": "Validation de la Version Test...", + "viaText": "via", "victoryText": "Victoire!", "voteDelayText": "Vous ne pouvez commencer un autre vote que dans ${NUMBER} secondes", "voteInProgressText": "Un vote est déjà en cours.", @@ -1985,5 +2117,6 @@ }, "yesAllowText": "Oui, Autoriser!", "yourBestScoresText": "Vos meilleurs scores", - "yourBestTimesText": "Vos meilleurs temps" + "yourBestTimesText": "Vos meilleurs temps", + "yourPrizeText": "Votre prix:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/german.json b/dist/ba_data/data/languages/german.json index 34bb04d0..e58facc8 100644 --- a/dist/ba_data/data/languages/german.json +++ b/dist/ba_data/data/languages/german.json @@ -1,13 +1,15 @@ { "accountSettingsWindow": { - "accountNameRules": "Der Konto Name darf kein Emoji oder andere spezielle Buchstaben enthalten.", + "accountNameRules": "Der Konto Name kann keine Emojis oder andere spezielle Zeichen enthalten", "accountProfileText": "Benutzerprofil", - "accountsText": "Konten", + "accountsText": "Accounts", "achievementProgressText": "Erfolge: ${COUNT} von ${TOTAL}", "campaignProgressText": "Kampagnen Fortschritt [Schwer]: ${PROGRESS}", "changeOncePerSeason": "Du kannst dies nur einmal pro Saison ändern.", - "changeOncePerSeasonError": "Du musst warten bis du das wieder in der nächsten Saison ändern kannst. (${NUM} Tage)", + "changeOncePerSeasonError": "Du musst warten auf die nächste Saison warten um dies zu ändern. (${NUM} Tage)", + "createAnAccountText": "Konto erstellen", "customName": "Benutzerdefinierter Name", + "deleteAccountText": "Account löschen", "googlePlayGamesAccountSwitchText": "Wenn Sie ein anderes Google-Konto verwenden möchten,\nVerwenden Sie die Google Play Games-App, um zu wechseln.", "linkAccountsEnterCodeText": "Code eingeben", "linkAccountsGenerateCodeText": "Code generieren", @@ -26,14 +28,16 @@ "setAccountNameDesc": "Wählen Sie den Namen aus, der für Ihr Konto angezeigt werden soll.\nSie können den Namen von einem Ihrer verlinkten\nKonten benutzen oder erstellen Sie einen einzigartigen benutzerdefinierten Name.", "signInInfoText": "Melde dich an, um deinen Fortschritt in der Cloud zu speichern,\nTickets zu verdienen und an Turnieren teilzunehmen.", "signInText": "Anmelden", + "signInWithAnEmailAddressText": "Gib eine E-Mail Adresse an.", "signInWithDeviceInfoText": "(ein automatisches Konto, das du nur auf diesem Gerät benutzen kannst)", "signInWithDeviceText": "Mit Gerät-Konto einloggen", "signInWithGameCircleText": "Mit Game Circle einloggen", "signInWithGooglePlayText": "Mit Google Play anmelden", "signInWithTestAccountInfoText": "(veraltete Kontoart, benutze Geräte-Kontos)", "signInWithTestAccountText": "Mit Testkonto einloggen", + "signInWithText": "Gib es an mit${SERVICE}", "signInWithV2InfoText": "(Ein Account der auf allen Plattformen funktioniert)", - "signInWithV2Text": "Einloggen mit einem BombSquad Account", + "signInWithV2Text": "Einloggen mit einem ${APP_NAME} Account", "signOutText": "Abmelden", "signingInText": "Anmelden...", "signingOutText": "Abmelden...", @@ -340,9 +344,14 @@ "titleText": "Spiel hinzufügen", "titleTextScale": 1.0 }, + "addToFavoritesText": "Zu Favoriten hinzufügen", + "addedToFavoritesText": "'${NAME}' zu Favoriten hinzugefügt.", + "allText": "Alle", "allowText": "Erlauben", "alreadySignedInText": "Dein Account wird schon von einem anderen Gerät verwendet;\nbitte wechsle den Account oder schließe das Spiel auf\ndeinem anderen Gerät und versuche es nochmal.", "apiVersionErrorText": "Das Modul ${NAME} kann nicht geladen werden. Es benutzt API-Version ${VERSION_USED}, aber wir brauchen ${VERSION_REQUIRED}.", + "applyText": "Anwenden", + "areYouSureText": "Bist du dir sicher?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" erlaubt das nur, wenn Kopfhörer angeschlossen sind)", "headRelativeVRAudioText": "Kopf-Orientiertes VR Audio", @@ -367,14 +376,24 @@ "boostText": "Boost", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} ist in der App konfiguriert.", "buttonText": "Taste", - "canWeDebugText": "Möchtest du, dass BombSquad automatisch Fehler, Abstürze\nund Benutzeraktivitäten an den Entwickler sendet?\n\nDiese Daten enthalten keinerlei persönliche Informationen\nund helfen, das Spiel reibungslos und fehlerfrei zu erhalten.", + "canWeDebugText": "Möchtest du, dass ${APP_NAME} automatisch Fehler, Abstürze\nund Benutzeraktivitäten an den Entwickler sendet?\n\nDiese Daten enthalten keinerlei persönliche Informationen\nund helfen, das Spiel reibungslos und fehlerfrei zu erhalten.", "cancelText": "Abbrechen", "cantConfigureDeviceText": "Entschuldigung, ${DEVICE} ist nicht konfigurierbar.", "challengeEndedText": "Diese Herausforderung ist beendet.", "chatMuteText": "Chat stummschalten", "chatMutedText": "Chat stumm", "chatUnMuteText": "Chat aktivieren", + "chests": { + "prizeOddsText": "Preis Chancen", + "reduceWaitText": "Wartezeit verkürzen", + "slotDescriptionText": "Hier könnte eine Truhe sein.\n\nVerdiene Truhen, indem du Kampagnenlevels spielst,\nin Turnieren gewinnst und durch das Erreichen von \nErfolgen.", + "slotText": "Truhen Slot ${NUM}", + "slotsFullWarningText": "WARNUNG: Alle Ihre Truhenplätze sind voll.\nAlle Truhen, die du in diesem Spiel verdienst, sind verloren.", + "unlocksInText": "Freigeschaltet In" + }, "choosingPlayerText": "", + "claimText": "Beanspruchen", + "codesExplainText": "Die Codes werden verwaltet von dem Entwickler,\nDieser diagnostiziert und korrigiert Kontenprobleme.", "completeThisLevelToProceedText": "Du musst dieses Level\nabschließen um fortzufahren!", "completionBonusText": "Bewältigungsbonus", "configControllersWindow": { @@ -464,6 +483,7 @@ "titleText": "Touchscreen einstellen", "touchControlsScaleText": "Touch Steuerung Skalierung" }, + "configureDeviceInSystemSettingsText": "${DEVICE} kann in der System Settings App eingestellt werden.", "configureItNowText": "Konfiguriere es jetzt?", "configureText": "Konfigurieren", "connectMobileDevicesWindow": { @@ -509,7 +529,7 @@ "powerRankingPointsToRankedText": "(${CURRENT} von ${REMAINING} pkte)", "powerRankingText": "Power Rang", "prizesText": "Preise", - "proMultInfoText": "Spieler mit dem ${PRO} Upgrade\nbekommen zu ${PERCENT}% mehr Punkte hier.", + "proMultInfoText": "Spieler mit dem ${PRO} Upgrade\nbekommen ${PERCENT}% Bonuspunkte.", "seeMoreText": "Sieh weitere...", "skipWaitText": "Überspringen", "timeRemainingText": "Übrige Zeit", @@ -577,6 +597,7 @@ "demoText": "Demo", "denyText": "Verweigern", "deprecatedText": "Veraltet", + "descriptionText": "Beschreibung", "desktopResText": "Desktop Auflösung", "deviceAccountUpgradeText": "Achtung:\nDu bist mit einem Gerät-Konto angemeldet (${NAME}).\nGerät-Konten werden in einem kommendem Update entfernt.\nVerbessere zu einem V2 Konto, wenn du deinen Fortschritt behalten willst.", "difficultyEasyText": "Leicht", @@ -587,6 +608,10 @@ "disableRemoteAppConnectionsText": "Remote-App Verbindungen verbieten", "disableXInputDescriptionText": "Erlaubt mehr als 4 Controller aber kann schlechter funktionieren.", "disableXInputText": "XInput deaktivieren", + "disabledText": "Deaktiviert", + "discardText": "Verwerfen", + "discordFriendsText": "Suchst du neue Leute mit denen du spielen kannst? Trete unserem Discord bei und finde neue Freunde!", + "discordJoinText": "Treten Sie Discord bei", "doneText": "Fertig", "drawText": "Unentschieden", "duplicateText": "dublizieren", @@ -621,6 +646,7 @@ "localProfileText": "Lokales Profil", "nameDescriptionText": "Spielername", "nameText": "Name", + "profileAlreadyExistsText": "Ein Profil mit diesem Namen existiert schon.", "randomText": "zufällig", "titleEditText": "Profil bearbeiten", "titleNewText": "Neues Profil", @@ -660,6 +686,7 @@ "useMusicFolderText": "Ordner mit Musikdateien" }, "editText": "bearbeiten", + "enabledText": "Atkiviert", "endText": "Ende", "enjoyText": "Viel Spaß!", "epicDescriptionFilterText": "${DESCRIPTION} In epischer Zeitlupe.", @@ -671,6 +698,8 @@ "errorText": "Fehler", "errorUnknownText": "unbekannter Fehler", "exitGameText": "${APP_NAME} verlassen?", + "expiredAgoText": "Seit ${T} ausgelaufen", + "expiresInText": "Läuft aus in ${T}", "exportSuccessText": "'${NAME}' exportiert.", "externalStorageText": "externer Datenspeicher", "failText": "Fehlgeschlagen", @@ -707,6 +736,8 @@ "editText": "Playlist\nbearbeiten", "gameListText": "Spieleliste", "newText": "Neue\nPlaylist", + "pointsToWinText": "Punkte um zu Gewinnen", + "seriesLengthText": "Serienlänge", "showTutorialText": "Tutorial anzeigen", "shuffleGameOrderText": "Zufällige Spielreihenfolge", "titleText": "${TYPE}-Playlists bearbeiten" @@ -735,6 +766,7 @@ "copyCodeConfirmText": "Veranstalten Sie eine private Party", "copyCodeText": "Code kopieren", "dedicatedServerInfoText": "Das beste Ergebnis wird mit einem dedizierten Server erreicht. Auf bombsquadgame.com/server steht wie es geht.", + "descriptionShortText": "Nutz das Party Fenster um eine Party zu kreieren.", "disconnectClientsText": "Dadurch werden die ${COUNT} Spieler in Ihrer\nParty getrennt. Sind Sie sicher ?", "earnTicketsForRecommendingAmountText": "Freunde bekommen ${COUNT} Tickets, wenn sie das Spiel ausprobieren.\n(Du bekommst ${YOU_COUNT} für jeden, der es tut.)", "earnTicketsForRecommendingText": "Empfehle das Spiel an Freunde \nund ihr bekommt beide Tickets.", @@ -748,10 +780,10 @@ "friendPromoCodeAwardText": "Du bekommst ${COUNT} Tickets bei jeder Verwendung.", "friendPromoCodeExpireText": "Der Code wird in ${EXPIRE_HOURS} Stunden ungültig und funktioniert nur für neue Spieler.", "friendPromoCodeInfoText": "Kann für ${COUNT} Tickets eingelöst werden.\n\nGehe zu \"Einstellungen -> Erweitert -> Gutscheincode eingeben\" im Spiel um den Code einzulösen.\nBesuche bombsquadgame.com um das Spiel für alle unterstützten Platformen herunterzuladen.\nDieser Code wird in ${EXPIRE_HOURS} Stunden ungültig und kann nur von neuen Spielern eingelöst werden.", - "friendPromoCodeInstructionsText": "Um ihn einzulösen, öffne ${APP_NAME} und gehe zu \"Einstellungen->Erweitert->Gutscheincode eingeben\".\nAuf bombsquadgame.com findest du Links zum Download für alle unterstützten Plattformen.", + "friendPromoCodeInstructionsText": "Um ihn einzulösen,öffne ${APP_NAME} und gehe zu \"Einstellungen->erweitert-Information senden\".Auf bombsquad.com findest du Links zum Download für alle unterstützen\n Plattformen.", "friendPromoCodeRedeemLongText": "Er kann für ${COUNT} kostenlose Tickets von bis zu ${MAX_USES} Personen eingelöst werden.", "friendPromoCodeRedeemShortText": "Es kann im Spiel für ${COUNT} eingelöst werden.", - "friendPromoCodeWhereToEnterText": "(in \"Einstellungen->Erweitert->Gutscheincode eingeben\")", + "friendPromoCodeWhereToEnterText": "(In \"Einstellungen->erweitert->Informationen senden\")", "getFriendInviteCodeText": "Bekomme einen Einladungscode für Freunde", "googlePlayDescriptionText": "Lade Google Play Freunde zu deiner Party ein:", "googlePlayInviteText": "Einladen", @@ -783,6 +815,7 @@ "manualYourLocalAddressText": "Deine Lokale Adresse", "nearbyText": "In der Nähe", "noConnectionText": "", + "noPartiesAddedText": "Keine Partys ergänzt", "otherVersionsText": "(andere Versionen)", "partyCodeText": "Party Code", "partyInviteAcceptText": "Akzeptieren", @@ -855,6 +888,12 @@ "youHaveShortText": "Du hast ${COUNT}", "youHaveText": "Du hast ${COUNT} Tickets" }, + "goldPass": { + "desc1InfTokensText": "Unendliche Token.", + "desc2NoAdsText": "Keine Werbung.", + "desc3ForeverText": "Dauerhaft.", + "goldPassText": "Gold Pass" + }, "googleMultiplayerDiscontinuedText": "Sorry, Googles Multiplayerservice ist nicht länger verfügbar.\nIch arbeite so schnell wie möglich an einem Ersatz.\nBis dahin, versuche bitte eine andere Verbindungsmethode.\n-Eric", "googlePlayPurchasesNotAvailableText": "Google Play-Käufe sind nicht verfügbar.\nMöglicherweise müssen Sie Ihre Store-App aktualisieren.", "googlePlayServicesNotAvailableText": "Google Play-Dienste sind nicht verfügbar.\nEinige App-Funktionen sind möglicherweise deaktiviert.", @@ -864,10 +903,12 @@ "autoText": "Automatisch", "fullScreenCmdText": "Vollbildmodus (Cmd-F)", "fullScreenCtrlText": "Vollbildmodus (Strg-F)", + "fullScreenText": "Vollbild", "gammaText": "Gamma", "highText": "Hoch", "higherText": "Höher", "lowText": "Niedrig", + "maxFPSText": "Max FPS", "mediumText": "Mittel", "neverText": "Niemals", "resolutionText": "Auflösung", @@ -949,6 +990,7 @@ "importText": "Importieren", "importingText": "Wird importiert...", "inGameClippedNameText": "Im Spiel angezeigter Name wird \n\"${NAME}\"", + "inboxText": "Nachrichten", "installDiskSpaceErrorText": "ERROR: Installation wurde nicht abgeschlossen.\nEs ist nicht genug Speicherplatz verfügbar.\nVersuche es erneut, nachdem genügend Speicher freigegeben wurde.", "internal": { "arrowsToExitListText": "drücke ${LEFT} oder ${RIGHT}, um die Liste zu verlassen", @@ -1005,12 +1047,14 @@ "touchScreenJoinWarningText": "Du bist mit dem Touchscreen beigetreten.\nWenn das ein Versehen war, drücke 'Menü->Spiel Beenden' damit.", "touchScreenText": "TouchScreen", "trialText": "Testversion", + "unableToCompleteTryAgainText": "Diese Aktion ist gerade nicht möglich. \nBitte versuche es später erneut", "unableToResolveHostText": "Fehler: Verbindung zum Host konnte nicht aufgelöst werden.", "unavailableNoConnectionText": "Zurzeit nicht verfügbar. (Keine Internetverbindung?)", "vrOrientationResetCardboardText": "Benutze dies,um die VR orientierung zurückzusetzen.\nUm das Spiel spielen zu können, brauchst du einen externen controller.", "vrOrientationResetText": "Kalibriere VR Orientierung.", "willTimeOutText": "(wird unterbrochen, wenn keine Eingabe)" }, + "inventoryText": "Inventar", "jumpBoldText": "SPRING", "jumpText": "Spring", "keepText": "Halten", @@ -1057,8 +1101,11 @@ "seasonEndsMinutesText": "Die Saison endet in ${NUMBER} Minuten.", "seasonText": "Saison ${NUMBER}", "tournamentLeagueText": "Du musst die ${NAME} Liga erreichen um dieses Turnier zu spielen.", - "trophyCountsResetText": "Die Trophäenzahl wird nächste Season zurückgesetzt." + "trophyCountsResetText": "Die Trophäenzahl wird nächste Season zurückgesetzt.", + "upToDateBonusDescriptionText": "Spiele mit den neuesten Bombsquad Version \nerhalten hier einen ${PERCENT}%igen Bonus.", + "upToDateBonusText": "Aktuell-Bonus" }, + "learnMoreText": "Erfahre mehr", "levelBestScoresText": "Bestes Ergebnis bei ${LEVEL}", "levelBestTimesText": "Beste Zeiten bei ${LEVEL}", "levelFastestTimesText": "Schnellste Zeit auf ${LEVEL}", @@ -1105,6 +1152,8 @@ "modeArcadeText": "Arcade-Modus", "modeClassicText": "Klassischer Modus", "modeDemoText": "Demo Modus", + "moreSoonText": "Mehr ist in Arbeit...", + "mostDestroyedPlayerText": "Meist zerstörter Spieler", "mostValuablePlayerText": "Wertvollster Spieler", "mostViolatedPlayerText": "Meist getöteter Spieler", "mostViolentPlayerText": "Brutalster Spieler", @@ -1121,6 +1170,7 @@ "nameSuicideText": "${NAME} begeht Selbstmord.", "nameText": "Name", "nativeText": "Native Einstellung", + "newExclaimText": "Neu!", "newPersonalBestText": "Neuer persönlicher Rekord!", "newTestBuildAvailableText": "Ein neuerer Test-Build ist erhältlich (${VERSION} Build ${BUILD}).\nZu holen auf ${ADDRESS}", "newText": "Neu", @@ -1132,13 +1182,17 @@ "noExternalStorageErrorText": "Kein externer Datenspeicher auf dem Gerät gefunden", "noGameCircleText": "Fehler: nicht in GameCircle eingeloggt", "noJoinCoopMidwayText": "Koop-Spiele können nicht während des Spiels betreten werden.", + "noMessagesText": "Keine Nachrichten.", + "noPluginsInstalledText": "Keine Plugins installiert", "noProfilesErrorText": "Du hast kein Spielerprofil, deshalb ist dein Name \"${NAME}\".\nGehe zu Einstellungen->Spielerprofile um ein Profil anzulegen.", "noScoresYetText": "Noch kein Punktestand.", + "noServersFoundText": "Keine Server gefunden.", "noThanksText": "Nein Danke", "noTournamentsInTestBuildText": "WARNUNG: Turnierpunkte von dieser Testversion werden ignoriert.", "noValidMapsErrorText": "Keine gültigen Karten für diesen Spieltyp gefunden.", "notEnoughPlayersRemainingText": "Nicht genug Spieler übrig; Spiel verlassen oder neues Spiel starten.", "notEnoughPlayersText": "Du benötigst mindestens ${COUNT} Spieler, um dieses Spiel zu starten.", + "notEnoughTicketsText": "Nicht genügend Tickets!", "notNowText": "Nicht jetzt", "notSignedInErrorText": "Du musst dich hierfür einloggen.", "notSignedInGooglePlayErrorText": "Hierfür musst du dich mit Google Play anmelden", @@ -1151,6 +1205,9 @@ "onText": "An", "oneMomentText": "Einen Moment...", "onslaughtRespawnText": "${PLAYER} steigt in Welle ${WAVE} wieder ein", + "openMeText": "Öffne mich!", + "openNowText": "Jetzt öffnen", + "openText": "Öffnen", "orText": "${A} oder ${B}", "otherText": "Sonstiges...", "outOfText": "(#${RANK} von ${ALL})", @@ -1246,6 +1303,8 @@ "punchText": "Schlagen", "purchaseForText": "Für ${PRICE} kaufen", "purchaseGameText": "Spiel kaufen", + "purchaseNeverAvailableText": "Sorry, Einkäufe sind auf dieser Plattform nicht möglich.\nLog dich in einen anderen Account einer anderen Plattform ein, und versuche dies von dort aus erneut.", + "purchaseNotAvailableText": "Dieser Einkauf ist nicht möglich.", "purchasingText": "Bezahlt...", "quitGameText": "${APP_NAME} beenden?", "quittingIn5SecondsText": "Verlasse das Spiel in 5 Sekunden...", @@ -1288,6 +1347,7 @@ "version_mismatch": "Versionskonflikt.\nVersuch es mit den aktuellen Versionen von\nBombSquad und BombSquad Remote noch einmal." }, "removeInGameAdsText": "Schalte \"${PRO}\" im Store frei, um Werbung zu entfernen.", + "removeInGameAdsTokenPurchaseText": "FÜR LIMITIERTE ZEIT: kaufe IRGENDEIN Token Pack und die Werbungen werden entfernt.", "renameText": "Name ändern", "replayEndText": "Wiederholung beenden", "replayNameDefaultText": "Letztes Spiel ansehen", @@ -1308,7 +1368,9 @@ "revertText": "Zurücksetzen", "runText": "Rennen", "saveText": "Speichern", - "scanScriptsErrorText": "Fehler beim scannen der Skripts; sehe Protokoll für Details.", + "scanScriptsErrorText": "Fehler beim Scannen der Skripts; siehe Protokoll für Details.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} und ${NUM} weitere(s) Modul(e) muss an API ${API} angepasst werden.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} muss an API ${API} angepasst werden.", "scoreChallengesText": "Punkte Herausforderungen", "scoreListUnavailableText": "Bestenliste ist nicht verfügbar", "scoreText": "Punkte", @@ -1319,6 +1381,7 @@ }, "scoreWasText": "(war ${COUNT})", "selectText": "Auswählen", + "sendInfoDescriptionText": "Senden Sie Konto- und App-informationen zum Entwickler.\nBitte ergänzen Sie Ihren Namen und den Grund des Sendens", "seriesWinLine1PlayerText": "GEWINNT DIE", "seriesWinLine1Scale": 0.65, "seriesWinLine1TeamText": "GEWINNT DIE", @@ -1340,24 +1403,32 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(Eine einfache, Controller-freundliche Bildschirmtastatur für Texte)", - "alwaysUseInternalKeyboardText": "Immer interne Tastatur benutzen", + "alwaysUseInternalKeyboardText": "Immer die interne Tastatur benutzen", "benchmarksText": "Benchmarks & Stress-Tests", + "devToolsText": "Entwicklungswerkzeuge", "disableCameraGyroscopeMotionText": "Deaktivieren Sie die Kamera-Gyroskop-Bewegung", - "disableCameraShakeText": "Deaktivieren Sie Camera Shake", + "disableCameraShakeText": "Deaktivieren Sie Kamera-Bewegungen.", "disableThisNotice": "(Du kannst diese Notiz in den erweiterten Einstellungen ändern.)", "enablePackageModsDescriptionText": "(Aktiviert installierte Mods aber deaktiviert den Mehrspielermodus)", "enablePackageModsText": "Local Package Mods aktivieren", "enterPromoCodeText": "Gutscheincode eingeben", "forTestingText": "Wichtig: Diese Werte sind nur für Tests und werden später wieder zurückgesetzt.", "helpTranslateText": "${APP_NAME}'s Übersetzungen sind der Community zu\nverdanken. Wenn du eine Übersetzung hinzufügen oder \nverbessern willst, folge dem Link unten. Danke im Voraus!", + "insecureConnectionsDescriptionText": "nicht empfohlen, kann dir jedoch die Online Play Funktion\nin eingeschränkten Ländern ermöglichen", + "insecureConnectionsText": "Instabile Verbindungen verwenden", "kickIdlePlayersText": "Inaktive Spieler verbannen", "kidFriendlyModeText": "Kinderfreundlicher Modus (Reduzierte Gewalt, etc.)", "languageText": "Sprache", "moddingGuideText": "Modding Anleitung", + "moddingToolsText": "Modding Werkzeuge", "mustRestartText": "Das Spiel muss neugestartet werden um die Änderungen wirksam zu machen.", "netTestingText": "Netzwerk Tests", "resetText": "Zurücksetzen", + "sendInfoText": "Information senden", "showBombTrajectoriesText": "Zeige die Bomben-Flugbahn", + "showDemosWhenIdleText": "Zeigen sie Abstimmungen, when sie inaktiv sind", + "showDeprecatedLoginTypesText": "Zeigen sie Login-Möglichkeiten", + "showDevConsoleButtonText": "Zeigen sie den Konsolen-Knopf", "showInGamePingText": "Zeige Ping im Spiel", "showPlayerNamesText": "Zeige Spielernamen", "showUserModsText": "Zeige Mods-Ordner", @@ -1366,8 +1437,8 @@ "translationFetchErrorText": "Übersetzungsstatus nicht verfügbar....", "translationFetchingStatusText": "prüfe Übersetzungsstatus...", "translationInformMe": "Informiere mich, wenn meine Sprache Updates benötigt.", - "translationNoUpdateNeededText": "Die ausgewählte Sprache ist aktuell; Juhuuu!", - "translationUpdateNeededText": "** die ausgewählte Sprache ist nicht aktuell!! **", + "translationNoUpdateNeededText": "Die aktuelle Sprache ist auf dem neuesten Stand; Juhuuu!", + "translationUpdateNeededText": "** Die ausgewählte Sprache benötigt Updates!! **", "vrTestingText": "VR Tests" }, "shareText": "Teilen", @@ -1377,6 +1448,9 @@ "signInWithGameCenterText": "Nutze die Game Center app,\num dich anzumelden.", "singleGamePlaylistNameText": "Nur ${GAME}", "singlePlayerCountText": "1 Spieler", + "sizeLargeText": "Groß", + "sizeMediumText": "Mittel", + "sizeSmallText": "Klein", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Charakterauswahl", @@ -1402,6 +1476,7 @@ }, "spaceKeyText": "Leer", "statsText": "Statistiken", + "stopRemindingMeText": "Nicht mehr erinnern", "storagePermissionAccessText": "Dies benötigt Zugriff auf deinen Speicher", "store": { "alreadyOwnText": "Du besitzt bereits ${NAME}!", @@ -1453,6 +1528,8 @@ "storeText": "Laden", "submitText": "Bestätigen", "submittingPromoCodeText": "Code wird übertragen...", + "successText": "Erfolg!", + "supportEmailText": "Wenn du irgendwelche Probleme mit der App hast, \nKontaktiere bitte den Entwickler ${EMAIL}", "teamNamesColorText": "Team Namen/Farben...", "teamsText": "Teams", "telnetAccessGrantedText": "Telnet Zugang aktiviert.", @@ -1463,6 +1540,7 @@ "testBuildValidatedText": "Testversion ist gültig; Viel Spaß!", "thankYouText": "Vielen Dank für deine Hilfe und viel Spaß!!", "threeKillText": "DREIFACH KILL!!", + "ticketsDescriptionText": "Tickets können zum Freischalten von Charakteren\nKarten, Minispiele und mehr im Shop freizuschalten.\n\nTickets können in Truhen gefunden werden, die durch\nKampagnen, Turnieren und Erfolge gewonnen werden.", "timeBonusText": "Zeitbonus", "timeElapsedText": "Vergangene Zeit", "timeExpiredText": "Zeit abgelaufen!", @@ -1473,10 +1551,24 @@ "tipText": "Tipp", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Hole Token", + "notEnoughTokensText": "Nicht genug Token!", + "numTokensText": "${COUNT} Token", + "openNowDescriptionText": "Du hast genug Münzen\num jetzt zu öffnen - du brauchst nicht \nzu warten.", + "shinyNewCurrencyText": "Bombsquad's neue glänzende Währung.", + "tokenPack1Text": "Kleines Token Paket", + "tokenPack2Text": "Mittleres Token Paket", + "tokenPack3Text": "Großes Token Paket", + "tokenPack4Text": "Riesen Token Paket", + "tokensDescriptionText": "Token werden verwendet, um die Freischaltung von Truhen zu beschleunigen\nund für andere Spiel- und Kontofunktionen.\n\nDu kannst Token im Spiel gewinnen oder sie\nin Paketen kaufen. Oder kaufe einen Gold Pass\nfür unendlich viele.", + "youHaveGoldPassText": "Du hast den Gold Pass.\nAlle Token-Einkäufe sind kostenlos.\nViel Spaß!" + }, "topFriendsText": "Top Freunde", "tournamentCheckingStateText": "Überprüfe Turnier Status; Bitte warten...", "tournamentEndedText": "Dieses Turnier ist zu Ende. Ein Neues startet bald.", "tournamentEntryText": "Turnier beitreten", + "tournamentFinalStandingsText": "Endstand", "tournamentResultsRecentText": "Neueste Turnierergebnisse", "tournamentStandingsText": "Tournier Tabelle", "tournamentText": "Turnier", @@ -1550,6 +1642,18 @@ "Uber Onslaught": "Unmöglich heftiger Angriff", "Uber Runaround": "Unmöglich an der Nase herumführen" }, + "displayItemNames": { + "${C} Tickets": "${C} Tickets", + "${C} Tokens": "${C} Tokens", + "Chest": "Truhe", + "L1 Chest": "L1 Truhe", + "L2 Chest": "L2 Truhe", + "L3 Chest": "L3 Truhe", + "L4 Chest": "L4 Truhe", + "L5 Chest": "L5 Truhe", + "L6 Chest": "L6 Truhe", + "Unknown Chest": "Unbekannte Truhe" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sei eine Zeit lang der Auserwählte, um zu gewinnen.\nTöte ihn, um selbst zum Auserwählten zu werden.", "Bomb as many targets as you can.": "Zerbombe so viele Ziele wie Du kannst.", @@ -1655,6 +1759,7 @@ "Korean": "Koreanisch", "Malay": "Malaiisch", "Persian": "Persisch", + "PirateSpeak": "Piratensprache", "Polish": "Polnisch", "Portuguese": "Portugiesisch", "Romanian": "Rumänisch", @@ -1729,6 +1834,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Cheating erkannt; deine Punkte und Preise sind für ${COUNT} Tage gesperrt.", "Could not establish a secure connection.": "Konnte keine sichere Verbindung herstellen.", "Daily maximum reached.": "Tageslimit erreicht.", + "Daily sign-in reward": "Tägliche Login Belohnung", "Entering tournament...": "Trete Turnier bei...", "Invalid code.": "Ungültiger Code", "Invalid payment; purchase canceled.": "Ungültige Zahlung; Einkauf abgebrochen.", @@ -1738,11 +1844,14 @@ "Item unlocked!": "Gegenstand freigeschaltet!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VERLINKUNG VERWEIGERT. ${ACCOUNT} beinhaltet\nwichtige Daten, die ALLE VERLOREN wären.\nDu kannst andersherum verlinken, wenn du willst\n(Du würdest stattdessen DIESE Account-Daten verlieren)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Den Account ${ACCOUNT} mit diesem Account verknüpfen?\nJeglicher Fortschritt des Accounts ${ACCOUNT} wird verloren gehen!\nDies kann nicht rückgängig gemacht werden! Fortfahren?", + "Longer streaks lead to better rewards.": "Je länger die Streaks, desto besser die Belohnung.", "Max number of playlists reached.": "Max Anzahl von Wiedergabelisten erreicht.", "Max number of profiles reached.": "Max Anzahl der Profile erreicht.", "Maximum friend code rewards reached.": "Maximale Anzahl an Einladungsbelohnungen erreicht.", "Message is too long.": "Nachricht ist zu lang.", + "New tournament result!": "Neues Turnier Ergebnis!", "No servers are available. Please try again soon.": "Keine Server verfügbar. Schau nachher noch einmal vorbei.", + "No slots available. Free a slot and try again.": "Keine Slots mehr verfügbar. Mach einen Slot frei und versuche es noch einmal", "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" erfolgreich aktualisiert.", "Profile could not be upgraded.": "Profil konnte nicht aktualisiert werden.", "Purchase successful!": "Einkauf erfolgreich!", @@ -1752,7 +1861,9 @@ "Sorry, this code has already been used.": "Tut uns leid, dieser Code wurde bereits eingelöst.", "Sorry, this code has expired.": "Tut uns leid, dieser Code ist nicht mehr gültig.", "Sorry, this code only works for new accounts.": "Tut uns leid, dieser Code kann nur mit einem neuen Account eingelöst werden.", + "Sorry, this has expired.": "Sorry, das ist abgelaufen.", "Still searching for nearby servers; please try again soon.": "Suche immernoch nach Servern in der Nähe; schau nachher noch einmal vorbei.", + "Streak: ${NUM} days": "Streak: ${NUM} Tage", "Temporarily unavailable; please try again later.": "Vorübergehend nicht verfügbar. Bitte versuche es später noch einmal.", "The tournament ended before you finished.": "Das Turnier endete bevor du ins Ziel kamst.", "This account cannot be unlinked for ${NUM} days.": "Dieser Account kann nicht für ${NUM} Tage entknüpft werden.", @@ -1763,19 +1874,28 @@ "Tournaments require ${VERSION} or newer": "Turniere benötigen Version ${VERSION} oder neuer", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Den Account ${ACCOUNT} von diesem Account entknüpfen?\nJeglicher Fortschritt auf ${ACCOUNT} wird zurückgesetzt.\n(außer Erfolge in manchen Fällen)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "Beschwerden von Hacking sind für deinen Account aufgetreten.\nAccount, welche des Hackings verdächtigt werden, werden gesperrt. Bitte spiele gerecht.", + "Wait reduced!": "Wartezeit verkürzt!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Warnung: Diese Version des Spiels verwendet veraltete Kontodaten. Einige Inhalte könnten fehlen oder nicht aktuell sein.\nBitte aktualisiere auf eine neuere Version, um deine aktuellen Kontodaten anzuzeigen.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Willst du deinen Gerät-Account mit diesem Account verlinken?\n\nDein Gerät-Account: ${ACCOUNT1}\nDieser Account: ${ACCOUNT2}\n\nDies wird dir ermöglichen, deinen Fortschritt zu behalten.\nAchtung: Du kannst es nicht rückgängig machen!", "You already own this!": "Du besitzt es bereits!", "You can join in ${COUNT} seconds.": "Du kannst in ${COUNT} Sekunden beitreten", "You don't have enough tickets for this!": "Du hast nicht genug Tickets dafür!", "You don't own that.": "Du besitzt das nicht.", "You got ${COUNT} tickets!": "Du hast ${COUNT} Tickets!", + "You got ${COUNT} tokens!": "Du hast ${COUNT} Token bekommen!", "You got a ${ITEM}!": "Du kriegst ein ${ITEM}!", + "You got a chest!": "Du hast eine Truhe bekommen!", + "You got an achievement reward!": "Du hast eine Belohnung für einen Erfolg erhalten!", "You have been promoted to a new league; congratulations!": "Du bist eine Liga aufgestiegen; Glückwunsch!", + "You lost a chest! (All your chest slots were full)": "Du hast eine Truhe verloren! (Alle Truhen Slots waren besetzt)", + "You must update the app to view this.": "Aktualisiere die App um es anzuzeigen.", "You must update to a newer version of the app to do this.": "Du musst deine Version updaten, um dies zu tun.", "You must update to the newest version of the game to do this.": "Du musst zur neusten Version des Spiels updaten um dies zu tun.", "You must wait a few seconds before entering a new code.": "Du musst ein wenig warten bevor du einen neuen Code eingeben kannst.", + "You placed #${RANK} in a tournament!": "Du bist #${RANK} in einem Turnier geworden!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Du hast den #${RANK} Platz im letzten Turnier erreicht. Danke fürs Spielen!", "Your account was rejected. Are you signed in?": "Dein Account wurde abgelehnt. Bist du eingeloggt?", + "Your ad views are not registering. Ad options will be limited for a while.": "Deine Anzeigenaufrufe werden derzeit nicht erfasst. Die Auswahl an Anzeigenoptionen ist vorübergehend eingeschränkt.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Die Kopie dieses Spiels wurde modifiziert.\nÄnderungen rückgängig machen & neu versuchen.", "Your friend code was used by ${ACCOUNT}": "Dein Freundschafts-Code wurde von ${ACCOUNT} verwendet." }, @@ -1929,11 +2049,14 @@ "toSkipPressAnythingText": "(beliebige Taste drücken um Tutorial zu überspringen)" }, "twoKillText": "DOPPEL KILL!", + "uiScaleText": "UI Wert", "unavailableText": "nicht verfügbar", + "unclaimedPrizesText": "Es warten noch Belohnungen auf dich!", "unconfiguredControllerDetectedText": "Unkonfigurierter Controller erkannt:", "unlockThisInTheStoreText": "Das muss im Store freigeschaltet werden.", "unlockThisProfilesText": "Um mehr als ${NUM} Profile zu erstellen, brauchst du:", "unlockThisText": "Um das zu entsperren brauchst du:", + "unsupportedControllerText": "Der Controller \"${NAME}\" wird nicht unterstützt", "unsupportedHardwareText": "Entschuldigung, diese Hardware wird nicht unterstützt.", "upFirstText": "Zuerst:", "upNextText": "Als Nächstes in Spiel ${COUNT}:", @@ -1941,12 +2064,16 @@ "upgradeText": "Verbessern", "upgradeToPlayText": "Upgrade auf \"${PRO}\" im Store um das zu Spielen.", "useDefaultText": "Standard benutzen", + "userSystemScriptsCreateText": "Erschaffen Sie Benutzer-System-Scripts", + "userSystemScriptsDeleteText": "Löschen Sie Benutzer-System-Scripts", "usesExternalControllerText": "Das Spiel nutzt einen externen Controller für die Eingaben.", "usingItunesText": "benutze Musik-App für Hintergrundmusik...", "usingItunesTurnRepeatAndShuffleOnText": "Stelle sicher, dass iTunes ZUFÄLLIG wiedergibt und ALLE wiederholt.", "v2AccountLinkingInfoText": "Um V2 Kontos zu verknüpfen, benutze den 'Konto Verwalten' Knopf.", + "v2AccountRequiredText": "Dazu wird ein V2 Account benötigt. Upgrade dein Account und versuche es erneut.", "validatingBetaText": "Verifizieren der Beta...", "validatingTestBuildText": "Bestätige Testversion...", + "viaText": "über", "victoryText": "Sieg!", "voteDelayText": "Die nächste Abstimmung kann erst in ${NUMBER} Sekunden gestartet werden.", "voteInProgressText": "Es wird bereits eine Abstimmung durchgeführt.", @@ -2022,5 +2149,6 @@ }, "yesAllowText": "Ja, erlauben!", "yourBestScoresText": "Deine besten Punktzahlen", - "yourBestTimesText": "Deine besten Zeiten" + "yourBestTimesText": "Deine besten Zeiten", + "yourPrizeText": "Deine Belohnung:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/gibberish.json b/dist/ba_data/data/languages/gibberish.json index 3968829f..0481f76e 100644 --- a/dist/ba_data/data/languages/gibberish.json +++ b/dist/ba_data/data/languages/gibberish.json @@ -1,14 +1,16 @@ { "accountRejectedText": "You ac woefije obj acwoew. Aj cowier wore cs?", "accountSettingsWindow": { - "accountNameRules": "Acoief coej. c woejf. cwoef ocoweofwjfj c wjefowfowef wocjowefffz", + "accountNameRules": "Acoief coej. woejf. cwoef ocoweofwjfj c wjefowfowef wocjowedffz", "accountProfileText": "(acczntl prfflzlf)", "accountsText": "Acctntzz", "achievementProgressText": "Achilfjasdflz: ${COUNT} ouzt of ${TOTAL}", "campaignProgressText": "Cmapghan Progflzl: ${PROGRESS}", "changeOncePerSeason": "owe c wow chofu wefwoefjwofjowcowfwf.", "changeOncePerSeasonError": "You cows ow woefj woifjwo ec oweo fowijf owiejf (${NUM} cowefwe)", + "createAnAccountText": "Crjoiew an Acoiejfdf", "customName": "Cow oj wojNaoa", + "deleteAccountText": "Delft Cosdfsdf", "deviceSpecificAccountText": "Crrlzfjowf uznfl a divwfo-zpijfwo ancnfo ${NAME}", "googlePlayGamesAccountSwitchText": "If cows objc aw;eoifjw efoGoogl coweijwoejr,\nOc wore aero two cw oerjwoer jo gw spoeor.", "linkAccountsEnterCodeText": "Enrlr Cfdsz", @@ -28,14 +30,16 @@ "setAccountNameDesc": "Selcow f cjwo ot afoa fw jcpaoewj fwocowefj.\nYou wolf wc. weowyc oawe awoefm mcapowefi \ncoat aocjweo towirowmcowiefownr.", "signInInfoText": "Sgn inz tz strz yr prograrzz inz\nthz cld, rnzr tckrz, rnz", "signInText": "Sggnz Inz", + "signInWithAnEmailAddressText": "Sif c woe w oo wefwioje ofiewj dfjdf", "signInWithDeviceInfoText": "(an coiwjfow fcoa cowj efj woj cowij eofjwoj foijs aofij )", "signInWithDeviceText": "Sngi foicj oj de voa cwoiejfw", "signInWithGameCircleText": "Sgn in gh Gm Cirflc", "signInWithGooglePlayText": "Snf ocj weo fGOofl Plfl", "signInWithTestAccountInfoText": "(lgjo cac cojef ot; oeco doic w eofjw oero )", "signInWithTestAccountText": "Sjc weo fwtjwoefj cowefwf", + "signInWithText": "Sign fit cweof ${SERVICE}", "signInWithV2InfoText": "(an zofj c woof woke wo Eire wf ofjjowg)", - "signInWithV2Text": "Sngo cow erwoj CBombSOudds acorjds.", + "signInWithV2Text": "Sngo cow erwoj ${APP_NAME} acorjds.", "signOutText": "Sgngz Ozt", "signingInText": "Sgngngn infz..", "signingOutText": "Sngning ozt..", @@ -342,9 +346,14 @@ "titleText": "Ádzd Gámzé", "titleTextScale": 1.01 }, + "addToFavoritesText": "Add owej owjwffwfwe", + "addedToFavoritesText": "Added '${NAME}' for cow jowdif.", + "allText": "Alcllwerf", "allowText": "Alzéow", "alreadySignedInText": "Yr co wcowief woeijo wife ewf;\norc woeful oj ceofjwoejfowief\nocjwoef weofwocijweofw.", "apiVersionErrorText": "Cznt lzdz mdls ${NAME}; zt tarng faptr ${VERSION_USED}; wz rojafoqrz ${VERSION_REQUIRED}.", + "applyText": "Appcfwf", + "areYouSureText": "A foe fwocijwe?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Aztoz\" enablez thz onlzl when hedifphz arnz plzzdd inz)", "headRelativeVRAudioText": "Hzad Rlztefijv VRZ Azdjfozl", @@ -369,14 +378,25 @@ "boostText": "Bfzesf", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} ís cónfigúred ín thé ápp itszlf.", "buttonText": "béttzn", - "canWeDebugText": "Woíld yoí lúké BombZqíád to áítomátúcálly réport\nbígz, crázhéz, ánd bázúc ízágé únfo to thé dévélopér?\n\nThúz dátá contáúnz no pérzonál únformátúon ánd hélpz\nkéép thé gámé rínnúng zmoothly ánd bíg-fréép.", + "canWeDebugText": "Woíld yoí lúké ${APP_NAME} to áítomátúcálly réport\nbígz, crázhéz, ánd bázúc ízágé únfo to thé dévélopér?\n\nThúz dátá contáúnz no pérzonál únformátúon ánd hélpz\nkéép thé gámé rínnúng zmoothly ánd bíg-fréép.", "cancelText": "Czéanczel", "cantConfigureDeviceText": "Sórry, ${DEVICE} ús nút cónfígúrzble.", "challengeEndedText": "Thzl cowfo jan fa eofnwoefnw.", "chatMuteText": "Mmof wChad", "chatMutedText": "Chad mamba", "chatUnMuteText": "Unobiaje Chafb", + "chests": { + "levelChestText": "LR${NUM} Czfjwer", + "prizeOddsText": "Pzoierj Odfsds", + "reduceWaitText": "Roijwoef Wjwore", + "slotDescriptionText": "THowi fwoeifj wo pwoejr s.\n\nWOewr c woej fjpwoe ow erja otjfpoweijr,\nocjwpeo. cowiej rrhpag, and pco wejrwpot\ncaowej cowiers.", + "slotText": "Chsof sdlfjoef ${NUM}", + "slotsFullWarningText": "WARNINEF: All owe fwoe fowior ;woeffufll.\nAOcn weow eroapoghwpeoi we. owejpwoejowe.", + "unlocksInText": "Ucowefij If" + }, "choosingPlayerText": "", + "claimText": "Clwefijwe", + "codesExplainText": "Cody wc woeir wcpwep oijwoeifj\nwoe wefjwe ofiwjeocijwoerer.", "completeThisLevelToProceedText": "Yóz múst cómplítz\nthís lével tú próceed!", "completionBonusText": "Cúmplezión Búnís", "configControllersWindow": { @@ -466,6 +486,7 @@ "titleText": "Cónfígúre Tóuchszreen", "touchControlsScaleText": "Tóuch Cóntróls Scále" }, + "configureDeviceInSystemSettingsText": "${DEVICE} otic w ejowei fajowe cjwoei woeirj dfwf.", "configureItNowText": "Cónfígzre ít nów?", "configureText": "Cónfúgzre", "connectMobileDevicesWindow": { @@ -579,6 +600,7 @@ "demoText": "Dmfwef", "denyText": "Dénziy", "deprecatedText": "Dowefowicjwer", + "descriptionText": "Djcowiejfwdf", "desktopResText": "Dzlflfjz Rzflz", "deviceAccountUpgradeText": "Wowierj:\nWofiwj c weojfw duo wdjfo weir are(${NAME}).\nDowjc weowje r ofjowei fjwoeodjfowdofijwodfjf.\nUpeworwe coweoijwV2 ocwoe roweijroidjjfj owejowejd.", "difficultyEasyText": "Ezrz", @@ -589,6 +611,10 @@ "disableRemoteAppConnectionsText": "Disojf c woij ewof-app cowjf woejwe", "disableXInputDescriptionText": "Allow mor wow ejo4 cow oeicjwo cobu oaf woejfowie jowrj", "disableXInputText": "Dio cow eofwije", + "disabledText": "Dfewfczfwef", + "discardText": "Dfwecwer", + "discordFriendsText": "Weor owe fwjeowi cow fowijfowjdfdf?\nJJowjef c jewel dODIj c jdjfosijfdfs!", + "discordJoinText": "JWeoj wc c wwdofijsd", "doneText": "Dónz", "drawText": "Drawz", "duplicateText": "DSFcoiwjef", @@ -601,8 +627,10 @@ "gameListText": "Gámé Lzúst", "listNameText": "Plzljlfz Nmflf", "nameText": "Néáme", + "pointsToWinText": "JWP er OWejrd", "removeGameText": "Rzmóve\nGzmze", "saveText": "Sézve Lzést", + "seriesLengthText": "S oere cowejrd", "titleText": "Plzltls Edirtzlr" }, "editProfileWindow": { @@ -623,6 +651,7 @@ "localProfileText": "(lcllf proriocf)", "nameDescriptionText": "Pléyzr Náme", "nameText": "Núme", + "profileAlreadyExistsText": "We c weir wet fj c where jggafjw fweworer jdfdf.", "randomText": "rándzm", "titleEditText": "Edít Prófílze", "titleNewText": "Néw Prófílze", @@ -662,6 +691,7 @@ "useMusicFolderText": "Fldlzr ofz Mzlfic Flzlz" }, "editText": "Edf", + "enabledText": "Efweecwef", "endText": "Enzf", "enjoyText": "Enfjofjw!", "epicDescriptionFilterText": "${DESCRIPTION} Ín ípic slúw mztíon.", @@ -673,6 +703,8 @@ "errorText": "Errórz", "errorUnknownText": "unknznlz errzzz", "exitGameText": "$Excej ${APP_NAME}", + "expiredAgoText": "Expiofwef ${T} awoifje", + "expiresInText": "Expoijfwe f in ${T}", "exportSuccessText": "'${NAME}' woejpcj", "externalStorageText": "Extzljrzl Stjrfjzfgz", "failText": "Fáilz", @@ -709,6 +741,8 @@ "editText": "Ezltjf\nPlaflfzlz", "gameListText": "Gzéme Lízt", "newText": "Núw\nPlzlrlrzl", + "pointsToWinText": "Peer c word fdjfw", + "seriesLengthText": "Soft cwojerr", "showTutorialText": "Shzwlf Trltlrjlzjf", "shuffleGameOrderText": "Shúfflze Gáme Oéder", "titleText": "Cmtlajrz ${TYPE} Plzlsfwz" @@ -738,6 +772,7 @@ "copyCodeText": "Cpoef Cwfdf", "copyConfirmText": "COpic for cowejwdf.", "dedicatedServerInfoText": "For code wocj woiejfowiejf, loci joweijf owiejfw. Se eocwj efowiejo wcoweijf woeifowoco er.", + "descriptionShortText": "Us fow cower. gowf pwoij df odfj g pawor aryh cowier.", "disconnectClientsText": "Thz wlzl dicntjf thz ${COUNT} pljflaf (s)\ninc yrrz prthra. Arz yrz fsrru?", "earnTicketsForRecommendingAmountText": "Fofofj oicow ${COUNT} ocwjoe f cow ef woefje\n(aocweo fwjoefi jo${YOU_COUNT} cowiejfowi oie)", "earnTicketsForRecommendingText": "Shz thz gom \nfo cowiej coiwoij...", @@ -754,7 +789,7 @@ "friendPromoCodeInstructionsText": "To Us ocj , ofijwe ${APP_NAME} oafn aco\"segoingaf- aocij weoifjwoe fowiejoijcowijcoiwjef.\nSee ofjc oiwejfowje foajfo weofjodijf oiasjgo isjdfo ijaweoijfowije oiwjoifjw.", "friendPromoCodeRedeemLongText": "It cnf vow weofjwoefi joef ${COUNT} ffoij cowijetoi cwoiej fo ${MAX_USES} pcojfofz.", "friendPromoCodeRedeemShortText": "It cnf br coefwf fwfof ${COUNT} toico foin ciwfj gmes.", - "friendPromoCodeWhereToEnterText": "(inz \"Settdfings->Adwefwced->Eftcer Codze\")", + "friendPromoCodeWhereToEnterText": "(inz \"Settdfings->Adwefwced->Eftcder Codze\")", "getFriendInviteCodeText": "Gz Frjor Infivo Cdz", "googlePlayDescriptionText": "Invlt Gglglz Plzlz plzlfer tz yzr prtaryz:", "googlePlayInviteText": "Invtlzz", @@ -787,6 +822,7 @@ "manualYourLocalAddressText": "Yrrz lcl addratrz:", "nearbyText": "Woiwjefd", "noConnectionText": "", + "noPartiesAddedText": "Not cower wo cowdj fwd", "otherVersionsText": "(otco verosfjso)", "partyCodeText": "Prewjr Cdfew", "partyInviteAcceptText": "Acczlfp", @@ -861,6 +897,12 @@ "youHaveShortText": "you hv f ${COUNT}", "youHaveText": "yz hv ${COUNT} tickrrz" }, + "goldPass": { + "desc1InfTokensText": "Infowef oTjwof.", + "desc2NoAdsText": "Nz Weft", + "desc3ForeverText": "Fejrwoijfz.", + "goldPassText": "Goose Ppzif" + }, "googleMultiplayerDiscontinuedText": "Sowoer Gojf wel wouwen weoioc long wf won.\nI wow oe wefwjr pif g wfpawouja c oeij fw ocjaoiejowr.\nUntil. cowier oa j fapefij cpoypt ao coonnec awoiery.\n-Ercff", "googlePlayPurchasesNotAvailableText": "Weofiiwj woe woerd wieofjwe\ncome foe rj eofiaj cpwoe jrowjer..dd", "googlePlayServicesNotAvailableText": "GOowf cpw ef A coweij woerj.\nWomb woof cape wgwoijc we coowiejrerdss.", @@ -870,10 +912,12 @@ "autoText": "Aúto", "fullScreenCmdText": "Fúllézreen (Cmd-F)", "fullScreenCtrlText": "Fúlzcréen (Ctrl-F)", + "fullScreenText": "Ffjoefzlefw", "gammaText": "Gámza", "highText": "Hígh", "higherText": "Híghrz", "lowText": "Lózw", + "maxFPSText": "Mxf cWEf", "mediumText": "Mzdíum", "neverText": "Névzer", "resolutionText": "Résólution", @@ -955,6 +999,7 @@ "importText": "Icwefwe", "importingText": "Imcowiew..", "inGameClippedNameText": "ic weof owef\n\"${NAME}\"", + "inboxText": "Iboiwjef", "installDiskSpaceErrorText": "ERROR: Unzlbj ao ppc pwef oj oinosjs.\nYos may aoefo wocw oeitjoidosdfdve.\nCjfewf wocjdo spac ando ro gaing.", "internal": { "arrowsToExitListText": "préss ${LEFT} ór ${RIGHT} tó exút lzst", @@ -1011,12 +1056,14 @@ "touchScreenJoinWarningText": "Yz hv jofndsf woijt iafh doctoucohdsf.\nIf oth dfawas do oasdf osdft mwne owijf oadsjf.", "touchScreenText": "TóuchScrzén", "trialText": "tríál", + "unableToCompleteTryAgainText": "Unweojw cowe rwpor oijwe fwoer noww.\nPlze fow cowe gagainf.", "unableToResolveHostText": "Error: cow e fwjeociwjeorir.", "unavailableNoConnectionText": "Tho fiw ficj woiejf paowejf (no itnwotower connecotjs?)", "vrOrientationResetCardboardText": "Us this to weoojeif co VR owfjow ego\nTz pc we fwotj oa ocw eoowf eo awoifoacoincwr.", "vrOrientationResetText": "VR ooiwjfowif rnefz.", "willTimeOutText": "(wzlf tmz oat if idle)" }, + "inventoryText": "Inoejowfjwf", "jumpBoldText": "JZMP", "jumpText": "Júmp", "keepText": "Kéepz", @@ -1064,8 +1111,11 @@ "seasonEndsMinutesText": "Seaonf woeo cowi fj${NUMBER} mcoinwefoij.", "seasonText": "Seocwofj ${NUMBER}", "tournamentLeagueText": "Yzz mff erwr ${NAME} leg foic woefin woef oeijfwfew.", - "trophyCountsResetText": "Trphy cofo wuecw owef owioiafowf." + "trophyCountsResetText": "Trphy cofo wuecw owef owioiafowf.", + "upToDateBonusDescriptionText": "Plwefj cowe fowc woer weoirjo\nc woejf weowerj r ${PERCENT}% ocw edfh.", + "upToDateBonusText": "Up-Ff-Odfjw DbJfdjs." }, + "learnMoreText": "Loweifj cowe", "levelBestScoresText": "Bsfwo cowiejo ef${LEVEL}", "levelBestTimesText": "Best wfm coi ${LEVEL}", "levelFastestTimesText": "Fztjst tmzf on ${LEVEL}", @@ -1112,6 +1162,8 @@ "modeArcadeText": "Aroc Mofwfz", "modeClassicText": "Cjwofej mDofd", "modeDemoText": "Dfwocij Mmdff", + "moreSoonText": "Morew owjeo zoonwf...", + "mostDestroyedPlayerText": "Mowe Sfewo f Cpwowjef", "mostValuablePlayerText": "Móst Válúablz Pláyér", "mostViolatedPlayerText": "Móst Víoláted Pláyer", "mostViolentPlayerText": "Móst Víolznt Pláyér", @@ -1128,6 +1180,7 @@ "nameSuicideText": "${NAME} cómmittéd súizide.", "nameText": "Noiwjfe", "nativeText": "Nztvvz", + "newExclaimText": "Nwefw1!", "newPersonalBestText": "Néw pérsónzl bést!", "newTestBuildAvailableText": "A nwlf tat blfjl is aviflflzblz! (${VERSION} blzd ${BUILD}).\nGzt iz tat ${ADDRESS}", "newText": "Ncw", @@ -1139,13 +1192,17 @@ "noExternalStorageErrorText": "Nz xtenrlf stlfsdf fnff onf thz dfvfojfzz", "noGameCircleText": "Errór: nút lúggzd íntó Góme Cúrclz", "noJoinCoopMidwayText": "Có-óp gúmzs cán't bz jóinzd mídwáy.", + "noMessagesText": "No wwoej wced", + "noPluginsInstalledText": "No Plugiwue sowiej fwdf", "noProfilesErrorText": "Yoú hávz nó pláyerz prófilzs, só yóu're stzck wíth '${NAME}'.\nGó tz Sétzings->Pláyerz Prófiles tú mzke yóurszlf á prófile.", "noScoresYetText": "Nz scrrlz ytz.", + "noServersFoundText": "Neo c who wj wo eij.", "noThanksText": "Nó Thánkz", "noTournamentsInTestBuildText": "WOREwr: WOTo cwoefw coif wefiidfjdf cow ekfwoejowijerwdifwdf.", "noValidMapsErrorText": "Nó válíd máps fóund fúr thzs gáme typz.", "notEnoughPlayersRemainingText": "Nt zefwnoef plrjr rmeinging; exit anfo iwfj owjf oj ga emga;", "notEnoughPlayersText": "Yf nfdf a taflew ${COUNT} pfo wotj wofijow afo game!", + "notEnoughTicketsText": "Not Fowej Tickewerwe!", "notNowText": "Nót Núw", "notSignedInErrorText": "Yz mst bz snginf intof yrrz accnt tz dz thzz.", "notSignedInGooglePlayErrorText": "Ym fij cow fj wo cowe toiw jcoj ojwoefj owi.", @@ -1158,6 +1215,9 @@ "onText": "Ón", "oneMomentText": "One Mmcowmerz..", "onslaughtRespawnText": "${PLAYER} wúll réspawn das wávz ${WAVE}", + "openMeText": "Opwef cMF", + "openNowText": "Opzef Nweer", + "openText": "Opwefw", "orText": "${A} orz ${B}", "otherText": "Ofowiejf....", "outOfText": "(#${RANK} oút ófz ${ALL})", @@ -1253,6 +1313,8 @@ "punchText": "Púzch", "purchaseForText": "Púrcháse fúrz ${PRICE}", "purchaseGameText": "Púrchúze Gáme", + "purchaseNeverAvailableText": "Some f , zf w owe f;woef fjsdgoiwejf sldfjsdjfsdf.\nGJ who woe roe rwhe gpwepgoi elf. dfoifj g;weoi jwo. fwjgw theorieorjdsd f woof wdofjf.", + "purchaseNotAvailableText": "Thief o c;weo weoifj weft odin other.", "purchasingText": "Prjrcjfz...", "quitGameText": "Qcoifj ${APP_NAME}", "quittingIn5SecondsText": "Quéttzng ín 5 sécznds...", @@ -1296,6 +1358,7 @@ "version_mismatch": "Veroi jmoiowoejf\nMkac aot co boaisoijero caoioisd fjaoer\nadc ot oacouweotu vowe ron aga." }, "removeInGameAdsText": "Unlkjfj \"${PRO}\" in cowj wje of wejfoiwfoo oifoiwjef.", + "removeInGameAdsTokenPurchaseText": "LWEFJOE COJW EREFW: Pruwo cwoi Ao fogjwe cwoe reowj owie ain-gm woafj owwrds.", "renameText": "Rzngmlz", "replayEndText": "Enz Rpllz", "replayNameDefaultText": "Lzts Gmzl Rplzlz", @@ -1318,6 +1381,8 @@ "runText": "Rúun", "saveText": "Sávez", "scanScriptsErrorText": "Error(w) frolic weir ro; cj weowje ici woeijwer.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} dfsf ${NUM} w woeifjw fwjef webd weoifjwoef ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} fwejfwjef weoifjwefffefwwef ${API}.", "scoreChallengesText": "Scóre Chálléngúz", "scoreListUnavailableText": "Sczerl lzst unvnslfljblz.", "scoreText": "Szóre", @@ -1328,6 +1393,7 @@ }, "scoreWasText": "(wús ${COUNT})", "selectText": "Slézcz", + "sendInfoDescriptionText": "Snff ac c woof wc owei. jf;woef; a gwoiefj.\ncc c woe cw Rowe orijwg gwpofij wpeoifjwefd.", "seriesWinLine1PlayerText": "WZNNPLL THZ", "seriesWinLine1Scale": 0.65, "seriesWinLine1TeamText": "WNZTTTM THZ", @@ -1351,6 +1417,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(a smpd a, condofia efjwefoajewofoiaj;s a sodifj a;osdfjoitest f)", "alwaysUseInternalKeyboardText": "Alzlt usl Intenralf kyBerz", "benchmarksText": "Bnchmkwr & Staf-Tsfsfz", + "devToolsText": "Dow Aocjwe", "disableCameraGyroscopeMotion": "Disa fe come won aweGowyeo CMosndf", "disableCameraGyroscopeMotionText": "Dislike og wefo cwei oweiaMowerdns", "disableCameraShakeText": "SDi Cmanan Blobofs", @@ -1360,14 +1427,21 @@ "enterPromoCodeText": "Eznter Cdzs", "forTestingText": "Ntz: thz vlarj farz olflf rzz tsffcn anz wllz bz llfsf whnzl thzz app exrtzz.", "helpTranslateText": "${APP_NAME} lngalsdf transaldflksdfj arz fjocdmaosdf\nsprnarted effrztzs. Ifsdf oud'fu likzz to cmdfoasdf corectsf\na sd fjafdsoijdf, flfowefj thz fljlnkdd blzljf. Thansdlfn in andncas!", + "insecureConnectionsDescriptionText": "now come fowdifjowdf ckwdf , c,woer\no woef owiefjw f cpawp a;oiweroijdf", + "insecureConnectionsText": "Sefu cwoe co wi cwodijfdfd", "kickIdlePlayersText": "Kzkck Idlzlf Plzjrs", "kidFriendlyModeText": "Krz-Frjijglfz-Mzdz (rdfjifz voioifjf, fz)", "languageText": "Lnglfjslfd", "moddingGuideText": "Mddzng Gdufnzsd", + "moddingToolsText": "Meowed eFwefwf", "mustRestartText": "Yz msg restar thz gmm fof this tk ttk effectsz.", "netTestingText": "Ntwkrz Tsstcg", "resetText": "Rsttz", + "sendInfoText": "Show cowdf", "showBombTrajectoriesText": "Shzlz Bomf Tfwoejcwoefz", + "showDemosWhenIdleText": "Sho cwoefj c wdofdfjdfwf", + "showDeprecatedLoginTypesText": "Show woe fjwoc woejoweo fwef", + "showDevConsoleButtonText": "Sho c weroiw c wo cwoije fwois", "showInGamePingText": "Shoe o co fowl Png", "showPlayerNamesText": "SHzlfjl Plzlrr Nmzlzlls", "showUserModsText": "Shzl Mdsz Fldlrz", @@ -1387,6 +1461,9 @@ "signInWithGameCenterText": "To loci wo gamg wofiw efoiwjef.\ncoaej goajb oaj Game foc etapp.", "singleGamePlaylistNameText": "Jzff ${GAME}", "singlePlayerCountText": "1 pláyzr", + "sizeLargeText": "Lwfefwdf", + "sizeMediumText": "MFwefwf", + "sizeSmallText": "WSDfjwf", "soloNameFilterText": "${NAME} Sólzo", "soundtrackTypeNames": { "CharSelect": "Czárazter Sélection", @@ -1412,6 +1489,7 @@ }, "spaceKeyText": "spzz", "statsText": "Sfawfwf", + "stopRemindingMeText": "Stoij fPRo wwcoe Pfm", "storagePermissionAccessText": "Tho cowefj woiejowefw.", "store": { "alreadyOwnText": "Yorz alrlfzl wozl ${NAME}!", @@ -1463,6 +1541,8 @@ "storeText": "Stzlrle", "submitText": "Scowiejfwef", "submittingPromoCodeText": "Subjfoif Cdssz...", + "successText": "Sensded!", + "supportEmailText": "IF wc weoif joweij c woeifjowiejorwer\nc who we fweofiwjefo ${EMAIL}.", "teamNamesColorText": "Tmcoj Conor/ Coarle...", "teamsText": "Tééáémés", "telnetAccessGrantedText": "Tzélnt acczzss énazledz.", @@ -1473,6 +1553,7 @@ "testBuildValidatedText": "Tst Bjldf Vlaldkfsf; Enjzjf!", "thankYouText": "Thánk yóu fór yóur súppórt! Enjóy thé gáme!!", "threeKillText": "TRÍPLZ KÚLL!!", + "ticketsDescriptionText": "Towfjwef cowej rocw eoi woujcoiwu eor, gowbof\nocowo wper ewrjwefow fowije ostrooiwjeofwrs.\n\nToco weo jweori weotwocoiw eowijoer oiwejf\nCow eower gpaogj woef owjefapef wigowijeo iw we.", "timeBonusText": "Tíme Bónús", "timeElapsedText": "Tíme Elápszd", "timeExpiredText": "Tzmz Exprireizdd", @@ -1483,10 +1564,24 @@ "tipText": "Tízp", "titleText": "Bmbmsqdz", "titleVRText": "BomboFjof VR", + "tokens": { + "getTokensText": "Gje Cowjerr", + "notEnoughTokensText": "Nt come. fowijodifj!", + "numTokensText": "${COUNT} Tlwefjwf", + "openNowDescriptionText": "Yowu cw oeo we ofiwjeroj\ncow eoowe rwo oweifuwef\now w oeijrer.", + "shinyNewCurrencyText": "Boiwfw wet fwoeifj wofz ofwroru.", + "tokenPack1Text": "Smeow Tlwkf Pcer", + "tokenPack2Text": "Mfowefj howei roweirdf", + "tokenPack3Text": "Lwofiw lw wore doijfdf", + "tokenPack4Text": "JWfowji howei oweirjdf", + "tokensDescriptionText": "Towefjw cowe rowjf. fa;weof wegogowijeoiwjf\nfow ef cowiej roweir gjpgoj fw eojrweio ga;oijw\n\nYoucwe orwe c weowherapogpouggj foiwejow\nagpo cpaowerp.. Thgapoeiwjj cowejrhghapjzoejf\nwoicw eo wor apojpcowieo g gjeiwroeijds.", + "youHaveGoldPassText": "You who owe rowjfosijdf.\nAlf wo cwoerpwer rwoer f.\nCwjodi!" + }, "topFriendsText": "Tóp Fríendz", "tournamentCheckingStateText": "Chkfjfowef oitwof oweifja oef pawoej owef...", "tournamentEndedText": "This foil jefoi weoa echo sd. An ewoifj wo oowifjowe soon.", "tournamentEntryText": "Tnofjwfe oecowiejw", + "tournamentFinalStandingsText": "Fiowefj Stdfijwef", "tournamentResultsRecentText": "Rcnet Touaofius aRamalsdf.", "tournamentStandingsText": "Tzewfjwoij Stndfalfjz", "tournamentText": "Tanfowijfowef", @@ -1526,6 +1621,22 @@ "Zoe": "Zob", "Zola": "Zlefw" }, + "chestNames": { + "Chest": "Czjofwf", + "L1": "LZ1", + "L1 Chest": "LX1 CHzer", + "L2": "LZ2", + "L2 Chest": "LX2 CHzer", + "L3": "LZ3", + "L3 Chest": "LX3 CHzer", + "L4": "LZ4", + "L4 Chest": "LX4 CHzer", + "L5": "LZ5", + "L5 Chest": "LX5 CHzer", + "L6": "LZ6", + "L6 Chest": "LX6 CHzer", + "Unknown Chest": "Ucwoejrwer Cjoefwijf" + }, "coopIconNames": { "Infinite\nOnslaught": "Infíníte\nÓnsláught", "Infinite\nRunaround": "Ínfíníte\nRúnaróúnd", @@ -1561,6 +1672,18 @@ "Uber Onslaught": "Ubzr Onzláught", "Uber Runaround": "Ubúr Runáround" }, + "displayItemNames": { + "${C} Tickets": "${C} Towfijwezz", + "${C} Tokens": "${C} Tjowefjdfzzz", + "Chest": "Cjoziejr", + "L1 Chest": "LZ1 Cohwerd", + "L2 Chest": "LZ2 Cjzoerr", + "L3 Chest": "LZ3 Coijewr", + "L4 Chest": "LZ4 Cheowrd", + "L5 Chest": "LZ5 Coewer", + "L6 Chest": "LZ6 Cowiejrer", + "Unknown Chest": "Unoweijr Coizjerer" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bé thé chósen ónz fór a léngth éf tíme tó wzn.\nKzll thé chósen óne tz bécome út.", "Bomb as many targets as you can.": "Bmb ojwe fo cj woef weoijcoj ofz.", @@ -1644,39 +1767,45 @@ "languages": { "Arabic": "Aroijwe", "Belarussian": "Blfrurzfozz", - "Chinese": "Choifwef Soimcwoef", - "ChineseTraditional": "Cheifwoefjw Trwwefsdfs", + "Chinese": "Chweoifwej - Sompefwe", + "ChineseSimplified": "CHowef - Smpfoewfdf", + "ChineseTraditional": "Choweijwer - Transitiondsf", "Croatian": "Crrlzlrrs", "Czech": "Czffef", - "Danish": "Dnishsdl", + "Danish": "Dnailöş", "Dutch": "Dtchjdflz", - "English": "Englfjlzjsh", + "English": "Enfizikik", "Esperanto": "Esprorjjzlz", "Filipino": "Fefjwoeifj", "Finnish": "Fnnizhsh", - "French": "Frnzhfhn", - "German": "Grmmzndn", - "Gibberish": "Gibberish", + "French": "Froktury", + "German": "Deutgwiz", + "Gibberish": "Abuktarika", "Greek": "Gaofwef", - "Hindi": "Hfjofz", + "Hindi": "Panokallas", "Hungarian": "Hngjgozf", "Indonesian": "Inofiqdson", "Italian": "Itzllfjssnn", - "Japanese": "Jpndjsjzes", + "Japanese": "Capnokas", "Korean": "Kornesnzn", "Malay": "FJwoerjjdf", "Persian": "Psdfsdf", + "PirateSpeak": "Pirafw ef ocOSIf", "Polish": "Pzlishz", "Portuguese": "Portuguenejs", + "PortugueseBrazil": "Powerower - Brfoisjfewfd", + "PortuguesePortugal": "Porwofweuf - Poweijfdffz", "Romanian": "Rmrfoijfzf", "Russian": "Rzznrsn", "Serbian": "Socowiejf", - "Slovak": "Slihdtbjoy", - "Spanish": "Snsdnsh", + "Slovak": "Zokkis", + "Spanish": "Snaddies", + "SpanishLatinAmerica": "Spoweijwe. - Ljf foewfij oAmweroijd", + "SpanishSpain": "Spwoefj - Zpfwjefdf", "Swedish": "Swdiiszh", "Tamil": "Tmfiewf", "Thai": "Thzff", - "Turkish": "Twfoijwef", + "Turkish": "Turiyako", "Ukrainian": "Ukckwef", "Venetian": "Vwvowefdf", "Vietnamese": "Vjefowiewer" @@ -1730,17 +1859,19 @@ "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "And foci wej fowif ijcowjer.\nPle eocj w jocose fowl jeowijeo few fj cijwoiejr. fofofifjow e ciweocywe.", "An error has occurred; (${ERROR})": "An cow fc woof wcef; (${ERROR})", "An error has occurred; please contact support. (${ERROR})": "An cowed c woefj wcoi woof weiojrwe rj goije ${ERROR})", - "An error has occurred; please contact support@froemling.net.": "An f oco ao ocio wj ; pocj oco woei fsuupo co co ifoiwnet", + "An error has occurred; please contact support@froemling.net.": "An f oco ao ocio wj ; pocj oco woei fsuupo co co ifoiwnet support@froemling.net gwizing patüköç.", "An error has occurred; please try again later.": "An cowjef win woes owe p apowejrowjers.", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Ac woef oi eowic woiej fowije foijcwe?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTHci weo woi efoiw ojo ij!!", "BombSquad Pro unlocked!": "Boijfdfsjef pon occoijfs!", "Can't link 2 accounts of this type.": "Cnoj' oi n aoco i ot oaifftz.", "Can't link 2 diamond league accounts.": "Cnoi' oin koci o2 doi co fla cairjrs.", - "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Cn't coi oi; could up vo io ${COUNT} oi c ioicoicuors.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Cn't coi oi; could up vo io möaksokato ${COUNT} oi c ioicoicuors.", "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Chowcj eof weoc jco; oe jwoeijf wojcwjeowfj woejf o${COUNT} dzf.", "Could not establish a secure connection.": "Cjfoi cn ooi a tac c oweocoicoinr.", - "Daily maximum reached.": "Dfilaf mciwfjiwf rechced.", + "Daily maximum reached.": "Dfilaf möaksokato ravhgedök.", + "Daily sign-in reward": "Dilse Sf wcowe owOSDfwrd", "Entering tournament...": "Ernwoefijweo jfowjefw...", + "Higher streaks lead to better rewards.": "Hfweo lstor fljit f ob oijtow rewrds.", "Invalid code.": "Invflijf cddz.", "Invalid payment; purchase canceled.": "Info ejcwpeopwer; purwup cowefjwef.", "Invalid promo code.": "Ivnfjfo pmpwf cdffz.", @@ -1749,11 +1880,14 @@ "Item unlocked!": "Iwerw cowefjwoeijwer!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKING FOFJWEF. ${ACCOUNT} o iwjof\nowe oijwe c woeoijwf oAL FJOEJI OCJW.\nYou off leojwoer wcowe foiwjefojweoiwf\n(a c owfw oefjTHIS c weoojw oesf)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Lcjwe fwofj o ${ACCOUNT} to cowejfweof?\nAll wefoiwejtthosjic w ${ACCOUNT} cowiejf tjsl.\nThis wefowondot onsof. Aojr tyocu wsure?", - "Max number of playlists reached.": "Mx nfmow oijeplyalfaf rcnoahfd.", - "Max number of profiles reached.": "Mc fjpasdofj c owiejfowe oiwjefsd.", - "Maximum friend code rewards reached.": "Cmwoe oc wo Ego wel jacoweij weer.", + "Longer streaks lead to better rewards.": "LFowe jewoi ewr c weorj eowr efoiwjersr", + "Max number of playlists reached.": "Möaks nfmow oijeplyalfaf rcnoahfd.", + "Max number of profiles reached.": "Möks fresadora c owiejfowe rafgexed.", + "Maximum friend code rewards reached.": "Cmwoe oc wo Ego wel jacoweij weer möaksiöas.", "Message is too long.": "CMew ociwje owe el.", + "New tournament result!": "Nwef toaiwjowcw orursllsst!", "No servers are available. Please try again soon.": "Ns seroiejwc wefjwoe wj. Ple wer wfwef ewfowes.", + "No slots available. Free a slot and try again.": "Nz sliejfwo capoejw f. Fizi cowie rw gjwoe woerdd.", "Profile \"${NAME}\" upgraded successfully.": "Profjojf \"${NAME}\" oupfuap coj woijsfsf.", "Profile could not be upgraded.": "Profojfo coild onot foj bupfrade.", "Purchase successful!": "Pcjofj scwcserfflz!", @@ -1763,7 +1897,9 @@ "Sorry, this code has already been used.": "Srrc, thiz codds has aoiwjre bndd usdd.", "Sorry, this code has expired.": "Sorrro, thi cowf ahs arowjers.", "Sorry, this code only works for new accounts.": "Srror, this cod ojfowf work for know accarrn.", + "Sorry, this has expired.": "Sorrr, wot wf coijwoe rjexpirrd.", "Still searching for nearby servers; please try again soon.": "Stjowf sera cj focnwoeir eserevers; pell cutlery a gao cốn.", + "Streak: ${NUM} days": "Srowefj ${NUM} wsdfdsf", "Temporarily unavailable; please try again later.": "Tmwoef wf oucwof wf; cowejf awoj cwoijers.", "The tournament ended before you finished.": "Thf weoijw oeij aoejf aowejf owjeof aiwjeofjwef.", "This account cannot be unlinked for ${NUM} days.": "Th ow co ref w owjoso o ${NUM} dyafsoef.", @@ -1774,19 +1910,28 @@ "Tournaments require ${VERSION} or newer": "Toijfw qojwce ${VERSION} or wcoiwej", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Uncljwf ${ACCOUNT} cowed wthosijf?\nAll cowejt ocjiwf ${ACCOUNT} cowiest dois.\n(expo fowefj etwohoa tand Costers)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "WARNOEF: com owe fw epfojwe. cj weo fjwefo wejfo wef jocij eowiefwef.\nCoaj owe fwefjwoo oweoifwoe fj ewrj woc. Ppel fwo c worywwr.", + "Wait reduced!": "Woer rowicjowijer!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Weofwief: T wof weio ocwe gipwoej. gowef apf wiefhp woiefpf weof wociwjeoirower odfowfjowjfdf.\nOW fw ef wejotiewt hgpgoregpw98g4g f wocow eij agoiweo g ghgpw gpwoepoipatajfwe owefwef.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Wocj weo ocj woiej fowj ofj aioj ojt;oi df joijwotijs?\n\nYoc uweof c owej owijf ${ACCOUNT1}\nThoci wef coj woeijf ${ACCOUNT2}\n\nThoc jweo owej fow cwi efod odo focwoe.\nWocj fo : cwo c weof odo fauoino!", "You already own this!": "Yz fwowefoi coiweno fjoz!", "You can join in ${COUNT} seconds.": "You won cowier fwoef ${COUNT} coiwejf.", "You don't have enough tickets for this!": "Yz dfoiwf ahv weoj fwoitjoicker fz thzz!", "You don't own that.": "You loci jeff jwoefwe.", - "You got ${COUNT} tickets!": "Y zfowej f${COUNT{ ticeofjwe!", + "You got ${COUNT} tickets!": "Y zfowej f${COUNT} ticeofjwe!", + "You got ${COUNT} tokens!": "You got ${COUNT} tokewfjwf!", "You got a ${ITEM}!": "Yzz gtzz z ${ITEM}!", + "You got a chest!": "Yor foiwje rgo c chserser!!!", + "You got an achievement reward!": "You cowe owf woef weg;oai cower jower!", "You have been promoted to a new league; congratulations!": "Yf co efoj woef woecj owejfoiwef lfj ; congaroiwjf woes!", + "You lost a chest! (All your chest slots were full)": "Ycowe wo sowfweo ! (ALlco weofi wf o; cwoer orul)", + "You must update the app to view this.": "Yowu cow woef jwowo ejwe;oij wofjwoed.", "You must update to a newer version of the app to do this.": "Yz mocu upc oig owc owt oc o ca; ;apc oi oj ;oj.", "You must update to the newest version of the game to do this.": "Yocwe fweoowo weotjosij;ow. woeower weroso taotoautats.", "You must wait a few seconds before entering a new code.": "Yzz msfgt wt a fz cwcfwf bfrrzz entef wcnfz cdszz.", + "You placed #${RANK} in a tournament!": "Yozu c wpefo wef j #${RANK} oci wef wocwj otjwerd.", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Yz wf ooiwef #${RANK} ofijwe oijw oijef . Thansf afpaflalay!", "Your account was rejected. Are you signed in?": "Yoew cowcjwe woe woeiowirwo eirjw co weoijfow ej?", + "Your ad views are not registering. Ad options will be limited for a while.": "Ywer f wefi wue fiwe ifwiuehriweurhd, Abd fiwe fiwheigiweir hfsdfdsf,", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Yr coijw epowf oief oaefoiwfowjef\nPlejasefoaw efojw oefjwoejo aciowejrow.", "Your friend code was used by ${ACCOUNT}": "Yrrj cof owf owcjowj fwoafeof ${ACCOUNT}" }, @@ -1813,12 +1958,12 @@ "Flag Idle Return Time": "Flág Ídle Rétúrn Tímz", "Flag Touch Return Time": "Flág Tzch Rétúrn Tímz", "Hold Time": "Hólz Tímz", - "Kills to Win Per Player": "Kílls tó Wín Pér Plzáyer", - "Laps": "Lápz", + "Kills to Win Per Player": "Gebertzerto tórku Wenn Piérko Plzáyer", + "Laps": "Ląkzl", "Lives Per Player": "Lívz Pérz Pláyrr", "Long": "Lónggz", "Longer": "Lóngrzz", - "Mine Spawning": "Míne Spáwning", + "Mine Spawning": "Mõvn okmalako", "No Mines": "Nz Mfjfnzl", "None": "Núnz", "Normal": "Nórmzll", @@ -1837,10 +1982,10 @@ "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Wjocief cwf ${NAME}: jojwo / ocjo efoiwefj wcoweok owerjoijdof." }, "teamNames": { - "Bad Guys": "Bázd Gúyzs", + "Bad Guys": "Juardz gùårdz'n", "Blue": "Blzúe", - "Good Guys": "Gzóod Gúys", - "Red": "Réd" + "Good Guys": "Gzóod Gùårdz'n", + "Red": "Vegco" }, "tips": { "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Á perfectly timed running-jumping-zpin-punch cán kill in á zingle hit\nánd eárn yóu lifelóng rezpect fróm yóur friendz.", @@ -1940,11 +2085,14 @@ "toSkipPressAnythingText": "(tpz rz pzrzl anthfljzf tz skpfz tuzfjrlrrz)" }, "twoKillText": "DÓÚBLZ KÍLL!", + "uiScaleText": "SUFwfef", "unavailableText": "unavlfldsfjlbz", + "unclaimedPrizesText": "You c weo inp xo fowe fwiejrpdof!", "unconfiguredControllerDetectedText": "Uncónfzgúred cúntrzllír dítzctíd:", "unlockThisInTheStoreText": "Thz mf voi eunlcoef owef joiefsfrwe.", "unlockThisProfilesText": "To cowier co we ${NUM} pcoer, cow oicoj:", "unlockThisText": "Tz ncowifj ocje, ycon fneeds:", + "unsupportedControllerText": "Sorwfw, contorlwef \"${NAME}\" oweifj wcjwoeir.", "unsupportedHardwareText": "Srrz, thz hardwrz isz nt spprted bz thz vejerelr dlzl gmpzz.", "upFirstText": "Uzp férzt:", "upNextText": "Úp nézt ín gámz ${COUNT}:", @@ -1952,12 +2100,16 @@ "upgradeText": "Upgrorz", "upgradeToPlayText": "Upgglf tz \"${PRO}\" iz j wojcwoef paljf zs.", "useDefaultText": "Uzl Dflfjtzlz", + "userSystemScriptsCreateText": "Cwjof come rw dfoodwijfdf", + "userSystemScriptsDeleteText": "Down wc old. owiejf odfdf", "usesExternalControllerText": "Thz gjf coiwjef oif owicoiwefj owejf owejoojof", "usingItunesText": "Ufwefw Mfwoef co ef srnweoicjowe...", "usingItunesTurnRepeatAndShuffleOnText": "Plzelz mkdk srzlc shfflds isON anz andpreld is ALZ unz iTunes", "v2AccountLinkingInfoText": "To ljeowirj V2 sojowe, use fo 'Mnawefw Acoiwo' bons.", + "v2AccountRequiredText": "Thaw cw eo iwefio V2 Oicwe j. PC wepfo woj welag Wofiwj iowjoejfdffd.", "validatingBetaText": "Válúdztíng Bztá...", "validatingTestBuildText": "Vldfjdfoi jtese-bsdfasfd...", + "viaText": "sdf", "victoryText": "Vúctzry!", "voteDelayText": "You caecowe oefo wocj woeiwo ${NUMBER} wocijwoef.", "voteInProgressText": "A voiajf coiwje fwooeio wcwer.", @@ -1998,7 +2150,7 @@ }, "wiimoteListenWindow": { "listeningText": "Líszéngng Fúr Wíímztes...", - "pressText": "Prész Wíimzte bóttzns 1 azd 2 símultáneoúsly.", + "pressText": "Prész Wíimzte bóttzns 1 azd 2 símultáneoúsly.\n", "pressText2": "Onz néwer Wiímótes wíth Moóión Plús búilt ón, przss thé réd 'sync' búttón ón thé bzck ónstzad.", "pressText2Scale": 0.55, "pressTextScale": 1.0 @@ -2009,7 +2161,7 @@ "listenText": "Lústzn", "macInstructionsText": "Makú zurú your Wáá áz off and Bluútooth áz únablúd\non your Mac, thún prúzz 'Láztún'. Wáámotú zupport can\nbú a bát flaky, zo you may havú to try a fúw támúz\nbúforú you gút a connúctáon.\n\nBluútooth zhould handlú up to 7 connúctúd dúvácúz,\nthough your málúagú may vary.\n\nBombZquad zupportz thú orágánal Wáámotúz, Nunchukz,\nand thú Clazzác Controllúr.\nThú núwúr Wáá Rúmotú Pluz now workz too\nbut not wáth attachmúntz.", "macInstructionsTextScale": 0.7, - "thanksText": "Thznks té thz DérwiinRémote táam\nFúr máking thés pzsséble.", + "thanksText": "Thznks té thz DérwiinRémote táam\nFúr máking thés pzsséble.\n", "thanksTextScale": 0.8, "titleText": "Wzimóte Sztúp" }, @@ -2035,5 +2187,6 @@ }, "yesAllowText": "Yús, Allúwz!", "yourBestScoresText": "Yózr Bést Scúrzszz", - "yourBestTimesText": "Yózr Bést Tímés" + "yourBestTimesText": "Yózr Bést Tímés", + "yourPrizeText": "Yowe ppwefdzz:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/greek.json b/dist/ba_data/data/languages/greek.json index decc2bb3..f473ff81 100644 --- a/dist/ba_data/data/languages/greek.json +++ b/dist/ba_data/data/languages/greek.json @@ -6,7 +6,9 @@ "campaignProgressText": "Πρόοδος Ιστορίας [Δύσκολο]: ${PROGRESS}", "changeOncePerSeason": "Μπορείτε να το αλλάξετε μόνο μία φορά ανά σεζόν.", "changeOncePerSeasonError": "Πρέπει να περιμένετε μέχρι την επόμενη σεζόν για να το αλλάξετε ξανά (${NUM} days)", + "createAnAccountText": "Δημιουργήστε έναν Λογαριασμό", "customName": "Προσαρμοσμένο Όνομα", + "deleteAccountText": "Διαγραφή λογαριασμού", "googlePlayGamesAccountSwitchText": "Αν θέλετε να χρησιμοποιείσετε έναν διφορετικό λογαριασμό Google,\nχρησιμοποιείστε την εφαρμογή Google Play Games γιανα αλλάξετε.", "linkAccountsEnterCodeText": "Εισάγετε Κωδικό", "linkAccountsGenerateCodeText": "Δημιουργήστε Κωδικό", @@ -24,14 +26,16 @@ "setAccountNameDesc": "Επιλέξτε το όνομα που θα φαίνεται στο λογαριασμό σας. Μπορείτε\nνα χρησιμοποιήσετε το όνομα ενός από τους δεσμευμένους σας\nλογαριασμούς ή να δημιουργήσετε ένα μοναδικό, προσαρμοσμένο όνομα.", "signInInfoText": "Συνδεθείτε για να συλλέξετε εισητήρια, να συναγωνιστείτε στο διαδίκτυο\nκαι να μοιραστείτε τη πρόοδο σας ανάμεσα σε διάφορες συσκευές.", "signInText": "Σύνδεση", + "signInWithAnEmailAddressText": "Συνδεθείτε με μία διεύθυνση email", "signInWithDeviceInfoText": "(ένας λογαριασμός μονάχα διαθέσιμος από αυτή τη συσκευή)", "signInWithDeviceText": "Σύνδεση με λογαριασμό συσκευής", "signInWithGameCircleText": "Σύνδεση με Game Circle", "signInWithGooglePlayText": "Σύνδεση με Google Play", "signInWithTestAccountInfoText": "(προσωρινός λογαριασμός. Δημιουργήστε λογαριασμό συσκευής για συνέχιση προόδου)", "signInWithTestAccountText": "Σύνδεση με δοκιμαστικό λογαριασμό", + "signInWithText": "Σύνδεση μέσω ${SERVICE}", "signInWithV2InfoText": "ένας λογαριασμός που λειτουργεί σε όλες τις πλατφορμες", - "signInWithV2Text": "Συνδεθείτε με ένα λογαριασμό BombSquad", + "signInWithV2Text": "Συνδεθείτε με έναν λογαριασμό ${APP_NAME}", "signOutText": "Αποσύνδεση", "signingInText": "Σύνδεση...", "signingOutText": "Αποσύνδεση...", @@ -39,6 +43,7 @@ "titleText": "Λογαριασμός", "unlinkAccountsInstructionsText": "Επιλέξτε έναν λογαριασμό για αποδέσμευση", "unlinkAccountsText": "Αποδέσμευση Λογαριασμών", + "unlinkLegacyV1AccountsText": "Αποδέσμευση Παλιών (V1) Λογαριασμών", "v2LinkInstructionsText": "Χρησημοποιήστε αυτόν τον σύνδεσμο για να δημιουργήσετε έναν λογαριασμό ή για να συνδεθείτε.", "viaAccount": "(μέσω λογαριασμού ${NAME})", "youAreSignedInAsText": "Είστε συνδεδεμένοι ως:" @@ -332,9 +337,14 @@ "getMoreGamesText": "Περισσότερα Παιχνίδια...", "titleText": "Προσθήκη Παιχνιδιού" }, + "addToFavoritesText": "Προσθήκη στα αγαπημένα", + "addedToFavoritesText": "Προστέθηκε το '${NAME}' στα αγαπημένα.", + "allText": "Όλα", "allowText": "Να Επιτρέπεται", "alreadySignedInText": "Ο λογαριασμός σας είναι συνδεδεμένος από άλλη συσκευή.\nΠαρακαλώ, άλλαξε το λογαριασμό σας ή απενεργοποίησε \nτο παιχνίδι από τις άλλες συσκευες σας και ξαναπροσπάθηστε.", "apiVersionErrorText": "Can't load module ${NAME}; it targets api-version ${VERSION_USED}; we require ${VERSION_REQUIRED}.", + "applyText": "Εφαρμογή", + "areYouSureText": "Είστε σίγουροι;", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(Το \"Αυτόματο\" ενεργοποιεί αυτό μόνο όταν έχουν συνδεθεί ακουστικά)", "headRelativeVRAudioText": "Ρυθμίσεις σχετικές με VR ακουστικά", @@ -356,14 +366,24 @@ "boostText": "Ώθηση", "bsRemoteConfigureInAppText": "Το ${REMOTE_APP_NAME} είναι οριστικοποιημένο στην εφαρμογή από μόνο του.", "buttonText": "κουμπί", - "canWeDebugText": "Θα θέλατε το BombSquad να στέλνει αυτόματη αναφορά σφαλμάτων,\nκατάρρευσης, και πληροφορίες βασικής χρήσης στο δημιουργό του;\n\nΤα δεδομένα δε περιέχουν προσωπικές σας πληροφορίες και\nβοηθούν το παιχνίδι να τρέχει ομαλά χωρίς σφάλματα.", + "canWeDebugText": "Θα θέλατε το ${APP_NAME} να στέλνει αυτόματη αναφορά σφαλμάτων,\nκατάρρευσης, και πληροφορίες βασικής χρήσης στο δημιουργό του;\n\nΤα δεδομένα δε περιέχουν προσωπικές σας πληροφορίες και\nβοηθούν το παιχνίδι να τρέχει ομαλά χωρίς σφάλματα.", "cancelText": "Άκυρο", "cantConfigureDeviceText": "Συγνώμη, η συσκευή ${DEVICE} είναι μη οριστικοποιήσιμη.", "challengeEndedText": "Αυτή η πρόκληση έχει τελειώσει.", "chatMuteText": "Σίγαση Συζήτησης", "chatMutedText": "Συζήτηση σε Σίγαση", "chatUnMuteText": "Απενεργοποίηση Σίγασης", + "chests": { + "prizeOddsText": "Πιθανότητες βραβείων", + "reduceWaitText": "Μείωστε την παραμονή", + "slotDescriptionText": "Αυτή η θέση μπορεί να κρατήσει ένα σεντούκι.\n\nΝικήστε σεντούκια παίζοντας επίπεδα ιστορίας,\nσυμμετέχοντας σε τουρνουά, και ολοκληρώνοντας\nεπιτεύγματα.", + "slotText": "Θέση σεντουκιού ${NUM}", + "slotsFullWarningText": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Όλες οι θέσεις σεντουκιών σας είναι γεμάτες.\nΟποιαδήποτε σεντούκια κερδίσετε σε αυτό το παιχνίδι θα χαθούν.", + "unlocksInText": "Ξεκλειδώνεται Σε" + }, "choosingPlayerText": "<επιλογή παίκτη>", + "claimText": "Διεκδήκηση", + "codesExplainText": "Οι κωδικοί παρέχονται από τον δημιουργό για τη\nδιάγνωση και την επιδιόρθωση προβλημάτων λογαριασμού.", "completeThisLevelToProceedText": "Πρέπει να ολοκληρώσετε αυτό\nτο επίπεδο για να προχωρήσετε!", "completionBonusText": "Μπόνους Ολοκλήρωσης", "configControllersWindow": { @@ -444,6 +464,7 @@ "swipeText": "swipe", "titleText": "Οριστικοποίηση Οθόνης Αφής" }, + "configureDeviceInSystemSettingsText": "Η συσκευή ${DEVICE} μπορεί να προσαρμοστεί απο τις ρυθμίσεις της συσκευής σας.", "configureItNowText": "Οριστικοποίηση τώρα;", "configureText": "Οριστικοποίηση", "connectMobileDevicesWindow": { @@ -547,6 +568,7 @@ "demoText": "Επίδειξη", "denyText": "Απαγόρευση", "deprecatedText": "Καταργήθηκε", + "descriptionText": "Περιγραφή", "desktopResText": "Ανάλυση Σταθερού Η/Υ", "deviceAccountUpgradeText": "Προσοχή:\nΧρησιμοποιειτέ ένα λογαριασμό συσκευής(${NAME}).\nΟι λογαριασμοί συσκευών θα αφαιρεθούν σε μέλλουσα ενημέρωση.\nΑναβαθμίστε σε ένα λογαριασμό V2 αν θέλετε να διατηρήσετε την πρόοδο σας.", "difficultyEasyText": "Εύκολο", @@ -557,6 +579,10 @@ "disableRemoteAppConnectionsText": "Απενεργοποίηση Συνδέσεων Ασύρματης Εφαρμογής", "disableXInputDescriptionText": "Επιτρέπει περισσότερα από 4 χειριστήρια αλλά μπορεί να μη λειτουργήσει.", "disableXInputText": "Απενεργοποίηση XIinput", + "disabledText": "Απενεργοποιημένο", + "discardText": "Απόρριψη", + "discordFriendsText": "Θέλετε να βρείτε νέους φίλους για να παίξετε;\nΜπείτε στο Discord μας και βρείτε νέους φίλους!", + "discordJoinText": "Μπείτε στο Discord", "doneText": "Έγινε", "drawText": "Ισοπαλία", "duplicateText": "Διπλοτυπία", @@ -589,6 +615,7 @@ "localProfileText": "(τοπικό προφίλ)", "nameDescriptionText": "Όνομα Παίκτη", "nameText": "Όνομα", + "profileAlreadyExistsText": "Υπάρχει ήδη προφίλ με αυτό το όνομα.", "randomText": "τυχαίο", "titleEditText": "Επεξεργασία Προφίλ", "titleNewText": "Νέο Προφίλ", @@ -624,6 +651,7 @@ "useMusicFolderText": "Φάκελος Αρχείων Μουσικής" }, "editText": "Επεξεργασία", + "enabledText": "Ενεργοποιημένο", "endText": "Τέλος", "enjoyText": "Απολαύστε!", "epicDescriptionFilterText": "${DESCRIPTION} Σε επικά αργή κίνηση.", @@ -635,6 +663,8 @@ "errorText": "Σφάλμα", "errorUnknownText": "άγνωστο σφάλμα", "exitGameText": "Έξοδος από το ${APP_NAME};", + "expiredAgoText": "Έληξε πριν από ${T}", + "expiresInText": "Λήγει σε ${T}", "exportSuccessText": "Έγινε εξαγωγή του στοιχείου '${NAME}'.", "externalStorageText": "Εξωτερικός Αποθηκευτικός Χώρος", "failText": "Αποτυχία", @@ -669,6 +699,8 @@ "duplicateText": "Διπλοτυπία\nΛίστας", "editText": "Επεξεργασία\nΛίστας", "newText": "Νέα\nΛίστα", + "pointsToWinText": "Πόντοι Έως Νίκη", + "seriesLengthText": "Μήκος Σειράς", "showTutorialText": "Προβολή Εκπαιδευτικού Βίντεο", "shuffleGameOrderText": "Ανακάτεμα Ουράς Παιχνιδιών", "titleText": "Προσαρμογή Λίστων Παιχνιδιών ${TYPE}" @@ -694,6 +726,7 @@ "copyCodeConfirmText": "Ο κωδικός αντιγράφηκε στο πρόχειρο.", "copyCodeText": "Αντιγράψτε τον κωδικό", "dedicatedServerInfoText": "Για καλύτερα αποτελέσματα, οργανώστε έναν σταθερό διακομιστή. Βλέπε bombsquadgame.com/server.", + "descriptionShortText": "Χρησιμοποιήστε το παράθυρο συγκέντρωσης για να φτιάξετε ένα πάρτυ.", "disconnectClientsText": "Συνεχίζοντας θα αποσυνδεθούν ${COUNT} παίκης/ες\nαπο τη συγκέντρωσή σας. Είστε σίγουροι?", "earnTicketsForRecommendingAmountText": "Οι φίλοι σας θα λάβουν ${COUNT} εισητήρια αν δοκιμάσουν το παιχνίδι\n(και εσείς θα λάβετε ${YOU_COUNT} για τον καθένα)", "earnTicketsForRecommendingText": "Μοιραστείτε το παιχνίδι\nγια δωρεάν εισητήρια...", @@ -706,10 +739,10 @@ "friendHasSentPromoCodeText": "${COUNT} εισητήρια ${APP_NAME} από ${NAME}", "friendPromoCodeAwardText": "Θα λάμβάνετε από ${COUNT} εισητήρια για κάθε χρήση.", "friendPromoCodeExpireText": "Αυτός ο κωδικός λήγει σε ${EXPIRE_HOURS} ώρες και λειτουργεί μόνο για νέα μέλη.", - "friendPromoCodeInstructionsText": "Για να το αξιοποιήσετε, ανοίξτε το ${APP_NAME} και ακολουθήστε το \"Ρυθμίσεις->Σύνθετες->Εισαγωγή Κωδικού\".\nΒλέπε bombsquadgame.com για συνδέσμους της εφαρμογής σε όλες τις υποστηριζόμενες πλατφόρμες.", + "friendPromoCodeInstructionsText": "Για να το αξιοποιήσετε, ανοίξτε το ${APP_NAME} και ακολουθήστε το \"Ρυθμίσεις->Σύνθετες->Αποστολή Πληροφοριών\".\nΒλέπε bombsquadgame.com για συνδέσμους της εφαρμογής σε όλες τις υποστηριζόμενες πλατφόρμες.", "friendPromoCodeRedeemLongText": "Μπορεί να εξαργυρωθεί για ${COUNT} δωρεάν εισητήρια από έως ${MAX_USES} άτομα.", "friendPromoCodeRedeemShortText": "Μπορεί να εξαργυρωθεί για ${COUNT} εισητήρια στο παιχνίδι.", - "friendPromoCodeWhereToEnterText": "(στο \"Ρυθμίσεις->Σύνθετες->Εισαγωγή Κωδικού\")", + "friendPromoCodeWhereToEnterText": "(στο \"Ρυθμίσεις->Σύνθετες->Αποστολή Πληροφοριών\")", "getFriendInviteCodeText": "Αποκτήστε Κωδικό Πρόσκλησης Φίλων", "googlePlayDescriptionText": "Προσκάλεσε Google Play παίκτες στη συγκέντρωσή σας:", "googlePlayInviteText": "Πρόσκληση", @@ -741,6 +774,7 @@ "manualYourLocalAddressText": "Η τοπική σας διεύθυνση:", "nearbyText": "Κοντινά", "noConnectionText": "<εκτός σύνδεσης>", + "noPartiesAddedText": "Δεν Προστέθηκαν Πάρτι", "otherVersionsText": "(άλλες εκδόσεις)", "partyCodeText": "Κωδικός Party", "partyInviteAcceptText": "Αποδοχή", @@ -804,6 +838,12 @@ "youHaveShortText": "έχετε ${COUNT}", "youHaveText": "έχετε ${COUNT} εισιτήρια" }, + "goldPass": { + "desc1InfTokensText": "Άπειρα κέρματα.", + "desc2NoAdsText": "Καθόλου διαφημίσεις.", + "desc3ForeverText": "Για πάντα.", + "goldPassText": "Χρυσό Πάσο" + }, "googleMultiplayerDiscontinuedText": "Συγνώμη, φαίνεται πως η υπηρεσία πολλών παικτών της Google δεν είναι πλέον διαθέσιμη.\nΠροσπαθώ να βρω αντικατάσταση όσο πιο γρήγορα γίνεται.\nΜέχρι τότε, παρακαλώ δοκιμάστε άλλο τρόπο σύνδεσης.\n-Eric", "googlePlayPurchasesNotAvailableText": "Οι αγορές Google Play δεν είναι διαθέσιμες.\nΜπορεί να χρειάζεται να ενημερώσετε την εφαρμογή σας.", "googlePlayServicesNotAvailableText": "Οι υπηρεσίες Google Play δεν είναι διαθέσιμες.\nΚάποιες λειτουργείες μπορεί να είναι απενεργοποιμένες.", @@ -812,10 +852,12 @@ "alwaysText": "Πάντα", "fullScreenCmdText": "Πλήρης Οθόνη (Cmd-F)", "fullScreenCtrlText": "Πλήρης Οθόνη (Ctrl-F)", + "fullScreenText": "Πλήρης Οθόνη", "gammaText": "Gamma", "highText": "Υψηλό", "higherText": "Υψηλότερο", "lowText": "Χαμηλό", + "maxFPSText": "Όριο FPS", "mediumText": "Μέτριο", "neverText": "Ποτέ", "resolutionText": "Ανάλυση", @@ -880,6 +922,7 @@ "importText": "Εισαγωγή", "importingText": "Εισαγωγή...", "inGameClippedNameText": "θα εμφανίζεται ως\n\"${NAME}\"", + "inboxText": "Εισερχόμενα", "installDiskSpaceErrorText": "ΣΦΑΛΜΑ: Αδύνατη η ολοκλήρωση της εγκατάστασης.\nΕνδέχεται να ξεμείνατε από αποθηκευτικό χώρο στη\nσυσκεύη. Αδειάστε λίγο χώρο και ξαναπροσπαθήστε.", "internal": { "arrowsToExitListText": "πατήστε ${LEFT} ή ${RIGHT} για έξοδο από τη λίστα", @@ -934,12 +977,14 @@ "timeOutText": "(ο χρόνος λήγει σε ${TIME} δευτερόλεπτα)", "touchScreenJoinWarningText": "Έχετε ενταχθεί με την οθόνη αφής.\nΑν συνέβη καταλάθος πατήστε με αυτή στο 'Μενού->Έξοδος Παιχνιδιού'.", "touchScreenText": "Οθόνη Αφής", + "unableToCompleteTryAgainText": "Δεν μπορεί να ολοκληρωθεί αυτό τώρα.\nΠαρακαλώ προσαπθήστε ξανά.", "unableToResolveHostText": "Σφάλμα: αδύνατη η επίλυση του οικοδεσπότη.", "unavailableNoConnectionText": "Αυτό είναι προς το παρόν μη διαθέσιμο (χωρίς πρόσβαση στο διαδίκτυο;)", "vrOrientationResetCardboardText": "Χρησιμοποιήστε το για την επαναφορά το προσανατολισμού VR.\nΓια να παίξετε το παιχνίδι θα χρειαστείτε ένα εξωτερικό χειριστήριο.", "vrOrientationResetText": "Έγινε επαναφορά του VR προσανατολισμού.", "willTimeOutText": "(θα σταματήσει αν παραμείνει αδρανής)" }, + "inventoryText": "Αποθήκη", "jumpBoldText": "ΑΛΜΑ", "jumpText": "Άλμα", "keepText": "Κράτησέ τες", @@ -986,8 +1031,11 @@ "seasonEndsMinutesText": "Η σεζόν λήγει σε ${NUMBER} λεπτά.", "seasonText": "Σεζόν ${NUMBER}", "tournamentLeagueText": "Πρέπει να φτάσετε στην κατηγορία ${NAME} για να συμμετάσχετε σε αυτό το τουρνουά.", - "trophyCountsResetText": "Ο αριθμός των βραβείων θα υποστεί επαναφορά στην επόμενη σεζόν." + "trophyCountsResetText": "Ο αριθμός των βραβείων θα υποστεί επαναφορά στην επόμενη σεζόν.", + "upToDateBonusDescriptionText": "Οι παίκτες που τρέχουν μία πρόσφατη έκδοση του παιχνιδιού\nλαμβάνουν ένα μπόνους ${PERCENT}% εδώ.", + "upToDateBonusText": "Μπόνους εκσυγχρονισμού" }, + "learnMoreText": "Μάθετε Περισσότερα", "levelBestScoresText": "Οι υψηλότερες βαθμολογίες στο επίπεδο ${LEVEL}", "levelBestTimesText": "Οι καλύτεροι χρόνοι στο επίπεδο ${LEVEL}", "levelIsLockedText": "Το επίπεδο ${LEVEL} είναι κλειδωμένο.", @@ -1027,9 +1075,12 @@ "maxConnectionsText": "Μέγιστος Αριθμός Συνδέσεων", "maxPartySizeText": "Μέγιστος Αριθμός Συγκέντρωσης", "maxPlayersText": "Μέγιστος Αριθμός Παικτών", + "merchText": "Εμπόρευμα!", "modeArcadeText": "Λειτουργία \"Arcade\"", "modeClassicText": "Κλασσική λειτουργία", "modeDemoText": "Δοκιμαστική λειτουργία", + "moreSoonText": "Περισσότερα έρχονται σύντομα...", + "mostDestroyedPlayerText": "Πιο Κατεστραμμένος", "mostValuablePlayerText": "Πολυτιμότερος Παίκτης", "mostViolatedPlayerText": "Πιο Ξυλοδαρμένος Παίκτης", "mostViolentPlayerText": "Πιο Βίαιος Παίκτης", @@ -1056,7 +1107,9 @@ "noContinuesText": "(χωρίς \"Συνέχιση\")", "noExternalStorageErrorText": "Δεν βρέθηκε εξωτερικός αποθηκευτικός χώρος σε αυτή τη συσκευή", "noGameCircleText": "Σφάλμα: δεν έχετε συνδεθεί στο GameCircle", + "noPluginsInstalledText": "Καθόλου Πρόσθετα Εγκατεστημένα", "noScoresYetText": "Δεν υπάρχουν βαθμολογίες ακόμη.", + "noServersFoundText": "Δεν βρέθηκαν διακομηστές.", "noThanksText": "Όχι Ευχαριστώ", "noTournamentsInTestBuildText": "ΠΡΟΣΟΧΗ: Τα σκορ του τουρνουά από αυτή τη δοκιμαστική έκδοση θα αγνοηθούν.", "noValidMapsErrorText": "Δεν βρέθηκαν έγκυροι χάρτες γι' αυτόν τον τύπο παιχνιδιού.", @@ -1125,7 +1178,11 @@ "pleaseWaitText": "Παρακαλώ περιμένετε...", "pluginClassLoadErrorText": "Σφάλμα φορτώνοντας πρόσθετο '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Σφάλμα επερξεγάζοντας πρόσθετο '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "συνδέω Ρυθμίσεις", + "pluginsAutoEnableNewText": "Αυτόματη ενεργοποίηση νέων προσθηκών", "pluginsDetectedText": "Νέα πρόσθετο/α εντοπίστηκαν. Επανεκκινήστε την εφαρμογή για να τα ενεργοποιήσετε, ή διαμορφώστε τα στις ρυθμίσεις.", + "pluginsDisableAllText": "Απενεργοποίηση όλων των προσθηκών", + "pluginsEnableAllText": "Ενεργοποίηση όλων των προσθέτων", "pluginsRemovedText": "${NUM} πρόσθετο/α δεν εντοπίζονται πια.", "pluginsText": "Πρόσθετα", "practiceText": "Πρακτική", @@ -1218,7 +1275,9 @@ "revertText": "Επαναφορά", "runText": "Τρέξιμο", "saveText": "Αποθήκευση", - "scanScriptsErrorText": "Σφάλματα σάρωσης σάρωσης; δείτε το αρχείο καταγραφής για λεπτομέρειες.", + "scanScriptsErrorText": "Σφάλμα(α) κατά τη σάρωση σεναρίων. Δείτε το αρχείο καταγραφής για λεπτομέρειες.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} και ${NUM} άλλη(ες) λειτουργείες χρειάζεται(ονται) για το api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "Το ${PATH} χρειάζεται να αναβαθμιστεί για το api ${API}", "scoreChallengesText": "Προκλήσεις Βαθμολογίας", "scoreListUnavailableText": "Λίστα βαθμολογίας μη διαθέσιμη.", "scoreText": "Βαθμολογία", @@ -1229,6 +1288,7 @@ }, "scoreWasText": "(ήταν ${COUNT})", "selectText": "Επιλογή", + "sendInfoDescriptionText": "Στέλνει πληροφορίες λογαριασμού και κατάστασης εφαρμογής στον δημιουργό.\nΠαρακαλούμε να συμπεριλάβετε το όνομά σας ή την αιτία αποστολής.", "seriesWinLine1PlayerText": "ΚΕΡΔΙΣΕ ΤΗ", "seriesWinLine1TeamText": "ΚΕΡΔΙΣΕ ΤΗ", "seriesWinLine1Text": "ΚΕΡΔΙΣΕ ΤΗ", @@ -1244,8 +1304,9 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(ένα απλό, φιλικό με τα χειριστήρια πληκτρολόγιο οθόνης για επεξεργασία κειμένου)", - "alwaysUseInternalKeyboardText": "Πάντα να Χρησιμοποιείται το Εσωτερικό Πληκτρολόγιο", + "alwaysUseInternalKeyboardText": "Πάντα να χρησιμοποιείται το εσωτερικό πληκτρολόγιο", "benchmarksText": "Έλεγχοι Απόδοσης & Κόπωσης", + "devToolsText": "Εργαλεία Δημιουργού", "disableCameraGyroscopeMotionText": "Απενεργοποιήστε γυροσκοπική κίνηση της κάμερας", "disableCameraShakeText": "Απενεργοποιήστε το κούνημα της κάμερας", "disableThisNotice": "(μπορείτε να απενεργοποιήσετε αυτή τήν ειδοποίηση στις σύνθετες ρυθμίσεις)", @@ -1254,14 +1315,20 @@ "enterPromoCodeText": "Εισαγωγή Κωδικού", "forTestingText": "Σημείωση: αυτές οι τιμές είναι μονάχα για έλεγχο και θα χαθούν όταν πραγματοποιηθεί έξοδος από την εφαρμογή.", "helpTranslateText": "Οι μη Αγγλικές μεταφράσεις του ${APP_NAME} είναι υποστιριζόμενες\nαπό την κοινότητα. Αν θα θέλατε να συνεισφέρετε ή να διορθώσετε μια\nμετάφραση ακολουθήστε τον παρακάτω σύνδεσμο. Ευχαριστώ προκαταβολικά!", - "kickIdlePlayersText": "Αποβολή Άπραγων Παικτών", + "kickIdlePlayersText": "Αποβολή άπραγων παικτών", "kidFriendlyModeText": "Λειτουργία για Παιδιά (μειωμένη βία, κτλ)", "languageText": "Γλώσσα", "moddingGuideText": "Οδηγός Τροποποίησης", + "moddingToolsText": "Εργαλεία Τροποποίησης", "mustRestartText": "Για να λειτουργήσει, πρέπει να επανεκκινήσετε το παιχνίδι.", "netTestingText": "Έλεγχος Δικτύου", "resetText": "Επαναφορά", + "sendInfoText": "Αποστολή πληροφοριών", "showBombTrajectoriesText": "Εμφάνιση Πορείας Βόμβας", + "showDemosWhenIdleText": "Προβολή ντέμο σε αδράνεια", + "showDeprecatedLoginTypesText": "Εμφάνιση καταργημένων τύπων εισόδου", + "showDevConsoleButtonText": "Εμφάνιση κουμπιού κονσόλας προγραμματιστών", + "showInGamePingText": "Εμφάνιση καθυστέρησης εντός-παιχνιδιού", "showPlayerNamesText": "Προβολή Ονομάτων Παικτών", "showUserModsText": "Προβολή Φακέλου Πακέτων Τροποποίησης", "titleText": "Σύνθετες", @@ -1269,8 +1336,8 @@ "translationFetchErrorText": "κατάσταση μεταφράσεων μη διαθέσιμη", "translationFetchingStatusText": "έλεγχος κατάστασης μεταφράσεων...", "translationInformMe": "Πληροφόρησέ με όταν η γλώσσα μου χρειάζεται ενημερώσεις", - "translationNoUpdateNeededText": "η συγγεκριμμένη γλώσσα είναι ενημερωμένη, γιούπι!", - "translationUpdateNeededText": "** η συγκεκριμένη γλώσσα χρειάζεται ενημερώσεις!! **", + "translationNoUpdateNeededText": "Η συγκεκριμένη γλώσσα είναι ενημερωμένη, γιούπι!", + "translationUpdateNeededText": "** Η συγκεκριμένη γλώσσα χρειάζεται ενημερώσεις!! **", "vrTestingText": "Έλεγχος VR" }, "shareText": "Κοινοποίηση", @@ -1280,6 +1347,9 @@ "signInWithGameCenterText": "Για να χρησιμοποιήσετε έναν λογαριασμό Game Center,\nσυνδεθείτε σε αυτόν με την εφαρμογή Game Center.", "singleGamePlaylistNameText": "Μόνο ${GAME}", "singlePlayerCountText": "1 παίκτης", + "sizeLargeText": "Μεγάλο", + "sizeMediumText": "Μέτριο", + "sizeSmallText": "Μικρό", "soloNameFilterText": "Σόλο ${NAME}", "soundtrackTypeNames": { "CharSelect": "Επιλογή Χαρακτήρα", @@ -1352,6 +1422,8 @@ "storeText": "Κατάστημα", "submitText": "Υποβολή", "submittingPromoCodeText": "Υποβολή Κωδικού...", + "successText": "Επιτυχία!", + "supportEmailText": "Εάν αντιμετωπίζετε προβλήματα με την εφαρμογή, παρακαλώ να στείλετε e-mail \nστο ${EMAIL}", "teamNamesColorText": "Ονόματα/Χρώμματα Ομάδων...", "telnetAccessGrantedText": "Πρόσβαση telnet ενεργοποιημένη.", "telnetAccessText": "Πρόσβαση telnet εντοπίστηκε. Να επιτρέπεται;", @@ -1532,6 +1604,7 @@ "Italian": "Ιταλικά", "Japanese": "Ιαπωνέζικα", "Korean": "Κορεάτικα", + "Malay": "Μαλεσιακά", "Persian": "Πέρσικα", "Polish": "Πολωνικά", "Portuguese": "Πορτογαλικά", @@ -1799,11 +1872,13 @@ "toSkipPressAnythingText": "(πατήστε ή πιέστε οτιδήποτε για να παραλείψετε το εκπαιδευτικό βίντεο)" }, "twoKillText": "ΔΙΠΛΟΣ ΦΟΝΟΣ!", + "uiScaleText": "Κλίμακα UI", "unavailableText": "μη διαθέσιμο", "unconfiguredControllerDetectedText": "Εντοπίστηκε μη διαμορφωμένο χειριστήριο:", "unlockThisInTheStoreText": "Αυτό πρέπει να ξεκλειδωθεί στο κατάστημα.", "unlockThisProfilesText": "Για να δημιουργήσετε περισσότερα από ${NUM} προφίλ, χρειάζεστε:", "unlockThisText": "Για να το ξεκλειδώσετε, χρειάζεστε:", + "unsupportedControllerText": "Συγνώμη, το χειρηστήριο \"${NAME}\" δεν υποστηρίζεται.", "unsupportedHardwareText": "Συγνώμη, αυτό το υλισμικό δεν υποστηρίζεται από αυτή την έκδοση του παιχνιδιού.", "upFirstText": "Για αρχή:", "upNextText": "Στη συνέχεια, παιχνίδι ${COUNT}:", @@ -1811,10 +1886,13 @@ "upgradeText": "Αναβάθμιση", "upgradeToPlayText": "Ξεκλειδώστε το \"${PRO}\" στο κατάστημα του παιχνιδιού για να μπορείτε να το παίξετε.", "useDefaultText": "Χρήση Προκαθορισμένων", + "userSystemScriptsCreateText": "Δημιουργία Κωδικών Συστήματος Χρήστη", + "userSystemScriptsDeleteText": "Διαγραφή Κωδικών Συστήματος Χρήστη", "usesExternalControllerText": "Αυτό το παιχνίδι χρησιμοποιεί ένα εξωτερικό χειριστήριο για είσοδο.", "usingItunesText": "Χρήση εφαρμογής μουσικής για ηχητική υπόκρουση...", "v2AccountLinkingInfoText": "Για να δεσμεύσετε λογαριασμούς V2, χρησιμοιποιήστε το κουμπί 'Διαχείριση Λογαριασμού'.", "validatingTestBuildText": "Επικύρωση Δοκιμαστικής Έκδοσης...", + "viaText": "μέσω", "victoryText": "Νίκη!", "voteDelayText": "Δεν μπορείτε να ξαναξεκινήσετε ψηφοφορία για ${NUMBER} δευτ.", "voteInProgressText": "Μια ψηφοφορία βρίσκεται ήδη σε εξέλιξη.", diff --git a/dist/ba_data/data/languages/hindi.json b/dist/ba_data/data/languages/hindi.json index 1fdbcf80..3bfa7d40 100644 --- a/dist/ba_data/data/languages/hindi.json +++ b/dist/ba_data/data/languages/hindi.json @@ -7,7 +7,9 @@ "campaignProgressText": "अभियान प्रगति [कठिन]: ${PROGRESS}", "changeOncePerSeason": "आप केवल प्रति सीजन इसे एक बार बदल सकते हैं।", "changeOncePerSeasonError": "आपको इसे फिर से बदलने के लिए अगले सीज़न तक इंतजार करना होगा (${NUM} दिन)", + "createAnAccountText": "खाता बनाएं", "customName": "अनुकूल नाम", + "deleteAccountText": "खाता हटा दो", "googlePlayGamesAccountSwitchText": "अगर आप किसी भिन्न Google खाते का उपयोग करना चाहते हैं,\n स्विच करने के लिए Google Play गेम्स ऐप का उपयोग करें।", "linkAccountsEnterCodeText": "कोड डालीए", "linkAccountsGenerateCodeText": "काेड उत्पन्न करे", @@ -25,14 +27,16 @@ "setAccountNameDesc": "अपने खाते के लिए प्रदर्शित करने के लिए नाम चुनें। \nआप अपने लिंक किए गए किसी एक से नाम का उपयोग कर सकते हैं \nखातों या अनन्य कस्टम नाम बनाएं", "signInInfoText": "सभी यंत्रों पर अपनी प्रगति को संग्रहीत करने के लिए, \nटिकट कमाने, टूर्नामेंट में प्रतिस्पर्धा करने के लिए साइन इन करें |", "signInText": "साइन इन", + "signInWithAnEmailAddressText": "ईमेल पते से साइन इन करें", "signInWithDeviceInfoText": "(एक स्वचालित खता जिसका सिर्फ इस यंत्र से प्रयोग किया जा सकता है)", "signInWithDeviceText": "इस डिवाइस के साथ साइन इन करें", "signInWithGameCircleText": "Game circle के साथ प्रवेश करे", "signInWithGooglePlayText": "गूगल प्ले से साईन ईन करे", "signInWithTestAccountInfoText": "(पुराना खाते का प्ररूप; आगे के लिए यंत्र खाते का प्रयोग करें)", "signInWithTestAccountText": "परीक्षण के खाते से साइन इन करें", + "signInWithText": "${SERVICE} से साइन इन करे।", "signInWithV2InfoText": "(एक खाता जो सभी प्लेटफार्मों पर काम करता है)", - "signInWithV2Text": "BombSquad खाते से साइन इन करें", + "signInWithV2Text": "${APP_NAME} खाते से साइन इन करें", "signOutText": "साइन आउट", "signingInText": "साइन इन हो रहा है...", "signingOutText": "साइन आउट हो रहा है...", @@ -43,9 +47,10 @@ "titleText": "खाता", "unlinkAccountsInstructionsText": "अनलिंक करने के लिए एक खाता चुनें", "unlinkAccountsText": "खाते अनलिंक करें", + "unlinkLegacyV1AccountsText": "लैगेसी (V1) खाते को एनलिंक करे", "v2LinkInstructionsText": "खाता बनाने या साइन इन करने के लिए इस लिंक का उपयोग करें।", "viaAccount": "(खाता ${NAME} के माध्यम से)", - "youAreSignedInAsText": "आप इस खाते से साइनड इन हो: " + "youAreSignedInAsText": "आप इस खाते से साइनड इन हो:" }, "achievementChallengesText": "उपलब्धि की चुनौतियां", "achievementText": "उपलब्धि", @@ -336,9 +341,14 @@ "getMoreGamesText": "और गेम्स कि जानकारी पायें", "titleText": "गेम जोड़ें" }, + "addToFavoritesText": "पसंदीदा में जोड़े।", + "addedToFavoritesText": "'${NAME}' को पसंदीदा में जोड़ा गया हैं।", + "allText": "सभी", "allowText": "अनुमति दें", "alreadySignedInText": "आपका खाता किसी अन्य डिवाइस से साइन किया गया है; \nकृपया खातों को स्विच करें या अपने गेम को अन्य डिवाइस \nपर बंद करें और फिर से प्रयास करें", "apiVersionErrorText": "${NAME} मौड्यूल लोड नहीं हो पाया ; यह एपीआई - संस्करण ${VERSION_USED} पे काम करने का प्रयास कर रहा है ; हमें संस्करण ${VERSION_REQUIRED} चाहिए |", + "applyText": "अवदेना करे", + "areYouSureText": "क्या आप निश्चित हो", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"स्वयं\" इसे तभी शुरू करेगा जब हैडफ़ोन लगें हों)", "headRelativeVRAudioText": "सर के सापेक्ष वीआर ध्वनि", @@ -360,14 +370,24 @@ "boostText": "प्रोत्साहन", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} को एप्लीकेशन के अन्दर से ही कॉन्फ़िगर करें |", "buttonText": "बटन", - "canWeDebugText": "क्या आप बोम्ब-स्क्वाड को अपने आप खराबियों व \nआधारभूत उपयोग कि जानकारी भेजना चाहते हैं ? \n\nइस जानकारी में कुछ भी व्यक्तिगत नहीं होता है व \nयह गेम को सुचारू रूप से बिना खराबियों के चलने में सहायता करता है |", + "canWeDebugText": "क्या आप ${APP_NAME} को अपने आप खराबियों व \nआधारभूत उपयोग कि जानकारी भेजना चाहते हैं ? \n\nइस जानकारी में कुछ भी व्यक्तिगत नहीं होता है व \nयह गेम को सुचारू रूप से बिना खराबियों के चलने में सहायता करता है |", "cancelText": "रद्द करें", "cantConfigureDeviceText": "माफ़ करें  ${DEVICE} कांफिग्युरेब्ल नहीं है |", "challengeEndedText": "यह चुनौती समाप्त हो चूकि हैं", "chatMuteText": "बातचीत मौन करें", "chatMutedText": "बातचीत मौन हो गई है", "chatUnMuteText": "बातचीत दोबारा शुरू करें", + "chests": { + "prizeOddsText": "पुरस्कार की संभावना", + "reduceWaitText": "इंतज़ार कम करें", + "slotDescriptionText": "यह स्लॉट एक संदूक रख सकता है।\n\nअभियान स्तर खेलकर चेस्ट अर्जित करें,\nटूर्नामेंट में जगह बनाना, और पूरा करना\nउपलब्धियाँ.", + "slotText": "चेस्ट स्लॉट ${NUM}", + "slotsFullWarningText": "चेतावनी: आपके सभी चेस्ट स्लॉट भरे हुए हैं।\nइस गेम में आप जो भी चेस्ट अर्जित करेंगे वह खो जाएगा।", + "unlocksInText": "में अनलॉक करता है" + }, "choosingPlayerText": "<खिलाड़ी चुना जा रहा है>", + "claimText": "दावा", + "codesExplainText": "खाता समस्याओं के निदान और सुधार के लिए डेवलपर \nद्वारा कोड प्रदान किए जाते हैं ।", "completeThisLevelToProceedText": "आपको यह पड़ाव पार करना पड़ेगा आगे बढ़ने के लिए !", "completionBonusText": "पूर्णता पुरस्कार", "configControllersWindow": { @@ -448,6 +468,7 @@ "swipeText": "स्वाइप", "titleText": "टच स्क्रीन को कॉन्फ़िगर करें" }, + "configureDeviceInSystemSettingsText": "${DEVICE} को सिस्टम सेटिंग्स एप में कंफीगर कर सकते हैं।", "configureItNowText": "अभी कॉन्फ़िगर करें ?", "configureText": "कॉन्फ़िगर", "connectMobileDevicesWindow": { @@ -459,7 +480,7 @@ "forIOSText": "आई-ओ-एस के लिए:", "getItForText": "${REMOTE_APP_NAME} पायें आई-ओ-एस के लिए एप्पल एप्लीकेशन भंडार से \nव एंड्राइड के लिए गूगल प्ले भंडार या अमेज़न एप्लीकेशन भंडार से |", "googlePlayText": "गूगल प्ले स्टोर", - "titleText": "मोबाइल यंत्र का नियंत्रक के रूप में प्रयोग करते हुए: " + "titleText": "मोबाइल यंत्र का नियंत्रक के रूप में प्रयोग करते हुए:" }, "continuePurchaseText": "${PRICE} के खर्चे पर जारी रखें ?", "continueText": "जारी रखें", @@ -550,6 +571,7 @@ "demoText": "डेमो", "denyText": "अस्वीकृत करें", "deprecatedText": "पदावनत", + "descriptionText": "डीसकरिपषण", "desktopResText": "डेस्कटॉप रेज़ोल्यूशन", "deviceAccountUpgradeText": "चेतावनी:\n आप डिवाइस खाते (${NAME}) से साइन इन हैं।\n डिवाइस खातों को भविष्य के अपडेट में हटा दिया जाएगा।\n यदि आप अपनी प्रगति को बनाए रखना चाहते हैं तो V2 खाते में अपग्रेड करें।", "difficultyEasyText": "आसन", @@ -560,6 +582,10 @@ "disableRemoteAppConnectionsText": "रिमोट के ऐप्प कनेक्शन्स को बंद करे", "disableXInputDescriptionText": "4 नियंत्रकों से अधिक की अनुमति देता है लेकिन साथ ही साथ काम नहीं कर सकते", "disableXInputText": "Xinput अक्षम करें", + "disabledText": "डिसेबल्ड", + "discardText": "खारिज करना", + "discordFriendsText": "क्या आप खेलने के लिए नए लोगों की तलाश करना चाहते हैं? \n हमारे डिस्कोर्ड में शामिल हों और नए दोस्त खोजें!", + "discordJoinText": "डिस्कोर्ड में शामिल हों", "doneText": "हो गया", "drawText": "बराबर", "duplicateText": "प्रतिलिपि", @@ -593,6 +619,7 @@ "localProfileText": "(स्थानिक पार्श्वचित्र)", "nameDescriptionText": "खिलाड़ी का नाम", "nameText": "नाम", + "profileAlreadyExistsText": "खाता इस नाम से पहेले ही बन चूका है", "randomText": "यादृच्छिक", "titleEditText": "पार्श्वचित्र को संपादित करें", "titleNewText": "नया पार्श्वचित्र बनायें", @@ -628,6 +655,7 @@ "useMusicFolderText": "गाने कि फाइल्स का फोल्डर" }, "editText": "संपादित करें", + "enabledText": "इनेब्ल", "endText": "समाप्त", "enjoyText": "मज़ा लें !", "epicDescriptionFilterText": "${DESCRIPTION} उत्कृष्ट धीमे गति में।", @@ -639,6 +667,8 @@ "errorText": "त्रुटी", "errorUnknownText": "अज्ञात त्रुटी", "exitGameText": "${APP_NAME} से निकास करें ?", + "expiredAgoText": "${T} पहले समाप्त हो गया", + "expiresInText": "${T} में समाप्त होता है", "exportSuccessText": "'${NAME}' निर्यात हुआ", "externalStorageText": "बाहरी संचयन", "failText": "असफल", @@ -660,7 +690,7 @@ "fiveKillText": "पांच हत्या !!!", "flawlessWaveText": "त्रुटिरहित लहर !", "fourKillText": "चार हत्या !!!", - "friendScoresUnavailableText": "दोस्तों के अंक उनुप्लाब्ध हैं ", + "friendScoresUnavailableText": "दोस्तों के अंक उनुप्लाब्ध हैं", "gameCenterText": "गेम-सेण्टर", "gameCircleText": "गेम-सर्किल", "gameLeadersText": "गेम ${COUNT} के सरदार", @@ -673,6 +703,8 @@ "duplicateText": "प्लेलिस्ट कि \nछवि बनायें", "editText": "प्लेलिस्ट को \nसंपादित करें", "newText": "नयी \nप्लेलिस्ट", + "pointsToWinText": "पौइनटस जीतने के लिए", + "seriesLengthText": "श्रृंखला की लंबाई", "showTutorialText": "ट्युटोरियल दिखाएँ", "shuffleGameOrderText": "गेम के क्रमांक को मिलाएं", "titleText": "${TYPE} प्लेलिस्ट को अपने हिसाब से बदलें" @@ -683,7 +715,7 @@ "gamesToText": "${WINCOUNT} जीते और ${LOSECOUNT} हारे", "gatherWindow": { "aboutDescriptionLocalMultiplayerExtraText": "ध्यान रखें: किसी भी यंत्र पे एक से ज्यादा खिलाड़ी हो सकते हैं \nअगर आपके पास पर्याप्त नियंत्रक हैं", - "aboutDescriptionText": "पार्टी इकट्ठा करने के लिए इन टैब्स का प्रयोग करें | \n\nपार्टी में आप गेम व \nप्रतियोगिता अपने दोस्तों के साथ \nअलग यंत्रो पे भी खेल सकते हैं | \n\nऊपरी-दायें हाथ कोने में उपस्थित ${PARTY} बटन का प्रयोग करके \nआप अपनी पार्टी से बात कर सकते हैं | (नियंत्रक पे ${BUTTON} दबाएँ मेनू में) ", + "aboutDescriptionText": "पार्टी इकट्ठा करने के लिए इन टैब्स का प्रयोग करें | \n\nपार्टी में आप गेम व \nप्रतियोगिता अपने दोस्तों के साथ \nअलग यंत्रो पे भी खेल सकते हैं | \n\nऊपरी-दायें हाथ कोने में उपस्थित ${PARTY} बटन का प्रयोग करके \nआप अपनी पार्टी से बात कर सकते हैं | (नियंत्रक पे ${BUTTON} दबाएँ मेनू में)", "aboutText": "इसके बारे में", "addressFetchErrorText": "<पता पाने में त्रुटी>", "appInviteInfoText": "दोस्तों को बोम्ब-स्क्वाड खेलने के लिए आमंत्रित करें\nऔर आपको ${COUNT} टिकेट मुफ्त मिलेंगे | हर\nदोस्त के आपको ${YOU_COUNT} टिकेट मिलेंगे |", @@ -699,6 +731,7 @@ "copyCodeConfirmText": "कोड को क्लिपबोर्ड पर कॉपी किया गया है", "copyCodeText": "कोड को कॉपी करें", "dedicatedServerInfoText": "श्रेष्ठ परिणामों के लिए, एक समर्पित सर्वर सेट करें. कैसे जानने के लिए bombsquadgame.com/server देखें.", + "descriptionShortText": "किसी पार्टी को इकट्ठा करने के लिए एकत्रित विंडो का उपयोग करें।", "disconnectClientsText": "यह आपके पार्टी में ${COUNT} \nखिलाड़ियों का सम्बन्ध तोड़ देगा", "earnTicketsForRecommendingAmountText": "यदि वे गेम को आज़माते हैं तो दोस्तों को ${COUNT} \nटिकट मिलेंगे (और आप प्रत्येक के लिए ${YOU_COUNT} प्राप्त करेंगे)", "earnTicketsForRecommendingText": "मुफ्त के टिकेट \nके लिए गेम को बाटें...", @@ -711,10 +744,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} टिकेट मिले ${NAME} से", "friendPromoCodeAwardText": "आपको ${COUNT} टिकेट मिलेंगे हर बार इसका प्रयोग किया जाता है", "friendPromoCodeExpireText": "आपका कोड सिर्क नयें खिलाड़ियों के लिए चलेगा और ${EXPIRE_HOURS} घंटों के बाद काम करना बंद कर देगा", - "friendPromoCodeInstructionsText": "इसका प्रयोग करने के लिए, ${APP_NAME} खोले और फिर \"सेटिंग->उन्नत सेटिंग->कोड डालें\" में जाएँ \nअधिक जानकारी के लिए bombsquadgame.com व डाउनलोड करने के लिए पे जाएँ |", + "friendPromoCodeInstructionsText": "इसका उपयोग करने के लिए, ${APP_NAME} खोलें और \"सेटिंग्स->उन्नत->जानकारी भेजें\" पर जाएँ।\nसभी समर्थित प्लेटफ़ॉर्म के लिए डाउनलोड लिंक के लिए bombsquadgame.com देखें।", "friendPromoCodeRedeemLongText": "यह ${COUNT} मुफ्त के टिकेट के लिए प्रयोग किया जा सकता है अधकतम  ${MAX_USES} लोगों के द्वारा |", "friendPromoCodeRedeemShortText": "यह ${COUNT} मुफ्त के टिकेट के लिए प्रयोग किया जा सकता है गेम के अन्दर |", - "friendPromoCodeWhereToEnterText": "(\"सेटिंग->उन्नत सेटिंग->कोड डालें\" में जाएँ )", + "friendPromoCodeWhereToEnterText": "(\"सेटिंग्स->उन्नत->जानकारी भेजें\" में)", "getFriendInviteCodeText": "दोस्त आमंत्रण कोड पायें", "googlePlayDescriptionText": "गूगल प्ले के खिलाड़ियों को अपनी पार्टी में आमंत्रण दें:", "googlePlayInviteText": "आमंत्रण दें", @@ -746,6 +779,7 @@ "manualYourLocalAddressText": "आपका स्थानीय पता:", "nearbyText": "आस/पास", "noConnectionText": "<कोई कनेक्शन नहीं है>", + "noPartiesAddedText": "कोई दल नहीं जोड़ा गया", "otherVersionsText": "(कोई और संस्करण)", "partyCodeText": "दल कोड", "partyInviteAcceptText": "स्वीकार करें", @@ -810,6 +844,12 @@ "youHaveShortText": "आपके पास ${COUNT} हैं", "youHaveText": "आपके पास ${COUNT} टिकेट हैं" }, + "goldPass": { + "desc1InfTokensText": "अनगिनत टोकन.", + "desc2NoAdsText": "कोई विज्ञापन नहीं.", + "desc3ForeverText": "हमेशा के लिए.", + "goldPassText": "गोल्ड पास" + }, "googleMultiplayerDiscontinuedText": "क्षमा करें, गूगल की एक साथ खेलने की सेवा अब उपलब्ध नहीं है। \nमैं जितनी जल्दी हो सके एक प्रतिस्थापन पर काम कर रहा हूं।\nतब तक, कृपया दूसरी जुडने की विधि आज़माएँ। \n-Eric", "googlePlayPurchasesNotAvailableText": "गूगल प्ले से ख़रीदारी उपलब्ध नहीं हैं।\nआपको अपना स्टोर ऐप अपडेट करना पड़ सकता है।", "googlePlayServicesNotAvailableText": "गूगल प्ले सर्विसेज उपलब्ध नहीं है।\nऐप की कुछ कार्यक्षमता अक्षम हो सकती है।", @@ -818,10 +858,12 @@ "alwaysText": "हमेशा", "fullScreenCmdText": "संपूर्ण स्क्रीन में चलायें (सी-एम्-डी + ऍफ़)", "fullScreenCtrlText": "संपूर्ण स्क्रीन में चलायें (सी-टी-आर-एल + ऍफ़)", + "fullScreenText": "पूर्ण स्क्रीन", "gammaText": "चमक", "highText": "ज्यादा", "higherText": "और ज्यादा", "lowText": "कम", + "maxFPSText": "अधिकतम एफ.पी.एस.", "mediumText": "ठीक ठाक", "neverText": "कभी नहीं", "resolutionText": "रेज़ोल्यूशन", @@ -882,6 +924,7 @@ "importText": "आयात करें", "importingText": "आयात कर रहा है...", "inGameClippedNameText": "खेल में होगा \n\"${NAME}\"", + "inboxText": "इनबॉक्स", "installDiskSpaceErrorText": "त्रुटी: इनस्टॉल ख़तम नहीं कर पाया | \nआपके यंत्र पे जगह ख़तम हो सकती है | \nजगह खली कर के फिर से प्रयास करें |", "internal": { "arrowsToExitListText": "सूचि से बाहर निकलने केलिए ${LEFT} या ${RIGHT} दबाएँ", @@ -936,12 +979,14 @@ "timeOutText": "(समय ख़तम होने में ${TIME} सेकंड)", "touchScreenJoinWarningText": "आपने टच स्क्रीन से जोड़ा है | \nअगर यह गलती से हुआ है तो 'मेनू -> गेम छोड़ें' से बाहर निकल जाएँ |", "touchScreenText": "टच स्क्रीन", + "unableToCompleteTryAgainText": "इसे अभी पूरा करने में असमर्थ।\nकृपया पुन: प्रयास करें।", "unableToResolveHostText": "त्रुटि: होस्ट को हल करने में असमर्थ हैं।", "unavailableNoConnectionText": "यह अभी उपलब्ध नहीं है | (इन्टरनेट कनेक्शन है ना ?)", "vrOrientationResetCardboardText": "वी-आर अनुस्थापन रिसेट करने के लिए इसका प्रयोग करें | \nगेम खेलने के लिए आपको एक बाहरी नियंत्रक चाहिए होगा |", "vrOrientationResetText": "वी-आर अनुस्थापन रिसेट", "willTimeOutText": "(समय ख़तम हो जायेगा अगर आलसी रहेंगे)" }, + "inventoryText": "भंडार", "jumpBoldText": "कूदें", "jumpText": "कूदें", "keepText": "रखें", @@ -988,8 +1033,11 @@ "seasonEndsMinutesText": "सीज़न ख़तम होगा ${NUMBER} मिनटों में |", "seasonText": "सीज़न संख्या ${NUMBER}", "tournamentLeagueText": "इस प्रतियोगिता में हिस्सा लेने के लिए आपको ${NAME} संघ तक पहले पहुंचना होगा", - "trophyCountsResetText": "ट्रॉफी कि संख्या अगले सीज़न में रिसेट हो जायेगी" + "trophyCountsResetText": "ट्रॉफी कि संख्या अगले सीज़न में रिसेट हो जायेगी", + "upToDateBonusDescriptionText": "खिलाड़ी इसका नवीनतम संस्करण चला रहे हैं\nगेम को यहां ${PERCENT}% बोनस प्राप्त होता है।", + "upToDateBonusText": "नवीनतम बोनस" }, + "learnMoreText": "और अधिक जानें", "levelBestScoresText": "${LEVEL} पर सर्वश्रेष्ठ स्कोर", "levelBestTimesText": "${LEVEL} पर सबसे अच्छे समय", "levelFastestTimesText": "सबसे तेज़ ${LEVEL} स्तर पे", @@ -1031,9 +1079,12 @@ "maxConnectionsText": "अधिकतम कनेक्शन", "maxPartySizeText": "अधिकतम पार्टी का आकार", "maxPlayersText": "अधिकतम खिलाड़ी", + "merchText": "मर्च!", "modeArcadeText": "आर्केड मोड", "modeClassicText": "क्लासिक मोड", "modeDemoText": "डेमो मोड", + "moreSoonText": "और अधिक जल्द ही आ रहा है...", + "mostDestroyedPlayerText": "सर्वाधिक नष्ट खिलाड़ी", "mostValuablePlayerText": "सबसे ज्यादा कीमती खिलाड़ी", "mostViolatedPlayerText": "सबसे ज्यादा उल्लंघित खिलाड़ी", "mostViolentPlayerText": "सबसे ज्यादा हिंसात्मक खिलाड़ी", @@ -1050,6 +1101,7 @@ "nameSuicideText": "${NAME} ने आत्म-हत्या कर ली |", "nameText": "नाम", "nativeText": "मूलभूत", + "newExclaimText": "ताज़ा!", "newPersonalBestText": "नया निजी उत्तम अंक !", "newTestBuildAvailableText": "एक नया परीक्षा का संस्करण उपलब्ध है ! \n(${VERSION} बिल्ड ${BUILD}). इसे ${ADDRESS} से पायें |", "newText": "नया", @@ -1060,13 +1112,17 @@ "noContinuesText": "(कोई जारी रखना नहीं)", "noExternalStorageErrorText": "कोई बाहरी संचयन करने कि जगह नहीं मिली", "noGameCircleText": "त्रुटी: गेम-सर्किल में लॉग-इन नहीं हैं |", + "noMessagesText": "कोई संदेश नहीं.", + "noPluginsInstalledText": "कोई प्लगइन इंस्टॉल नहीं है", "noProfilesErrorText": "आपकी कोई खिलाड़ी पार्श्वचित्र नहीं है, इसलिए आप '${NAME}' नाम के साथ फंसे हैं |\nसेटिंग -> खिलाड़ी पार्श्वचित्र में जाके अपने लिए पार्श्वचित्र बनायें |", "noScoresYetText": "अभी तक कोई स्कोर नहीं है |", + "noServersFoundText": "कोई सरवर्स नहीं मिलें।", "noThanksText": "नहीं धन्यवाद", "noTournamentsInTestBuildText": "चेतावनी: इस टेस्ट बिल्ड से खेलकूद-प्रतियोगिता के खेल के अंकों को नजरअंदाज कर दिया जाएगा।", "noValidMapsErrorText": "इस गेम ढंग के लिए कोई नक्शा नहीं मिला", "notEnoughPlayersRemainingText": "पर्याप्त खिलाड़ी बाकी नहीं हैं; बंद कर के नया गेम शुरू करें |", "notEnoughPlayersText": "आपको कम से कम ${COUNT} खिलाड़ी चाहिए गेम शुरू करने के लिए !", + "notEnoughTicketsText": "पर्याप्त टिकट नहीं!", "notNowText": "अभी नहीं", "notSignedInErrorText": "यह करने के लिए आपको अपने खाते में साइन इन करना पड़ेगा", "notSignedInGooglePlayErrorText": "आपको गूगल प्ले से साइन इन करना पड़ेगा यह करने के लिए |", @@ -1079,6 +1135,9 @@ "onText": "चालू करें", "oneMomentText": "एक क्षण...", "onslaughtRespawnText": "${PLAYER} फिर से जिन्दा होगा लहर ${WAVE} में", + "openMeText": "मुझे खोलो!", + "openNowText": "अभी खोलें", + "openText": "खुला", "orText": "${A} या ${B}", "otherText": "अन्य", "outOfText": "(${ALL} में से #${RANK})", @@ -1130,7 +1189,11 @@ "pleaseWaitText": "कृपया प्रतीक्षा करें...", "pluginClassLoadErrorText": "प्लगइन क्लास '${PLUGIN}' लोड करने में त्रुटि: ${ERROR}", "pluginInitErrorText": "प्लगइन '${PLUGIN}' शुरुआत करने में त्रुटि: ${ERROR}", + "pluginSettingsText": "प्लगइन सेटिंग्स", + "pluginsAutoEnableNewText": "ऑटो सक्षम नया प्लगइन", "pluginsDetectedText": "नए प्लगइन्स पता चले। उन्हें सक्रिय करने के लिए पुनरारंभ करें, या उन्हें सेटिंग्स में कॉन्फ़िगर करें।", + "pluginsDisableAllText": "सभी प्लगइन्स को अक्षम करें", + "pluginsEnableAllText": "सभी प्लगइन्स सक्षम करें", "pluginsRemovedText": "${NUM} प्लगइन्स अब नहीं मिले।", "pluginsText": "प्लगइन्स", "practiceText": "अभ्यास", @@ -1161,10 +1224,12 @@ "punchText": "मुक्का", "purchaseForText": "${PRICE} के भाव पे खरीदें", "purchaseGameText": "गेम खरीदें", + "purchaseNeverAvailableText": "क्षमा करें, इस बिल्ड पर खरीदारी उपलब्ध नहीं है।\nकिसी अन्य प्लेटफ़ॉर्म पर अपने खाते में साइन इन करने और वहां से खरीदारी करने का प्रयास करें।", + "purchaseNotAvailableText": "यह ख़रीदना संभव नहीं है|", "purchasingText": "खरीद रहे हैं...", "quitGameText": "${APP_NAME} को बंद कर दें ?", "quittingIn5SecondsText": "५ सेकंड में बंद कर रहे हैं...", - "randomPlayerNamesText": "किशोर, यश, ख्याति, शालिनी, आदित्य, उमेस, निश्चिंत, भाविक, रिशव, तुषार, राहुल, अमोल, मिशेल, प्रियंका, कल्याण, रियान, दिविज, हरी, आदर्श, कौस्तुभ, ज़ोया, सीनू, प्रतीक, ज़ारा, रुक्सार, शकील, पूजा, शबनम, शेरा, चेतन, समीर, टोनी, अजय, आकाश, पंकज, आरती, शबाना, मुमताज़, शुभम, शिवम्, लकेव, सचिन, दीपक, अक्षय, अर्जुन, किशन, राधा, विश्वनाथ, शालू, विमल, शिवा, पप्पू, नरेंद्र, आज़म, अनमोल, काजल, संध्या, दिनेश, प्रिंस, आनंद, अज़हर, पवन, अभिषेक, विवेक", + "randomPlayerNamesText": "किशोर, यश, ख्याति, शालिनी, आदित्य, उमेस, निश्चिंत, भाविक, रिशव, तुषार, राहुल, अमोल, मिशेल, प्रियंका, कल्याण, रियान, दिविज, हरी, आदर्श, कौस्तुभ, ज़ोया, सीनू, प्रतीक, ज़ारा, रुक्सार, शकील, पूजा, शबनम, शेरा, चेतन, समीर, टोनी, अजय, आकाश, पंकज, आरती, शबाना, मुमताज़, शुभम, शिवम्, लकेव, सचिन, दीपक, अक्षय, अर्जुन, किशन, राधा, विश्वनाथ, शालू, विमल, शिवा, पप्पू, नरेंद्र, आज़म, अनमोल, काजल, संध्या, दिनेश, प्रिंस, आनंद, अज़हर, पवन, अभिषेक, विवेक, बेवन", "randomText": "अनियमित", "rankText": "पद", "ratingText": "मूल्यांकन", @@ -1202,6 +1267,7 @@ "version_mismatch": "संस्करण मेल नहीं खा रहे हैं | \nयह सुनिश्चित कर लें कि बोम्ब-स्क्वाड गेम और \nरिमोट पर नवीनतम संस्करण है और पुनः प्रयास करें |" }, "removeInGameAdsText": "${PRO} को भंडार में खरीदें गेम के बीच आने वाले एड्स को हटाने के लिए |", + "removeInGameAdsTokenPurchaseText": "सीमित समय की पेशकश: इन-गेम विज्ञापनों को हटाने के लिए कोई भी टोकन पैक खरीदें।", "renameText": "नाम बदलें", "replayEndText": "रीप्ले बंद करें", "replayNameDefaultText": "आखिरी गेम का रीप्ले", @@ -1222,7 +1288,9 @@ "revertText": "पूर्व स्तिथि में लायें", "runText": "दोडें", "saveText": "सुरक्षित करें", - "scanScriptsErrorText": "स्क्रिप्ट्स को स्कैन करने में त्रुटि; विवरण के लिए लॉग देखें।", + "scanScriptsErrorText": "स्क्रिप्ट्स स्कैन करने में गलती; विवरण के लिए लॉग देखें।", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} और ${NUM} अन्य मॉड्यूल को ए.पी.आई. ${API} के लिए अद्यतन करने की आवश्यकता है।", + "scanScriptsSingleModuleNeedsUpdatesText": "एपीआई ${API} के लिए ${PATH} को अद्यतन करने की आवश्यकता है।", "scoreChallengesText": "अंकों कि चुनौतियाँ", "scoreListUnavailableText": "अंकों कि सूचि अभी उपस्थित नहीं है", "scoreText": "अंक", @@ -1233,6 +1301,7 @@ }, "scoreWasText": "(${COUNT} था)", "selectText": "चुनें", + "sendInfoDescriptionText": "अकाउंट और एप हालत की इनफो डेवलापर को बेजती है\nबेजने के अपना नाम और कारण बताईए", "seriesWinLine1PlayerText": "विजयी", "seriesWinLine1TeamText": "विजयी", "seriesWinLine1Text": "विजयी", @@ -1250,6 +1319,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(एक साधारण, नियंत्रक से आसानी इ प्रयोग हो जाने वाला कीबोर्ड)", "alwaysUseInternalKeyboardText": "हमेशा गेम के कीबोर्ड का प्रयोग करें", "benchmarksText": "बेंचमार्क व तनाव परीक्षण", + "devToolsText": "देव उपकरण", "disableCameraGyroscopeMotionText": "कैमरा गायरोस्कोप गतिवान बंद करे", "disableCameraShakeText": "कैमरा की हलचल बंद करे", "disableThisNotice": "(आप उन्नत सेटिंग में इस नोटिस को अक्षम कर सकते हैं)", @@ -1258,14 +1328,22 @@ "enterPromoCodeText": "कोड डालें", "forTestingText": "टिपण्णी: यह संख्याएं सिर्फ परीक्षण के लिए हैं, और एप्लीकेशन के बंद होने पर खो जायेंगी |", "helpTranslateText": "${APP_NAME} के अनुवाद एक सामुदायिक प्रयास का परिणाम हैं | \nअगर आप इसमें अपना योगदान देना चाहते हैं \nया कुछ ठीक करना चाहते हैं तो निचे दी गयी लिंक को देखें | धन्यवाद !", + "insecureConnectionsDescriptionText": "अनुशंसित नहीं है,\nलेकिन प्रतिबंधित देशों या नेटवर्कों से ऑनलाइन खिलाड़ियों को अनुमति दे सकता है है", + "insecureConnectionsText": "असुरक्षित कनेक्शन का उपयोग करें", "kickIdlePlayersText": "निष्क्रिय खिलाडियों को बाहर निकाल दें", "kidFriendlyModeText": "बच्चों के अनुकूल करें (कम हिंसा, आदि)", "languageText": "भाषा", "moddingGuideText": "परिवर्तन करने कि गाइड", + "moddingToolsText": "मोडी़ग टूलस", "mustRestartText": "इसके लागू होने के लिए आपको गेम को पुनः शुरू करना पड़ेगा |", "netTestingText": "नेटवर्क पर परीक्षण", "resetText": "रीसेट", + "sendInfoText": "खबर बेजिए", "showBombTrajectoriesText": "बोम्ब का पथ दिखाएँ", + "showDemosWhenIdleText": "निष्क्रिय होने पर डेमो दिखाएं", + "showDeprecatedLoginTypesText": "अप्रचलित लॉगिन प्रकार दिखाएँ", + "showDevConsoleButtonText": "डेव कंसोल बटन दिखाएँ", + "showInGamePingText": "गेम पिंग में दिखाएं", "showPlayerNamesText": "खिलाड़ी का नाम दिखाएँ", "showUserModsText": "परिवर्तनों का फोल्डर दिखाएँ", "titleText": "उन्नत", @@ -1284,6 +1362,9 @@ "signInWithGameCenterText": "गेम केंद्र खाते का उपयोग करने के लिए, \nगेम सेंटर एप के साथ साइन इन करें।", "singleGamePlaylistNameText": "केवल ${GAME}", "singlePlayerCountText": "1 खिलाड़ी", + "sizeLargeText": "बडा", + "sizeMediumText": "बराबर", + "sizeSmallText": "चोटा", "soloNameFilterText": "अकेले ${NAME}", "soundtrackTypeNames": { "CharSelect": "कैरेक्टर का चयन", @@ -1309,6 +1390,7 @@ }, "spaceKeyText": "स्पेस", "statsText": "स्टैट्‍स", + "stopRemindingMeText": "मुझे याद दिलाना बंद करो", "storagePermissionAccessText": "इसमें संग्रहण एक्सेस की आवश्यकता है", "store": { "alreadyOwnText": "आपके पास ${NAME} पहले से ही है!", @@ -1318,7 +1400,7 @@ "charactersText": "पात्र", "comingSoonText": "जल्द आ रहा है...", "extrasText": "अतिरिक्त", - "freeBombSquadProText": "बम्ब्सक्वाड अब नि:शुल्क है, लेकिन जब से आपने मूल रूप से इसे खरीदा था \nतब आप हैं बम्ब्सक्वाड प्रो उन्नयन और ${COUNT} टिकट आपको धन्यवाद के रूप में दिए जा रहे हैं। \nनई सुविधाओं का आनंद लें, और अपने समर्थन के लिए धन्यवाद! \n-एरिक", + "freeBombSquadProText": "बम्ब्सक्वाड अब नि:शुल्क है, लेकिन जब से आपने मूल रूप से इसे खरीदा था \nतब आप हैं बम्ब्सक्वाड प्रो उन्नयन और ${COUNT} टिकट आपको धन्यवाद के रूप में दिए जा रहे हैं। \nनई सुविधाओं का आनंद लें, और अपने समर्थन के लिए धन्यवाद! \n-एरिक ", "holidaySpecialText": "छुट्टी विशेष", "howToSwitchCharactersText": "(पात्र असाइन और कस्टमाइज़ करने के लिए जाएं \"${SETTINGS} -> ${PLAYER_PROFILES}\" पर)", "howToUseIconsText": "(इन का उपयोग करने के लिए वैश्विक खिलाड़ी प्रोफाइल (खाता विंडो में) बनाएं)", @@ -1356,6 +1438,8 @@ "storeText": "दुकान", "submitText": "जमा करें", "submittingPromoCodeText": "संहिता जमा कर रहा है ...", + "successText": "सफल!", + "supportEmailText": "यदि आप किसी भी समस्या का सामना कर रहे हैं ऐप, \nकृपया ईमेल करें ${EMAIL}।", "teamNamesColorText": "टीम के नाम / रंग ...", "telnetAccessGrantedText": "टेलनेट एक्सेस सक्षम है", "telnetAccessText": "टेलनेट पहुंच का पता चला; अनुमति देते हैं?", @@ -1365,6 +1449,7 @@ "testBuildValidatedText": "परीक्षण निर्माण मान्य; आनंद लें!", "thankYouText": "आपके सहयोग के लिए धन्यवाद! खेल का लुफ्त उठाओ!!", "threeKillText": "तिहरा हत्या!!", + "ticketsDescriptionText": "टिकटों का उपयोग पात्रों को अनलॉक करने के लिए किया जा सकता है,\nस्टोर में मानचित्र, मिनीगेम्स और बहुत कुछ।\n\nटिकट जीते गए चेस्ट में पाए जा सकते हैं\nअभियान, टूर्नामेंट और उपलब्धियाँ।", "timeBonusText": "समय बोनस", "timeElapsedText": "समय बीता", "timeExpiredText": "समय समाप्त", @@ -1375,10 +1460,24 @@ "tipText": "टिप", "titleText": "बमस्क्वाड", "titleVRText": "बमस्क्वाड व.र.", + "tokens": { + "getTokensText": "टोकन ले", + "notEnoughTokensText": "पर्याप्त टोकन नहीं है!", + "numTokensText": "${COUNT} टोकन", + "openNowDescriptionText": "आपके पास पर्याप्त टोकन हैं\nइसे अभी खोलें - आप ऐसा नहीं करेंगे\nइंतजार करने की जरूरत है.", + "shinyNewCurrencyText": "बॉम्बस्क्वाड की चमकदार नई मुद्रा।", + "tokenPack1Text": "छोटा टोकन पैक", + "tokenPack2Text": "मध्यम टोकन पैक", + "tokenPack3Text": "बड़ा टोकन पैक", + "tokenPack4Text": "जंबो टोकन पैक", + "tokensDescriptionText": "चेस्ट अनलॉक को तेज़ करने के लिए टोकन का उपयोग किया जाता है\nऔर अन्य गेम और खाता सुविधाओं के लिए।\n\nआप गेम में टोकन जीत सकते हैं या उन्हें खरीद सकते हैं\nपैक्स में. या अनंत के लिए एक गोल्ड पास खरीदें\nटोकन और उनके बारे में फिर कभी नहीं सुनना।", + "youHaveGoldPassText": "आपके पास गोल्ड पास है।\nसभी टोकन खरीद निःशुल्क हैं।\nआनंद ले!" + }, "topFriendsText": "अच्छे दोस्त", "tournamentCheckingStateText": "प्रतियोगिता की जांच हो रही है; कृपया प्रतीक्षा करें...", "tournamentEndedText": "यह प्रतियोगिता समाप्त हो गया है। एक नया जल्द ही शुरू होगा।", "tournamentEntryText": "प्रतियोगिता प्रवेश", + "tournamentFinalStandingsText": "अंतिम स्थिति", "tournamentResultsRecentText": "हालिया प्रतियोगिता परिणाम", "tournamentStandingsText": "प्रतियोगिता स्टैंडिंग्स", "tournamentText": "प्रतियोगिता", @@ -1434,6 +1533,18 @@ "Uber Onslaught": "महा हमला", "Uber Runaround": "महा रनराउंड" }, + "displayItemNames": { + "${C} Tickets": "${C} टिकट", + "${C} Tokens": "${C} टोकन", + "Chest": "छाती", + "L1 Chest": "एल1 छाती", + "L2 Chest": "एल2 छाती", + "L3 Chest": "एल3 छाती", + "L4 Chest": "एल4 छाती", + "L5 Chest": "एल5 छाती", + "L6 Chest": "एल6 छाती", + "Unknown Chest": "अज्ञात छाती" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "जीतने के लिए लंबे समय तक चुने गए व्यक्ति बनें। \nइसे चुनने के लिए चुने हुए को मार डालो।", "Bomb as many targets as you can.": "जितना संभव हो उतने लक्ष्य पर बम मारें ।", @@ -1536,7 +1647,9 @@ "Italian": "इतालवी", "Japanese": "जापानी", "Korean": "कोरियाई", + "Malay": "मलय", "Persian": "फ़ारसी", + "PirateSpeak": "डाकू भाषा", "Polish": "पोलिश", "Portuguese": "पुर्तगाली", "Romanian": "रोमानियाई", @@ -1608,6 +1721,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "धोखाधड़ी का पता चला; स्कोर और पुरस्कार ${COUNT} दिनों के लिए निलंबित कर दिए गए हैं।", "Could not establish a secure connection.": "एक सुरक्षित कनेक्शन स्थापित नहीं कर सका।", "Daily maximum reached.": "दैनिक अधिकतम पहुंच गया।", + "Daily sign-in reward": "दैनिक साइन-इन इनाम", "Entering tournament...": "टूर्नामेंट में प्रवेश ...", "Invalid code.": "अमान्य कोड।", "Invalid payment; purchase canceled.": "अमान्य भुगतान; खरीद रद्द।", @@ -1617,11 +1731,14 @@ "Item unlocked!": "सामग्री अनलॉक!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "जुड़ाव अस्वीकृत। ${ACCOUNT} में महत्वपूर्ण डेटा शामिल है \nजो सभी खो जाएंगे। यदि आप चाहते हैं \nतो आप विपरीत क्रम में लिंक कर सकते हैं \n(और इसके बजाय इस खाते का डेटा खो दें)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "इस खाते में ${ACCOUNT} खाता लिंक करें? \n${ACCOUNT} पर मौजूद सभी डेटा खो जाएंगे। \nइसे असंपादित नहीं किया जा सकता है। क्या आपको यकीन है?", + "Longer streaks lead to better rewards.": "लंबी स्ट्रीक्स से बेहतर पुरस्कार मिलते हैं।", "Max number of playlists reached.": "प्लेलिस्ट की अधिकतम संख्या तक पहुंच गई।", "Max number of profiles reached.": "प्रोफाइल की अधिकतम संख्या तक पहुंच गया।", "Maximum friend code rewards reached.": "अधिकतम मित्र कोड पुरस्कार पहुंचे।", "Message is too long.": "संदेश बहुत लंबा है।", + "New tournament result!": "नया टूर्नामेंट परिणाम!", "No servers are available. Please try again soon.": "कोई सर्वर उपलब्ध नहीं हैं। कृपया शीघ्र ही पुन: प्रयास करें।", + "No slots available. Free a slot and try again.": "कोई स्लॉट उपलब्ध नहीं है. एक स्लॉट खाली करें और पुनः प्रयास करें।", "Profile \"${NAME}\" upgraded successfully.": "प्रोफाइल \"${NAME}\" सफलतापूर्वक अपग्रेड किया गया।", "Profile could not be upgraded.": "प्रोफ़ाइल को अपग्रेड नहीं किया जा सका।", "Purchase successful!": "खरीद सफल!", @@ -1631,7 +1748,9 @@ "Sorry, this code has already been used.": "क्षमा करें, यह कोड पहले ही इस्तेमाल हो चुका है।", "Sorry, this code has expired.": "क्षमा करें, यह कोड समाप्त हो गया है।", "Sorry, this code only works for new accounts.": "क्षमा करें, यह कोड केवल नए खातों के लिए काम करता है।", + "Sorry, this has expired.": "क्षमा करें, इसकी समय सीमा समाप्त हो गई है.", "Still searching for nearby servers; please try again soon.": "अभी भी आस-पास के सर्वर खोज रहे हैं; कृपया जल्द ही पुन: प्रयास करें।", + "Streak: ${NUM} days": "स्ट्रीक: ${NUM} दिन", "Temporarily unavailable; please try again later.": "अस्थाई रूप से अनुपलब्ध; बाद में पुन: प्रयास करें।", "The tournament ended before you finished.": "टूर्नामेंट समाप्त होने से पहले समाप्त हो गया।", "This account cannot be unlinked for ${NUM} days.": "यह खाता ${NUM} दिनों के लिए अनलिंक नहीं किया जा सकता है।", @@ -1642,19 +1761,28 @@ "Tournaments require ${VERSION} or newer": "टूर्नामेंटों को ${VERSION} या नए की आवश्यकता होती है", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "इस खाते से ${ACCOUNT} अनलिंक करें? ${ACCOUNT} \nपर मौजूद सभी डेटा रीसेट हो जाएंगे। \n(कुछ मामलों में उपलब्धियों को छोड़कर)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "चेतावनी: आपके खाते के खिलाफ हैकिंग की शिकायतें जारी की गई हैं। \nहैकिंग के लिए पाए गए खातों पर प्रतिबंध लगा दिया जाएगा। कृपया ईमानदार से खेलें।", + "Wait reduced!": "इंतज़ार कम हुआ!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "चेतावनी: गेम का यह संस्करण पुराने खाता डेटा तक सीमित है; चीज़ें गुम या पुरानी लग सकती हैं।\nकृपया अपना नवीनतम खाता डेटा देखने के लिए गेम के नए संस्करण में अपग्रेड करें।", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "क्या आप अपने डिवाइस खाते को इस से लिंक करना चाहते हैं? \n\nआपका डिवाइस खाता ${ACCOUNT1} है \nयह खाता ${ACCOUNT2} है \n\nयह आपको अपनी मौजूदा प्रगति को रखने की अनुमति देगा। \nचेतावनी: इसे पूर्ववत नहीं किया जा सकता है", "You already own this!": "आप पहले से ही इसे खरीद चुके है!", "You can join in ${COUNT} seconds.": "आप ${COUNT} सेकंड में शामिल हो सकते हैं।", "You don't have enough tickets for this!": "आपके पास इसके लिए पर्याप्त टिकट नहीं हैं!", "You don't own that.": "आप उसका स्वामित्व नहीं रखते हैं।", "You got ${COUNT} tickets!": "आपको ${COUNT} टिकट मिल गए हैं!", + "You got ${COUNT} tokens!": "आपको ${COUNT} टोकन मिल गए!", "You got a ${ITEM}!": "आपको ${ITEM} मिला है!", + "You got a chest!": "तुम्हें एक संदूक मिल गया!", + "You got an achievement reward!": "आपको एक उपलब्धि पुरस्कार मिला!", "You have been promoted to a new league; congratulations!": "आपको एक नए लीग में पदोन्नत किया गया है; बधाई!", + "You lost a chest! (All your chest slots were full)": "आपने एक संदूक खो दिया! (आपके सभी चेस्ट स्लॉट भरे हुए थे)", + "You must update the app to view this.": "इसे देखने के लिए आपको ऐप को अपडेट करना होगा।", "You must update to a newer version of the app to do this.": "ऐसा करने के लिए आपको ऐप के एक नए संस्करण में अपडेट करना होगा।", "You must update to the newest version of the game to do this.": "ऐसा करने के लिए आपको गेम के नवीनतम संस्करण में अपडेट करना होगा।", "You must wait a few seconds before entering a new code.": "नया कोड दर्ज करने से पहले आपको कुछ सेकंड इंतजार करना होगा।", + "You placed #${RANK} in a tournament!": "आपने एक टूर्नामेंट में #${RANK} रखा!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "आपने पिछले टूर्नामेंट में #${RANK} रैंक किया था। खेलने के लिए शुक्रिया!", "Your account was rejected. Are you signed in?": "आपका खाता अस्वीकृत कर दिया गया है। क्या आप हस्ताक्षरित हैं?", + "Your ad views are not registering. Ad options will be limited for a while.": "आपके विज्ञापन दृश्य पंजीकृत नहीं हो रहे हैं. विज्ञापन विकल्प कुछ समय के लिए सीमित रहेंगे।", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "खेल की आपकी प्रति संशोधित कर दी गई है। \nकृपया किसी भी बदलाव को वापस करें और पुनः प्रयास करें।", "Your friend code was used by ${ACCOUNT}": "आपका मित्र कोड ${ACCOUNT} द्वारा उपयोग किया गया था" }, @@ -1803,11 +1931,14 @@ "toSkipPressAnythingText": "(शिक्षण छोड़ने के लिए कुछ भी स्पर्श करे या दबाएं)" }, "twoKillText": "दोहरी हत्या", + "uiScaleText": "यू आई सकेल", "unavailableText": "उपलब्ध नहीं", + "unclaimedPrizesText": "आपके पास लावारिस पुरस्कार हैं!", "unconfiguredControllerDetectedText": "बिना विन्यास वाले नियंत्रक का पता चला:", "unlockThisInTheStoreText": "यह स्टोर में अनलॉक होना चाहिए।", "unlockThisProfilesText": "${NUM} प्रोफ़ाइल बनाने के लिए, आपको इसकी आवश्यकता है:", "unlockThisText": "इसे अनलॉक करने के लिए, आपको इसकी आवश्यकता है:", + "unsupportedControllerText": "क्षमा करें, नियंत्रक \"${NAME}\" समर्थित नहीं है।", "unsupportedHardwareText": "क्षमा करें, यह हार्डवेयर गेम के इस निर्माण द्वारा समर्थित नहीं है।", "upFirstText": "सर्व प्रथम", "upNextText": "गेम ${COUNT} में अगला:", @@ -1815,10 +1946,14 @@ "upgradeText": "अभ्युत्थान", "upgradeToPlayText": "इन-गेम स्टोर में इसे चलाने के लिए \"${PRO}\" अनलॉक करें।", "useDefaultText": "पूर्व निर्धारित उपयोग करें", + "userSystemScriptsCreateText": "डसतमालक सिस्टम सृ‍‌‌इपट बनाईए", + "userSystemScriptsDeleteText": "डीलीइट यूजर्स सिस्टम सिकरीपट", "usesExternalControllerText": "यह गेम इनपुट के लिए बाहरी नियंत्रक का उपयोग करता है।", "usingItunesText": "गाने के लिए संगीत ऐप का उपयोग कर रहे है ...", "v2AccountLinkingInfoText": "V2 खातों को लिंक करने के लिए, 'खाता प्रबंधित करें' बटन का उपयोग करें।", + "v2AccountRequiredText": "इसके लिए V2 खाते की आवश्यकता है। अपना खाता अपग्रेड करें और पुनः प्रयास करें।", "validatingTestBuildText": "परीक्षण निर्माण मान्य ...", + "viaText": "के जरिए", "victoryText": "विजय!", "voteDelayText": "आप ${NUMBER} सेकंड के लिए एक और वोट शुरू नहीं कर सकते हैं", "voteInProgressText": "एक वोट पहले ही प्रगति पर है।", @@ -1884,5 +2019,6 @@ }, "yesAllowText": "हाँ, आज्ञा दें", "yourBestScoresText": "आपका बेस्ट स्कोर।", - "yourBestTimesText": "आपका सर्वोत्तम समय" + "yourBestTimesText": "आपका सर्वोत्तम समय", + "yourPrizeText": "आपका पुरस्कार:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/hungarian.json b/dist/ba_data/data/languages/hungarian.json index 769c7edc..a6c94364 100644 --- a/dist/ba_data/data/languages/hungarian.json +++ b/dist/ba_data/data/languages/hungarian.json @@ -3,16 +3,19 @@ "accountNameRules": "A fiók neve nem tartalmazhat emojikat és más speciális karaktereket", "accountProfileText": "(Felhasználó profilok)", "accountsText": "Fiókok", - "achievementProgressText": "Eredmènyek: ${COUNT} a(z) ${TOTAL}-ból/ből.", + "achievementProgressText": "Eredmények: ${COUNT} a(z) ${TOTAL}-ból/ből.", "campaignProgressText": "Kampány haladás(nehéz mód): ${PROGRESS}", "changeOncePerSeason": "Ebben a szezonban ezt csak egyszer változtathatod meg.", "changeOncePerSeasonError": "Várj a következő szezonig, hogy ezt megint megváltoztasd (${NUM} nap)", + "createAnAccountText": "Fiók létrehozása", "customName": "Egyedi név", + "deleteAccountText": "Fiók Törlése", "deviceSpecificAccountText": "Csak erről az eszközről lehet elérni ezt a profilt: ${NAME}", + "googlePlayGamesAccountSwitchText": "Ha másik Google fiókot használnál, használd a Google Játékok alkalmazást.", "linkAccountsEnterCodeText": "Írd Be A Kódot", "linkAccountsGenerateCodeText": "Kód Generálása", "linkAccountsInfoText": "(vidd át előrehaladásodat akár több eszközre is)", - "linkAccountsInstructionsNewText": "Két fiók összekapcsolásához először hozzon létre egy kódot\nés írja be a második kódot. Adatok a\na második számlát majd megosztják egymással.\n(Az első fiókból származó adatok elveszhetnek)\n\nÖsszesen akár ${COUNT} fiókot is összekapcsolhat.\n\nFONTOS: csak az Ön tulajdonában lévő fiókokat kapcsolja össze;\nHa kapcsolatba lépsz a barátok fiókjaival, akkor nem fogsz\negyszerre tud online játszani.", + "linkAccountsInstructionsNewText": "Két fiók összekapcsolásához az első fiókon hozz létre egy kódot\nés írd be a második fiókba. Az adatok a\na második fiókon majd megosztják egymással.\n(Az első fiókból származó adatok elvesznek)\n\nÖsszesen akár ${COUNT} fiókot is összekapcsolhat.\n\nFONTOS:\nCsak a tulajdonodban lévő fiókokat kapcsold össze;\nHa összekapcsolsz egyet az egyik barátodéval, nem fogtok tudni egyszerre online játszani.", "linkAccountsInstructionsText": "Hogy párosíts két profilt, generálj egy kódot\naz egyiken majd írd be a kapott kódot a másikon.\nAz előrehaladás és a megvásárolt dolgok is párosításra kerülnek .\nÖsszesen ${COUNT} profilt tudsz összehangolni.\n\nFONTOS:Csak olyan profilt csatlakoztass ami a tiéd!\nHogyha profilt csatlakoztatsz a barátaiddal\nakkor nem fogsz tudni játszani azonos időben!\n\nLégy óvatos!Ezt a lépést nem lehet visszavonni!", "linkAccountsText": "Profilok Párosítása", "linkedAccountsText": "Párosított Profilok:", @@ -21,18 +24,20 @@ "resetProgressConfirmNoAchievementsText": "Ez visszaállítja a co-op haladásodat és \nhelyi legmagasabb pontszámaidat (de a jegyeidet nem). \nEz nem vissza vonható. Biztos vagy benne?", "resetProgressConfirmText": "Ez visszaállítja a co-op haladásodat,\nteljesítményeidet és helyi legmagasabb pontszámaidat\n(de a jegyeidet nem). Ez nem vissza vonható.\nBiztos vagy benne?", "resetProgressText": "Haladás visszaállítása", - "setAccountName": "Állítsa be a fiók nevét", + "setAccountName": "Állítsd be a fiók nevét", "setAccountNameDesc": "Válassza ki a megjeleníteni kívánt fiók nevét.\nHasználhatja a nevét az egyik kapcsoltól\nfiókokat, vagy egyedi egyedi nevet hozhat létre.", "signInInfoText": "Lépj be, hogy tudj jegyeket gyűjteni, online versenyezni\nés elérni az eredményeidet akár több eszközről is.", "signInText": "Bejelentkezés", - "signInWithDeviceInfoText": "(Autómatikus fiók csak ezen az eszközön elérhető)", + "signInWithAnEmailAddressText": "Jelentkezz be egy email címmel", + "signInWithDeviceInfoText": "(Automatikus fiók csak ezen az eszközön elérhető)", "signInWithDeviceText": "Bejelentkezés az eszköz felhasználójával.", "signInWithGameCircleText": "Lépj be a Game Circle fiókodba", "signInWithGooglePlayText": "Belépés Google fiókkal", "signInWithTestAccountInfoText": "(Egy régi típusú felhasználó; Mostantól a készülék felhasználóját használd.)", "signInWithTestAccountText": "Bejelentkezés teszt felhasználóval", + "signInWithText": "Bejelentkezés ${SERVICE}-(v)al /-(v)el", "signInWithV2InfoText": "(egy fiók, amely minden platformon működik)", - "signInWithV2Text": "Jelentkezzen be BombSquad fiókkal", + "signInWithV2Text": "Jelentkezzen be egy ${APP_NAME} fiókkal", "signOutText": "Kijelentkezés", "signingInText": "Bejelentkezés...", "signingOutText": "Kijelentkezés...", @@ -43,9 +48,10 @@ "titleText": "Felhasználó", "unlinkAccountsInstructionsText": "Válassz ki egy fiókot a leválasztáshoz", "unlinkAccountsText": "Fiókok leválasztása", - "v2LinkInstructionsText": "Használja ezt a linket fiók létrehozásához vagy bejelentkezéshez.", - "viaAccount": "(számlán keresztül ${NAME})", - "youAreSignedInAsText": "Be vagy jelentkezve, mint:" + "unlinkLegacyV1AccountsText": "(V1) fiókok lecsatolása", + "v2LinkInstructionsText": "Használd ezt a linket fiók létrehozásához vagy bejelentkezéshez.", + "viaAccount": "(${NAME} fiókon keresztül )", + "youAreSignedInAsText": "Eként vagy bejelentkezve:" }, "achievementChallengesText": "Teljesítmény kihívások", "achievementText": "Teljesítmény", @@ -55,7 +61,7 @@ "descriptionComplete": "Megöltél 3 rosszfiút TNT-vel", "descriptionFull": "Ölj meg 3 rosszfiút TNT-vel a(z) ${LEVEL}-n", "descriptionFullComplete": "Megöltél 3 rosszfiút TNT-vel a(z) ${LEVEL}-n", - "name": "Bumm Megy a Dinamit" + "name": "Bumm! Megy a Dinamit" }, "Boxer": { "description": "Nyerj bombák használata nélkül", @@ -65,7 +71,7 @@ "name": "Boxoló" }, "Dual Wielding": { - "descriptionFull": "Csatlakoztass 2 kontrollert(hardvert vagy applikáció)", + "descriptionFull": "Csatlakoztass 2 kontrollert (hardvert vagy applikációt)", "descriptionFullComplete": "2 kontroller csatlakoztatva (hardver vagy applikáció)", "name": "Dupla Hadonászás" }, @@ -187,7 +193,7 @@ "Pro Football Victory": { "description": "Nyerd meg a játékot", "descriptionComplete": "Megnyerted a játékot", - "descriptionFull": "Nyerdmeg a játékot a(z) ${LEVEL} pályán", + "descriptionFull": "Nyerd meg a játékot a(z) ${LEVEL} pályán", "descriptionFullComplete": "Megnyerted a játékot a(z) ${LEVEL} pályán", "name": "${LEVEL} Győzelem" }, @@ -254,7 +260,7 @@ }, "Stayin' Alive": { "description": "Nyerj halál nélkül", - "descriptionComplete": "Nyerj anélkül hogy meghalnál.", + "descriptionComplete": "Nyertél anélkül, hogy meghalnál.", "descriptionFull": "Nyerd meg a ${LEVEL} pályát halál nélkül", "descriptionFullComplete": "${LEVEL} pálya megnyerve halál nélkül", "name": "Maradj életben!" @@ -336,9 +342,14 @@ "getMoreGamesText": "Több Játékmód...", "titleText": "Játék Hozzáadása" }, + "addToFavoritesText": "Hozzáadás a kedvencekhez", + "addedToFavoritesText": "'${NAME}' hozzáadva a kedvencekhez.", + "allText": "Minden", "allowText": "Engedélyezés", "alreadySignedInText": "A fiókoddal be vagy jelentkezve egy másik eszközről;\nkérlek cserélj fiókot vagy zárd be a játékot \na másik eszközön és próbáld újra", "apiVersionErrorText": "Nem lehet betölteni a ${NAME} modult jelenlegi verzió:${VERSION_USED}; szükséges verió:${VERSION_REQUIRED}.", + "applyText": "Alkalmaz", + "areYouSureText": "Biztos vagy benne?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Automatikus\" csak akkor érhető el ha csatlakoztatva van egy fejhallgató)", "headRelativeVRAudioText": "Head-Relative hangzás", @@ -360,14 +371,23 @@ "boostText": "Boost", "bsRemoteConfigureInAppText": "A(z) ${REMOTE_APP_NAME} a saját alkalmazásában konfigurálódik.", "buttonText": "Gomb", - "canWeDebugText": "Szeretnéd, ha a BombSquad automatikusan jelentené a hibákat, \ncrash-eléseket, és általános használati infókat a fejlesztőknek?\n\nEz az adat nem tartalmaz személyes információkat és segít\na játék sima és hibamentes futásának megtartásában.", + "canWeDebugText": "Szeretné, ha a(z) ${APP_NAME} automatikusan bejelentené a hibákat, \nösszeomlásokat és alapvető használati információkat a fejlesztőnek?\n\nEzek az adatok nem tartalmaznak személyes adatokat és segítséget nyújtanak\nhogy a játék zökkenőmentesen és hibamentesen működjön.", "cancelText": "Mégse", "cantConfigureDeviceText": "Bocs, ${DEVICE} nem beállítható.", "challengeEndedText": "Ez a kihívás már végét ért.", "chatMuteText": "Chat némítása", "chatMutedText": "Chat némítva", "chatUnMuteText": "Chat némítás feloldása", + "chests": { + "prizeOddsText": "A nyeremények lehetnek:", + "reduceWaitText": "Idő csökkentése", + "slotDescriptionText": "Ez a retesz egy láda tárolására alkalmas.\n\nLádákat szerezhetsz a kampány pályákról, \nversenyekről és \nmérföldkövek eléréséért.", + "slotText": "${NUM}. Láda rekesz", + "slotsFullWarningText": "Figyelem! A láda tartó reteszeid tele vannak. \nBármilyen láda, amit ebben a játékban szerzel, el fog veszni." + }, "choosingPlayerText": "", + "claimText": "Begyűjtés", + "codesExplainText": "A kódokkal diagnosztizálni és javítani tudod az esetlegesen felmerülő,\n fiókoddal kapcsolatos problémákat.", "completeThisLevelToProceedText": "Teljesítened kell ezt\na szintet a folytatáshoz!", "completionBonusText": "Befejezési Bónusz", "configControllersWindow": { @@ -435,7 +455,7 @@ "keyboard2NoteText": "A legtöbb billentyűzet csak pár gombnyomást érzékel egyszerre,\nszóval jobb ha használtok két játékos esetén jobb, \nhogy ha egy második billentyűzetet is használtok.\nFontos, hogy ebben az esetben is be kell állítani \naz egyéni vezérlést." }, "configTouchscreenWindow": { - "actionControlScaleText": "Akció Panel Átmérőja", + "actionControlScaleText": "Akció Panel Átmérője", "actionsText": "Akciók", "buttonsText": "gombok", "dragControlsText": "", @@ -448,6 +468,7 @@ "swipeText": "nyilak", "titleText": "Érintőképernyő Konfigurálása" }, + "configureDeviceInSystemSettingsText": "${DEVICE} konfigurálását a rendszerbeállításokban tudod megtenni", "configureItNowText": "Most Konfigurálod?", "configureText": "Konfigurálás", "connectMobileDevicesWindow": { @@ -549,7 +570,10 @@ "deleteText": "Törlés", "demoText": "Demo", "denyText": "Megtagad", + "deprecatedText": "Elavult", + "descriptionText": "Leírás", "desktopResText": "Asztali Felbontás", + "deviceAccountUpgradeText": "Hé!\nEgy eszközfiókkal vagy bejelentkezve (${NAME}). \nEgy jövőbeli frissítésben az ezeket az eszközfiókokat eltávolítjuk.\nFejleszd fiókod V2-es fiókra ha meg szeretnéd tartani a haladásod és a többi cuccaidat.", "difficultyEasyText": "Könnyű", "difficultyHardOnlyText": "Csak Nehéz Mód", "difficultyHardText": "Nehéz", @@ -558,6 +582,10 @@ "disableRemoteAppConnectionsText": "Irányító Alkalmazások Letiltása", "disableXInputDescriptionText": "Engedélyezi ,hogy 4-nél több kontroller is csatlakozhasson ,viszont nem biztos a hibátlan működés.", "disableXInputText": "XInput kikapcsolása", + "disabledText": "Kikapcsolva", + "discardText": "Elvetés", + "discordFriendsText": "Szeretnél barátokat találni?\nCsatlakozz a Discord szerverünkre!", + "discordJoinText": "Csatlakozás a discord szerverre", "doneText": "Elvégezve", "drawText": "Döntetlen", "duplicateText": "Másolás", @@ -582,7 +610,7 @@ "checkingAvailabilityText": "\"${NAME}\" név ellenőrzése...", "colorText": "szín", "getMoreCharactersText": "Több Karakter Szerzése...", - "getMoreIconsText": "Szerezz több ikont...", + "getMoreIconsText": "Több ikon szerzése...", "globalProfileInfoText": "A teljes körű játékos profilok garantálják az egyedi \nnevet a játékban, és feloldják az ikonokat is.", "globalProfileText": "(teljes körű profil)", "highlightText": "fénypont", @@ -591,6 +619,7 @@ "localProfileText": "(alkalmi profil)", "nameDescriptionText": "Játékos Név", "nameText": "Név", + "profileAlreadyExistsText": "Egy ugyan ilyen nevű profil már létezik!", "randomText": "véletlen", "titleEditText": "Profil Szerkesztése", "titleNewText": "Új Profil", @@ -600,7 +629,7 @@ }, "editSoundtrackWindow": { "cantDeleteDefaultText": "Nem törölheted az alap betétdalt.", - "cantEditDefaultText": "Nem lehet szerkeszteni az alap betétdalt. Duplázd meg vagy csinálj egy újat.", + "cantEditDefaultText": "Nem lehet szerkeszteni az alap betétdalt. Duplikáld, vagy csinálj egy újat.", "cantOverwriteDefaultText": "Nem lehet felülírni az alap betétdalt", "cantSaveAlreadyExistsText": "Egy betétdal már létezik ilyen névvel!", "defaultGameMusicText": "", @@ -626,17 +655,20 @@ "useMusicFolderText": "Zene Fájlok Mappája" }, "editText": "Szerkesztés", + "enabledText": "Bekapcsolva", "endText": "Befejezés", "enjoyText": "Jó Játékot!", - "epicDescriptionFilterText": "${DESCRIPTION} A hatalmas lassú mozgásban", - "epicNameFilterText": "Hatalmas ${NAME}", + "epicDescriptionFilterText": "${DESCRIPTION} Az epikus lassú mozgásban", + "epicNameFilterText": "Epikus ${NAME}", "errorAccessDeniedText": "hozzáférés megtagadva", - "errorDeviceTimeIncorrectText": "Az eszközöd rossz időt mutat ennyi órával:${HOURS}.\nEz okozhat problémákat is.\nKérjük ellenőrizze az időt és idő-zónát a beállításokban.", + "errorDeviceTimeIncorrectText": "Az eszközöd rossz időt mutat ennyi órával:${HOURS}.\nEz okozhat problémákat is.\nKérjük ellenőrizd az időt és idő-zónát a beállításokban.", "errorOutOfDiskSpaceText": "Kifogyott a szabadhelyből", "errorSecureConnectionFailText": "Nem lehet kapcsolatot létrehozni a biztonságos felhővel;Az internet funkcionálása talán elbukik.", "errorText": "Hiba", "errorUnknownText": "ismeretlen hiba", "exitGameText": "Kilépsz a ${APP_NAME}-ból?", + "expiredAgoText": "Lejárt: ${T} óta", + "expiresInText": "Lejár ${T} múlva", "exportSuccessText": "'${NAME}' áthelyezve.", "externalStorageText": "Külső Tárhely", "failText": "Bukta", @@ -671,6 +703,8 @@ "duplicateText": "Lista\nMásolása", "editText": "Lista\nSzerkesztése", "newText": "Új\nLista", + "pointsToWinText": "Pont nyerésig", + "seriesLengthText": "Sorozat hossza", "showTutorialText": "Oktató végignézése", "shuffleGameOrderText": "Játék Rendelés Megkeverése", "titleText": "Szabd személyre a ${TYPE} Lejátszási listát" @@ -697,6 +731,7 @@ "copyCodeConfirmText": "Vágólapra másolva.", "copyCodeText": "Kód másolása", "dedicatedServerInfoText": "A legjobb eredményért, csinálj dedikált szerver.Útmutató:bombsquadgame.com/server", + "descriptionShortText": "A \"Toborzás\" ablakban összeállíthatsz egy csapatot.", "disconnectClientsText": "Ez le fogja csatlakoztatni a ${COUNT} játékost\na társaságodból. Biztos vagy benne?", "earnTicketsForRecommendingAmountText": "A barátaid kapni fognak ${COUNT} jegyet ha kipróbálják a játékot\n(és te is kapni fogsz ${YOU_COUNT} jegyet minden barátok általi kipróbálás után)", "earnTicketsForRecommendingText": "Terjeszd a játékot\ningyenes jegyekért...", @@ -710,7 +745,7 @@ "friendPromoCodeAwardText": "${COUNT} jegyet fogsz kapni minden egyes használásnál.", "friendPromoCodeExpireText": "Ez a kód ${EXPIRE_HOURS} óra múlva lejár és csak új játékosok használhatják.", "friendPromoCodeInfoText": "Ez a kód ${COUNT} jegyet ér.\n\nMenj a \"Beállítások->Haladó->Promóciós Kód Beírása\" a játékban, hogy aktiváld.\nLátogasd meg a bombsquadgame.com nevű weboldalt, a letöltési linkek eléréséhez.\nEz a kód csak ${EXPIRE_HOURS} óráig érvényes és csak új játékosok számára elérhető.", - "friendPromoCodeInstructionsText": "Hogy használhasd, nyisd meg a ${APP_NAME}-ot, menj a \"Beállítások->Haladó>Promóciós Kód Beírása\" menüpontba.\nÍrd be a kódod majd kattints a \"Küldés\" gombra. Látogasd meg a bombsquadgame.com weboldalt letöltési linkekért, és a támogatott eszközök listájáért.", + "friendPromoCodeInstructionsText": "A használatához nyissa meg a ${APP_NAME} alkalmazást, és lépjen a \"Beállítások->Speciális->Információ küldése\" menüpontra.\nA bombsquadgame.com oldalon megtalálja az összes támogatott platform letöltési linkjét.", "friendPromoCodeRedeemLongText": "${COUNT} jegyet ér és maximum ${MAX_USES} ember használhatja.", "friendPromoCodeRedeemShortText": "${COUNT} jegyet ér a játékon belül.", "friendPromoCodeWhereToEnterText": "(itt \"Beállítások->Haladó->Promóciós Kód Beírása\")", @@ -745,6 +780,7 @@ "manualYourLocalAddressText": "Lokális IP címed:", "nearbyText": "Közeli játékok", "noConnectionText": "", + "noPartiesAddedText": "Nincsenek hozzáadva játékok", "otherVersionsText": "(másik verziók)", "partyCodeText": "Party kód", "partyInviteAcceptText": "Elfogad", @@ -812,6 +848,12 @@ "youHaveShortText": "${COUNT} jegyed van", "youHaveText": "Neked ${COUNT} jegyed van." }, + "goldPass": { + "desc1InfTokensText": "Végtelen token.", + "desc2NoAdsText": "Nincsenek reklámok.", + "desc3ForeverText": "Örökké.", + "goldPassText": "Arany Pass." + }, "googleMultiplayerDiscontinuedText": "Bocsánat, A Google-nek a többjátékos szervisze többé nem elérhető.\nÉn most egy cserén dolgozok.\nAddig, Kérlek Válasz egy Másik Kapcsolódási lehetőséget.\n-Eric", "googlePlayPurchasesNotAvailableText": "A Google Play vásárlások nem elérhetőek.\nTalán frissíteni kell a vásárló alakalmazásod", "googlePlayServicesNotAvailableText": "A Google Play Szolgáltatások nem elérhetőek.\nNéhány része a játéknak talán le vannak tiltva", @@ -820,10 +862,12 @@ "alwaysText": "Mindig", "fullScreenCmdText": "Teljes képernyő (Cmd-F)", "fullScreenCtrlText": "Teljes képernyő (Ctrl-F)", + "fullScreenText": "Teljes képernyő", "gammaText": "Gamma", "highText": "Magas", "higherText": "Magasabb", "lowText": "Alacsony", + "maxFPSText": "Maximum FPS:", "mediumText": "Közepes", "neverText": "Soha", "resolutionText": "Felbontás", @@ -849,17 +893,17 @@ "jumpInfoText": "- Ugrás -\nUgorj keresztül kis hasadásokon,\nhogy távolabbra dobj dolgokat, és\nhogy sürgesd az öröm érzetét.", "orPunchingSomethingText": "Vagy megütni valamit, ledobni egy hegyről, és felrobbantani a lefele úton egy ragadós bombával.", "pickUpInfoText": "- Felvétel -\nRagadd meg a zászlót, ellenfelet,\nvagy akármi mást ami nincs rögzítve.\nNyomd meg még egyszer az eldobáshoz.", - "powerupBombDescriptionText": "Hagyja, hogy egyszerre három\nbombát is el tudj dobni.", + "powerupBombDescriptionText": "Ettől három bombát\nis el fogsz tudni dobni.", "powerupBombNameText": "Tripla-Bomba", "powerupCurseDescriptionText": "Talán ezeket elakarod kerülni.\n...vagy nem?", "powerupCurseNameText": "Átok", "powerupHealthDescriptionText": "Helyreállítja a teljes egészségedet.\nSose gondoltad volna.", "powerupHealthNameText": "Gyógyító-Csomag", - "powerupIceBombsDescriptionText": "Gyengébb mint a normál bombák,\nde hülten hagyja ellenfeleidet\nés különösen törékenyen.", + "powerupIceBombsDescriptionText": "Gyengébbek mint a normál bombák,\nde hülten hagyja ellenfeleidet.\nÉs különösen törékenyen!", "powerupIceBombsNameText": "Jég-Bombák", - "powerupImpactBombsDescriptionText": "Némileg gyengébb, mint az eredeti\nbombák, de becsapódásra robannak.", + "powerupImpactBombsDescriptionText": "Némileg gyengébbek, mint a normál\nbombák, de becsapódásra robannak.", "powerupImpactBombsNameText": "Ravasz-Bombák", - "powerupLandMinesDescriptionText": "Ezek 3-asával jönnek egy csomagba;\nHasznos a bázis védelemre vagy\na gyors ellenfelek megállítására.", + "powerupLandMinesDescriptionText": "Ezek 3-asával jönnek egy csomagban;\nHasznos a bázis védelemre vagy\na gyors ellenfelek megállítására.", "powerupLandMinesNameText": "Taposó-akna", "powerupPunchDescriptionText": "Felerősíti, gyorsítja, jobbá,\nés keményebbé teszi ütéseidet.", "powerupPunchNameText": "Box-Kesztyűk", @@ -884,6 +928,7 @@ "importText": "Importálás", "importingText": "Bemásolás...", "inGameClippedNameText": "játékbeli alak:\n\"${NAME}\"", + "inboxText": "Bejövő", "installDiskSpaceErrorText": "Hiba: Nem lehet teljesíteni a telepítést.\nTalán kifogytál a szabadhelyből az eszközödön.\nTakaríts egy kis helyet, és próbáld újra.", "internal": { "arrowsToExitListText": "nyomj ${LEFT}-t vagy ${RIGHT}-t a lista bezárásához", @@ -938,12 +983,14 @@ "timeOutText": "(Kifagyás ${TIME} másodpercen belül)", "touchScreenJoinWarningText": "Az érintőképernyővel csatlakoztál.\nHa ez egy hiba, akkor menj ide: Menü->Játék Elhagyása.", "touchScreenText": "Érintőképernyő", + "unableToCompleteTryAgainText": "Nem sikerült.\nKérlek próbáld újra.", "unableToResolveHostText": "Hiba: a host nem elérhető.", "unavailableNoConnectionText": "Ez a funkció nem elérhető (Nincs internet kapcsolat?).", "vrOrientationResetCardboardText": "Használd ezt, hogy visszaállíts a VR orientációkat.\nHogy játszhass csatlakoztatnod kell egy kontrollert.", "vrOrientationResetText": "VR orientáció újraindítása.", "willTimeOutText": "(lejár az idő, ha tétlen)" }, + "inventoryText": "Eszköztár", "jumpBoldText": "UGORJ", "jumpText": "Ugorj", "keepText": "Tartsd", @@ -966,7 +1013,7 @@ "killsText": "Ölések", "kioskWindow": { "easyText": "Könnyű", - "epicModeText": "Hatalmas mód", + "epicModeText": "Epikus mód", "fullMenuText": "Teljes menü", "hardText": "Nehéz", "mediumText": "Közepes", @@ -990,8 +1037,11 @@ "seasonEndsMinutesText": "Szezonból hátralévő idő:${NUMBER} perc.", "seasonText": "Szezon ${NUMBER}", "tournamentLeagueText": "Hogy ebbe a tornába be tudj nevezni,el kell érned ezt a ligát:${NAME}", - "trophyCountsResetText": "A trófeák a következő szezonban lenullázódnak." + "trophyCountsResetText": "A trófeák a következő szezonban lenullázódnak.", + "upToDateBonusDescriptionText": "Ha legújabb verzióval játszol,\n${PERCENT}%-os bónuszt kapsz.", + "upToDateBonusText": "\"Legújabb verzió\" bónusz" }, + "learnMoreText": "Tudj meg többet", "levelBestScoresText": "Legjobb eredmények a ${LEVEL}-es szinten.", "levelBestTimesText": "Legjobb időeredmények a ${LEVEL}-es szinten", "levelFastestTimesText": "Legjobb idők a ${LEVEL}-n", @@ -1033,9 +1083,12 @@ "maxConnectionsText": "Max. Eszközök", "maxPartySizeText": "Maximum Parti Méret", "maxPlayersText": "Max. Játékosok", + "merchText": "Termékek!", "modeArcadeText": "Árkád mód", "modeClassicText": "Klasszikus mód", "modeDemoText": "Demó mód", + "moreSoonText": "Nemsokára több tartalom érkezik!", + "mostDestroyedPlayerText": "Legtöbbször megsemmisített játékos", "mostValuablePlayerText": "Legértékesebb Játékos", "mostViolatedPlayerText": "Legtöbbször Megölt Játékos", "mostViolentPlayerText": "Legerőszakosabb Játékos", @@ -1052,6 +1105,7 @@ "nameSuicideText": "${NAME} öngyilkosságot követett el.", "nameText": "Név", "nativeText": "Eredeti", + "newExclaimText": "Új!", "newPersonalBestText": "Új személyi rekord!", "newTestBuildAvailableText": "Egy újabb teszt szerkezet elérhető! (${VERSION} build ${BUILD}).\nSzerezd meg a ${ADDRESS}-n", "newText": "Új", @@ -1062,17 +1116,22 @@ "noContinuesText": "(újraéledés nélkül)", "noExternalStorageErrorText": "Nincs megtalálható külső tárhely ezen az eszközön", "noGameCircleText": "Hiba: nincs bejelentkezve egy JátékKörbe", + "noMessagesText": "Nincsenek üzenetek.", + "noPluginsInstalledText": "Nincsenek hozzáadva pluginok", "noProfilesErrorText": "Nincs játékos profilod, tehát te most '${NAME}'-val nyomulsz.\nMenj a Beállítások->Játékos Profilok-ba hogy csinálj magadnak egy profilt-", "noScoresYetText": "Nincs még pontod.", + "noServersFoundText": "Nem találhatók szerverek", "noThanksText": "Nem Köszönöm", "noTournamentsInTestBuildText": "FIGYELEM: A tournament pontok ebből a teszt épitésből ki lesznek hagyva.", "noValidMapsErrorText": "Nem található pálya ehhez a játéktípushoz.", "notEnoughPlayersRemainingText": "Nincs elég játékos. Lépj ki és kezdj egy új játékot.", "notEnoughPlayersText": "A játék elindításához, minimum ${COUNT} játékos szükséges!", + "notEnoughTicketsText": "Nincs elég jegyed!", "notNowText": "Most Nem", "notSignedInErrorText": "Be kell jelentkezned a művelethez.", "notSignedInGooglePlayErrorText": "Be kell jelentkezned Google Play-el a művelethez.", "notSignedInText": "nem vagy bejelentkezve", + "notUsingAccountText": "Megjegyzés: a ${SERVICE} fiók figyelmen kívül hagyása.\n Ha használni szeretné, lépjen a \"Fiók -> Bejelentkezés a ${SERVICE} segítségével\".", "nothingIsSelectedErrorText": "Nem választottál ki semmit!", "numberText": "#${NUMBER}", "offText": "Ki", @@ -1080,6 +1139,9 @@ "onText": "Be", "oneMomentText": "Egy pillanat...", "onslaughtRespawnText": "${PLAYER} újraéled a következő körben (${WAVE})", + "openMeText": "Nyiss ki!", + "openNowText": "Azonnali kinyitás", + "openText": "Kinyitás", "orText": "${A} vagy ${B}", "otherText": "Egyéb...", "outOfText": "(#${RANK} a ${ALL}-ból/-ből)", @@ -1131,7 +1193,11 @@ "pleaseWaitText": "Kérljek várj...", "pluginClassLoadErrorText": "Nem sikerült egy hoozáadást betölteni '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Nem sikerült elkezdeni az egyik hozzáadást '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Plugin beállítások", + "pluginsAutoEnableNewText": "Új Pluginok auto. bekapcs.", "pluginsDetectedText": "Új hozzáadások érzékelve. Indítsa újra az alkalmazást az aktiváláshoz, vagy szerkesztés őket a beállításokban", + "pluginsDisableAllText": "Összes plugin kikapcsolása", + "pluginsEnableAllText": "Összes plugin bekapcsolása", "pluginsRemovedText": "${NUM} hozzáadás(ok) mostmár nem találhatóak", "pluginsText": "Pluginok", "practiceText": "Gyakorlás", @@ -1162,6 +1228,8 @@ "punchText": "Ütés", "purchaseForText": "Megvétel ennyiért:${PRICE}", "purchaseGameText": "Játék megvásárlása", + "purchaseNeverAvailableText": "Sajnos ezen a builden nem lehet vásárolni.\n Próbáljon meg bejelentkezni fiókjába egy másik platformon, és onnan vásárolni.", + "purchaseNotAvailableText": "Ez a vásárlás nem elérhető.", "purchasingText": "Vásárlás folyamatban...", "quitGameText": "Kilépsz a ${APP_NAME}-ból?", "quittingIn5SecondsText": "Kilépés 5 másodpercen belül...", @@ -1203,6 +1271,7 @@ "version_mismatch": "Verzió hiba.\nLégy biztos abban hogy a BombSqad Irányító\na legújabb verzióval rendelkezik, és próbáld újra." }, "removeInGameAdsText": "Old fel a \"${PRO}\"-t az áruházból hogy eltávolítsd a játékbeli reklámokat.", + "removeInGameAdsTokenPurchaseText": "Korlátozott idejű ajánlat: Vásárold meg bármelyik token csomagot, hogy eltávolítsd a reklámokat.", "renameText": "Átnevezés", "replayEndText": "Visszajátszás Befejezése", "replayNameDefaultText": "Utolsó Játék visszajátszás", @@ -1223,7 +1292,9 @@ "revertText": "Visszateker", "runText": "Futás", "saveText": "Mentés", - "scanScriptsErrorText": "Hiba a szkriptek szkennelésében; részletek a naplóban.", + "scanScriptsErrorText": "Hiba a szkriptek szkennelésében. részletek a naplóban.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} és ${NUM} modult api ${API}-ra kell frissítened, hogy működjenek", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH}-t api ${API}-ra kell frissítened hogy működjenek.", "scoreChallengesText": "Pontszám Kihívások", "scoreListUnavailableText": "A pontszám lista nem elérhető.", "scoreText": "Pont", @@ -1234,6 +1305,7 @@ }, "scoreWasText": "(${COUNT} volt)", "selectText": "Válassz", + "sendInfoDescriptionText": "Fiók- és alkalmazásállapot-információkat küld el a fejlesztőnek.\nKérjük, adja meg a nevét vagy a küldés okát.", "seriesWinLine1PlayerText": "NYERTE MEG A", "seriesWinLine1TeamText": "NYERTE MEG A", "seriesWinLine1Text": "NYERTE MEG A", @@ -1250,24 +1322,33 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(kontroller barát billentyűzet a szöveg szerkesztéséhez)", - "alwaysUseInternalKeyboardText": "Használjon Belső Billentyűzetet", + "alwaysUseInternalKeyboardText": "Mindig Használjon Belső Billentyűzetet", "benchmarksText": "Teljesítmény és Stressz Teszt", - "disableCameraGyroscopeMotionText": "Kamera Gyroscope kikapcsolása", - "disableCameraShakeText": "Kamera rázást Kikapcsolni", + "devToolsText": "Fejlesztői Eszközök", + "disableCameraGyroscopeMotionText": "Kamera Giroszkóp mozgás kikapcsolása", + "disableCameraShakeText": "Kamera rázás kikapcsolása", "disableThisNotice": "(kikapcsolhatod ezt a beállítások menüben)", "enablePackageModsDescriptionText": "(engedélyez a plusz helyeket a modoknak, viszont letiltja a hálózati játékot)", "enablePackageModsText": "Helyi Modok Engedélyezése ", "enterPromoCodeText": "Kód beírása", "forTestingText": "Megj.:ezek az értékek csak tesztek és az alkalmazás bezárásával együtt törlődnek.", "helpTranslateText": "A ${APP_NAME} nem Angol fordításait a közösség végzi.\nHa szeretnél fordítani vagy hibát javítani akkor \nhasználd ezt a linket. Előre is köszönöm!", - "kickIdlePlayersText": "Tétlen Játékosok Kirúgása", + "insecureConnectionsDescriptionText": "nem ajánlott, de engedélyezheti az online játékot \nkorlátozott országokból vagy hálózatokból", + "insecureConnectionsText": "Nem biztonságos kapcsolatok használata", + "kickIdlePlayersText": "Rúgd a tétlen játékosokat", "kidFriendlyModeText": "Gyerekbarát Mód (erőszak csökkentése,stb.)", "languageText": "Nyelv", "moddingGuideText": "Modolási Útmutató", + "moddingToolsText": "Moddolási eszközök", "mustRestartText": "Újra kell indítanod a játékot a módosítások érvénybe lépéséhez.", "netTestingText": "Hálózat Tesztelése", "resetText": "Visszaállítás", + "sendInfoText": "Kűldj Infót", "showBombTrajectoriesText": "Bomba Pályájának Mutatása", + "showDemosWhenIdleText": "Demók megjelenítése üresjáratban", + "showDeprecatedLoginTypesText": "Elavult bejelentkezési típúsok megjelenítése", + "showDevConsoleButtonText": "A fejlesztői konzol gomb megjelenítése", + "showInGamePingText": "A játékon belüli ping megjelenítése", "showPlayerNamesText": "Játékos Név Mutatása", "showUserModsText": "Mod Mappák Mutatása", "titleText": "Haladó", @@ -1275,8 +1356,8 @@ "translationFetchErrorText": "fordítási státusz elérhetetlen", "translationFetchingStatusText": "Fordítási státusz ellenőrzése...", "translationInformMe": "Értesítsen, ha a nyelvem fordítását frissíteni kell", - "translationNoUpdateNeededText": "A jelenlegi nyelv naprakész; woohoo!", - "translationUpdateNeededText": "**a jelenlegi nyelv frissítésre szorul!!**", + "translationNoUpdateNeededText": "Az aktuális nyelv naprakész; woohoo!", + "translationUpdateNeededText": "** A jelenlegi nyelv frissítésre szorul!! **", "vrTestingText": "VR Tesztelése" }, "shareText": "Megosztás", @@ -1286,12 +1367,15 @@ "signInWithGameCenterText": "Hogy használd a Játék Központ felhasználódat\njelentkezz be a Játék Központban.", "singleGamePlaylistNameText": "Csak ${GAME}", "singlePlayerCountText": "1 játékos", + "sizeLargeText": "Óriás", + "sizeMediumText": "Közepes", + "sizeSmallText": "Kicsi", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Karakter Választás", "Chosen One": "A kiválasztott", - "Epic": "Hatalmas Módú Játékok", - "Epic Race": "Hatalmas Verseny", + "Epic": "Epikus Módú Játékok", + "Epic Race": "Epikus Verseny", "FlagCatcher": "Szerezd meg a Zászlót", "Flying": "Boldog Gondolatok", "Football": "Football", @@ -1361,6 +1445,8 @@ "storeText": "Bolt", "submitText": "Érvényesítsd", "submittingPromoCodeText": "Promóciós Kód Érvényesítése...", + "successText": "Siker!", + "supportEmailText": "Ha bármi problémát észlesz a játékkal, kérlek írd meg az alábbi e-mailen:\n${EMAIL}", "teamNamesColorText": "Csapatnevek/csapatszínek...", "telnetAccessGrantedText": "Telnet hozzáférés engedélyezve.", "telnetAccessText": "Telnet hozzáférés észlelve. Engedélyezed?", @@ -1370,6 +1456,7 @@ "testBuildValidatedText": "A Teszt Verzió Naprakész;Élvezd!", "thankYouText": "Köszi a támogatást. Jó játékot!", "threeKillText": "TRIPLA ÖLÉS!", + "ticketsDescriptionText": "A jegyekkel karaktereket,\npályákat,\nés minijátékokat tudsz feloldani. \n\nJegyekhez a ládákból tudsz jutni.", "timeBonusText": "Idő Bónusz", "timeElapsedText": "Eltelt Idő", "timeExpiredText": "Lejárt az idő", @@ -1380,10 +1467,23 @@ "tipText": "Tipp", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Szerezz Tokeneket", + "notEnoughTokensText": "Nincs elég tokened!", + "numTokensText": "${COUNT} Tokenek", + "shinyNewCurrencyText": "BombSquad fényes új fizetőeszköze.", + "tokenPack1Text": "Kicsi Token Csomag", + "tokenPack2Text": "Közepes Token Csomag", + "tokenPack3Text": "Nagy Token Csomag", + "tokenPack4Text": "Óriás Token Csomag", + "tokensDescriptionText": "A tokenekkel a ládák \nkinyitási idejét rövidítheted le,\nés még néhány más dolgot\ntudsz velük csinálni.\n\nTokeneket nyerni, vagy vásárolni is tudsz.", + "youHaveGoldPassText": "Megvan az Arany Pass.\nMinden token vásárlás ingyenes.\nÉlvezd!" + }, "topFriendsText": "Top Barátok", "tournamentCheckingStateText": "Torna állapotának ellenőrzése;Kérlek várj...", "tournamentEndedText": "Ez a torna befejeződött.Az új torna hamarosan kezdődik.", "tournamentEntryText": "Belépés a Tornába", + "tournamentFinalStandingsText": "Végleges állás", "tournamentResultsRecentText": "Legutóbbi Tornában elért helyezésed", "tournamentStandingsText": "Torna Állása", "tournamentText": "Bajnokság", @@ -1439,6 +1539,18 @@ "Uber Onslaught": "Über Támadás", "Uber Runaround": "Über Szaladgálás" }, + "displayItemNames": { + "${C} Tickets": "${C} jegy", + "${C} Tokens": "${C} token", + "Chest": "Láda", + "L1 Chest": "1-es szintű láda", + "L2 Chest": "2-es szintű láda", + "L3 Chest": "3-as szintű láda", + "L4 Chest": "4-es szintű láda", + "L5 Chest": "5-ös szintű láda", + "L6 Chest": "6-os szintű láda", + "Unknown Chest": "Ismeretlen láda" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Légy a kiválasztott egy ideig hogy nyerj.\nÖld meg a kiválasztottat, hogy te légy az.", "Bomb as many targets as you can.": "Bombázz annyi célpontot, amennyit csak tudsz.", @@ -1447,7 +1559,7 @@ "Crush ${ARG1} of your enemies.": "Zúzz szét ${ARG1}-t az ellenségeidből.", "Defeat all enemies.": "Győzz le minden ellenséget.", "Dodge the falling bombs.": "Térj ki minden hulló bomba elől.", - "Final glorious epic slow motion battle to the death.": "A végső dicső hatalmas lassú mozgásos csata a halálig.", + "Final glorious epic slow motion battle to the death.": "A végső dicső epikus csata a halálig.", "Gather eggs!": "Gyűjts tojásokat!", "Get the flag to the enemy end zone.": "Juttasd el a zászlót az ellenséges zóna végére.", "How fast can you defeat the ninjas?": "Milyen gyorsan győzöd le a ninja-kat?", @@ -1541,7 +1653,9 @@ "Italian": "Olasz", "Japanese": "Japán", "Korean": "Koreai", + "Malay": "Maláj", "Persian": "Perzsa", + "PirateSpeak": "Kalóznyelv", "Polish": "Lengyel", "Portuguese": "Portugál", "Romanian": "Román", @@ -1583,7 +1697,7 @@ "Zigzag": "Zigzag" }, "playlistNames": { - "Just Epic": "Csak Hatalmas", + "Just Epic": "Csak Epikus", "Just Sports": "Csak Sportok" }, "scoreNames": { @@ -1613,6 +1727,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Csalás észlelve; a pontok és nyeremények felfüggesztve ${COUNT} napig.", "Could not establish a secure connection.": "Nem lehet megbízható kapcsolatot létesíteni.", "Daily maximum reached.": "Napi maximum elérve.", + "Daily sign-in reward": "Napi belépésért járó jutalom", "Entering tournament...": "Belépés a tornába...", "Invalid code.": "Hibás kód.", "Invalid payment; purchase canceled.": "Érvénytelen fizetési mód; fizetés visszavonva.", @@ -1622,11 +1737,14 @@ "Item unlocked!": "Elem feloldva!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "KAPCSOLAT FENNTARTVA. ${ACCOUNT} tartalmaz\njelentős adatok, amelyek MINDEN elvesznének.\nÖsszekapcsolhatja az ellenkező sorrendben, ha szeretné\n(és ehelyett elveszíti a fiók adatait)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Összekötöd a/az ${ACCOUNT} fiókot ehhez a fiókhoz?\nMinden létező adat a/az ${ACCOUNT} fiókon elveszik.\nEzt nem tudod majd visszavonni. Biztos vagy benne?", + "Longer streaks lead to better rewards.": "Naponta egyre jobb jutalmakat kapsz.", "Max number of playlists reached.": "Maximum listaszám elérve.", "Max number of profiles reached.": "Maximum profilszám elérve.", "Maximum friend code rewards reached.": "Maximum barát kód elérve.", "Message is too long.": "Az üzenet túl hosszú.", + "New tournament result!": "Új verseny eredmény!", "No servers are available. Please try again soon.": "A szerverek nem elérhetőek. Kérlek próbáld újra később.", + "No slots available. Free a slot and try again.": "Nincs több rekesz. Szabadíts fel egyet, és próbáld újra", "Profile \"${NAME}\" upgraded successfully.": "A \"${NAME}\" profil teljes körűvé fejlesztve.", "Profile could not be upgraded.": "A profilt nem lehet frissíteni.", "Purchase successful!": "Vásárlás sikeres!", @@ -1636,7 +1754,9 @@ "Sorry, this code has already been used.": "Ezt a kódot már használták.", "Sorry, this code has expired.": "Ez a kód már lejárt.", "Sorry, this code only works for new accounts.": "Ezt a kódot csak új játékosok használhatják.", + "Sorry, this has expired.": "Bocsi, ez már lejárt.", "Still searching for nearby servers; please try again soon.": "Keresés közeli szerverek iránt...", + "Streak: ${NUM} days": "${NUM} napos széria", "Temporarily unavailable; please try again later.": "Jelenleg elérhetetlen; kérlek próbáld újra később.", "The tournament ended before you finished.": "A torna lezárult mielőtt te befejezted volna.", "This account cannot be unlinked for ${NUM} days.": "Ezt a fiókot nem tudod leválasztani ${NUM} napig.", @@ -1647,19 +1767,27 @@ "Tournaments require ${VERSION} or newer": "A versenyhez ${VERSION} verzió vagy újabb szükséges.", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Leválasztod ${ACCOUNT} erről a fiókról?\nAz összes adat innen: ${ACCOUNT} törölve lesz. \n(Kivéve a mérföldkövek egyes esetekben)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "FIGYELMEZTETÉS: fiókod ellen panaszok érkeztek csalásért.\nA csaláson kapott fiókok tiltva lesznek. Kérlek játsz tisztességesen.", + "Wait reduced!": "Várakozási idő csökkentve!", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Szeretnéd hogy a készülék felhasználója ez legyen?\n\nA készülék mostani felhasználója: ${ACCOUNT1}\nEz a felhasználó: ${ACCOUNT2}\n\nEz megtartja a mostani teljesítményed.\nVigyázat: ez nem visszavonható!", "You already own this!": "Már birtoklod ezt!", "You can join in ${COUNT} seconds.": "Beléphetsz ${COUNT} másodperc múlva.", "You don't have enough tickets for this!": "Nincs elég jegyed a vásárláshoz!", "You don't own that.": "Te nem rendelkezel ezzel.", "You got ${COUNT} tickets!": "Kaptál ${COUNT} jegyet!", + "You got ${COUNT} tokens!": "${COUNT} tokened van.", "You got a ${ITEM}!": "Kaptál egy ${ITEM}-t!", + "You got a chest!": "Kaptál egy ládát!", + "You got an achievement reward!": "Jutalmat kaptál a teljesítményedért!", "You have been promoted to a new league; congratulations!": "Feljutottál egy új ligába; Gratulálunk!", + "You lost a chest! (All your chest slots were full)": "Elvesztettél egy ládát! (minden ládatartó rekeszed tele van)", + "You must update the app to view this.": "Frissítsd az alkalmazást, hogy ezt megnézhesd.", "You must update to a newer version of the app to do this.": "Frissítened kell a játékot az újabb verzióra, hogy megtehesd ezt.", "You must update to the newest version of the game to do this.": "Frissítened kell a játék legújabb verziójára hogy ezt meg tudd tenni.", "You must wait a few seconds before entering a new code.": "Várnod kell pár másodpercet egy új kód beírásához.", + "You placed #${RANK} in a tournament!": "#${RANK}-dik/ik lettél a versenyen!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Az előző tornában elért helyezésed:#${RANK}.Köszönjük a játékot!", "Your account was rejected. Are you signed in?": "Fiókod elutasítva. Be vagy jelentkezve?", + "Your ad views are not registering. Ad options will be limited for a while.": "A hirdetésmegtekintések nem regisztrálódnak. A hirdetési lehetőségek egy ideig korlátozottak lesznek.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "A játékod módosítva lett.\nÁllíts vissza minden módosítást és próbáld újra.", "Your friend code was used by ${ACCOUNT}": "A promóciós kódod használva volt ${ACCOUNT} által" }, @@ -1682,7 +1810,7 @@ "Enable Impact Bombs": "Ragadós Bomba engedélyezve", "Enable Triple Bombs": "Háromszoros Bomba engedélyezve", "Entire Team Must Finish": "Az Egész csapatnak be kell érnie", - "Epic Mode": "Hatalmas Mód", + "Epic Mode": "Epikus Mód", "Flag Idle Return Time": "Zászló Tétlen Visszatérés Idő", "Flag Touch Return Time": "Zászló Érintés Visszatérési Idő", "Hold Time": "Kitartási Idő", @@ -1775,18 +1903,18 @@ "phrase04Text": "Sok tárgy a ${APP_NAME}-ban FIZIKÁRA alapszik.", "phrase05Text": "Például, ha ütsz...", "phrase06Text": "..a sérülés az őkleid gyorsaságán múlik.", - "phrase07Text": "Látod? Nem mozdultunk, szóval ez alig sebezte meg ${NAME}-t.", + "phrase07Text": "Látod? Nem mozdultunk, szóval ez alig sebezte meg ${NAME}et.", "phrase08Text": "Most ugorjunk és pörögjünk hogy sebességre tegyünk szert.", "phrase09Text": "Áh, így jobb.", "phrase10Text": "A futás is segít.", - "phrase11Text": "Tartsd lenyomva AKÀRMELYIK gombot a futáshoz.", + "phrase11Text": "Tartsd lenyomva AKÁRMELYIK gombot a futáshoz.", "phrase12Text": "Extra-király ütésért, próbálj futni és pörögni.", "phrase13Text": "Hopsz; bocs ezért ${NAME}", - "phrase14Text": "Feltudsz venni és eldobni dolgokat, csak úgy mint a zászlót... vagy ${NAME}-t.", - "phrase15Text": "Végül, van bomba.", + "phrase14Text": "Fel tudsz venni és eldobni dolgokat, csak úgy mint a zászlót... vagy ${NAME}ot.", + "phrase15Text": "Végül, van a bomba.", "phrase16Text": "A bomba dobás gyakorlatot vesz igénybe.", - "phrase17Text": "Áú! Nem nagyon jódobás!", - "phrase18Text": "Mozgás segít távolabbra dobni.", + "phrase17Text": "Áú! Nem valami jó dobás!", + "phrase18Text": "A mozgás segít távolabbra dobni.", "phrase19Text": "Az ugrás segít magasabbra dobni.", "phrase20Text": "\"Ostorozz\" a bombáddal, hogy még messzebbre is dobd.", "phrase21Text": "Beidőzíteni a bombádat, trükkös lehet.", @@ -1794,7 +1922,7 @@ "phrase23Text": "Próbáld meg \"kisütni\" a kanócot egy vagy két másodpercre.", "phrase24Text": "Hurrá! Jól megsült.", "phrase25Text": "Jólvan, ez csak erről szól.", - "phrase26Text": "Kapd el őket, tigris!", + "phrase26Text": "Kapd el őket, te vadállat!", "phrase27Text": "Emlékezz az edzésedre, és élve jössz vissza!", "phrase28Text": "...jah, talán...", "phrase29Text": "Sok szerencsét!", @@ -1809,11 +1937,13 @@ "toSkipPressAnythingText": "(tapints vagy nyomj meg akármit az oktató átlépéséhez)" }, "twoKillText": "DUPLA ÖLÉS!", + "uiScaleText": "UI skála", "unavailableText": "elérhetetlen", "unconfiguredControllerDetectedText": "Konfigurált vezérlő felismerve:", "unlockThisInTheStoreText": "Ennek feloldva kell lennie az áruházban.", "unlockThisProfilesText": "Hogy készíts több mint ${NUM} profilt, kelleni fog:", "unlockThisText": "Hogy ezt felold, szükséged van ezekre:", + "unsupportedControllerText": "Bocsi, de a(z) \"${NAME}\" nevű kontroller nem támogatott", "unsupportedHardwareText": "Bocs, ez a hárdver nem támogatott a játék ezen szerkezete által.", "upFirstText": "Elsőként:", "upNextText": "A következő a ${COUNT}. játékban:", @@ -1821,10 +1951,15 @@ "upgradeText": "Frissítés", "upgradeToPlayText": "Old fel a \"${PRO}\"-t az áruházba, hogy játszhass ezzel.", "useDefaultText": "Alapértelmezett Használata", + "userSystemScriptsCreateText": "Felhasználói rendszer-scriptek létrehozása", + "userSystemScriptsDeleteText": "Felhasználói rendszer-scriptek törlése", "usesExternalControllerText": "Ez a játék egy külső vezérlőt használ bemenet gyanánt.", - "usingItunesText": "Itunes használása a zenéhez...", + "usingItunesText": "Itunes használata a zenéhez...", "usingItunesTurnRepeatAndShuffleOnText": "Kérlek bizonyosodj meg arról, hogy a keverés BE van kapcsolva és az ismétlés MINDEN-re van állítva az iTunes-on.", + "v2AccountLinkingInfoText": "Hogy V2-es fiókot kapcsolj, menj a 'fiók kezelése' gombra.", + "v2AccountRequiredText": "Ehhez V2 fiókra van szükség. Fejleszd a fiókodat és próbáld meg újra.", "validatingTestBuildText": "Teszt Szerkezet Érvényesítése...", + "viaText": "via", "victoryText": "Győzelem!", "voteDelayText": "Még nem indíthatsz szavazást újabb ${NUMBER} másodpercig", "voteInProgressText": "Már egy szavazás folyamatban van...", @@ -1856,6 +1991,7 @@ }, "waveText": "Hullám", "wellSureText": "Rendben!", + "whatIsThisText": "Ez meg micsoda?", "wiimoteLicenseWindow": { "titleText": "DarwiinRemote Szerzői jog" }, @@ -1876,7 +2012,7 @@ "winsText": "${NAME} nyert!", "workspaceSyncErrorText": "Nem sikerült szinkronizálni a következő munkaterületet: ${WORKSPACE}. Nézd a naplót további adatokért.", "workspaceSyncReuseText": "Nem lehet szinkronizálni a következő munkaterületet: ${WORKSPACE}. Előző munkaterület lesz használatban.", - "worldScoresUnavailableText": "Világ eredmények elérhetetlenek", + "worldScoresUnavailableText": "A globális eredmények elérhetetlenek", "worldsBestScoresText": "Világ legjobb eredményei", "worldsBestTimesText": "Világ legjobb idejei", "xbox360ControllersWindow": { @@ -1887,6 +2023,7 @@ "titleText": "Xbox 360 kontroller használata a ${APP_NAME}-ban:" }, "yesAllowText": "Igen, Engedélyez!", - "yourBestScoresText": "Te legjobb pontjaid", - "yourBestTimesText": "Te legjobb időid" + "yourBestScoresText": "A legjobb pontjaid", + "yourBestTimesText": "A legjobb időid", + "yourPrizeText": "A jutalmad:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/indonesian.json b/dist/ba_data/data/languages/indonesian.json index 2d188245..85220b4e 100644 --- a/dist/ba_data/data/languages/indonesian.json +++ b/dist/ba_data/data/languages/indonesian.json @@ -1,13 +1,15 @@ { "accountSettingsWindow": { - "accountNameRules": "Emoji atau karakter spesial lainnya tidak dapat digunakan untuk nama akun", + "accountNameRules": "Nama akun tidak boleh berisi emoji atau karakter khusus lainnya", "accountProfileText": "(profil akun)", "accountsText": "Akun", - "achievementProgressText": "Penghargaan: ${COUNT} dari ${TOTAL}", + "achievementProgressText": "Pencapaian: ${COUNT} dari ${TOTAL}", "campaignProgressText": "Kemajuan Ekspedisi [Sulit]: ${PROGRESS}", "changeOncePerSeason": "Kamu hanya dapat mengganti ini sekali per musim.", "changeOncePerSeasonError": "Kamu harus menunggu sampai musim berikutnya untuk menggantinya lagi (${NUM} hari)", + "createAnAccountText": "Buat akun", "customName": "Nama Khusus", + "deleteAccountText": "Hapus Akun", "googlePlayGamesAccountSwitchText": "Jika kamu ingin menggunakan akun Google yang lain,\ngunakan aplikasi Google Play Games untuk mengganti.", "linkAccountsEnterCodeText": "Masukkan kode", "linkAccountsGenerateCodeText": "Buat Kode", @@ -18,28 +20,30 @@ "linkedAccountsText": "Akun yang Tertaut:", "manageAccountText": "Manajemen Akun", "nameChangeConfirm": "Ganti namamu menjadi ${NAME}?", - "resetProgressConfirmNoAchievementsText": "Tindakan ini akan mengatur ulang kemajuan co-op dan\nskor tertinggi Kamu (kecuali tiket).\nTidak dapat dibatalkan. Apakah Kamu yakin?", - "resetProgressConfirmText": "Ini akan mengatur ulang kemajuan co-op,\npencapaian, dan skor tertinggi Kamu\n(kecuali tiket). Ini tidak dapat\ndibatalkan. Kamu yakin?", - "resetProgressText": "Atur Ulang kemajuan", + "resetProgressConfirmNoAchievementsText": "Tindakan ini akan mengatur ulang kemajuan co-op dan\nskor tertinggi kamu (kecuali tiketmu).\nIni tidak dapat dibatalkan. Apakah kamu yakin?", + "resetProgressConfirmText": "Ini akan mengatur ulang kemajuan co-op,\npencapaian, dan skor tertinggi kamu\n(kecuali tiketmu). Ini tidak dapat\ndibatalkan. Apakah kamu yakin?", + "resetProgressText": "Atur Ulang Kemajuan", "setAccountName": "Pasang Nama Akun", - "setAccountNameDesc": "Pilih nama yang ditampilkan untuk akun Kamu.\nGunakan nama dari akun yang tersambung atau\nbuatlah nama khusus baru.", - "signInInfoText": "Masuk untuk mendapatkan tiket, bermain daring,\ndan membagikan kemajuan permaian antar perangkat.", + "setAccountNameDesc": "Pilih nama yang ditampilkan untuk akun kamu.\nGunakan nama dari akun yang tersambung atau\nbuatlah nama khusus baru.", + "signInInfoText": "Masuk untuk mengumpulkan tiket, berkompetisi online,\ndan berbagi kemajuan di seluruh perangkat.", "signInText": "Masuk", + "signInWithAnEmailAddressText": "Masuk dengan alamat email", "signInWithDeviceInfoText": "(akun otomatis hanya tersedia untuk perangkat ini)", "signInWithDeviceText": "Masuk menggunakan akun perangkat", "signInWithGameCircleText": "Masuk dengan LingkarPermainan", "signInWithGooglePlayText": "Masuk menggunakan Google Play", "signInWithTestAccountInfoText": "(akun tipe lama; gunakan akun device untuk kedepannya)", "signInWithTestAccountText": "Masuk menggunakan akun percobaan", - "signInWithV2InfoText": "(Akun yang berfungsi di semua akun)", - "signInWithV2Text": "Daftar dengan akun bombsquad", + "signInWithText": "Masuk dengan ${SERVICE}", + "signInWithV2InfoText": "(akun yang berfungsi di semua akun)", + "signInWithV2Text": "Daftar dengan akun ${APP_NAME}", "signOutText": "Keluar", "signingInText": "Sedang masuk...", "signingOutText": "Sedang keluar...", "ticketsText": "Tiket:${COUNT}", "titleText": "Akun", "unlinkAccountsInstructionsText": "Pilih akun yang akan diputuskan.", - "unlinkAccountsText": "Memutus Akun.", + "unlinkAccountsText": "Putuskan Akun", "unlinkLegacyV1AccountsText": "Putuskan tautan Akun lama (V1)", "v2LinkInstructionsText": "Gunakan tautan ini untuk membuat akun atau masuk.", "viaAccount": "(melalui akun ${NAME})", @@ -63,13 +67,13 @@ "name": "Petinju" }, "Dual Wielding": { - "descriptionFull": "hubungkan 2 pengontrol (perangkat keras atau aplikasi)", - "descriptionFullComplete": "2 pengontrol terhubung (perangkat keras atau aplikasi)", + "descriptionFull": "Hubungkan 2 pengontrol (perangkat keras atau aplikasi)", + "descriptionFullComplete": "2 Pengontrol terhubung (perangkat keras atau aplikasi)", "name": "Dua Tangan" }, "Flawless Victory": { "description": "Menangkan pertandingan tanpa terkena serangan", - "descriptionComplete": "Menang Tanpa terkena Serangan", + "descriptionComplete": "Menang tanpa terkena serangan", "descriptionFull": "Menangkan ${LEVEL} tanpa terkena serangan", "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa terkena serangan", "name": "Kemenangan Mutlak" @@ -91,11 +95,11 @@ "descriptionComplete": "Memenangkan pertandingan tanpa memukul dan bom", "descriptionFull": "Menangkan ${LEVEL} tanpa memukul dan tanpa menggunakan bom", "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa memukul dan tanpa bom", - "name": "Got the Moves" + "name": "Mendapatkan Pergerakan" }, "In Control": { "descriptionFull": "hubungkan pengontrol (perangkat keras atau aplikasi)", - "descriptionFullComplete": "pengontrol terhubung (perangkat keras atau aplikasi)", + "descriptionFullComplete": "Pengontrol terhubung (perangkat keras atau aplikasi)", "name": "Terkendali" }, "Last Stand God": { @@ -162,17 +166,17 @@ "name": "Penyihir ${LEVEL}" }, "Precision Bombing": { - "description": "Menang tanpa mengambil kekuatan tambahan", - "descriptionComplete": "Memenangkan permainan tanpa mengambil kekuatan tambahan", - "descriptionFull": "Menangkan ${LEVEL} tanpa mengambil power-up", - "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa mengambil power-up", + "description": "Menang tanpa kotak bonus", + "descriptionComplete": "Menangkan permainan tanpa mengambil kotak bonus", + "descriptionFull": "Menang ${LEVEL} tanpa mengambil kotak bonus", + "descriptionFullComplete": "Menangkan ${LEVEL} tanpa mengambil kotak bonus", "name": "Pengebom Jitu" }, "Pro Boxer": { "description": "Menang tanpa menggunakan bom", - "descriptionComplete": "Menang tanpa menggunakan bom", - "descriptionFull": "Menangkan ${LEVEL} tanpa menggunakan bom", - "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa menggunakan bom", + "descriptionComplete": "Menangkan permainan tanpa menggunakan bom", + "descriptionFull": "Selesaikan ${LEVEL} tanpa menggunakan bom", + "descriptionFullComplete": "Selesaikan ${LEVEL} tanpa menggunakan bom", "name": "Petinju Handal" }, "Pro Football Shutout": { @@ -229,7 +233,7 @@ "descriptionComplete": "Mencetak skor 2000 poin", "descriptionFull": "Cetak skor 2000 poin pada ${LEVEL}", "descriptionFullComplete": "Mencetak skor 2000 poin pada ${LEVEL}", - "name": "Rajanya ${LEVEL}" + "name": "Dewanya ${LEVEL}" }, "Runaround Master": { "description": "Cetak skor 500 poin", @@ -248,27 +252,27 @@ "Sharing is Caring": { "descriptionFull": "Berhasil berbagi permainan dengan teman", "descriptionFullComplete": "Berhasil berbagi permainan dengan teman", - "name": "Berbagi adalah Peduli" + "name": "Berbagi berarti Peduli" }, "Stayin' Alive": { - "description": "Menangkan permainan tanpa mati", - "descriptionComplete": "Memenangkan permainan tanpa mati", - "descriptionFull": "Menangkan ${LEVEL} tanpa mati", - "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa mati", + "description": "Menang tanpa mati", + "descriptionComplete": "Menangkan permainan tanpa mati", + "descriptionFull": "Menang ${LEVEL} tanpa mati", + "descriptionFullComplete": "Menangkan ${LEVEL} tanpa mati", "name": "Bertahan Hidup" }, "Super Mega Punch": { - "description": "Buat 100% damage dengan satu pukulan", - "descriptionComplete": "Membuat 100% damage dengan satu pukulan", - "descriptionFull": "Buat 100% damage dengan satu pukulan pada ${LEVEL}", - "descriptionFullComplete": "Membuat 100% damage dengan satu pukulan pada ${LEVEL}", + "description": "Buat 100% kerusakan dengan satu pukulan", + "descriptionComplete": "Membuat 100% kerusakan dengan satu pukulan", + "descriptionFull": "Buat 100% kerusakan dengan satu pukulan pada ${LEVEL}", + "descriptionFullComplete": "Membuat 100% kerusakan dengan satu pukulan pada ${LEVEL}", "name": "Tinjuan Mega Super" }, "Super Punch": { - "description": "Buat 50% damage dengan satu pukulan", - "descriptionComplete": "Membuat 50% damage dengan satu pukulan", - "descriptionFull": "Buat 50% damage dengan satu pukulan pada ${LEVEL}", - "descriptionFullComplete": "Membuat 50% damage dengan satu pukulan pada ${LEVEL}", + "description": "Buat 50% kerusakan dengan satu pukulan", + "descriptionComplete": "Membuat 50% kerusakan dengan satu pukulan", + "descriptionFull": "Buat 50% kerusakan dengan satu pukulan pada ${LEVEL}", + "descriptionFullComplete": "Membuat 50% kerusakan dengan satu pukulan pada ${LEVEL}", "name": "Tinjuan Super" }, "TNT Terror": { @@ -281,7 +285,7 @@ "Team Player": { "descriptionFull": "Mulai permainan tim dengan 4+ pemain", "descriptionFullComplete": "Memulai permainan tim dengan 4+ pemain", - "name": "Pemain tim" + "name": "Pemain Tim" }, "The Great Wall": { "description": "Hentikan semua musuh", @@ -299,9 +303,9 @@ }, "Uber Football Shutout": { "description": "Menang tanpa memperbolehkan musuh mencetak skor", - "descriptionComplete": "Menang tanpa memperbolehkan musuh mencetak skor", - "descriptionFull": "Menangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", - "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "descriptionComplete": "Menangkan tanpa memperbolehkan musuh mencetak skor", + "descriptionFull": "Menang ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "descriptionFullComplete": "Menangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", "name": "${LEVEL} Beres" }, "Uber Football Victory": { @@ -326,24 +330,29 @@ "name": "Juara ${LEVEL}" } }, - "achievementsRemainingText": "Achievement Tersisa:", - "achievementsText": "Achievement", - "achievementsUnavailableForOldSeasonsText": "Maaf, spesifik achievement tidak tersedia untuk musim lama.", - "activatedText": "${THING} telah aktif", + "achievementsRemainingText": "Pencapaian Tersisa:", + "achievementsText": "Pencapaian", + "achievementsUnavailableForOldSeasonsText": "Maaf, pencapaian spesifik tidak tersedia untuk musim lama.", + "activatedText": "${THING} telah aktif.", "addGameWindow": { - "getMoreGamesText": "Game Lain...", - "titleText": "Tambah Game" + "getMoreGamesText": "Dapatkan Permainan Lain...", + "titleText": "Tambah Permainan" }, + "addToFavoritesText": "Tambahkan ke Favorit", + "addedToFavoritesText": "Tambah '${NAME}' ke dalam Favorit.", + "allText": "Semua", "allowText": "Izinkan", "alreadySignedInText": "Akunmu telah masuk di perangkat lain;\nSilakan beralih akun atau menutup permainanmu \ndi perangkat lain dan coba lagi.", "apiVersionErrorText": "Modul ${NAME} gagal dimuat; Menarget api-version ${VERSION_USED}; kami membutuhkan ${VERSION_REQUIRED}.", + "applyText": "Terapkan", + "areYouSureText": "Apakah kamu yakin?", "audioSettingsWindow": { - "headRelativeVRAudioInfoText": "(\"Auto\" nyalakan ini hanya jika menggunakan headphone)", + "headRelativeVRAudioInfoText": "(\"Otomatis\" nyalakan ini hanya jika menggunakan headphone)", "headRelativeVRAudioText": "VR Audio Head-Relative", "musicVolumeText": "Volume Musik", "soundVolumeText": "Volume Suara", "soundtrackButtonText": "Pengiring lagu", - "soundtrackDescriptionText": "(masukkan musik Kamu untuk diputar saat permainan)", + "soundtrackDescriptionText": "(masukkan musik kamu untuk diputar saat permainan)", "titleText": "Audio" }, "autoText": "Otomatis", @@ -351,28 +360,39 @@ "banThisPlayerText": "Melarang Pemain Ini", "bestOfFinalText": "Terbaik dari ${COUNT} Final", "bestOfSeriesText": "Terbaik dari ${COUNT}:", + "bestOfUseFirstToInstead": 0, "bestRankText": "Urutan terbaikmu #${RANK}", - "bestRatingText": "Rating terbaikmu ${RATING}", + "bestRatingText": "Nilai terbaikmu ${RATING}", "bombBoldText": "BOM", "bombText": "Bom", "boostText": "Dorongan", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} dikonfigurasi di aplikasinya sendiri.", "buttonText": "tombol", - "canWeDebugText": "Bolehkah BombSquad mengirim informasi kerusakan\ndan info penggunaan ke pengembang secara otomatis? \n\nData pribadi tidak akan dikirim dan\nmembantu game berjalan lebih baik.", + "canWeDebugText": "Bolehkah ${APP_NAME} untuk\nsecara otomatis melaporkan\nbug, kerusakan, dan\ninfo penggunaan dasar\nkepada pengembang?", "cancelText": "Batal", "cantConfigureDeviceText": "Maaf, ${DEVICE} tidak dapat dikonfigurasi.", - "challengeEndedText": "Tantangan selesai", - "chatMuteText": "Abaikan Percakapan", - "chatMutedText": "Percakapan Diabaikan", - "chatUnMuteText": "Menampilkan kembali percakapan", + "challengeEndedText": "Tantangan selesai.", + "chatMuteText": "Bisukan Percakapan", + "chatMutedText": "Percakapan Dibisukan", + "chatUnMuteText": "Tampilkan kembali percakapan", + "chests": { + "prizeOddsText": "Peluang Hadiah", + "reduceWaitText": "Kurangi Menunggu", + "slotDescriptionText": "Slot ini dapat menahan peti.\n\nDapatkan peti dengan memainkan level kampanye,\njuara di turnamen, dan menyelesaikan\npencapaian.", + "slotText": "Slot Peti ${NUM}", + "slotsFullWarningText": "PERINGATAN: Semua slot petimu penuh.\nPeti apa pun yang kamu peroleh dalam permainan ini akan hilang.", + "unlocksInText": "Terbuka dalam" + }, "choosingPlayerText": "", - "completeThisLevelToProceedText": "Kamu harus menyelesaikan\nlevel ini untuk dapat lanjut!", - "completionBonusText": "Bonus Kelengkapan", + "claimText": "Klaim", + "codesExplainText": "Kode telah disediakan oleh pengembang\nuntuk didiagnosa dan memperbaiki isu akun.", + "completeThisLevelToProceedText": "Kamu harus menyelesaikan\nlevel ini untuk melanjutkan!", + "completionBonusText": "Bonus Penyelesaian", "configControllersWindow": { "configureControllersText": "Atur Pengontrol", "configureKeyboard2Text": "Atur Keyboard Player 2", "configureKeyboardText": "Atur Keyboard", - "configureMobileText": "Perangkat ponsel sebagai pengontrol", + "configureMobileText": "Perangkat Ponsel sebagai Pengontrol", "configureTouchText": "Atur Kontrol Layar", "ps3Text": "Pengontrol PS3", "titleText": "Pengontrol", @@ -380,78 +400,79 @@ "xbox360Text": "Pengontrol Xbox 360" }, "configGamepadSelectWindow": { - "androidNoteText": "Catatan: pengontrol dapat digunakan berdasarkan versi Android Kamu.", - "pressAnyButtonText": "Tekan tombol kontroller yang\n ingin Kamu atur,,,", + "androidNoteText": "Catatan: pengontrol yang didukung bervariasi berdasarkan perangkat dan versi Android.", + "pressAnyButtonText": "Tekan tombol apapun di pengontrol\n yang ingin kamu atur...", "titleText": "Konfigurasi Pengontrol" }, "configGamepadWindow": { "advancedText": "Lanjutan", "advancedTitleText": "Pengaturan Pengontrol Lanjutan", - "analogStickDeadZoneDescriptionText": "(nyalakan ini jika karaktermu ngedrift saat kamu melepaskan analog stik)", - "analogStickDeadZoneText": "Analog Stick Zona Mati", - "appliesToAllText": "(Berlakukan ke semua kontrol tipe ini)", + "analogStickDeadZoneDescriptionText": "(nyalakan ini jika karaktermu ngedrift saat kamu melepaskan stik analog)", + "analogStickDeadZoneText": "Stik Analog Zona Mati", + "appliesToAllText": "(terapkan ke semua pengontrol tipe ini)", "autoRecalibrateDescriptionText": "(nyalakan ini jika karaktermu tidak bergerak dengan kecepatan penuh)", - "autoRecalibrateText": "Otomatis kalibrasi kembali stik analog", + "autoRecalibrateText": "Otomatis Kalibrasi Stik Analog", "axisText": "axis", "clearText": "hapus", "dpadText": "dpad", - "extraStartButtonText": "Tambahan tombol start", - "ifNothingHappensTryAnalogText": "Jika tidak terjadi apa-apa,coba berlakukan stik analog langsung", - "ifNothingHappensTryDpadText": "Jika tidak terjadi apa-apa,coba berlakukan ke d-pad langsung", - "ignoreCompletelyDescriptionText": "Cegah pengontrol ini untuk mempengaruhi game atau menu", + "extraStartButtonText": "Tambahan Tombol Start", + "ifNothingHappensTryAnalogText": "Jika tidak terjadi apa-apa, coba tetapkan ke stik analog.", + "ifNothingHappensTryDpadText": "Jika tidak terjadi apa-apa, coba tetapkan ke d-pad.", + "ignoreCompletelyDescriptionText": "(cegah pengontrol ini untuk mempengaruhi game atau menu)", "ignoreCompletelyText": "Abaikan Sepenuhnya", - "ignoredButton1Text": "Abaikan tombol 1", - "ignoredButton2Text": "Abaikan tombol 2", - "ignoredButton3Text": "Abaikan tombol 3", - "ignoredButton4Text": "Abaikan tombol 4", - "ignoredButtonDescriptionText": "(Gunakan ini untuk mencegah tombol 'home' atau 'sync' yang mempengaruhi UI)", - "pressAnyAnalogTriggerText": "Tekan Tombol analog....", - "pressAnyButtonOrDpadText": "Tekan Tombol dpad", + "ignoredButton1Text": "Abaikan Tombol 1", + "ignoredButton2Text": "Abaikan Tombol 2", + "ignoredButton3Text": "Abaikan Tombol 3", + "ignoredButton4Text": "Abaikan Tombol 4", + "ignoredButtonDescriptionText": "(gunakan ini untuk mencegah tombol 'home' atau 'sync' dari mempengaruhi UI)", + "pressAnyAnalogTriggerText": "Tekan tombol analog....", + "pressAnyButtonOrDpadText": "Tekan tombol dpad", "pressAnyButtonText": "Tekan tombol", - "pressLeftRightText": "Tekan Tombol kiri atau kanan", + "pressLeftRightText": "Tekan tombol kiri atau kanan", "pressUpDownText": "Tekan tombol atas atau bawah..", - "runButton1Text": "Jalankan tombol 1", - "runButton2Text": "Jalankan tombol 2", - "runTrigger1Text": "Jalankan pelatuk 1", - "runTrigger2Text": "Jalankan pelatuk 2", - "runTriggerDescriptionText": "(Analog memungkinkan kamu untuk lari pada berbagai kecepatan)", - "secondHalfText": "Gunakan ini untuk pengontrol kedua dari\n2-pengontrol-dalam-1 alat yang\nditunjukan sebagai pengontrol tunggal", + "runButton1Text": "Jalankan Tombol 1", + "runButton2Text": "Jalankan Tombol 2", + "runTrigger1Text": "Jalankan Pelatuk 1", + "runTrigger2Text": "Jalankan Pelatuk 2", + "runTriggerDescriptionText": "(analog memungkinkan kamu untuk lari pada berbagai kecepatan)", + "secondHalfText": "Gunakan ini untuk pengontrol kedua dari\n2-pengontrol-dalam-1 alat yang\nditunjukkan sebagai pengontrol tunggal.", "secondaryEnableText": "Aktifkan", - "secondaryText": "Pengontrol kedua", - "startButtonActivatesDefaultDescriptionText": "(Matikan jika tombol start Kamu lebih dari tombol 'menu')", - "startButtonActivatesDefaultText": "Tombol start mengaktifkan widget biasanya", + "secondaryText": "Pengontrol Sekunder", + "startButtonActivatesDefaultDescriptionText": "(matikan jika tombol start kamu lebih dari tombol 'menu')", + "startButtonActivatesDefaultText": "Tombol Start Mengaktifkan Widget Asal", "titleText": "Pengaturan Pengontrol", "twoInOneSetupText": "Pengaturan Pengontrol 2-dalam-1", - "uiOnlyDescriptionText": "(Cegah kontrol ini dari mengikuti permainan yang asli)", - "uiOnlyText": "Batas untuk menu guna", - "unassignedButtonsRunText": "Tidak berlakukan semua tombol lari", + "uiOnlyDescriptionText": "(cegah pengontrol ini dari bergabung sebuah permainan sebenarnya)", + "uiOnlyText": "Batas untuk Guna Menu", + "unassignedButtonsRunText": "Tidak Berlakukan Semua Tombol Lari", "unsetText": "", - "vrReorientButtonText": "Tombol reorientasi VR" + "vrReorientButtonText": "Tombol Reorientasi VR" }, "configKeyboardWindow": { - "configuringText": "Mengaturi ${DEVICE}", - "keyboard2NoteText": "Catatan: beberapa keyboard hanya dapat memasukan beberapa tombol yang ditekan pada satu waktu,\njadi memiliki keyboard pemain kedua mungkin bekerja lebih baik\njika ada pemisah keyboard yang terpasang untuk digunakan\nPerlu dicatat bahwa Kamu masih butuh memasukan tombol unik untuk\nkedua pemain di kasus ini" + "configuringText": "Mengatur ${DEVICE}", + "keyboard2NoteText": "Catatan: beberapa keyboard hanya dapat memasukan beberapa tombol yang ditekan pada satu waktu,\njadi memiliki keyboard pemain kedua mungkin bekerja lebih baik\njika ada pemisah keyboard yang terpasang untuk digunakan.\nPerlu dicatat bahwa kamu masih butuh memasukkan tombol unik untuk\nkedua pemain di kasus ini" }, "configTouchscreenWindow": { - "actionControlScaleText": "Ukuran kontrol aksi", + "actionControlScaleText": "Skala Kontrol Aksi", "actionsText": "Aksi", "buttonsText": "tombol", "dragControlsText": "< geser kontrol untuk memposisikannya >", - "joystickText": "joystick", - "movementControlScaleText": "Skala kontrol penggerak", + "joystickText": "joystik", + "movementControlScaleText": "Skala Kontrol Penggerak", "movementText": "Pergerakan", - "resetText": "Kembalikan ke awal", - "swipeControlsHiddenText": "Sembunyikan ikon geser", - "swipeInfoText": "Model kontrol 'geser' membutuhkan penggunaan sedikit \nnamun membuat mudah untuk bermain tanpa melihat pengontrol", + "resetText": "Ulangi", + "swipeControlsHiddenText": "Sembunyikan Ikon Geser", + "swipeInfoText": "Gaya kontrol 'geser' butuh sedikit terbiasa namun \nmembuat mudah untuk bermain tanpa melihat pengontrol.", "swipeText": "geser", - "titleText": "Atur layar sentuh" + "titleText": "Atur Layar Sentuh" }, + "configureDeviceInSystemSettingsText": "${DEVICE} dapat dikonfigurasikan pada aplikasi Pengaturan Sistem.", "configureItNowText": "Atur sekarang?", "configureText": "Konfigurasi", "connectMobileDevicesWindow": { "amazonText": "Amazon Appstore", - "appStoreText": "App store", - "bestResultsText": "Untuk hasil yang lebih baik, Kamu membutuhkan jaringan Wi-Fi yang bebas lag.\nKamu dapat menurunkan lag Wi-Fi dengan cara mematikan alat wireless lainnya,\ndengan bermain dekat dengan router Wi-Fi dan dengan menyambungkan ke host\ngame langsung ke jaringan via ethernet", + "appStoreText": "App Store", + "bestResultsText": "Untuk hasil yang lebih baik, kamu membutuhkan jaringan Wi-Fi yang bebas lag.\nKamu dapat menurunkan lag Wi-Fi dengan cara mematikan perangkat nirkabel lainnya,\ndengan bermain dekat dengan router Wi-Fi dan dengan menyambungkan ke host\ngame langsung ke jaringan via ethernet.", "explanationText": "Untuk menggunakan smartphone atau tablet sebagai pengontrol,\npasang \"${REMOTE_APP_NAME}\" app. Alat apapun dapat tersambung ke\n${APP_NAME} game melalui Wi-Fi, dan ini gratis!", "forAndroidText": "Untuk Android:", "forIOSText": "Untuk iOS:", @@ -464,40 +485,40 @@ "controlsText": "Kontrol", "coopSelectWindow": { "activenessAllTimeInfoText": "Ini akan tidak berlaku ke ranking semua waktu.", - "activenessInfoText": "Kelipatan ini naik di hari ketika Kamu bermain\ndan turun di haru ketika Kamu tidak bermain", + "activenessInfoText": "Kelipatan ini naik di hari ketika kamu bermain\ndan turun di hari ketika kamu tidak bermain", "activityText": "Aktivitas", - "campaignText": "Ekspedisi", - "challengesInfoText": "Dapatkan hadiah dengan menyelesaikan mini games\n\nHadiah dan tingkat kesulitan level bertambah\nsaat tantangan terselesaikan \ndan berkurang jika waktu habis atau menyerah", + "campaignText": "Kampanye", + "challengesInfoText": "Dapatkan hadiah dengan menyelesaikan mini games.\n\nHadiah dan tingkat kesulitan level bertambah\nsetiap kali tantangan terselesaikan dan\nberkurang jika waktu habis atau menyerah.", "challengesText": "Tantangan", - "currentBestText": "Terbaik saat ini", + "currentBestText": "Terbaik Saat Ini", "customText": "Kustom", "entryFeeText": "Masuk", - "forfeitConfirmText": "Kehilangan tantangan ini??", - "forfeitNotAllowedYetText": "Tantangan ini belum dapat hiang", - "forfeitText": "Kehilangan", + "forfeitConfirmText": "Menyerah tantangan ini?", + "forfeitNotAllowedYetText": "Tantangan ini belum dapat menyerah.", + "forfeitText": "Menyerah", "multipliersText": "Kelipatan", - "nextChallengeText": "Tantangan berikutnya", - "nextPlayText": "Permainan berikutnya", - "ofTotalTimeText": "Dari ${TOTAL}", - "playNowText": "Main sekarang", + "nextChallengeText": "Tantangan Berikut", + "nextPlayText": "Permainan Berikut", + "ofTotalTimeText": "dari ${TOTAL}", + "playNowText": "Main Sekarang", "pointsText": "Poin", - "powerRankingFinishedSeasonUnrankedText": "(Sesi berakhir tidak terangking)", + "powerRankingFinishedSeasonUnrankedText": "(musim berakhir tak berperingkat)", "powerRankingNotInTopText": "(tidak di atas ${NUMBER})", "powerRankingPointsEqualsText": "= ${NUMBER} poin", "powerRankingPointsMultText": "(x ${NUMBER} poin)", "powerRankingPointsText": "${NUMBER} poin", "powerRankingPointsToRankedText": "(${CURRENT} dari ${REMAINING} poin)", - "powerRankingText": "Rangking power", + "powerRankingText": "Peringkat Kekuatan", "prizesText": "Hadiah", - "proMultInfoText": "Pemain dengan peningkatan ${PRO}\nmendapatkan sebuah ${PERCENT}% poin tambahan disini.", + "proMultInfoText": "Pemain dengan peningkatan ${PRO}\nmendapatkan sebuah ${PERCENT}% poin tambahan di sini.", "seeMoreText": "Lebih...", "skipWaitText": "Lewati Tunggu", - "timeRemainingText": "Waktu tersisa", - "toRankedText": "untuk Peringkat", + "timeRemainingText": "Waktu Tersisa", + "toRankedText": "Ke Peringkat", "totalText": "Total", - "tournamentInfoText": "Bersaing untuk skor tinggi dengan\npemain lain di liga Kamu.\n\nHadiah diberikan ke atas\npapan skor", - "welcome1Text": "Selamat datang di ${LEAGUE}.Kamu dapat tingkatkan \nranking liga dengan dapatkan peringkat berlian, selesaikan \npenghargaan dan menenangkan piala di turnamen", - "welcome2Text": "Kamu juga dapat mendapatkan tiket dari aktivitas yang sama.\nTiket dapat digunakan untuk membuka karakter baru, peta, dan\nmini games,untuk masuk liga, dan lainnya", + "tournamentInfoText": "Bersaing untuk skor tinggi dengan\npemain lain di liga kamu.\n\nHadiah diberikan pada pemain skor\ntertinggi ketika waktu turnamen berakhir.", + "welcome1Text": "Selamat datang di ${LEAGUE}. Kamu dapat meningkatkan \nperingkat liga dengan mendapatkan nilai berlian, selesaikan \npencapaian, dan menenangkan piala di turnamen.", + "welcome2Text": "Kamu juga bisa mendapatkan tiket dari aktivitas yang sama.\nTiket dapat digunakan untuk membuka karakter baru, peta, dan\nmini-games, untuk masuk turnamen, dan lainnya.", "yourPowerRankingText": "Peringkat Kekuatan Kamu:" }, "copyConfirmText": "Tersalin ke papan klip.", @@ -506,13 +527,13 @@ "createEditPlayerText": "", "createText": "Buat", "creditsWindow": { - "additionalAudioArtIdeasText": "Audio tambahan,Early Artwork, dan ide dari ${NAME}", - "additionalMusicFromText": "Musik Tambahan Dari ${NAME}", - "allMyFamilyText": "Semua teman saya dan keluarga saya yang menolong untuk memainkan test", - "codingGraphicsAudioText": "Koding, Grafik, Dan audio dari ${NAME}", - "languageTranslationsText": "Penerjemah bahasa:", + "additionalAudioArtIdeasText": "Audio Tambahan, Karya Seni Awal, dan Ide oleh ${NAME}", + "additionalMusicFromText": "Musik tambahan dari ${NAME}", + "allMyFamilyText": "Semua teman saya dan keluarga saya yang menolong untuk coba memainkan", + "codingGraphicsAudioText": "Koding, Grafik, Dan Audio oleh ${NAME}", + "languageTranslationsText": "Penerjemah Bahasa:", "legalText": "Legal:", - "publicDomainMusicViaText": "Musik publik dominan via ${NAME}", + "publicDomainMusicViaText": "Musik Domain Publik via ${NAME}", "softwareBasedOnText": "Software ini berasal dari bagian kerja dari ${NAME}", "songCreditText": "${TITLE} Dimainkan oleh ${PERFORMER}\nKomposisi oleh ${COMPOSER}, Aransemen oleh ${ARRANGER}, Publikasi oleh ${PUBLISHER},\nSumber dari ${SOURCE}", "soundAndMusicText": "Suara & Musik:", @@ -532,9 +553,9 @@ "runCPUBenchmarkText": "Menjalankan CPU Benchmark", "runGPUBenchmarkText": "Jalankan GPU Benchmark", "runMediaReloadBenchmarkText": "Menjalankan Media-Reload Benchmark", - "runStressTestText": "Menjalankan test stress", + "runStressTestText": "Menjalankan uji stres", "stressTestPlayerCountText": "Jumlah Pemain", - "stressTestPlaylistDescriptionText": "Daftar Putar Stres Tes", + "stressTestPlaylistDescriptionText": "Daftar Putar Uji Stres", "stressTestPlaylistNameText": "Nama Daftar Putar", "stressTestPlaylistTypeText": "Tipe Daftar Putar", "stressTestRoundDurationText": "Durasi Permainan", @@ -548,22 +569,27 @@ "demoText": "Demo", "denyText": "Tolak", "deprecatedText": "Usang", + "descriptionText": "Keterangan", "desktopResText": "Resolusi Desktop", "deviceAccountUpgradeText": "Peringatan:\nKamu masuk dengan akun perangkat (${NAME}).\nAkun perangkat akan dihilangkan pada pembaharuan yg akan datang.\nTingkatkan ke akun V2 jika kamu ingin pertahankan kemajuanmu.", "difficultyEasyText": "Mudah", "difficultyHardOnlyText": "Khusus Mode Sulit", "difficultyHardText": "Sulit", - "difficultyHardUnlockOnlyText": "Level ekspedisi ini khusus untuk mode sulit. \nKamu pikir kamu bisa!?!?!", - "directBrowserToURLText": "dimohon langsung ke web-browser untuk URL:", + "difficultyHardUnlockOnlyText": "Level ini hanya dapat dibuka di mode sulit. \nKamu pikir kamu bisa!?!?!", + "directBrowserToURLText": "Mohon langsung ke web-browser untuk URL:", "disableRemoteAppConnectionsText": "Matikan Koneksi App-Remot", - "disableXInputDescriptionText": "Izinkan lebih dari 4 pengontrol tapi mungkin agak lemot.", + "disableXInputDescriptionText": "Izinkan lebih dari 4 pengontrol tapi mungkin tidak bekerja dengan baik.", "disableXInputText": "Blokir XInput", + "disabledText": "Dimatikan", + "discardText": "Buang", + "discordFriendsText": "Ingin mencari teman baru untuk bermain?\nGabung ke Discord kami dan temukan teman baru!", + "discordJoinText": "Gabung ke Discord", "doneText": "Selesai", "drawText": "Seri", "duplicateText": "Duplikat", "editGameListWindow": { "addGameText": "Tambah\nPermainan", - "cantOverwriteDefaultText": "Tidak dapat mengubah daftar putar asal!", + "cantOverwriteDefaultText": "Tidak dapat menimpa daftar putar asal!", "cantSaveAlreadyExistsText": "Daftar Putar dengan nama ini sudah ada!", "cantSaveEmptyListText": "Tidak dapat menyimpan daftar putar kosong!", "editGameText": "Ubah\nPermainan", @@ -574,42 +600,43 @@ "titleText": "Penyusun Daftar Putar" }, "editProfileWindow": { - "accountProfileInfoText": "Profil spesial ini mengikuti nama\ndan ikon sesuai akun Kamu.\n\n${ICONS}\n\nBuat profil lain untuk menggunakan\nnama dan ikon yang berbeda.", - "accountProfileText": "(Profil Akun)", + "accountProfileInfoText": "Profil spesial ini mengikuti nama\ndan ikon sesuai akun kamu.\n\n${ICONS}\n\nBuat profil lain untuk menggunakan\nnama dan ikon yang berbeda.", + "accountProfileText": "(profil akun)", "availableText": "Nama ini \"${NAME}\" tersedia.", - "characterText": "Karakter", - "checkingAvailabilityText": "Memeriksa Ketersediaan \"${NAME}\"...", + "characterText": "karakter", + "checkingAvailabilityText": "Memeriksa ketersediaan \"${NAME}\"...", "colorText": "warna", - "getMoreCharactersText": "Dapatkan karakter lain...", - "getMoreIconsText": "Dapatkan ikon lain...", + "getMoreCharactersText": "Dapatkan Karakter Lain...", + "getMoreIconsText": "Dapatkan Ikon Lain...", "globalProfileInfoText": "Profil pemain global dijamin untuk memiliki nama unik\ndi seluruh dunia. Termasuk juga ikon lain.", - "globalProfileText": "(Profil Global)", + "globalProfileText": "(profil global)", "highlightText": "highlight", "iconText": "ikon", "localProfileInfoText": "Profile lokal tidak mempunyai ikon dan nama \ntidak terjamin unik. Tingkatkan ke profil global \nuntuk mendapatkan nama unik dan dapat menambahkan ikon kustom.", - "localProfileText": "(Profil lokal)", + "localProfileText": "(profil lokal)", "nameDescriptionText": "Nama Pemain", "nameText": "Nama", - "randomText": "Acak", + "profileAlreadyExistsText": "Profil dengan nama tersebut sudah ada.", + "randomText": "acak", "titleEditText": "Ubah Profil", "titleNewText": "Profil Baru", "unavailableText": "\"${NAME}\" tidak tersedia; coba nama lain.", - "upgradeProfileInfoText": "Ini akan jadi nama Kamu dalam game ini\ndan memungkinkan Kamu untuk menetapkan ikon kustom.", + "upgradeProfileInfoText": "Ini akan jadi nama kamu dalam game ini\ndan memungkinkan kamu untuk menetapkan ikon kustom.", "upgradeToGlobalProfileText": "Tingkatkan ke Profil Global" }, "editSoundtrackWindow": { "cantDeleteDefaultText": "Kamu tidak dapat menghapus soundtrack asal.", "cantEditDefaultText": "Tidak dapat mengubah soundtrack asal. Gandakan atau buat soundtrack baru.", - "cantOverwriteDefaultText": "tidak dapat menimpa soundtrack asal", - "cantSaveAlreadyExistsText": "Soundtrack dengan nama ini telah digunakan!", + "cantOverwriteDefaultText": "Tidak dapat menimpa soundtrack asal", + "cantSaveAlreadyExistsText": "Soundtrack dengan nama itu telah ada!", "defaultGameMusicText": "", "defaultSoundtrackNameText": "Soundtrack Asal", "deleteConfirmText": "Hapus Soundtrack:\n\n'${NAME}'?", "deleteText": "Hapus\nSoundtrack", - "duplicateText": "Gandakan\nSoundtrack", - "editSoundtrackText": "Pengaturan Soundtrack", + "duplicateText": "Duplikat\nSoundtrack", + "editSoundtrackText": "Editor Soundtrack", "editText": "Ubah\nSoundtrack", - "fetchingITunesText": "Mengambil playlist Music App...", + "fetchingITunesText": "mengambil daftar putar Apl. Musik...", "musicVolumeZeroWarning": "Perhatian: suara musik menjadi 0", "nameText": "Nama", "newSoundtrackNameText": "Soundtrack saya ${COUNT}", @@ -621,25 +648,28 @@ "titleText": "Soundtrack", "useDefaultGameMusicText": "Musik Game Asal", "useITunesPlaylistText": "Daftar Putar Apl. Musik", - "useMusicFileText": "Data Musik (mp3, dll)", - "useMusicFolderText": "berkas dari Data Musik" + "useMusicFileText": "File Musik (mp3, dll)", + "useMusicFolderText": "Berkas dari File Musik" }, "editText": "Edit", + "enabledText": "Dinyalakan", "endText": "Akhiri", "enjoyText": "Nikmati!", "epicDescriptionFilterText": "${DESCRIPTION} dalam slow-motion yang epik.", "epicNameFilterText": "${NAME} Epik", "errorAccessDeniedText": "akses ditolak", - "errorDeviceTimeIncorrectText": "Waktu di perangkatmu berbeda ${HOURS} jam.\nIni akan menyebabkan masalah.\nSilahkan cek pengaturan jam dan zona waktu anda.", + "errorDeviceTimeIncorrectText": "Waktu di perangkatmu berbeda ${HOURS} jam.\nIni akan menyebabkan masalah.\nSilahkan cek pengaturan jam dan zona waktu kamu.", "errorOutOfDiskSpaceText": "media penyimpanan tidak cukup", "errorSecureConnectionFailText": "Tidak bisa mendirikan koneksi aman; fungsi jaringan mungkin gagal.", "errorText": "Kesalahan!", "errorUnknownText": "kesalahan tak teridentifikasi", "exitGameText": "Keluar dari ${APP_NAME}?", - "exportSuccessText": "'${NAME}' TEREXPORT", + "expiredAgoText": "Kadaluarsa ${T} yang lalu", + "expiresInText": "Kadaluarsa dalam ${T}", + "exportSuccessText": "'${NAME}' terekspor.", "externalStorageText": "Penyimpanan Eksternal", "failText": "Gagal", - "fatalErrorText": "O-ow, sesuatu hilang atau rusak. \nCoba install ulang BombSquad atau kontak\n${EMAIL} untuk bantuan.", + "fatalErrorText": "O-ow, sesuatu hilang atau rusak.\nCoba pasang ulang BombSquad atau hubungi\n${EMAIL} untuk bantuan.", "fileSelectorWindow": { "titleFileFolderText": "Pilih File atau Folder", "titleFileText": "Ambil File", @@ -647,56 +677,59 @@ "useThisFolderButtonText": "Gunakan Folder" }, "filterText": "Filter", - "finalScoreText": "Skor Final", - "finalScoresText": "Skor Final", - "finalTimeText": "Waktu Final", - "finishingInstallText": "Selesai menginstall, tunggu sebentar...", - "fireTVRemoteWarningText": "* Untuk mempermudah, gunakan\npengontrol permainan atau pasang\naplikasi '${REMOTE_APP_NAME}'\ndi HP atau tabletmu.", - "firstToFinalText": "Final Pertama Mencapai ${COUNT}", - "firstToSeriesText": "Pertama Mencapai ${COUNT}", + "finalScoreText": "Skor Akhir", + "finalScoresText": "Skor Akhir", + "finalTimeText": "Waktu Akhir", + "finishingInstallText": "Selesai memasang; tunggu sebentar...", + "fireTVRemoteWarningText": "* Untuk pengalaman lebih baik, gunakan\npengontrol permainan atau pasang\naplikasi '${REMOTE_APP_NAME}'\ndi HP dan tabletmu.", + "firstToFinalText": "Pertama Mencapai ${COUNT} Akhir", + "firstToSeriesText": "Pertama Mencapai ${COUNT} Seri", "fiveKillText": "MATI LIMA!!", "flawlessWaveText": "Gelombang Mulus!", "fourKillText": "MATI EMPAT!!", "friendScoresUnavailableText": "Skor teman tidak tersedia.", "gameCenterText": "PusatGame", "gameCircleText": "LingkaranGame", - "gameLeadersText": "Pemimpin Game ${COUNT}", + "gameLeadersText": "Pemimpin ${COUNT} Permainan", "gameListWindow": { "cantDeleteDefaultText": "Kamu tidak dapat menghapus daftar putar asal.", "cantEditDefaultText": "Tidak dapat mengubah Daftar Putar asal! Gandakan atau buat baru.", - "cantShareDefaultText": "Kamu tidak dapat bagikan playlist semula", + "cantShareDefaultText": "Kamu tidak dapat bagikan playlist semula.", "deleteConfirmText": "Hapus \"${LIST}\"?", "deleteText": "Hapus\nDaftar Putar", - "duplicateText": "Gandakan\nDaftar Putar", + "duplicateText": "Duplikat\nDaftar Putar", "editText": "Ubah\nDaftar Putar", "newText": "Buat\nDaftar Putar", + "pointsToWinText": "Poin Untuk Menang", + "seriesLengthText": "Panjang Seri", "showTutorialText": "Lihat Panduan", "shuffleGameOrderText": "Acak Urutan Game", "titleText": "Ubah ${TYPE} Daftar Putar" }, "gameSettingsWindow": { - "addGameText": "Tambah Game" + "addGameText": "Tambah Permainan" }, - "gamesToText": "${WINCOUNT} menang lawan ${LOSECOUNT} menang", + "gamesToText": "${WINCOUNT} menang lawan ${LOSECOUNT}", "gatherWindow": { - "aboutDescriptionLocalMultiplayerExtraText": "Catatan: tiap perangkat dapat punya lebih dari\nsatu pemain jika memang ada pengontrol yang cukup.", - "aboutDescriptionText": "Gunakan tab ini untuk mengadakan acara.\n\nDengan adanya acara, Kamu dapat bermain\ndengan teman di perangkat yang berbeda.\n\nGunakan tombol ${PARTY} di kanan atas\nuntuk chat dan berinteraksi di acara. \n(pada pengontrol, tekan ${BUTTON} saat di menu)", - "aboutText": "Perihal", + "aboutDescriptionLocalMultiplayerExtraText": "Ingat: tiap perangkat dalam acara dapat punya lebih\ndari satu pemain jika memang ada pengontrol yang cukup.", + "aboutDescriptionText": "Gunakan tab ini untuk mengadakan acara.\n\nDengan adanya acara, kamu dapat bermain\ndengan teman di perangkat yang berbeda.\n\nGunakan tombol ${PARTY} di kanan atas\nuntuk chat dan berinteraksi di acara. \n(pada pengontrol, tekan ${BUTTON} saat di menu)", + "aboutText": "Tentang", "addressFetchErrorText": "", "appInviteMessageText": "${NAME} mengirim ${COUNT} tiket ke ${APP_NAME}", "appInviteSendACodeText": "Kirimkan Kode", "appInviteTitleText": "Undangan Aplikasi ${APP_NAME}", - "bluetoothAndroidSupportText": "(bekerja dengan semua Android yang punya Bluetooth)", + "bluetoothAndroidSupportText": "(bekerja dengan semua Android yang mendukung Bluetooth)", "bluetoothDescriptionText": "Buat/ikut acara lewat Bluetooth:", - "bluetoothHostText": "Adakan acara!", - "bluetoothJoinText": "Ikut acara!", + "bluetoothHostText": "Adakan acara lewat Bluetooth", + "bluetoothJoinText": "Ikut acara lewat Bluetooth", "bluetoothText": "Bluetooth", "checkingText": "memeriksa...", "copyCodeConfirmText": "Kode disalin ke papan klip.", "copyCodeText": "Salin Kode", - "dedicatedServerInfoText": "Untuk hasil terbaik, buatlah server yang bagus. Lihat bombsquadgame.com/server untuk membuatnya", + "dedicatedServerInfoText": "Untuk hasil terbaik, buatlah server khusus. Lihat bombsquadgame.com/server untuk mempelajari caranya.", + "descriptionShortText": "Gunakan jendela bersama untuk mengadakan pesta.", "disconnectClientsText": "Ini akan memutuskan sambungan ${COUNT} pemain\ndi acaramu. Apa kamu yakin?", - "earnTicketsForRecommendingAmountText": "Teman Kamu akan mendapatkan ${COUNT} tiket jika mereka memainkan game ini\n(dan Kamu akan mendapatkan ${YOU_COUNT} untuk setiap mereka memainkan game ini)", + "earnTicketsForRecommendingAmountText": "Teman akan mendapatkan ${COUNT} tiket jika mereka memainkan game ini\n(dan kamu akan mendapatkan ${YOU_COUNT} untuk setiap mereka yang bermain)", "earnTicketsForRecommendingText": "Bagikan permainan\nuntuk tiket gratis...", "emailItText": "Lewat Surel", "favoritesSaveText": "Simpan Sebagai Favorit", @@ -707,41 +740,42 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tiket dari ${NAME}", "friendPromoCodeAwardText": "Kamu akan mendapatkan ${COUNT} tiket setiap kode ini digunakan.", "friendPromoCodeExpireText": "kode ini akan berakhir dalam ${EXPIRE_HOURS} jam dan hanya berlaku untuk pemain baru.", - "friendPromoCodeInstructionsText": "Untuk menggunakannya, buka ${APP_NAME} dan buka \"Pengaturan-> Lanjutan-> Masukkan Kode\".\nLihat bombsquadgame.com untuk tautan unduhan untuk semua platform yang didukung.", - "friendPromoCodeRedeemLongText": "ini dapat digunakan untuk ${COUNT} tiket gratis hingga batas maksimal ${MAX_USES} orang.", - "friendPromoCodeRedeemShortText": "ini dapat digunkanan untuk mendapatkan ${COUNT} tiket.", - "friendPromoCodeWhereToEnterText": "(di \"Pengaturan-> Lanjutan-> Masukkan Kode\")", + "friendPromoCodeInstructionsText": "Untuk menggunakan, buka ${APP_NAME} dan pergi ke \"Pengaturan->Lanjutan->Kirim Info\".\nKunjungi bombsquadgame.com untuk link unduhan untuk semua platform yang didukung.", + "friendPromoCodeRedeemLongText": "Ini dapat ditukarkan untuk ${COUNT} tiket gratis hingga batas maksimal ${MAX_USES} orang.", + "friendPromoCodeRedeemShortText": "Ini dapat ditukarkan untuk ${COUNT} tiket dalam permainan.", + "friendPromoCodeWhereToEnterText": "(di \"Pengaturan->Lanjutan->Kirim Info\")", "getFriendInviteCodeText": "Dapatkan Kode Undangan Teman", "googlePlayDescriptionText": "Undang pemain Google Play ke acaramu:", "googlePlayInviteText": "Undang", - "googlePlayReInviteText": "Ada ${COUNT} pemain Google Play di acaramu\nyang akan terputus jika Kamu undang ulang. \nJangan lupa masukan mereka ke undangan.", + "googlePlayReInviteText": "Ada ${COUNT} pemain Google Play di acaramu\nyang akan terputus jika kamu undang ulang. \nMasukkan mereka ke undangan baru untuk mengundang mereka lagi.", "googlePlaySeeInvitesText": "Lihat Undangan", "googlePlayText": "Google Play", "googlePlayVersionOnlyText": "(versi Android / Google Play)", - "hostPublicPartyDescriptionText": "Selenggarakan Acara Publik", + "hostPublicPartyDescriptionText": "Buat Acara Publik", "hostingUnavailableText": "Hosting Tidak Tersedia", - "inDevelopmentWarningText": "Catatan:\n\nBermain dalam jaringan masih baru dan dalam\nperkembangan. Sementara, sangat disarankan para\npemain ada di jaringan Wi-Fi yang sama.", + "inDevelopmentWarningText": "Catatan:\n\nBermain dalam jaringan masih baru dan dalam\npengembangan. Untuk sekarang, sangat disarankan para\npemain ada di jaringan Wi-Fi yang sama.", "internetText": "Internet", - "inviteAFriendText": "Teman Kamu belum memainkan ini? undang mereka sekarang\ndan mereka akan mendapatkan ${COUNT} tiket gratis.", + "inviteAFriendText": "Temanmu belum memiliki permainan? Undang mereka untuk\nmencoba dan mereka akan mendapatkan ${COUNT} tiket gratis.", "inviteFriendsText": "Undang Teman", "joinPublicPartyDescriptionText": "Gabung dengan Acara Publik", "localNetworkDescriptionText": "Bergabunglah dengan Acara Terdekat (LAN, Bluetooth, dll.)", "localNetworkText": "Jaringan Lokal", - "makePartyPrivateText": "Buat acaraku pribadi", - "makePartyPublicText": "Buat acaraku publik", + "makePartyPrivateText": "Buat Acaraku Pribadi", + "makePartyPublicText": "Buat Acaraku Publik", "manualAddressText": "Alamat", "manualConnectText": "Hubungkan", "manualDescriptionText": "Ikut acara di alamat:", "manualJoinSectionText": "Gabung Berdasarkan Alamat", - "manualJoinableFromInternetText": "Apakah Kamu dapat bergabung internet?:", + "manualJoinableFromInternetText": "Apakah kamu dapat bergabung dari internet?:", "manualJoinableNoWithAsteriskText": "TIDAK*", "manualJoinableYesText": "YA", - "manualRouterForwardingText": "*untuk memperbaiki, coba dengan mengkonfigurasi router ke UDP port ${PORT} ke alamat lokal Kamu", + "manualRouterForwardingText": "*untuk memperbaiki, coba dengan mengkonfigurasi router forward ke UDP port ${PORT} ke alamat lokal kamu", "manualText": "Manual", - "manualYourAddressFromInternetText": "Alamat Kamu dari internet:", - "manualYourLocalAddressText": "Alamat lokal Kamu:", - "nearbyText": "Dekat", + "manualYourAddressFromInternetText": "Alamat kamu dari internet:", + "manualYourLocalAddressText": "Alamat lokal kamu:", + "nearbyText": "Terdekat", "noConnectionText": "", + "noPartiesAddedText": "Tidak ada Acara yang Ditambahkan", "otherVersionsText": "(Versi lain)", "partyCodeText": "Kode Acara", "partyInviteAcceptText": "Terima", @@ -749,15 +783,15 @@ "partyInviteGooglePlayExtraText": "(Lihat tab 'Google Play' di jendela 'Berkumpul')", "partyInviteIgnoreText": "Abaikan", "partyInviteText": "${NAME} mengundangmu\nke acaranya!", - "partyNameText": "Nama acara", + "partyNameText": "Nama Acara", "partyServerRunningText": "Server acara Anda sedang berjalan.", "partySizeText": "ukuran acara", "partyStatusCheckingText": "memeriksa status...", "partyStatusJoinableText": "sekarang orang lain dapat gabung ke acaramu dari internet", - "partyStatusNoConnectionText": "Tidak dapat terhubung ke server", - "partyStatusNotJoinableText": "orang lain gak dapat gabung ke acaramu lewat internet", + "partyStatusNoConnectionText": "tidak dapat terhubung ke server", + "partyStatusNotJoinableText": "orang lain tidak dapat gabung ke acaramu lewat internet", "partyStatusNotPublicText": "acaramu bukan acara publik", - "pingText": "Ping", + "pingText": "ping", "portText": "Port", "privatePartyCloudDescriptionText": "Acara pribadi dijalankan di server cloud khusus; tidak diperlukan konfigurasi router.", "privatePartyHostText": "Adakan Acara Pribadi", @@ -767,20 +801,20 @@ "publicText": "Publik", "requestingAPromoCodeText": "Memesan Kode...", "sendDirectInvitesText": "Kirim Undangan", - "shareThisCodeWithFriendsText": "Bagikan kode ini ke teman-teman mu!", + "shareThisCodeWithFriendsText": "Bagikan kode ini ke teman-teman mu:", "showMyAddressText": "Tunjukkan Alamatku", "startHostingPaidText": "Host Sekarang Dengan ${COST}", "startHostingText": "Host", "startStopHostingMinutesText": "Anda dapat memulai dan menghentikan hosting gratis untuk ${MINUTES} menit berikutnya.", "stopHostingText": "Hentikan Hosting", "titleText": "Gabung", - "wifiDirectDescriptionBottomText": "Jika semua perangkat punya tab 'Wi-Fi Direct', maka seharusnya semua dapat saling\nkoneksi. Ketika sudah konek semua, buat team\ndi tab 'Jaringan Lokal', seperti Wi-Fi biasa.\n\nUntuk hasil maksimal, host Wi-Fi Direct juga harus sebagai host team di ${APP_NAME}.", - "wifiDirectDescriptionTopText": "Wi-Fi Direct dapat digunakan untuk koneksi Android tanpa hotspot.\nBekerja paling bagus pada Android 4.2 lebih.\n\nUntuk itu, buka Pengaturan Wi-Fi dan pilih 'Wi-Fi Direct' di menu.", + "wifiDirectDescriptionBottomText": "Jika semua perangkat punya 'Wi-Fi Direct' panel, mereka seharusnya bisa menggunakannya\nuntuk mencari dan terhubung satu sama lain. Ketika semua perangkat telah terhubung, kamu dapat\nbuat acara di sini menggunakan tab 'Jaringan Lokal', sama seperti dengan jaringan Wi-Fi biasa.\n\nUntuk hasil maksimal, host Wi-Fi Direct juga harus sebagai host acara di ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct dapat digunakan untuk koneksi Android tanpa hotspot.\nBekerja paling bagus pada Android 4.2 atau lebih baru.\n\nUntuk itu, buka Pengaturan Wi-Fi dan pilih 'Wi-Fi Direct' di menu.", "wifiDirectOpenWiFiSettingsText": "Buka Pengaturan Wi-Fi", "wifiDirectText": "Wi-Fi Direct", "worksBetweenAllPlatformsText": "(bekerja antar platform)", - "worksWithGooglePlayDevicesText": "(bekerja antar perangkat yang menggunakan versi Android)", - "youHaveBeenSentAPromoCodeText": "Kamu telah mengirim sebuah kode promo ${APP_NAME}!" + "worksWithGooglePlayDevicesText": "(bekerja antar perangkat yang menggunakan versi Android) ", + "youHaveBeenSentAPromoCodeText": "Kamu telah mengirim sebuah ${APP_NAME} kode promo:" }, "getTicketsWindow": { "freeText": "Gratis!", @@ -796,27 +830,35 @@ "ticketPack5Text": "Paket Tiket Raksasa", "ticketPack6Text": "Paket Tiket Berlimpah", "ticketsFromASponsorText": "Tonton iklan\nuntuk ${COUNT} tiket", - "ticketsText": "${COUNT} tiket", + "ticketsText": "${COUNT} Tiket", "titleText": "Dapatkan Tiket", "unavailableLinkAccountText": "Maaf, pembelian tidak dapat dilakukan di perangkat ini.\nsebagai antisipasi, kamu dapat menautkan akun ini ke perangkat\nlain dan melakukan pembelian di sana.", - "unavailableTemporarilyText": "mohon maaf, saat ini layanan tidak tersedia; mohon dicoba lagi lain waktu.", + "unavailableTemporarilyText": "Mohon maaf, saat ini layanan tidak tersedia; mohon dicoba lagi lain waktu.", "unavailableText": "Maaf, tidak tersedia.", "versionTooOldText": "Maaf, versi permainan ini terlalu usang; silahkan perbaharui dengan yang terbaru.", "youHaveShortText": "kamu memiliki ${COUNT}", "youHaveText": "kamu memiliki ${COUNT} tiket" }, + "goldPass": { + "desc1InfTokensText": "Token tidak terbatas.", + "desc2NoAdsText": "Tidak ada iklan.", + "desc3ForeverText": "Selamanya.", + "goldPassText": "Tiket Emas" + }, "googleMultiplayerDiscontinuedText": "Maaf, Google's multiplayer service tidak lagi tersedia.\nSaya sedang bekerja pada penggantian secepat mungkin.\nHingga saat itu, silakan coba metode koneksi lainnya.\n-Eric", - "googlePlayPurchasesNotAvailableText": "Pembayaran Google Play tidak tersedia.\nMungkin perlu memperbaharui Playstore anda.", + "googlePlayPurchasesNotAvailableText": "Pembayaran Google Play tidak tersedia.\nKamu perlu memperbaharui apl. Store mu.", "googlePlayServicesNotAvailableText": "Layanan Google Play tidak tersedia.\nBeberapa fungsi dari aplikasi mungkin padam.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Selalu", "fullScreenCmdText": "Layar Penuh (Cmd-F)", "fullScreenCtrlText": "Layar Penuh (Ctrl+F)", + "fullScreenText": "Layar Penuh", "gammaText": "Gamma", "highText": "Tinggi", "higherText": "Tertinggi", "lowText": "Rendah", + "maxFPSText": "FPS Maks", "mediumText": "Sedang", "neverText": "Tak Pernah", "resolutionText": "Resolusi", @@ -828,42 +870,43 @@ "visualsText": "Visual" }, "helpWindow": { - "bombInfoText": "- Bomb -\nLebih kuat dari Tinju, tapi\ndapat menjadi bom bunuh diri.\nCoba untuk melempar sebelum\nsumbu akan habis.", - "canHelpText": "${APP_NAME} Solusinya!", - "controllersInfoText": "Kamu dapat bermain ${APP_NAME} dengan temanmu melalui sebuah\nJaringan, atau kamu dapat bermain dalam perangkat yang sama\njika kamu memiliki kontrol yang cukup. ${APP_NAME} menyediakan\npengontrol digital melalui aplikasi '${REMOTE_APP_NAME}'.\nlihat di Pengaturan -> Kontrol untuk info lebih lanjut.", - "controllersInfoTextRemoteOnly": "Anda bisa bermain ${APP_NAME} bersama dengan teman melalui jaringan, \natau kalian semua bisa bermain di perangkat yang sama dengan menggunakan ponsel sebagai pengontrol melalui aplikasi \n'${REMOTE_APP_NAME}' gratis.", - "controllersText": "Kontrol", - "controlsSubtitleText": "karakter ${APP_NAME} Memiliki beberapa gerakan dasar:", + "bombInfoText": "- Bomb -\nLebih kuat dari Tinju, tapi\ndapat menjadi bom bunuh diri.\nCoba untuk melempar sebelum\nsumbunya habis.", + "bombInfoTextScale": 0.5, + "canHelpText": "${APP_NAME} dapat menolong!", + "controllersInfoText": "Kamu dapat bermain ${APP_NAME} dengan temanmu melalui sebuah jaringan, atau kamu \ndapat bermain dalam perangkat yang sama jika kamu memiliki pengontrol yang cukup.\n${APP_NAME} mendukung berbagai macam pengontrol; kamu bahkan dapat menggunakan ponsel \nsebagai pengontrol melalui apl. gratis '${REMOTE_APP_NAME}'.\nLihat di Pengaturan->Pengontrol untuk info lebih lanjut.", + "controllersInfoTextRemoteOnly": "Kamu bisa bermain ${APP_NAME} bersama dengan teman melalui jaringan, atau kalian\nsemua bisa bermain di perangkat yang sama dengan menggunakan ponsel sebagai \npengontrol melalui aplikasi '${REMOTE_APP_NAME}' gratis.", + "controllersText": "Pengontrol", + "controlsSubtitleText": "Karakter bersahabatmu ${APP_NAME} memiliki beberapa gerakan dasar:", "controlsText": "Kontrol", - "devicesInfoText": "Versi VR dari ${APP_NAME} dapat dimainkan lewat jaringan dengan\nversi reguler. Jadi siapkan ponsel, Tablet atau Komputermu\ndan Mainkan Game ini! Fitur ini juga dapat menjadi menyenangkan\ndengan cara mengizinkan orang lain melihat permainan Kamu saat\nmenggunakan VR!", + "devicesInfoText": "Versi VR dari ${APP_NAME} dapat dimainkan lewat jaringan dengan\nversi reguler. Jadi siapkan ponsel, Tablet, dan Komputermu\ndan mainkan game ini. Fitur ini juga dapat menjadi menyenangkan\ndengan cara mengizinkan orang lain melihat permainan kamu saat\nmenggunakan VR!", "devicesText": "Perangkat", - "friendsGoodText": "Sangat diperlukan. ${APP_NAME} Sangat menyenangkan dengan beberapa\npemain (maksimal 8 pemain) dalam sekali permainan.", + "friendsGoodText": "Sangat diperlukan. ${APP_NAME} sangat menyenangkan dengan beberapa\npemain (maksimal 8 pemain) dalam sekali permainan.", "friendsText": "Teman", - "jumpInfoText": "- Lompat -\nLompat untuk melewati gundukan,\nmelempar lebih jauh, dan\nmengekspresikan kebehagiaan Kamu.", + "jumpInfoText": "- Lompat -\nLompat untuk melewati celah,\nmelempar lebih jauh, dan\nmengekspresikan kebehagiaan kamu.", "orPunchingSomethingText": "Atau menghajar sesuatu, melemparnya ke Jurang, dan meledakannya dengan beberapa bom mematikan.", "pickUpInfoText": "- Angkat -\nMengangkat Bendera, Musuh, atau\napapun yang tidak melekat di tanah.\nTekan sekali lagi untuk melempar.", - "powerupBombDescriptionText": "Memberikan Kamu 3 bom sekaligus.\nLebih baik dari pada 1.", + "powerupBombDescriptionText": "Memberikan kamu 3 bom sekaligus\nlebih baik dari pada satu.", "powerupBombNameText": "Bomb Beruntun", "powerupCurseDescriptionText": "Hindari ini segera jika kamu \ntidak ingin mati!", "powerupCurseNameText": "Kutukan", - "powerupHealthDescriptionText": "Mengembalikan darah Kamu\nseperti semula.", + "powerupHealthDescriptionText": "Mengembalikan darah kamu\nseperti semula.", "powerupHealthNameText": "Kotak Medis", - "powerupIceBombsDescriptionText": "Lebih lemah dari bom biasa\ntapi membuat musuh Kamu beku,\npanik, gelisah, dan rapuh.", + "powerupIceBombsDescriptionText": "Lebih lemah dari bom biasa\ntapi membuat musuh kamu beku,\ndan rapuh.", "powerupIceBombsNameText": "Bom Beku", "powerupImpactBombsDescriptionText": "Sedikit lebih lemah dari bom\nbiasa, tapi akan meledak saat terbentur.", "powerupImpactBombsNameText": "Bom Pemicu", - "powerupLandMinesDescriptionText": "berisi 3 paket; berguna untuk\nbertahan atau menghentikan\nlangkah musuhmu.", + "powerupLandMinesDescriptionText": "Berisi 3 paket; Berguna untuk\nbertahan atau menghentikan\nlangkah musuhmu.", "powerupLandMinesNameText": "Ranjau", "powerupPunchDescriptionText": "Membuat tinjumu lebih kuat,\nlebih cepat, bahkan lebih baik.", "powerupPunchNameText": "Sarung Tinju", - "powerupShieldDescriptionText": "menahan beberapa serangan\nsehingga darah Kamu tidak berkurang.", + "powerupShieldDescriptionText": "Menahan beberapa serangan\nsehingga darah kamu tidak berkurang.", "powerupShieldNameText": "Energi Pelindung", "powerupStickyBombsDescriptionText": "Lengket ke apapun yang tersentuh.\nSungguh Menjijikkan.", "powerupStickyBombsNameText": "Bom Lengket", "powerupsSubtitleText": "Jelas sekali, tidak ada game yang bakal seru tanpa Kekuatan Tambahan:", "powerupsText": "Kekuatan Tambahan", - "punchInfoText": "- Tinju -\nTinju lebih merusak saat\nKamu bergerak cepat. Jadi lari\ndan berputarlah seperti orang gila.", - "runInfoText": "- Lari -\nSEMUA tombol dapat digunakan untuk lari. Kecuali tombol pusar Kamu, haha. Lari\ndapat membuat Kamu cepat tapi sulit untuk berbelok, jadi hati-hati dengan jurang.", + "punchInfoText": "- Tinju -\nTinju lebih merusak saat\nkamu bergerak cepat. Jadi lari\ndan berputarlah seperti orang gila.", + "runInfoText": "- Lari -\nSEMUA tombol dapat digunakan untuk lari. Lari dapat membuat kamu cepat tapi\nsulit untuk berbelok, jadi hati-hati dengan jurang.", "someDaysText": "Terkadang, kamu ingin sekali menghajar sesuatu atau menghancurkan sesuatu.", "titleText": "Bantuan ${APP_NAME}", "toGetTheMostText": "Untuk menikmati game ini, kamu perlu menyiapkan:", @@ -872,71 +915,74 @@ "holdAnyButtonText": "", "holdAnyKeyText": "", "hostIsNavigatingMenusText": "- ${HOST} sedang merenung untuk memilih menu -", - "importPlaylistCodeInstructionsText": "Masukan kode untuk mengimpor playlist :", + "importPlaylistCodeInstructionsText": "Masukan kode untuk mengimpor daftar putar:", "importPlaylistSuccessText": "Terimpor ${TYPE} daftar putar '${NAME}'", "importText": "Impor", "importingText": "Mengimpor...", "inGameClippedNameText": "dalam game akan\n\"${NAME}\"", - "installDiskSpaceErrorText": "ERROR: Gagal menginstall. \nMungkin penyimpanan Kamu terlalu penuh. \nMohon hapus beberapa file dan coba lagi.", + "inboxText": "Kotak Masuk", + "installDiskSpaceErrorText": "KESALAHAN: Gagal memasang. \nMungkin penyimpanan kamu terlalu penuh. \nMohon hapus beberapa file dan coba lagi.", "internal": { "arrowsToExitListText": "tekan ${LEFT} atau ${RIGHT} untuk keluar", - "buttonText": "Tombol", - "cantKickHostError": "Kamu tak dapat mengeluarkan host", + "buttonText": "tombol", + "cantKickHostError": "Kamu tak dapat mengeluarkan host.", "chatBlockedText": "${NAME} di blokir chatnya selama ${TIME} detik.", "connectedToGameText": "'${NAME}' Bergabung", "connectedToPartyText": "Bergabung ke team ${NAME}!", "connectingToPartyText": "Menyambung...", - "connectionFailedHostAlreadyInPartyText": "Sambungan Gagal, Host sedang dalam team lain.", + "connectionFailedHostAlreadyInPartyText": "Sambungan gagal; host sedang dalam team lain.", "connectionFailedPartyFullText": "Koneksi gagal; acara sudah penuh", "connectionFailedText": "Gagal Menghubungkan.", - "connectionFailedVersionMismatchText": "Gagal menghubungkan; Host sedang menjalankan versi lain dari game ini.\nPastikan kamu memperbarui game lalu coba lagi.", + "connectionFailedVersionMismatchText": "Gagal menghubungkan; host sedang menjalankan versi lain dari game ini.\nPastikan kalian berdua sudah memperbaharui lalu coba lagi.", "connectionRejectedText": "Sambungan ditolak.", "controllerConnectedText": "${CONTROLLER} tersambung.", "controllerDetectedText": "1 pengontrol terdeteksi.", "controllerDisconnectedText": "${CONTROLLER} terputus.", "controllerDisconnectedTryAgainText": "${CONTROLLER} terputus. Silahkan menghubungkan kembali.", - "controllerForMenusOnlyText": "Pengontrol ini tidak dapat digunakan untuk bermain, hanya untuk memilih menu.", + "controllerForMenusOnlyText": "Pengontrol ini tidak dapat digunakan untuk bermain; hanya untuk memilih menu.", "controllerReconnectedText": "${CONTROLLER} terhubung kembali.", "controllersConnectedText": "${COUNT} pengontrol terhubung.", "controllersDetectedText": "${COUNT} pengontrol terdeteksi.", "controllersDisconnectedText": "${COUNT} pengontrol terputus.", - "corruptFileText": "Data rusak terdeteksi. dimohon untuk pasang ulang, atau kirimkan surel ke ${EMAIL}", + "corruptFileText": "Data rusak terdeteksi. Mohon untuk pasang ulang, atau kirimkan surel ke ${EMAIL}", "errorPlayingMusicText": "Gagal memutar musik: ${MUSIC}", - "errorResettingAchievementsText": "Tidak dapat mengulang Online Achievments; dimohon coba lagi.", + "errorResettingAchievementsText": "Tidak dapat mengulang pencapaian online; mohon coba lagi lain waktu.", "hasMenuControlText": "${NAME} mempunyai kendali menu.", "incompatibleNewerVersionHostText": "Host menggunakan versi baru dari game ini\nSilakan perbarui dan coba lagi", - "incompatibleVersionHostText": "Host berjalan dengan versi yang berbeda dengan game.\nPastikan Kamu up-to-date dan coba lagi", + "incompatibleVersionHostText": "Host berjalan dengan versi yang berbeda dengan game.\nPastikan kalian berdua memperbaharui dan coba lagi.", "incompatibleVersionPlayerText": "${NAME} menjalankan versi game yang berbeda.\nPastikan versi game kalian sama dan coba lagi.", - "invalidAddressErrorText": "Error: alamat tidak jelas.", - "invalidNameErrorText": "Error: nama tidak jelas.", - "invalidPortErrorText": "Error: port tidak jelas.", + "invalidAddressErrorText": "Kesalahan: alamat tidak jelas.", + "invalidNameErrorText": "Kesalahan: nama tidak jelas.", + "invalidPortErrorText": "Kesalahan: port tidak jelas.", "invitationSentText": "Undangan terkirim.", "invitationsSentText": "${COUNT} undangan terkirim.", "joinedPartyInstructionsText": "Seseorang bergabung di acaramu.\nTekan 'Main' untuk mulai permainan.", "keyboardText": "Keyboard", - "kickIdlePlayersKickedText": "Mengeluarkan ${NAME} karena diam.", - "kickIdlePlayersWarning1Text": "${NAME} akan dikeluarkan dalam ${COUNT} detik jika masih diam.", - "kickIdlePlayersWarning2Text": "(Kamu dapat mematikan ini di Pengaturan -> Lanjutan)", + "kickIdlePlayersKickedText": "Mengeluarkan ${NAME} karena nganggur.", + "kickIdlePlayersWarning1Text": "${NAME} akan dikeluarkan dalam ${COUNT} detik jika masih nganggur.", + "kickIdlePlayersWarning2Text": "(kamu dapat mematikan ini di Pengaturan -> Lanjutan)", "leftGameText": "Keluar '${NAME}'.", "leftPartyText": "Keluar dari acara ${NAME}'", "noMusicFilesInFolderText": "Folder tidak memiliki file musik.", "playerJoinedPartyText": "${NAME} bergabung ke acara!", "playerLeftPartyText": "${NAME} keluar dari acara.", "rejectingInviteAlreadyInPartyText": "Membatalkan undangan (sudah ada di acara).", - "serverRestartingText": "Memulai ulang. Silakan masuk dalam beberapa saat lagi", + "serverRestartingText": "Server memulai ulang. Silahkan gabung dalam beberapa saat lagi...", "serverShuttingDownText": "Server sedang menutup...", - "signInErrorText": "Gagal masuk", + "signInErrorText": "Gagal masuk.", "signInNoConnectionText": "Gagal masuk. (apa jaringanmu tidak terkoneksi internet?)", - "telnetAccessDeniedText": "ERROR: pengguna tidak mengizinkan akses telnet.", + "telnetAccessDeniedText": "KESALAHAN: pengguna tidak mengizinkan akses telnet.", "timeOutText": "(waktu akan habis dalam ${TIME} detik lagi)", - "touchScreenJoinWarningText": "Kamu telah bergabung dengan layar sentuh.\nJika ini kesalahan. tekan 'Menu->Mode Penonton' saja", + "touchScreenJoinWarningText": "Kamu telah bergabung dengan layar sentuh.\nJika ini kesalahan, tekan 'Menu->Tinggalkan Permainan' dengan itu.", "touchScreenText": "Layar Sentuh", - "unableToResolveHostText": "Error:Tidak dapat menyambung pada server", + "unableToCompleteTryAgainText": "Tidak dapat menyelesaikannya saat ini.\nSilakan coba lagi.", + "unableToResolveHostText": "Kesalahan: tidak dapat menyambung pada server.", "unavailableNoConnectionText": "Maaf, layanan tidak tersedia (apa jaringanmu tidak terkoneksi internet?)", - "vrOrientationResetCardboardText": "Gunakan ini untuk mengulang orientasi VR.\nUntuk memainkan game ini Kamu harus mempunyai kontroller eksternal.", - "vrOrientationResetText": "Atur ulang orientasi VR", - "willTimeOutText": "(waktu habis jika diam)" + "vrOrientationResetCardboardText": "Gunakan ini untuk mengulang orientasi VR.\nUntuk memainkan game ini kamu harus mempunyai pengontrol eksternal.", + "vrOrientationResetText": "Atur ulang orientasi VR.", + "willTimeOutText": "(waktu habis jika nganggur)" }, + "inventoryText": "Inventaris", "jumpBoldText": "LOMPAT", "jumpText": "Lompat", "keepText": "Simpan", @@ -947,13 +993,13 @@ "kickOccurredText": "${NAME} dikeluarkan.", "kickQuestionText": "Keluarkan ${NAME}?", "kickText": "Keluarkan", - "kickVoteCantKickAdminsText": "Admin tidak dapat dikeluarkan", - "kickVoteCantKickSelfText": "Kamu tidak dapat mengeluarkan dirimu sendiri", + "kickVoteCantKickAdminsText": "Admin tidak dapat dikeluarkan.", + "kickVoteCantKickSelfText": "Kamu tidak dapat mengeluarkan dirimu sendiri.", "kickVoteFailedNotEnoughVotersText": "Tidak cukup pemain untuk pengambilan suara.", - "kickVoteFailedText": "Pengambilan suara untuk mengeluarkan pemain gagal", + "kickVoteFailedText": "Pengambilan suara untuk mengeluarkan pemain gagal.", "kickVoteStartedText": "Pengambilan suara untuk mengeluarkan ${NAME} sudah dimulai.", - "kickVoteText": "Tentukan suara untuk mengeluarkan", - "kickVotingDisabledText": "Pengambilan suara untuk mengeluarkan pemain di nonaktifkan", + "kickVoteText": "Tentukan Suara untuk Mengeluarkan", + "kickVotingDisabledText": "Pengambilan suara untuk mengeluarkan pemain di nonaktifkan.", "kickWithChatText": "Ketik ${YES} di kolom obrolan jika setuju dan ${NO} jika tidak setuju.", "killsTallyText": "${COUNT} pembunuhan", "killsText": "Pembunuhan", @@ -963,12 +1009,12 @@ "fullMenuText": "Semua Menu", "hardText": "Sulit", "mediumText": "Sedang", - "singlePlayerExamplesText": "Coontoh Main Sendiri / Berteman", + "singlePlayerExamplesText": "Satu Pemain / Contoh Mabar", "versusExamplesText": "Contoh Versus" }, - "languageSetText": "Bahasa yang sedang digunakan adalah \"${LANGUAGE}\".", + "languageSetText": "Bahasa saat ini adalah \"${LANGUAGE}\".", "lapNumberText": "Putaran ${CURRENT}/${TOTAL}", - "lastGamesText": "(${COUNT} game terakhir)", + "lastGamesText": "(${COUNT} permainan terakhir)", "leaderboardsText": "Papan Juara", "league": { "allTimeText": "Keseluruhan", @@ -977,28 +1023,31 @@ "leagueRankText": "Peringkat Liga", "leagueText": "Liga", "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", - "seasonEndedDaysAgoText": "Musim berakhir ${NUMBER} hari yang lalu", - "seasonEndsDaysText": "Musim berakhir ${NUMBER} hari lagi", - "seasonEndsHoursText": "Musim berakhir ${NUMBER} jam lagi", + "seasonEndedDaysAgoText": "Musim berakhir ${NUMBER} hari yang lalu.", + "seasonEndsDaysText": "Musim berakhir ${NUMBER} hari lagi.", + "seasonEndsHoursText": "Musim berakhir ${NUMBER} jam lagi.", "seasonEndsMinutesText": "Musim berakhir ${NUMBER} menit lagi", "seasonText": "Musim ${NUMBER}", - "tournamentLeagueText": "Kamu harus berada di liga ${NAME} untuk memasukinya", - "trophyCountsResetText": "Hitungan trofimu akan diulang di musim berikutnya" + "tournamentLeagueText": "Kamu harus berada di liga ${NAME} untuk memasuki turnamen ini.", + "trophyCountsResetText": "Hitungan trofimu akan diulang di musim berikutnya.", + "upToDateBonusDescriptionText": "Pemain yang menjalankan versi terbaru\npermainan menerima bonus ${PERCENT}% di sini.", + "upToDateBonusText": "Bonus Terkini" }, + "learnMoreText": "Pelajari Lebih Lanjut", "levelBestScoresText": "Skor terbaik di ${LEVEL}", "levelBestTimesText": "Waktu terbaik di ${LEVEL}", "levelFastestTimesText": "Waktu tercepat pada ${LEVEL}", "levelHighestScoresText": "Skor tertinggi pada ${LEVEL}", - "levelIsLockedText": "${LEVEL} terbuka.", - "levelMustBeCompletedFirstText": "Selesaikan ${LEVEL} dulu.", + "levelIsLockedText": "${LEVEL} terkunci.", + "levelMustBeCompletedFirstText": "Selesaikan ${LEVEL} terlebih dahulu.", "levelText": "Level ${NUMBER}", "levelUnlockedText": "Level Terbuka!", "livesBonusText": "Nyawa Tambahan", "loadingText": "memuat", - "loadingTryAgainText": "Memuat; Coba lagi nanti.. sabar ya..", + "loadingTryAgainText": "Memuat; coba lagi dalam beberapa saat...", "macControllerSubsystemBothText": "Keduanya (Tidak direkomendasikan)", "macControllerSubsystemClassicText": "Klasik", - "macControllerSubsystemDescriptionText": "Coba ubah ini jika pengontrol Kamu tidak bekerja", + "macControllerSubsystemDescriptionText": "(coba ubah ini jika pengontrol kamu tidak bekerja)", "macControllerSubsystemMFiNoteText": "Pengontrol yang dibuat-untuk-ios/Mac terdeteksi;\nKamu mungkin ingin mengaktifkanya melalui Pengaturan -> Pengontrol", "macControllerSubsystemMFiText": "Dibuat-untuk-iOS/Mac", "macControllerSubsystemTitleText": "Dukungan pengontrol", @@ -1006,63 +1055,70 @@ "creditsText": "Kredit", "demoMenuText": "Menu Demo", "endGameText": "Akhiri Permainan", - "endTestText": "Akhiri Pengetesan", + "endTestText": "Akhiri Uji Coba", "exitGameText": "Keluar dari Permainan", - "exitToMenuText": "Ke Menu?", + "exitToMenuText": "Keluar ke Menu?", "howToPlayText": "Cara bermain", "justPlayerText": "(Hanya ${NAME})", - "leaveGameText": "Mode Penonton", - "leavePartyConfirmText": "Yakin Ingin Keluar?", - "leavePartyText": "Keluar", + "leaveGameText": "Keluar Permainan", + "leavePartyConfirmText": "Yakin keluar dari acara?", + "leavePartyText": "Keluar Acara", "quitText": "Berhenti", "resumeText": "Lanjutkan", "settingsText": "Pengaturan" }, "makeItSoText": "Jadilah Demikian", - "mapSelectGetMoreMapsText": "Arena Lainnya", - "mapSelectText": "Pilih", - "mapSelectTitleText": "Arena ${GAME}", - "mapText": "Arena", + "mapSelectGetMoreMapsText": "Dapatkan Peta Lainnya...", + "mapSelectText": "Pilih...", + "mapSelectTitleText": "Peta ${GAME}", + "mapText": "Peta", "maxConnectionsText": "Koneksi maksimal", "maxPartySizeText": "Besar Ukuran Maksimal", "maxPlayersText": "Jumlah Pemain Maksimal", "merchText": "Merchandise!", - "modeArcadeText": "Mode Arcade", + "modeArcadeText": "Mode Arkade", "modeClassicText": "Mode Klasik", "modeDemoText": "Mode Demo", + "moreSoonText": "Akan segera hadir lebih banyak..", + "mostDestroyedPlayerText": "Banyak Pemain Dihancurkan", "mostValuablePlayerText": "Pemain Terunggul", "mostViolatedPlayerText": "Pemain Teraniaya", "mostViolentPlayerText": "Pemain Terkejam", "moveText": "Gerak", - "multiKillText": "${COUNT} MATI!!", + "multiKillText": "${COUNT} MATI!!!", "multiPlayerCountText": "${COUNT} pemain", - "mustInviteFriendsText": "CATATAN: kamu harus mengundang teman di\nopsi \"${GATHER}\" atau pasang\npengontrol untuk bermain di mode multi-pemain", - "nameBetrayedText": "${NAME} membunuh rekannya ${VICTIM}", + "mustInviteFriendsText": "Catatan: kamu harus mengundang teman di\nopsi \"${GATHER}\" panel atau pasang\npengontrol untuk bermain di mode multi-pemain.", + "nameBetrayedText": "${NAME} membunuh rekannya ${VICTIM}.", "nameDiedText": "${NAME} meninggal.", - "nameKilledText": "${NAME} membunuh ${VICTIM}", - "nameNotEmptyText": "Nama harus diisi!", - "nameScoresText": "${NAME} mencetak poin!", + "nameKilledText": "${NAME} membunuh ${VICTIM}.", + "nameNotEmptyText": "Nama tidak boleh kosong!", + "nameScoresText": "${NAME} Mencetak Poin!", "nameSuicideKidFriendlyText": "${NAME} meninggal tiba-tiba.", "nameSuicideText": "${NAME} bunuh diri.", "nameText": "Nama", "nativeText": "Asli", + "newExclaimText": "Baru!", "newPersonalBestText": "Rekor Pribadi Baru!", - "newTestBuildAvailableText": "Uji coba baru tersedia! (${VERSION} bangun ${BUILD}).\nDapatkan di ${ADDRESS}", + "newTestBuildAvailableText": "Uji coba baru tersedia! (${VERSION} build ${BUILD}).\nDapatkan di ${ADDRESS}", "newText": "Baru", - "newVersionAvailableText": "Versi ${APP_NAME} terbaru tersedia", - "nextAchievementsText": "Pencapaian berikutnya:", + "newVersionAvailableText": "Versi ${APP_NAME} terbaru tersedia! (${VERSION})", + "nextAchievementsText": "Pencapaian Berikutnya:", "nextLevelText": "Level Berikutnya", "noAchievementsRemainingText": "- tidak ada", "noContinuesText": "(tidak dapat melanjutkan)", - "noExternalStorageErrorText": "Tidak ada penyimpanan eksternal", + "noExternalStorageErrorText": "Tidak ada penyimpanan eksternal di perangkat ini", "noGameCircleText": "Kesalahan: tidak masuk ke LingkaranGame", + "noMessagesText": "Tidak ada pesan.", + "noPluginsInstalledText": "Tidak ada plugin yang terpasang", "noProfilesErrorText": "Kamu tidak punya profil pemain, jadi '${NAME}' dipakai. \nMasuk Pengaturan->Profil Pemain untuk membuat profil. ", "noScoresYetText": "Belum ada skor.", + "noServersFoundText": "Server tidak ditemukan.", "noThanksText": "Tidak, Terima kasih", - "noTournamentsInTestBuildText": "PERHATIAN: Skor turnamen dari build tes ini akan di abaikan", - "noValidMapsErrorText": "Tidak ada arena valid untuk game ini.", + "noTournamentsInTestBuildText": "PERINGATAN: Skor turnamen dari build uji coba ini akan di abaikan.", + "noValidMapsErrorText": "Tidak ada peta valid untuk tipe permainan ini.", "notEnoughPlayersRemainingText": "Tidak ada pemain tersisa; keluar dan main ulang.", "notEnoughPlayersText": "Kamu butuh sedikitnya ${COUNT} pemain untuk memulai permainan!", + "notEnoughTicketsText": "Tiket tidak cukup!", "notNowText": "Jangan Sekarang", "notSignedInErrorText": "Kamu harus masuk untuk lakukan ini.", "notSignedInGooglePlayErrorText": "Kamu harus masuk pakai Google Play untuk lakukan ini.", @@ -1075,26 +1131,29 @@ "onText": "Nyala", "oneMomentText": "Sebentar...", "onslaughtRespawnText": "${PLAYER} akan bangkit pada gelombang ${WAVE}", + "openMeText": "Buka Aku!", + "openNowText": "Buka Sekarang", + "openText": "Buka", "orText": "${A} atau ${B}", "otherText": "Lainnya...", "outOfText": "(#${RANK} dari ${ALL})", - "ownFlagAtYourBaseWarning": "Benderamu harus\nberada di basismu!", + "ownFlagAtYourBaseWarning": "Benderamu harus\nberada di basismu untuk mencetak skor!", "packageModsEnabledErrorText": "Game yang melalui jaringan tidak diperbolehkan ketika mod-paket-lokal diaktifkan (lihat Pengaturan->Lanjutan) ", "partyWindow": { "chatMessageText": "Pesan Obrolan", - "emptyText": "acaramu kosong", - "hostText": "(pembuat)", + "emptyText": "Acaramu kosong", + "hostText": "(pemilik)", "sendText": "Kirim", - "titleText": "acaramu" + "titleText": "Acaramu" }, "pausedByHostText": "(terhenti oleh pemilik)", "perfectWaveText": "Gelombang Sempurna!", "pickUpText": "Ambil", "playModes": { - "coopText": "Koloni", - "freeForAllText": "Saling bunuh", + "coopText": "Mabar", + "freeForAllText": "Bebas-untuk-Semua", "multiTeamText": "Multi-Tim", - "singlePlayerCoopText": "Pemain Tunggal / Lawan komputer", + "singlePlayerCoopText": "Pemain Tunggal / Mabar", "teamsText": "Tim" }, "playText": "Main", @@ -1106,7 +1165,7 @@ "playerCountAbbreviatedText": "${COUNT}p", "playerDelayedJoinText": "${PLAYER} akan masuk pada ronde berikutnya.", "playerInfoText": "Info Pemain", - "playerLeftText": "${PLAYER} meninggalkan game.", + "playerLeftText": "${PLAYER} meninggalkan permainan.", "playerLimitReachedText": "Batas pemain ${COUNT} tercapai; tidak dapat bergabung lagi.", "playerProfilesWindow": { "cantDeleteAccountProfileText": "Kamu tidak dapat menghapus akun profilmu.", @@ -1118,19 +1177,19 @@ "titleText": "Profil Pemain" }, "playerText": "Pemain", - "playlistNoValidGamesErrorText": "Playlist ini mempunyai game terbuka yang tidak valid.", - "playlistNotFoundText": "Daftar Putar tidak ditemukan", + "playlistNoValidGamesErrorText": "Daftar putar ini berisi permainan terbuka yang tidak valid.", + "playlistNotFoundText": "daftar Putar tidak ditemukan", "playlistText": "Daftar Putar", "playlistsText": "Daftar Putar", - "pleaseRateText": "Jika Kamu menyukai ${APP_NAME}, yuk luangkan waktu sejenak untuk menilai dan membubuhkan komentar. Ini akan membantu kami untuk menyempurnakan permainan yang akan datang.\n\nterima kasih!\n-eric", + "pleaseRateText": "Jika kamu menyukai ${APP_NAME}, yuk luangkan waktu sejenak \nuntuk menilai atau membubuhkan komentar. Ini akan membantu \nkami menyempurnakan dan mendukung permainan dalam pengembangan ke depannya.\n\nterima kasih!\n-eric", "pleaseWaitText": "Mohon tunggu...", - "pluginClassLoadErrorText": "Error saat memuat class plugin '${PLUGIN}':${ERROR}", - "pluginInitErrorText": "Error saat menjalankan plugin '${PLUGIN}': ${ERROR}", + "pluginClassLoadErrorText": "Kesalahan saat memuat class plugin '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Kesalahan saat menjalankan plugin '${PLUGIN}': ${ERROR}", "pluginSettingsText": "Pengaturan Plugin", "pluginsAutoEnableNewText": "Otomatis nyalakan Plugin", - "pluginsDetectedText": "Plugin baru terdeteksi. Mulai ulang game untuk mengaktifkan pluginnya, atau mengaturnya di pengaturan.", - "pluginsDisableAllText": "Matikan semua Plugin", - "pluginsEnableAllText": "Nyalakan semua Plugin", + "pluginsDetectedText": "Plugin baru terdeteksi. Mulai ulang untuk mengaktifkan pluginnya, atau mengaturnya di pengaturan.", + "pluginsDisableAllText": "Matikan Semua Plugin", + "pluginsEnableAllText": "Nyalakan Semua Plugin", "pluginsRemovedText": "${NUM} plugin tidak lagi ditemukan.", "pluginsText": "Plugin", "practiceText": "Latihan", @@ -1142,24 +1201,28 @@ "pressAnyKeyText": "Tekan apa saja...", "pressJumpToFlyText": "** Tekan tombol lompat terus menerus untuk terbang **", "pressPunchToJoinText": "tekan PUKUL untuk bergabung..", - "pressToOverrideCharacterText": "tekan ${BUTTONS} untuk menimpa karaktermu.", + "pressToOverrideCharacterText": "tekan ${BUTTONS} untuk menimpa karaktermu", "pressToSelectProfileText": "tekan ${BUTTONS} untuk memilih pemain", "pressToSelectTeamText": "tekan ${BUTTONS} untuk memilih tim", "promoCodeWindow": { "codeText": "Kode", "enterText": "Masuk" }, - "promoSubmitErrorText": "Kesalahan saat mengirim kode; periksa koneksi internet Kamu", + "promoSubmitErrorText": "Kesalahan saat mengirim kode; periksa koneksi internetmu", "ps3ControllersWindow": { - "macInstructionsText": "Matikan daya pada bagian belakang PS3-mu, pastikan\nBluetooth aktif pada Mac-mu, lalu hubungkan kontrollermu\nke Mac-mu dengan kabel USB untuk memasangkannya. Sekarang, Kamu\ndapat menggunakan kontrollermu dengan kabel USB atau Bluetooth.\n\nPada beberapa perangkat Mac, Kamu mungkin akan dimintai kata sandi ketika memasangkannya.\nJika ini terjadi, lihat beberapa petunjuk atau gunakan google untuk meminta bantuan.\n\n\n\n\n\nKontroller PS3 yang terhubung dengan jaringan akan terlihat pada daftar perangkat\ndalam System Preferences->Bluetooth. Kamu mungkin harus menghapusnya\ndalam daftar tersebut ketika Kamu ingin menggunakan kontroller PS3mu kembali.\n\nDan pastikan untuk memutuskannya dari Bluetooth ketika sedang tidak\ndigunakan atau baterainya akan secara otomatis terkuras.\n\nBluetooth biasanya menangani sampai 7 perangkat yang terhubung,\nmeski jarak tempuhmu berbeda.", - "ouyaInstructionsText": "Untuk menggunakan kontroller PS3mu dengan OUYA, hubungkan saja dengan kabel USB\nsekali untuk memasangkannya. Melakukan ini akan memutuskan kontrollermu yang lain, jadi\nKamu harus mengulang OUYA-mu dan cabut kabel USB.\n\nSekarang Kamu seharusnya dapat menggunakan kontrollermu untuk\nmenghubungkannya dengan jaringan. Ketika Kamu sudah selesai bermain, tekan tombol HOME\nselama 10 detik untuk mematikan kontroller; jika itu tetap menyala\nmaka bateraimu akan terkuras habis.", + "macInstructionsText": "Matikan daya pada bagian belakang PS3-mu, pastikan\nBluetooth aktif pada Mac-mu, lalu hubungkan kontrollermu\nke Mac-mu dengan kabel USB untuk memasangkannya. Sekarang, kamu\ndapat menggunakan kontrollermu dengan kabel USB atau Bluetooth.\n\nPada beberapa perangkat Mac, kamu mungkin akan dimintai kata sandi ketika memasangkannya.\nJika ini terjadi, lihat beberapa petunjuk atau gunakan google untuk meminta bantuan.\n\n\n\n\n\nKontroller PS3 yang terhubung dengan jaringan akan terlihat pada daftar perangkat\ndalam System Preferences->Bluetooth. Kamu mungkin harus menghapusnya\ndalam daftar tersebut ketika kamu ingin menggunakan kontroller PS3mu kembali.\n\nDan pastikan untuk memutuskannya dari Bluetooth ketika sedang tidak\ndigunakan atau baterainya akan secara otomatis terkuras.\n\nBluetooth biasanya menangani sampai 7 perangkat yang terhubung,\nmeski jarak tempuhmu berbeda.", + "macInstructionsTextScale": 0.7, + "ouyaInstructionsText": "Untuk menggunakan kontroller PS3mu dengan OUYA, hubungkan saja dengan kabel USB\nsekali untuk memasangkannya. Melakukan ini akan memutuskan pengontrol yang lain, jadi\nKamu harus mengulang OUYA-mu dan cabut kabel USB.\n\nSekarang kamu seharusnya dapat menggunakan pengontrol untuk\nmenghubungkannya dengan jaringan. Ketika kamu sudah selesai bermain, tekan tombol HOME\nselama 10 detik untuk mematikan pengontrol; jika itu tetap menyala\nmaka bateraimu akan terkuras habis.", + "ouyaInstructionsTextScale": 0.7, "pairingTutorialText": "memasangkan video petunjuk", - "titleText": "Menggunakan Kontroller PS3 dengan ${APP_NAME}:" + "titleText": "Menggunakan Pengontrol PS3 dengan ${APP_NAME}:" }, "punchBoldText": "PUKUL", "punchText": "Pukul", "purchaseForText": "Membeli dengan ${PRICE}", "purchaseGameText": "Membeli Game", + "purchaseNeverAvailableText": "Maaf, pembelian tidak tersedia pada versi ini.\nCoba masuk ke akun kamu di platform lain dan lakukan pembelian dari sana.", + "purchaseNotAvailableText": "Pembelian ini tidak tersedia.", "purchasingText": "Membeli...", "quitGameText": "Keluar ${APP_NAME}?", "quittingIn5SecondsText": "Keluar dalam 5 detik...", @@ -1167,10 +1230,10 @@ "randomText": "Acak", "rankText": "Peringkat", "ratingText": "Nilai", - "reachWave2Text": "Raih gelombang 2 untuk dapat peringkat", - "readyText": "Siap", + "reachWave2Text": "Raih gelombang 2 untuk dapat peringkat.", + "readyText": "siap", "recentText": "Terbaru", - "remoteAppInfoShortText": "${APP_NAME} akan menyenangkan ketika dimainkan dengan keluarga & teman.\nHubungkan satu atau lebih kontroller atau install app\n${REMOTE_APP_NAME} pada ponsel atau tablet untuk menggunakannya\nsebagai kontroller.", + "remoteAppInfoShortText": "${APP_NAME} akan menyenangkan ketika dimainkan dengan keluarga & teman.\nHubungkan satu atau lebih pengontrol atau pasang apl.\n${REMOTE_APP_NAME} pada ponsel atau tablet untuk menggunakannya\nsebagai pengontrol.", "remote_app": { "app_name": "Remot BombSquad", "app_name_short": "RemotBS", @@ -1180,7 +1243,7 @@ "capturing": "Menangkap…", "connected": "Terhubung.", "description": "Gunakan ponsel atau tabletmu sebagai pengontrol BombSquad.\nLebih dari 8 perangkat dapat terhubung sekaligus untuk keseruan multipemain lokal yang epik di sebuah TV atau tablet", - "disconnected": "Diputus server", + "disconnected": "Diputus oleh server.", "dpad_fixed": "tetap", "dpad_floating": "mengambang", "dpad_position": "Posisi D-Pad", @@ -1188,7 +1251,7 @@ "dpad_type": "Tipe D-Pad", "enter_an_address": "Masukkan Alamat", "game_full": "Permainan sudah penuh atau tidak menerima koneksi.", - "game_shut_down": "Permainan sudah berakhir", + "game_shut_down": "Permainan sudah berakhir.", "hardware_buttons": "Tombol Perangkat keras", "join_by_address": "Masuk pakai Alamat...", "lag": "Lag: ${SECONDS} detik", @@ -1196,32 +1259,35 @@ "run1": "Lari 1", "run2": "Lari 2", "searching": "Mencari BombSquad...", - "searching_caption": "Ketuk nama permainan yang kamu inginkan.\nPastikan Kamu berada di jaringan wifi yang sama dengan permainan tersebut.", + "searching_caption": "Ketuk nama permainan yang kamu ingin bergabung.\nPastikan kamu berada di jaringan wifi yang sama dengan permainan tersebut.", "start": "Mulai", "version_mismatch": "Versi tidak sama.\nPastikan kamu menggunakan BombSquad dan Remot BombSquad\ndengan versi terbaru dan coba lagi." }, - "removeInGameAdsText": "Buka \"${PRO}\" di toko untuk menghilangkan iklan game", + "removeInGameAdsText": "Buka \"${PRO}\" di toko untuk menghilangkan iklan game.", + "removeInGameAdsTokenPurchaseText": "PENAWARAN WAKTU TERBATAS: Beli paket token APAPUN untuk menghapus iklan dalam game.", "renameText": "Mengubah Nama", "replayEndText": "Akhiri Replay", - "replayNameDefaultText": "Replay Game Terakhir", - "replayReadErrorText": "Error membaca file replay.", - "replayRenameWarningText": "Ubah nama \"${REPLAY}\" setelah game jika Kamu ingin menyimpannya; jika tidak itu akan ditimpa.", - "replayVersionErrorText": "Maaf, replay ini dibuat dalam\nversi game yang berbeda dan tidak dapat digunakan", + "replayNameDefaultText": "Replay Permainan Terakhir", + "replayReadErrorText": "Kesalahan membaca file replay.", + "replayRenameWarningText": "Ubah nama \"${REPLAY}\" setelah permainan jika kamu ingin menyimpannya; jika tidak itu akan ditimpa.", + "replayVersionErrorText": "Maaf, replay ini dibuat dalam\nversi game yang berbeda dan tidak dapat digunakan.", "replayWatchText": "Nonton Replay", - "replayWriteErrorText": "Error menulis file replay", + "replayWriteErrorText": "Kesalahan menulis file replay.", "replaysText": "Replay", "reportPlayerExplanationText": "Gunakan alamat surel ini untuk melaporkan tindakan curang, kata-kata yang tidak pantas, atau kelakuan buruk lainnya.\nTolong jelaskan dibawah ini:", "reportThisPlayerCheatingText": "Curang", "reportThisPlayerLanguageText": "Bahasa Yang Tidak Pantas", - "reportThisPlayerReasonText": "Apa yang ingin Kamu laporkan?", - "reportThisPlayerText": "Laporkan pemain ini", + "reportThisPlayerReasonText": "Apa yang ingin kamu laporkan?", + "reportThisPlayerText": "Laporkan Pemain Ini", "requestingText": "Meminta...", "restartText": "Ulangi", "retryText": "Ulangi", "revertText": "Kembali", "runText": "Lari", "saveText": "Simpan", - "scanScriptsErrorText": "Galat saat memindai skrip; lihat log untuk detailnya.", + "scanScriptsErrorText": "Kesalahan saat memindai skrip. Lihat log untuk detailnya.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} dan ${NUM} modul lain perlu di perbaharui untuk api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} perlu di perbaharui untuk api ${API}.", "scoreChallengesText": "Tantangan Skor", "scoreListUnavailableText": "Daftar skor tidak ada", "scoreText": "Skor", @@ -1232,6 +1298,7 @@ }, "scoreWasText": "(adalah ${COUNT})", "selectText": "Pilih", + "sendInfoDescriptionText": "Mengirimkan informasi akun dan status aplikasi ke pengembang.\nHarap sertakan nama atau alasan pengiriman Anda.", "seriesWinLine1PlayerText": "MEMENANGKAN", "seriesWinLine1TeamText": "MEMENANGKAN", "seriesWinLine1Text": "MEMENANGKAN", @@ -1247,35 +1314,43 @@ "titleText": "Pengaturan" }, "settingsWindowAdvanced": { - "alwaysUseInternalKeyboardDescriptionText": "(keyboard dari BombSquad)", - "alwaysUseInternalKeyboardText": "Gunakan Keyboard Internal", - "benchmarksText": "Tes Stres dan Benchmark", - "disableCameraGyroscopeMotionText": "Nonaktikan Gerakkan Kamera Giroskop", - "disableCameraShakeText": "Nonaktifkan Gerakkan Kamera", - "disableThisNotice": "(Kamu dapat matikan peringatan ini di pengaturan tambahan)", + "alwaysUseInternalKeyboardDescriptionText": "(simpel, bersahabat dengan pengontrol keyboard pada layar untuk mengubah teks)", + "alwaysUseInternalKeyboardText": "Selalu gunakan keyboard internal", + "benchmarksText": "Uji Coba Stres & Benchmark", + "devToolsText": "Alat Pengembang", + "disableCameraGyroscopeMotionText": "Nonaktifkan gerakan giroskop kamera", + "disableCameraShakeText": "Nonaktifkan goyangan kamera", + "disableThisNotice": "(kamu dapat matikan peringatan ini di pengaturan tambahan)", "enablePackageModsDescriptionText": "(menyalakan kapabilitas modding ekstra menyebabkan kamu tidak dapat bermain di internet)", "enablePackageModsText": "Izinkan Paket Mod Lokal", "enterPromoCodeText": "Masukkan Kode", - "forTestingText": "NB: jumlah ini hanya untuk tes dan akan hilang saat keluar", - "helpTranslateText": "Terjemahan ${APP_NAME} selain Bahasa Inggris adalah bantuan \nkomunitas. Jika Kamu ingin membantu atau mengoreksi berkas\nterjemahan, silahkan masuk ke situs berikut. Terima kasih!", - "kickIdlePlayersText": "Keluarkan Pemain Diam", + "forTestingText": "NB: jumlah ini hanya untuk uji coba dan akan hilang saat aplikasi keluar.", + "helpTranslateText": "Terjemahan ${APP_NAME} selain Bahasa Inggris adalah bantuan \nkomunitas. Jika kamu ingin membantu atau mengoreksi berkas\nterjemahan, silahkan masuk ke situs berikut. Terima kasih!", + "insecureConnectionsDescriptionText": "tidak disarankan, tapi memungkinkan bermain daring\ndalam negara atau jaringan yang dibatasi", + "insecureConnectionsText": "Gunakan koneksi tidak aman", + "kickIdlePlayersText": "Mengeluarkan pemain yang menganggur", "kidFriendlyModeText": "Mode Dibawah Umur (kekerasan rendah, dll)", "languageText": "Bahasa", "moddingGuideText": "Cara Me-Modding", + "moddingToolsText": "Alat Modding", "mustRestartText": "Kamu harus memulai ulang permainan untuk menerapkan perubahan.", - "netTestingText": "Tes Jaringan", - "resetText": "Atur ulang", + "netTestingText": "Uji Coba Jaringan", + "resetText": "Atur Ulang", + "sendInfoText": "Kirim Info", "showBombTrajectoriesText": "Lihat Lintasan Bom", - "showInGamePingText": "Tampilkan Ping dalam permainan", + "showDemosWhenIdleText": "Tampilkan demo saat menganggur", + "showDeprecatedLoginTypesText": "Tampilkan jenis login yang tidak digunakan lagi", + "showDevConsoleButtonText": "Tampilkan tombol konsol pengembang", + "showInGamePingText": "Tampilkan ping dalam permainan", "showPlayerNamesText": "Tunjukkan Nama Pemain", "showUserModsText": "Lihat Folder Mod", "titleText": "Lanjutan", "translationEditorButtonText": "Penyunting Translasi ${APP_NAME}", - "translationFetchErrorText": "status translasi tidak tersedia.", + "translationFetchErrorText": "status terjemahan tidak tersedia.", "translationFetchingStatusText": "memeriksa status terjemahan...", - "translationInformMe": "Beritahu saya jika bahasa yang saya gunakan harus diperbarui", - "translationNoUpdateNeededText": "Bahasa saat ini sudah yang terbaru; woohoo!", - "translationUpdateNeededText": "** bahasa ini perlu diperbaharui! **", + "translationInformMe": "Beritahu saya jika bahasa yang saya gunakan harus diperbaharui", + "translationNoUpdateNeededText": "Bahasa saat ini adalah yang terkini; Woohoo!", + "translationUpdateNeededText": "** Bahasa saat ini perlu diperbaharui!! **", "vrTestingText": "Percobaan VR" }, "shareText": "Bagikan", @@ -1285,6 +1360,9 @@ "signInWithGameCenterText": "Untuk menggunakan akun Game Center,\nmasuk ke Game Center dahulu.", "singleGamePlaylistNameText": "Hanya ${GAME}", "singlePlayerCountText": "1 pemain", + "sizeLargeText": "Besar", + "sizeMediumText": "Sedang", + "sizeSmallText": "Kecil", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Pemilihan Karakter", @@ -1298,7 +1376,7 @@ "GrandRomp": "Penaklukan", "Hockey": "Hoki", "Keep Away": "Menjauh", - "Marching": "Bolak-Balik", + "Marching": "Berlarian", "Menu": "Menu Utama", "Onslaught": "Pembantaian", "Race": "Balapan", @@ -1310,6 +1388,7 @@ }, "spaceKeyText": "spasi", "statsText": "Statistik", + "stopRemindingMeText": "Berhenti mengingatkan ku", "storagePermissionAccessText": "Ini membutuhkan akses penyimpanan", "store": { "alreadyOwnText": "Kamu sudah punya ${NAME}!", @@ -1321,8 +1400,8 @@ "extrasText": "Extra", "freeBombSquadProText": "BombSquad sekarang gratis, karena dulu Kamu membelinya\nKamu mendapat tingkatan BombSquad Pro dan ${COUNT} tiket sebagai ucapan terima kasih.\nNikmati fitur barunya, dan terima kasih atas dukungannya!\n-Eric", "holidaySpecialText": "Spesial Liburan", - "howToSwitchCharactersText": "pergi ke \"${SETTINGS} -> ${PLAYER_PROFILES}\" untuk mengubah karakter", - "howToUseIconsText": "(Buatlah profil pemain global (dalam jendela akun) untuk menggunakan ini)", + "howToSwitchCharactersText": "(pergi ke \"${SETTINGS} -> ${PLAYER_PROFILES}\" untuk mengubah karakter)", + "howToUseIconsText": "(buatlah profil pemain global (dalam jendela akun) untuk menggunakan ini)", "howToUseMapsText": "(gunakan peta ini di tim/daftar putar bebasmu)", "iconsText": "Simbol", "loadErrorText": "Tidak dapat memuat halaman.\nCek koneksi internetmu.", @@ -1332,7 +1411,7 @@ "oneTimeOnlyText": "(sekali saja)", "purchaseAlreadyInProgressText": "Pembelian barang ini sedang dalam proses.", "purchaseConfirmText": "Beli ${ITEM}?", - "purchaseNotValidError": "Pembelian tidak valid.\nHubungi ${EMAIL} jika ini adalah error.", + "purchaseNotValidError": "Pembelian tidak valid.\nHubungi ${EMAIL} jika ini adalah kesalahan.", "purchaseText": "Membeli", "saleBundleText": "Paket Promo!", "saleExclaimText": "Dijual!", @@ -1343,9 +1422,9 @@ "totalWorthText": "*** ${TOTAL_WORTH} nilai! ***", "upgradeQuestionText": "Tingkatkan?", "winterSpecialText": "Spesial Musim Dingin", - "youOwnThisText": "- Kamu sudah memiliki ini -" + "youOwnThisText": "- kamu sudah memiliki ini -" }, - "storeDescriptionText": "Permainan dengan 8 pemain!\n\nLedakkan temanmu (atau komputer) dalam turnamen ledakkan seperti Ambil-Bendera, Bom-Hoki, dan Pertarungan-Mematikan-Epik-Gerakkan-Lambat\n\nDukungan pengontrol Sederhana dan pengontrol luas membuatnya mudah untuk 8 orang untuk beraksi; Kamu juga dapat menggunakan perangkat ponselmu sebagai pengontrol dengan aplikasi ‘BombSquad Remote’!\n\nAwas Bom!\n\nKunjungi www.froemling.net/bombsquad untuk informasi lebih lanjut.", + "storeDescriptionText": "Permainan dengan 8 pemain!\n\nLedakkan temanmu (atau komputer) dalam turnamen ledakkan seperti Ambil-Bendera, Bom-Hoki, dan Pertarungan-Mematikan-Epik-Gerakkan-Lambat\n\nDukungan pengontrol Sederhana dan pengontrol luas membuatnya mudah untuk 8 orang untuk beraksi; kamu juga dapat menggunakan perangkat ponselmu sebagai pengontrol dengan aplikasi ‘BombSquad Remote’!\n\nAwas Bom!\n\nKunjungi www.froemling.net/bombsquad untuk informasi lebih lanjut.", "storeDescriptions": { "blowUpYourFriendsText": "Meledakkan temanmu.", "competeInMiniGamesText": "Bersaing dalam mini-game mulai dari balapan sampai terbang.", @@ -1357,34 +1436,51 @@ "storeText": "Toko", "submitText": "Serahkan", "submittingPromoCodeText": "Menyerahkan Kode ...", - "teamNamesColorText": "Nama Tim / Warna ...", + "successText": "Sukses!", + "supportEmailText": "Jika kamu mengalami masalah apa pun pada\naplikasi, mohon segera kirim email ${EMAIL}.", + "teamNamesColorText": "Nama Tim / Warna...", "telnetAccessGrantedText": "Akses telnet aktif.", "telnetAccessText": "Akses telnet terdekteksi; izinkan?", "testBuildErrorText": "Percobaan ini tidak aktif lagi; tolong cek versi barunya.", "testBuildText": "Percobaan", - "testBuildValidateErrorText": "Tidak dapat mengesahkan percobaan. (Tidak tersedia koneksi internet?)", + "testBuildValidateErrorText": "Tidak dapat mengesahkan percobaan. (tak tersedia koneksi internet?)", "testBuildValidatedText": "Percobaan Sah; Nikmati!", - "thankYouText": "Terima kasih atas dukungan mu! Nikmati gamenya!!", - "threeKillText": "KEJAM ! 3 TERBUNUH", + "thankYouText": "Terima kasih atas dukunganmu! Nikmati permainannya!!", + "threeKillText": "3 TERBUNUH!!", + "ticketsDescriptionText": "Tiket dapat digunakan untuk membuka kunci karakter,\npeta, minigame, dan lainnya di toko.\n\nTiket dapat ditemukan di peti yang dimenangkan\nkampanye, turnamen, dan prestasi.", "timeBonusText": "Bonus Waktu", "timeElapsedText": "Waktu Berlalu", - "timeExpiredText": "Berakhir", + "timeExpiredText": "Waktu Berakhir", "timeSuffixDaysText": "${COUNT}h", "timeSuffixHoursText": "${COUNT}j", "timeSuffixMinutesText": "${COUNT}m", "timeSuffixSecondsText": "${COUNT}d", "tipText": "Petunjuk", - "titleText": "BomSquad", + "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Dapatkan Token", + "notEnoughTokensText": "Token tidak cukup!", + "numTokensText": "${COUNT} Token", + "openNowDescriptionText": "Kamu punya token yang\nCukup untuk membukanya \n-Kamu tidak perlu menunggu.", + "shinyNewCurrencyText": "Mata uang baru BombSquad yang berkilauan.", + "tokenPack1Text": "Token Kemasan Kecil", + "tokenPack2Text": "Token Kemasan Sedang", + "tokenPack3Text": "Token Kemasan Besar", + "tokenPack4Text": "Token Kemasan Jumbo", + "tokensDescriptionText": "Token digunakan untuk mempercepat pembukaan peti\ndan untuk fitur game dan akun lainnya.\n\nAnda dapat memenangkan token dalam game atau membelinya dalam kemasan.\nAtau beli Tiket Emas tanpa batas token\ndan tidak pernah mendengarnya lagi.", + "youHaveGoldPassText": "Kamu mempunyai Tiket Emas.\nSemua pembelian token gratis.\nSelamat menikmati!" + }, "topFriendsText": "Teman Terbaik", "tournamentCheckingStateText": "Memeriksa keadaan turnamen; harap tunggu...", - "tournamentEndedText": "Turnamen sudah berakhir. Turnamen yang baru akan mulai segera.", + "tournamentEndedText": "Turnamen sudah berakhir. Turnamen yang baru akan segera dimulai.", "tournamentEntryText": "Biaya Masuk Turnamen", + "tournamentFinalStandingsText": "Klasemen Akhir", "tournamentResultsRecentText": "Hasil Turnamen Terbaru", "tournamentStandingsText": "Hasil Terbaik Turnamen", "tournamentText": "Turnamen", "tournamentTimeExpiredText": "Waktu Turnamen Berakhir", - "tournamentsDisabledWorkspaceText": "Turnamen telah dinonaktifkan saat workspace(plugin/mod) aktif.\nUntuk mengaktifkan turnamen kembali, nonaktifkan dulu workspace anda dan mulai ulang gamenya.", + "tournamentsDisabledWorkspaceText": "Turnamen telah dinonaktifkan saat workspace(plugin/mod) aktif.\nUntuk mengaktifkan turnamen kembali, nonaktifkan dulu workspace kamu dan mulai ulang.", "tournamentsText": "Turnamen", "translations": { "characterNames": { @@ -1413,7 +1509,7 @@ "Spaz": "Spaz", "Taobao Mascot": "Maskot Taobao", "Todd": "Todd", - "Todd McBurton": "Rambo", + "Todd McBurton": "Todd McBurton", "Xara": "Xara", "Zoe": "Zoe", "Zola": "Zola" @@ -1422,9 +1518,9 @@ "${GAME} Training": "Latihan ${GAME}", "Infinite ${GAME}": "${GAME} Tanpa Batas", "Infinite Onslaught": "Pembantaian Tanpa Batas", - "Infinite Runaround": "Penjaga Tanpa Batas", + "Infinite Runaround": "Berlarian Tanpa Batas", "Onslaught Training": "Latihan Pembantaian", - "Pro ${GAME}": "${GAME} Profesional", + "Pro ${GAME}": "${GAME} Ahli", "Pro Football": "Rugby Ahli", "Pro Onslaught": "Pembantaian Ahli", "Pro Runaround": "Penjaga Ahli", @@ -1432,10 +1528,22 @@ "Rookie Football": "Rugby Pemula", "Rookie Onslaught": "Pembantaian Pemula", "The Last Stand": "Usaha Terakhir", - "Uber ${GAME}": "${GAME} Master", + "Uber ${GAME}": "${GAME} Uber", "Uber Football": "Rugby Uber", "Uber Onslaught": "Pembantaian Uber", - "Uber Runaround": "Master Penjaga" + "Uber Runaround": "Penjaga Uber" + }, + "displayItemNames": { + "${C} Tickets": "${C} Tiket", + "${C} Tokens": "${C} Token", + "Chest": "Peti", + "L1 Chest": "Peti Level 1", + "L2 Chest": "Peti Level 2", + "L3 Chest": "Peti Level 3", + "L4 Chest": "Peti Level 4", + "L5 Chest": "Peti Level 5", + "L6 Chest": "Peti Level 6", + "Unknown Chest": "Peti Misterius" }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah 'yang terpilih' dalam waktu yang ditentukan.\nBunuh 'yang terpilih' untuk menjadi 'yang terpilih'.", @@ -1448,26 +1556,26 @@ "Final glorious epic slow motion battle to the death.": "Pertarungan slow motion epik hingga kematian menjemput.", "Gather eggs!": "Kumpulkan telur!", "Get the flag to the enemy end zone.": "Bawa bendera sampai ujung lapangan.", - "How fast can you defeat the ninjas?": "Secepat apa kamu bisa mengalahkan para ninja?", + "How fast can you defeat the ninjas?": "Secepat apa kamu bisa kalahkan para ninja?", "Kill a set number of enemies to win.": "Hancurkan sejumlah musuh.", "Last one standing wins.": "Terakhir hidup menang.", "Last remaining alive wins.": "Terakhir hidup menang.", - "Last team standing wins.": "Habisi tim lawan.", + "Last team standing wins.": "Tim terakhir hidup menang.", "Prevent enemies from reaching the exit.": "Tahan musuh jangan sampai finish.", "Reach the enemy flag to score.": "Sentuh bendera lawan untuk skor.", - "Return the enemy flag to score.": "Kembalikan bendera musuh untuk menskor.", + "Return the enemy flag to score.": "Kembalikan bendera musuh untuk mencetak skor.", "Run ${ARG1} laps.": "Lari ${ARG1} putaran.", "Run ${ARG1} laps. Your entire team has to finish.": "Lari ${ARG1} putaran. Seluruh tim harus mencapai finish.", "Run 1 lap.": "Lari 1 putaran.", "Run 1 lap. Your entire team has to finish.": "Lari 1 putaran. Seluruh tim harus mencapai finish.", - "Run real fast!": "Lari! Ada Anjing!", + "Run real fast!": "Lari dengan cepat!", "Score ${ARG1} goals.": "Masukan ${ARG1} gol.", "Score ${ARG1} touchdowns.": "Cetak ${ARG1} touchdown.", "Score a goal.": "Cetak 1 Gol.", "Score a touchdown.": "Cetak 1 touchdown.", "Score some goals.": "Cetak beberapa gol.", "Secure all ${ARG1} flags.": "Amankan ${ARG1} bendera.", - "Secure all flags on the map to win.": "Amankan semua bendera di arena untuk menang.", + "Secure all flags on the map to win.": "Amankan semua bendera di peta untuk menang.", "Secure the flag for ${ARG1} seconds.": "Amankan bendera selama ${ARG1} detik.", "Secure the flag for a set length of time.": "Amankan bendera selama waktu yang ditentukan.", "Steal the enemy flag ${ARG1} times.": "Curi bendera musuh ${ARG1} kali.", @@ -1476,9 +1584,9 @@ "Touch the enemy flag ${ARG1} times.": "Sentuh bendera musuh ${ARG1} kali.", "Touch the enemy flag.": "Sentuh bendera musuh.", "carry the flag for ${ARG1} seconds": "bawa bendera selama ${ARG1} detik", - "kill ${ARG1} enemies": "Bunuh ${ARG1} musuh.", + "kill ${ARG1} enemies": "bunuh ${ARG1} musuh", "last one standing wins": "terakhir hidup menang", - "last team standing wins": "habisi tim lawan", + "last team standing wins": "tim terakhir hidup menang", "return ${ARG1} flags": "kembalikan ${ARG1} bendera", "return 1 flag": "kembalikan 1 bendera", "run ${ARG1} laps": "lari ${ARG1} putaran", @@ -1498,7 +1606,7 @@ "Chosen One": "Yang Terpilih", "Conquest": "Penguasaan", "Death Match": "Pertarungan Kematian", - "Easter Egg Hunt": "Memburu Easter Egg", + "Easter Egg Hunt": "Memburu Telur Paskah", "Elimination": "Eliminasi", "Football": "Rugby", "Hockey": "Hoki", @@ -1507,8 +1615,8 @@ "Meteor Shower": "Hujan Meteor", "Ninja Fight": "Perang Ninja", "Onslaught": "Pembantaian", - "Race": "Balap Liar", - "Runaround": "Jangan Kabur", + "Race": "Balapan", + "Runaround": "Berlarian", "Target Practice": "Sasaran Tembak", "The Last Stand": "Penyintas Terakhir" }, @@ -1519,8 +1627,8 @@ "languages": { "Arabic": "Arab", "Belarussian": "Belarusia", - "Chinese": "Mandarin (disederhanakan)", - "ChineseTraditional": "Cina tradisional", + "Chinese": "Mandarin (disederhanakan) ", + "ChineseTraditional": "Mandarin Tradisional", "Croatian": "Kroasia", "Czech": "Ceko", "Danish": "Denmark", @@ -1541,6 +1649,7 @@ "Korean": "Korea", "Malay": "Bahasa Malaysia", "Persian": "Persia", + "PirateSpeak": "Omongan Bajak Laut", "Polish": "Polandia", "Portuguese": "Portugis", "Romanian": "Romania", @@ -1566,7 +1675,7 @@ "Big G": "G Besar", "Bridgit": "Jembatan", "Courtyard": "Tempat Pengadilan", - "Crag Castle": "Kastil karang", + "Crag Castle": "Kastil Karang", "Doom Shroom": "Jamur Gelap", "Football Stadium": "Stadion Rugby", "Happy Thoughts": "Pikiran Bahagia", @@ -1594,72 +1703,87 @@ "Time Held": "Lama Kuasa" }, "serverResponses": { - "A code has already been used on this account.": "Sebuah kode sudah digunakan pada aku ini.", + "A code has already been used on this account.": "Sebuah kode sudah digunakan pada akun ini.", "A reward has already been given for that address.": "Hadiah telah diberikan ke alamat tersebut.", "Account linking successful!": "Berhasil menghubungkan akun!", "Account unlinking successful!": "Pemutusan akun berhasil!", "Accounts are already linked.": "Akun sudah dihubungkan.", - "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Menonton iklan tidak dapat diverifikasi.\nPastikan Anda menjalankan versi game yang resmi dan terbaru.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Menonton iklan tidak dapat diverifikasi.\nPastikan kamu menjalankan versi game yang resmi dan terbaru.", "An error has occurred; (${ERROR})": "Sebuah kesalahan telah terjadi; (${ERROR})", "An error has occurred; please contact support. (${ERROR})": "Sebuah kesalahan telah terjadi; tolong hubungi dukungan. (${ERROR})", - "An error has occurred; please contact support@froemling.net.": "Sebuah error telah terjadi; tolong hubungi support@froemling.net.", - "An error has occurred; please try again later.": "Sebuah error telah terjadi; mohon coba lagi nanti.", + "An error has occurred; please contact support@froemling.net.": "Sebuah kesalahan telah terjadi; tolong hubungi support@froemling.net.", + "An error has occurred; please try again later.": "Sebuah kesalahan telah terjadi; mohon coba lagi nanti.", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Kamu yakin ingin menghubungkan akun ini?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nIni tidak dapat ditunda!", "BombSquad Pro unlocked!": "BombSquad Pro terbuka!", - "Can't link 2 accounts of this type.": "Tidak dapat menghubungkan 2 tipe akun ini.", + "Can't link 2 accounts of this type.": "Tidak dapat menghubungkan 2 akun dari tipe ini.", "Can't link 2 diamond league accounts.": "Tidak dapat menghubungkan 2 akun liga berlian.", "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Tidak dapat menghubungkan; akan melampaui batas maksimum ${COUNT} akun yang dihubungkan.", - "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Kecurangan terdeteksi; skor dan hadiah ditahan selama ${COUNT} hari", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Kecurangan terdeteksi; skor dan hadiah ditahan selama ${COUNT} hari.", "Could not establish a secure connection.": "Tidak dapat menyeimbangkan koneksi yang aman.", "Daily maximum reached.": "Batas maksimal tercapai.", + "Daily sign-in reward": "Hadiah masuk harian", "Entering tournament...": "Memasuki turnamen...", - "Invalid code.": "Kode Salah", + "Invalid code.": "Kode salah.", "Invalid payment; purchase canceled.": "Pembayaran tidak valid; pembelian dibatalkan.", - "Invalid promo code.": "Promo kode salah.", + "Invalid promo code.": "Kode promo salah.", "Invalid purchase.": "Pembelian tidak valid.", "Invalid tournament entry; score will be ignored.": "Masukkan turnamen tidak valid; skor akan diabaikan.", "Item unlocked!": "Item dibuka!", - "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "PENAUTAN DITOLAK. ${ACCOUNT} berisi\ndata penting yang SEMUANYA AKAN HILANG.\nKamu dapat menautkannya dalam urutan yang berlawanan jika Kamu mau\n(dan kehilangan data akun INI sebagai gantinya)", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "PENAUTAN DITOLAK. ${ACCOUNT} berisi\ndata penting yang SEMUANYA AKAN HILANG.\nKamu dapat menautkannya dalam urutan yang berlawanan jika kamu mau\n(dan kehilangan data akun INI sebagai gantinya)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Menghubungkan akun ${ACCOUNT} ke akun ini?\nSemua data yang ada di ${ACCOUNT} akan hilang.\nIni tidak dapat dibatalkan. Apa kamu yakin?", + "Longer streaks lead to better rewards.": "Kemenangan yang lebih panjang akan menghasilkan hadiah yang lebih baik.", "Max number of playlists reached.": "Batas maksimum daftar putar tercapai.", "Max number of profiles reached.": "Batas maksimum profil tercapai.", "Maximum friend code rewards reached.": "Batas maksimum hadiah kode teman tercapai.", "Message is too long.": "Pesan terlalu panjang.", - "No servers are available. Please try again soon.": "Tidak ada server yang Tersedia. silakan coba lagi nanti", + "New tournament result!": "Hasil turnamen baru!", + "No servers are available. Please try again soon.": "Tidak ada server yang tersedia. Silahkan coba lagi nanti.", + "No slots available. Free a slot and try again.": "Tidak ada slot tersedia. Kosongkan slot dan coba lagi.", "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" berhasil ditingkatkan.", - "Profile could not be upgraded.": "Profile tidak dapat di tingkatkan.", + "Profile could not be upgraded.": "Profil tidak dapat di tingkatkan.", "Purchase successful!": "Pembelian sukses!", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Menerima ${COUNT} tiket untuk masuk.\nSilahkan kembali besok untuk menerima ${TOMORROW_COUNT}.", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Server tidak lagi mendukung permainan dengan versi ini;\nSilahkan perbarui ke versi yang lebih baru.", "Sorry, there are no uses remaining on this code.": "Maaf, kode ini tidak dapat dipakai lagi", - "Sorry, this code has already been used.": "Maaf,kode ini sudah digunakan", + "Sorry, this code has already been used.": "Maaf, kode ini sudah digunakan.", "Sorry, this code has expired.": "Maaf, kode ini sudah kadaluarsa.", "Sorry, this code only works for new accounts.": "Maaf, kode ini hanya berlaku untuk akun baru.", - "Still searching for nearby servers; please try again soon.": "Masih mencari server terdekat; silahkan coba lagi nanti", - "Temporarily unavailable; please try again later.": "Sedang tidak ada; mohon coba lagi nanti.", - "The tournament ended before you finished.": "Turnamen berakhir sebelum Kamu selesai.", + "Sorry, this has expired.": "Maaf, ini sudah kadaluarsa.", + "Still searching for nearby servers; please try again soon.": "Masih mencari server terdekat; silahkan coba lagi nanti.", + "Streak: ${NUM} days": "Beruntun: ${NUM} hari", + "Temporarily unavailable; please try again later.": "Sementara tidak tersedia; mohon coba lagi nanti.", + "The tournament ended before you finished.": "Turnamen berakhir sebelum kamu selesai.", "This account cannot be unlinked for ${NUM} days.": "Akun ini tidak dapat diputuskan untuk ${NUM} hari.", "This code cannot be used on the account that created it.": "Kode ini tidak dapat dipakai di akun yang membuatnya.", - "This is currently unavailable; please try again later.": "Ini saat ini tidak tersedia; silahkan coba lagi nanti.", - "This requires version ${VERSION} or newer.": "Ini membutuhkan versi ${VERSION} atau versi yang baru.", - "Tournaments disabled due to rooted device.": "Turnamen dinonaktifkan karena perangkat yang di-rooting.", + "This is currently unavailable; please try again later.": "Saat ini tidak tersedia; silahkan coba lagi nanti.", + "This requires version ${VERSION} or newer.": "Ini membutuhkan versi ${VERSION} atau yang lebih baru.", + "Tournaments disabled due to rooted device.": "Turnamen dinonaktifkan karena perangkat telah di-rooting.", "Tournaments require ${VERSION} or newer": "Turnamen membutuhkan ${VERSION} atau lebih baru", - "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Memutus ${ACCOUNT} dari akun ini?\nSemua data dari ${ACCOUNT} akan disetel ulang.\n(kecuali penghargaan di beberapa kasus)", - "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "PERINGATAN: keluhan tentang kecurangan telah diajukan terhadap akun Kamu.\nAkun yang ditemukan curang akan dilarang. Silakan bermain adil.", - "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Apakah Kamu mau menghubungkan akun perangkatmu dengan yang ini>\n\nAkun perangkatmu adalah ${ACCOUNT1}\nAkun ini adalah ${ACCOUNT2}\n\nIni akan mengizinkanmu untuk menyimpan datamu.\nPeringatan: ini tidak dapat dibatalkan!", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Memutus ${ACCOUNT} dari akun ini?\nSemua data dari ${ACCOUNT} akan disetel ulang.\n(kecuali untuk pencapaian di beberapa kasus)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "PERINGATAN: keluhan tentang kecurangan telah diajukan terhadap akun kamu.\nAkun yang ditemukan curang akan dilarang. Mohon bermain adil.", + "Wait reduced!": "Waktu menunggu dikurangi!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Peringatan: Versi game ini terbatas hanya ke data akun lama; beberapa hal mungkin tidak ada atau terlihat jadul.\nMohon untuk perbarui ke versi terbaru untuk melihat data baru akunmu.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Apakah kamu mau menghubungkan akun perangkatmu dengan yang ini?\n\nAkun perangkatmu adalah ${ACCOUNT1}\nAkun ini adalah ${ACCOUNT2}\n\nIni akan mengizinkanmu untuk menyimpan kemajuanmu.\nPeringatan: ini tidak dapat dibatalkan!", "You already own this!": "Kamu sudah mempunyai ini!", - "You can join in ${COUNT} seconds.": "Kamu dapat bergabung lagi pada ${COUNT} detik", + "You can join in ${COUNT} seconds.": "Kamu dapat bergabung lagi pada ${COUNT} detik.", "You don't have enough tickets for this!": "Kamu tidak mempunyai cukup tiket untuk ini!", "You don't own that.": "Kamu tidak memiliki itu.", "You got ${COUNT} tickets!": "Kamu dapat ${COUNT} tiket!", + "You got ${COUNT} tokens!": "Kamu dapat ${COUNT} token!", "You got a ${ITEM}!": "Kamu dapat ${ITEM}!", + "You got a chest!": "Kamu dapat peti!", + "You got an achievement reward!": "Kamu dapat hadiah pencapaian!", "You have been promoted to a new league; congratulations!": "Kamu dipromosikan ke liga yang baru; selamat!", - "You must update to a newer version of the app to do this.": "Kamu harus perbarui app ke versi yang baru untuk melakukan ini.", + "You lost a chest! (All your chest slots were full)": "Kamu kehilangan peti! (Semua slot petimu penuh)", + "You must update the app to view this.": "Kamu harus perbarui aplikasi agar dapat melihat ini.", + "You must update to a newer version of the app to do this.": "Kamu harus perbarui apl. ke versi yang baru untuk melakukan ini.", "You must update to the newest version of the game to do this.": "Kamu harus memperbaharui ke versi permainan yang lebih baru untuk melakukan ini.", "You must wait a few seconds before entering a new code.": "Kamu harus menunggu beberapa detik sebelum memasukkan kode yang baru.", + "You placed #${RANK} in a tournament!": "Kamu berada di peringkat #${RANK} pada turnamen!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Kamu peringkat ke #${RANK} pada turnament terakhir. Terima kasih sudah bermain!", - "Your account was rejected. Are you signed in?": "Akunmu ditolak. Apakah Kamu terdaftar?", - "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Salinan gamemu telah dimodifikasi.\nMohon kembalikan perubahan apapun dan coba lagi.", + "Your account was rejected. Are you signed in?": "Akunmu ditolak. Apakah kamu terdaftar?", + "Your ad views are not registering. Ad options will be limited for a while.": "Penayang iklan kamu tidak ter-registrasi. Opsi iklan mungkin terbatas untuk sementara waktu.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Salinan permainan kamu telah dimodifikasi.\nMohon kembalikan perubahan apapun dan coba lagi.", "Your friend code was used by ${ACCOUNT}": "Kode temanmu digunakan oleh ${ACCOUNT}" }, "settingNames": { @@ -1675,38 +1799,38 @@ "Allow Negative Scores": "Izinkan Skor Bernilai Negatif", "Balance Total Lives": "Total Nyawa Seimbang", "Bomb Spawning": "Bom Muncul", - "Chosen One Gets Gloves": "Yang Terpilih Mendapat Sarung Tinju", - "Chosen One Gets Shield": "Terpilih akan mendapatkan perisai", - "Chosen One Time": "Waktu Yang Terpilih", - "Enable Impact Bombs": "Izinkan Dampak Bom", + "Chosen One Gets Gloves": "Yang Terpilih Mendapatkan Sarung Tinju", + "Chosen One Gets Shield": "Yang Terpilih Mendapatkan Perisai", + "Chosen One Time": "Waktu Terpilih", + "Enable Impact Bombs": "Izinkan Bom Bentur", "Enable Triple Bombs": "Izinkan Bom Beruntun", - "Entire Team Must Finish": "Seluruh Tim Harus Melewati Finish", + "Entire Team Must Finish": "Seluruh Tim Harus Mencapai Finish", "Epic Mode": "Mode Epik", - "Flag Idle Return Time": "Waktu Bendera Diam Kembali", + "Flag Idle Return Time": "Waktu Bendera Nganggur Kembali", "Flag Touch Return Time": "Waktu Bendera Sentuh Kembali", "Hold Time": "Waktu Tunggu", "Kills to Win Per Player": "Pembunuhan untuk Para Pemain", - "Laps": "Lap", + "Laps": "Putaran", "Lives Per Player": "Nyawa Tiap Pemain", "Long": "Lama", "Longer": "Lama Sekali", "Mine Spawning": "Ranjau Muncul", "No Mines": "Tidak Ada Ranjau", "None": "Tak Satupun", - "Normal": "Sedang", + "Normal": "Normal", "Pro Mode": "Mode Ahli", - "Respawn Times": "Jeda Hingga Kembali", - "Score to Win": "Skor menang", + "Respawn Times": "Muncul Kembali Hingga", + "Score to Win": "Skor Menang", "Short": "Pendek", - "Shorter": "Pendek sekali", - "Solo Mode": "Mode Solo", + "Shorter": "Pendek Sekali", + "Solo Mode": "Mode Tunggal", "Target Count": "Jumlah Target", - "Time Limit": "Batas waktu" + "Time Limit": "Batas Waktu" }, "statements": { "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} didiskualifikasi karena ${PLAYER} meninggalkan permainan", - "Killing ${NAME} for skipping part of the track!": "Membunuh ${NAME} Karena melewati bagian permainan ini!", - "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Peringatan ke ${NAME}: turbo / tombol-spamming menjatuhkan Kamu." + "Killing ${NAME} for skipping part of the track!": "Membunuh ${NAME} karena melewati bagian permainan ini!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Peringatan ke ${NAME}: turbo / spam tombol menjatuhkanmu." }, "teamNames": { "Bad Guys": "Si Jahat", @@ -1715,50 +1839,50 @@ "Red": "Merah" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Lari-lompat-putar-dan pukul yang sempurna dan pada waktu yang tepat dapat\nmembunuh hanya dengan sekali serangan dan dapatkan penghargaan dari temanmu.", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Lari-lompat-putar-dan pukul yang sempurna dan pada waktu yang tepat dapat\nmembunuh hanya dengan sekali serangan dan dapatkan kehormatan dari temanmu.", "Always remember to floss.": "Selalu ingat untuk buang air.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Buat profil pemain untuk teman dan dirimu sendiri dengan\nnama dan penampilan yang kamu sukai daripada menggunakan yang acak.", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Kotak Terkutuk membuatmu menjadi bom waktu.\nSatu-satunya obat adalah mencari kotak medis.", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Selain penampilannya, semua kemampuan karakter sama,\npilih saja yang cocok untukmu.", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Jangan terlalu sombong dengan perisai energi; Kamu masih dapat dibuang ke dalam jurang.", - "Don't run all the time. Really. You will fall off cliffs.": "Jangan selalu berlari atau Kamu akan jatuh ke jurang.", - "Don't spin for too long; you'll become dizzy and fall.": "Jangan putar terlalu lama; kamu akan pusing dan jatuh.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Jangan terlalu sombong dengan perisai energi; kamu masih dapat dibuang ke dalam jurang.", + "Don't run all the time. Really. You will fall off cliffs.": "Jangan selalu berlari. Beneran nih. Kamu akan jatuh ke jurang.", + "Don't spin for too long; you'll become dizzy and fall.": "Jangan berputar terlalu lama; kamu akan pusing dan jatuh.", "Hold any button to run. (Trigger buttons work well if you have them)": "Tahan tombol apa saja untuk lari.", "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Tahan tombol apa saja untuk lari. Kamu akan menjadi lebih cepat\ntapi tidak dapat berbelok dengan lancar, hati-hati dengan jurang.", "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Bom es tidak cukup kuat, tetapi mereka membekukan\napapun yang mereka kena dan membuat orang mudah dihancurkan.", "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jika seseorang mengangkatmu, pukul dia dan dia akan melepaskanmu.\nIni bekerja didunia nyata juga.", - "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jika Kamu tidak mempunyai kontroller, pasang app '${REMOTE_APP_NAME}\npada perangkat handphonemu untuk menggunakannya sebagai kontroller.", - "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "", - "If you kill an enemy in one hit you get double points for it.": "Jika Kamu membunuh musuh dengan sekali serangan maka Kamu akan mendapat poin ganda.", - "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jika Kamu mengambil kutukan, satu-satunya harapanmu untuk hidup adalah\nmenemukan kotak medis dalam 5 detik.", - "If you stay in one place, you're toast. Run and dodge to survive..": "Jika Kamu berdiam diri saja, maka Kamu akan tamat. Lari dan menghindar untuk tetap hidup..", - "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jika Kamu mendapatkan banyak pemain yang masuk dan bergabung dalam permainan, aktifkan 'keluarkan pemain diam'\npada pengaturan untuk jaga-jaga jika seseorang lupa meninggalkan permainan.", - "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jika perangkatmu mulai panas atau Kamu mau menghemat baterai,\nturunkan \"Visual\" atau \"Resolusi\" pada Pengaturan->Grafis", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jika Kamu tidak mempunyai pengontrol, pasang apl. '${REMOTE_APP_NAME}\npada perangkat hand phonemu untuk menggunakannya sebagai pengontrol.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Jika bomb lengket menempel padamu, coba melompat-lompat dan berputar secara melingkar. Kamu mungkin\ndapat menyingkirkan bomb itu, atau tidak, momen terakhirmu akan menghibur.", + "If you kill an enemy in one hit you get double points for it.": "Jika kamu membunuh musuh dengan sekali serangan maka kamu akan mendapat poin ganda.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jika kamu mengambil kutukan, satu-satunya harapanmu untuk hidup adalah\nmenemukan kotak medis dalam 5 detik.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Jika kamu berdiam diri, maka kamu akan tamat. Lari dan menghindar untuk tetap hidup..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jika kamu mendapatkan banyak pemain yang masuk dan bergabung dalam permainan, aktifkan 'otomatis keluarkan pemain nganggur'\npada pengaturan untuk jaga-jaga jika seseorang lupa meninggalkan permainan.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jika perangkatmu mulai panas atau kamu mau menghemat baterai,\nturunkan \"Visual\" atau \"Resolusi\" pada Pengaturan->Grafis", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jika framerate-mu lemah, coba turunkan resolusi\natau visual dalam pengaturan grafis permainan.", "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Dalam Ambil-Benderanya, benderamu sendiri harus ada pada bentengmu untuk mencetak skor, jika tim lain\nakan mencetak skor, mengambil benderanya adalah cara yang bagus untuk menghentikannnya.", - "In hockey, you'll maintain more speed if you turn gradually.": "Dalam hoki, Kamu dapat mempertahankan kecepatanmu jika Kamu berbelok secara bertahap.", + "In hockey, you'll maintain more speed if you turn gradually.": "Dalam hoki, kamu dapat mempertahankan kecepatanmu jika kamu berbelok secara bertahap.", "It's easier to win with a friend or two helping.": "Lebih mudah menang jika dibantu teman.", "Jump just as you're throwing to get bombs up to the highest levels.": "Lompat sambil melempar bom untuk membuat bom melambung tinggi.", "Land-mines are a good way to stop speedy enemies.": "Ranjau adalah cara yang bagus untuk menghentikan musuh yang cepat.", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Banyak hal yang dapat diambil dan dilempar, termasuk pemain lain. Membuang\nmusuhmu ke jurang akan lebih efektif.", "No, you can't get up on the ledge. You have to throw bombs.": "Tidak, Kamu tidak dapat melewati pembatas. Kamu harus melempar bom.", - "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Pemain dapat masuk dan keluar ditengah-tengah permainan,\ndan Kamu juga dapat menyambung dan memutuskan kontroller.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Pemain dapat masuk dan keluar ditengah-tengah permainan,\ndan kamu juga dapat menyambung dan memutuskan pengontrol.", "Practice using your momentum to throw bombs more accurately.": "Latihan menggunakan momentum-mu untuk melempar bom lebih akurat.", - "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pukulan mendapatkan lebih banyak serangan ketika Kamu\nberlari, melompat, dan berputar.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pukulan mendapatkan lebih banyak serangan ketika kamu\nberlari, melompat, dan berputar.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Lari maju mundur untuk melempar bom\nsangat jauh.", "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Hancurkan sekumpulan musuh dengan\nmemasang TNT dan meledakkannya dengan bom.", "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Kepala adalah tempat yang paling rapuh, jadi menempelkannya dengan bom-lengket\nakan membuat musuhmu \"GAME OVER\".", "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Level ini tidak akan pernah berakhir, tetapi skor\nakan membuat semua takjub didunia ini.", - "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kekuatan lemparan tergantung dimana Kamu melempar.\nJika Kamu ingin melempar lebih lembut, jangan terlalu banyak bergerak.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kekuatan lemparan tergantung dimana kamu melempar.\nJika kamu ingin melempar lebih lembut, jangan terlalu banyak bergerak.", "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Bosan dengan soundtrack lama? Ganti dengan milikmu sendiri!\nLihat Pengaturan->Suara->Soundtrack", - "Try 'Cooking off' bombs for a second or two before throwing them.": "Cobalah menunggu sumbu bom-mu mati lalu lempar.", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Cobalah menunggu sumbu bom-mu terbakar beberapa detik lalu lempar.", "Try tricking enemies into killing eachother or running off cliffs.": "Cobalah menipu musuhmu dengan membuatnya saling membunuh atau lari ke jurang.", "Use the pick-up button to grab the flag < ${PICKUP} >": "Gunakkan tombol ambil untuk mengambil bendera < ${PICKUP} >", "Whip back and forth to get more distance on your throws..": "Jalan maju mundur untuk melempar lebih jauh..", "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Kamu dapat 'mengarahkan' tinjuanmu dengan memutar ke kiri atau ke kanan.\nIni berguna untuk memukul musuh di tepian atau membuat gol di permainan hoki.", "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Kamu dapat memperkirakan bom yang akan meledak dengan melihat warna percikan bom itu sendiri:\nKuning..Jingga..Merah..DUARRR.", "You can throw bombs higher if you jump just before throwing.": "Kamu dapat melempar bom lebih tinggi jika kamu melompat sebelum melemparnya.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Kamu akan kesakitan jika kamu menabrakan kepalamu ke benda lain,\nJadi,Jangan tabrakan kepalamu ke benda lain.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Kamu akan kesakitan jika kamu menabrakkan kepalamu ke benda lain,\nJadi, jangan tabrakan kepalamu ke benda lain.", "Your punches do much more damage if you are running or spinning.": "Pukulanmu akan lebih sakit jika kamu lari atau berputar-putar." } }, @@ -1766,52 +1890,55 @@ "trophiesText": "Piala", "trophiesThisSeasonText": "Piala Musim Ini", "tutorial": { - "cpuBenchmarkText": "Proses tutorial dengan kecepatan super cepat(CPU test)", - "phrase01Text": "Hai, apa kabar?", + "cpuBenchmarkText": "Proses tutorial dengan kecepatan super cepat (terutama uji coba kecepatan CPU)", + "phrase01Text": "Hai, apa kabar?", "phrase02Text": "Selamat Datang di ${APP_NAME}", "phrase03Text": "Ada sedikit tips untuk mengontrol karaktermu:", - "phrase04Text": "Banyak hal di ${APP_NAME} yang didasarkan pada FISIKA", - "phrase05Text": "Misalnya, ketika kamu meninju....", - "phrase06Text": "... kecepatan lenganmu memengaruhi tinjuanmu.", - "phrase07Text": "Lihat? Kamu hanya diam, jadi ${NAME} hanya kegelian", - "phrase08Text": "Sekarang, cobalah lompat sembari berputar supaya lebih cepat.", - "phrase09Text": "Hmm, lebih baik", - "phrase10Text": "Berlari juga membantu", + "phrase04Text": "Banyak hal di ${APP_NAME} yang didasarkan pada hukum FISIKA", + "phrase05Text": "Misalnya, ketika kamu meninju....", + "phrase06Text": "..kekuatan tinjuan-mu itu berdasarkan kecepatan ayunan lenganmu.", + "phrase07Text": "Tuh kan? Dia ngga gerak, si ${NAME} cuma kegelian.", + "phrase08Text": "Sekarang, coba lompat sambil berputar untuk dapat kecepatan lebih.", + "phrase09Text": "Nah, lebih nikmat.", + "phrase10Text": "Berlari juga membantu.", "phrase11Text": "Tahan tombol APA SAJA untuk berlari.", "phrase12Text": "Untuk tinjuan super maut, cobalah lari dan berputar.", - "phrase13Text": "Ups, maaf ya ${NAME}!", - "phrase14Text": "Kamu dapat mengangkat lalu melempar barang, bendera, atau mungkin.... ${NAME}", + "phrase13Text": "Ups, maaf ya ${NAME}.", + "phrase14Text": "Kamu dapat mengangkat dan melempar barang, bendera, bahkan.. Si ${NAME}", "phrase15Text": "Yang terakhir, BOM.", "phrase16Text": "Melempar bom butuh latihan.", - "phrase17Text": "Eh! Lemparanmu sangat buruk!", - "phrase18Text": "Lempar bom sambil lari juga membantu.", - "phrase19Text": "Lompat membuat lemparanmu makin tinggi.", + "phrase17Text": "Ouch! Lemparanmu payah.", + "phrase18Text": "Lempar bom sambil jalan juga membantu.", + "phrase19Text": "Melompat membuat lemparanmu makin tinggi.", "phrase20Text": "Lempar sambil berputar untuk lemparan terjauh.", - "phrase21Text": "Mengatur waktu bom dapat jadi sulit.", + "phrase21Text": "Prediksi waktu bom itu cukup sulit.", "phrase22Text": "Yah, meleset", "phrase23Text": "Tunggu bom hingga matang, lalu lempar.", - "phrase24Text": "Horee! Kerja Bagus.", - "phrase25Text": "Yap, sepertinya itu saja.", + "phrase24Text": "Yay! Kerja Bagus.", + "phrase25Text": "Yap, kayaknya itu aja.", "phrase26Text": "Hantam mereka, Joe!", - "phrase27Text": "Ingat latihanmu, agar kamu dapat kembali hidup-hidup!", - "phrase28Text": "... em, mungkin sih...", - "phrase29Text": "Semoga beruntung kawan !", + "phrase27Text": "Ingat latihanmu, supaya kamu DAPAT kembali hidup-hidup!", + "phrase28Text": "...ehm, mungkin sih...", + "phrase29Text": "Semoga beruntung kawan!", "randomName1Text": "Ucup", "randomName2Text": "Asep", "randomName3Text": "Galang", - "randomName4Text": "Suci", - "randomName5Text": "Aldi", + "randomName4Text": "Udin", + "randomName5Text": "Agus", "skipConfirmText": "Yakin ingin melompati pembelajaran? Tekan apa saja untuk konfirmasi.", - "skipVoteCountText": "${COUNT} dari ${TOTAL} suara untuk melewati pembelajaran", - "skippingText": "Melewati pembelajaran...", + "skipVoteCountText": "${COUNT} dari ${TOTAL} suara untuk melewati latihan", + "skippingText": "melewati latihan...", "toSkipPressAnythingText": "(tekan apa saja untuk melompati pembelajaran)" }, "twoKillText": "PEMBUNUHAN GANDA!", + "uiScaleText": "Skala UI", "unavailableText": "tidak tersedia", + "unclaimedPrizesText": "Kamu punya hadiah yang belum diterima!", "unconfiguredControllerDetectedText": "Pengontrol belum terkonfigurasi terdeteksi:", "unlockThisInTheStoreText": "Tersedia di toko terdekat.", - "unlockThisProfilesText": "Untuk membuat lebih dari ${NUM} profil, Kamu memerlukan:", - "unlockThisText": "Untuk buka ini,kamu membutuhkan:", + "unlockThisProfilesText": "Untuk membuat lebih dari ${NUM} profil, kamu membutuhkan:", + "unlockThisText": "Untuk buka ini, kamu membutuhkan:", + "unsupportedControllerText": "Maaf, pengontrol \"${NAME}\" tidak didukung.", "unsupportedHardwareText": "Maaf, perangkat ini tidak mendukung build permainan ini.", "upFirstText": "Game pertama:", "upNextText": "${COUNT} game berikutnya:", @@ -1819,11 +1946,15 @@ "upgradeText": "Tingkatkan", "upgradeToPlayText": "Buka \"${PRO}\" di toko game untuk bermain.", "useDefaultText": "Gunakan Default", + "userSystemScriptsCreateText": "Buat Skrip Sistem Pengguna", + "userSystemScriptsDeleteText": "Hapus Skrip Sistem Pengguna", "usesExternalControllerText": "Game ini menggunakan pengontrol external untuk input.", "usingItunesText": "Menggunakan soundtrack dari aplikasi Musik", "usingItunesTurnRepeatAndShuffleOnText": "Tolong pastikan lagu diacak dan diulang di iTunes. ", "v2AccountLinkingInfoText": "Untuk menautkan akun V2, gunakan tombol 'Manajemen Akun'.", - "validatingTestBuildText": "Memvalidasi Bangunan Tes...", + "v2AccountRequiredText": "Membutuhkan akun V2. Upgrade akunmu dan coba lagi.", + "validatingTestBuildText": "Memvalidasi Tes Build...", + "viaText": "melalui", "victoryText": "Menang!", "voteDelayText": "Kamu tidak dapat memulai pemilihan suara dalam ${NUMBER} detik", "voteInProgressText": "Pemilihan suara sedang dalam proses.", @@ -1840,17 +1971,17 @@ "deleteReplayButtonText": "Hapus\nReplay", "myReplaysText": "Replayku", "noReplaySelectedErrorText": "Tidak Ada Replay Terpilih", - "playbackSpeedText": "Kecepatan Putar Ulang: ${SPEED}", - "renameReplayButtonText": "Ganti\nNama", - "renameReplayText": "Mengubah nama\"${REPLAY}\" ke", + "playbackSpeedText": "Kecepatan Pemutaran: ${SPEED}", + "renameReplayButtonText": "Ganti Nama\nReplay", + "renameReplayText": "Mengubah nama \"${REPLAY}\" menjadi:", "renameText": "Ganti Nama", - "replayDeleteErrorText": "Galat menghapus replay", - "replayNameText": "Nama Replay", - "replayRenameErrorAlreadyExistsText": "Replay dengan nama yang sudah ada", - "replayRenameErrorInvalidName": "Tidak dapat menganti nama replay; nama invailid", - "replayRenameErrorText": "Error mengganti nama replay", - "sharedReplaysText": "Replay dibagikan", - "titleText": "Nonton", + "replayDeleteErrorText": "Kesalahan menghapus replay.", + "replayNameText": "Nama Rekaman", + "replayRenameErrorAlreadyExistsText": "Rekaman dengan nama tersebut sudah ada", + "replayRenameErrorInvalidName": "Tidak dapat mengganti nama rekaman; nama tidak valid", + "replayRenameErrorText": "Error mengganti nama rekaman", + "sharedReplaysText": "Replay Yang Dibagikan", + "titleText": "Tonton", "watchReplayButtonText": "Lihat\nReplay" }, "waveText": "Gelombang", @@ -1874,10 +2005,10 @@ "winsPlayerText": "${NAME} Menang!", "winsTeamText": "${NAME} Menang!", "winsText": "${NAME} Menang!", - "workspaceSyncErrorText": "Menyinkronkan ke ${WORKSPACE} error. Lihat log untuk lebih detailnya.", + "workspaceSyncErrorText": "Kesalahan menyinkronkan ke ${WORKSPACE}. Lihat log untuk lebih detailnya.", "workspaceSyncReuseText": "Tidak bisa menyinkronkan ${WORKSPACE}. Menggunakan kembali versi sinkronan sebelumnya.", "worldScoresUnavailableText": "Skor Dunia tidak tersedia.", - "worldsBestScoresText": "Nilai Terbaik Dunia", + "worldsBestScoresText": "Nilai Publik Terbaik", "worldsBestTimesText": "Waktu Terbaik Dunia", "xbox360ControllersWindow": { "getDriverText": "Dapatkan Driver", @@ -1888,6 +2019,7 @@ "titleText": "Menggunakan pengontrol Xbox 360 dengan ${APP_NAME}:" }, "yesAllowText": "Ya, Izinkan!", - "yourBestScoresText": "Skor terbaikmu", - "yourBestTimesText": "Waktu Terbaikmu" + "yourBestScoresText": "Skor Terbaikmu", + "yourBestTimesText": "Waktu Terbaikmu", + "yourPrizeText": "Hadiahmu:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/italian.json b/dist/ba_data/data/languages/italian.json index 0361c7f7..af0d014b 100644 --- a/dist/ba_data/data/languages/italian.json +++ b/dist/ba_data/data/languages/italian.json @@ -7,7 +7,9 @@ "campaignProgressText": "Progresso Campagna [Difficile]: ${PROGRESS}", "changeOncePerSeason": "Puoi cambiare questa cosa solo una volta a stagione.", "changeOncePerSeasonError": "Devi aspettare la prossima stagione per apportare delle modifiche (${NUM} days)", + "createAnAccountText": "Crea un'Account", "customName": "Nome Personalizzato", + "deleteAccountText": "Elimina Account", "deviceSpecificAccountText": "Stai usando un account automaticamente generato: ${NAME}", "googlePlayGamesAccountSwitchText": "Se desideri utilizzare un'altro account Google,\nutilizza l'app Google Play Games.", "linkAccountsEnterCodeText": "Inserisci il codice", @@ -17,24 +19,26 @@ "linkAccountsInstructionsText": "Per collegare due account, crea un codice su uno\ndei dispositivi e inserisci quel codice negli altri. \nProgressi e inventario verranno combinati.\nPuoi collegare fino a ${COUNT} account.\n\nIMPORTANTE: Collega solo account che possiedi!\nSe colleghi un account con un tuo amico non potrete\ngiocare allo stesso momento!\n \nInoltre: questa operazione non può essere annullata, quindi stai attento!", "linkAccountsText": "Collega account", "linkedAccountsText": "Account Collegati:", - "manageAccountText": "Gestisci account", + "manageAccountText": "Gestisci Account", "nameChangeConfirm": "Confermi di voler modificare il tuo nome in ${NAME}?", "notLoggedInText": "", - "resetProgressConfirmNoAchievementsText": "Stai per cancellare i tuoi progressi in\nmodalità cooperativa, i tuoi obbiettivi, i tuoi punteggi\nlocali (ma non i tuoi biglietti). \n\nL'operazione è irreversibile: continuare?", + "resetProgressConfirmNoAchievementsText": "Stai per cancellare i tuoi progressi in modalità cooperativa,\ni tuoi obiettivi ed i tuoi punteggi locali (ma non i tuoi biglietti). \nL'operazione è irreversibile: continuare?", "resetProgressConfirmText": "Stai per cancellare i tuoi progressi in\nmodalità cooperativa, i tuoi punteggi\nlocali e i tuoi obiettivi (ma non i tuoi biglietti).\nL'operazione è irreversibile: continuare?", "resetProgressText": "Cancella Progressi", "setAccountName": "Inserisci un nome utente", "setAccountNameDesc": "Seleziona quale nome visualizzare per il tuo account.\nPuoi usare quel nome per uno dei tuoi account collegati,\noppure creare un unico nome personalizzato.", "signInInfoText": "Accedi per raccogliere biglietti, competere online,\ne condividere i progressi tra i vari dispositivi.", "signInText": "Accedi", + "signInWithAnEmailAddressText": "Accedi con un indirizzo email", "signInWithDeviceInfoText": "(Un solo account automatico è disponibile per questo dispositivo)", "signInWithDeviceText": "Accedi con l'account del dispositivo", "signInWithGameCircleText": "Accedi con Game Circle", "signInWithGooglePlayText": "Accedi con Google Play", "signInWithTestAccountInfoText": "(tipo di account obsoleto; usa gli account dispositivo d'ora in poi)", "signInWithTestAccountText": "Accedi con un account di prova", + "signInWithText": "Accedi con ${SERVICE}", "signInWithV2InfoText": "(un account che funziona su tutte le piattaforme)", - "signInWithV2Text": "Effettua l'accesso con un account di BombSquad", + "signInWithV2Text": "Accedi con un account ${APP_NAME}", "signOutText": "Esci", "signingInText": "Accesso in corso...", "signingOutText": "Uscita in corso...", @@ -45,7 +49,7 @@ "titleText": "Account", "unlinkAccountsInstructionsText": "Seleziona un account da scollegare", "unlinkAccountsText": "Scollega Account", - "unlinkLegacyV1AccountsText": "Desvincular cuentas heredadas (V1)", + "unlinkLegacyV1AccountsText": "Scollega gli account legacy (V1)", "v2LinkInstructionsText": "Usa questo link per creare un account o accedere.", "viaAccount": "(tramite ${NAME})", "youAreLoggedInAsText": "Accesso effettuato come:", @@ -334,15 +338,20 @@ }, "achievementsRemainingText": "Trofei rimasti:", "achievementsText": "Trofei", - "achievementsUnavailableForOldSeasonsText": "Mi dispiace, ma gli obbiettivi non sono disponibili per le stagioni vecchie.", + "achievementsUnavailableForOldSeasonsText": "Mi dispiace, ma gli obiettivi non sono disponibili per le stagioni vecchie.", "activatedText": "${THING} attivato.", "addGameWindow": { "getMoreGamesText": "Ottieni Giochi...", "titleText": "Aggiungi Partita" }, + "addToFavoritesText": "Aggiungi ai Preferiti", + "addedToFavoritesText": "'${NAME}' aggiunto ai Preferiti", + "allText": "Tutto", "allowText": "Consenti", "alreadySignedInText": "Il tuo account è collegato da un altro dispositivo;\ncambia account o chiudi il gioco nel tuo altro\ndispositivo e riprova.", "apiVersionErrorText": "Impossibile caricare il modulo ${NAME}; sono installate le API versione ${VERSION_USED}; è richiesta la ${VERSION_REQUIRED}.", + "applyText": "Applica", + "areYouSureText": "Vuoi davvero procedere?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" abilitalo solo quando sono connesse delle cuffie)", "headRelativeVRAudioText": "Audio VR Head-Relative", @@ -367,14 +376,24 @@ "boostText": "Potenziamento", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} è configurato nell'app stessa.", "buttonText": "pulsante", - "canWeDebugText": "Vorresti che BombSquad segnalasse automaticamente bug, errori\ne informazioni sull'utilizzo direttamente allo sviluppatore?\n\nQuesti dati non contengono informazioni personali e aiutano a \nmantenere il gioco privo di bug e rallentamenti.", + "canWeDebugText": "Vorresti che ${APP_NAME} segnalasse automaticamente bug, errori\ne informazioni sull'utilizzo direttamente allo sviluppatore?\n\nQuesti dati non contengono informazioni personali e aiutano a \nmantenere il gioco privo di bug e rallentamenti.", "cancelText": "Annulla", "cantConfigureDeviceText": "Spiacente, ${DEVICE} non è configurabile.", "challengeEndedText": "Questa sfida è finita.", "chatMuteText": "Silenzia Chat", "chatMutedText": "Chat Silenziata", "chatUnMuteText": "Smuta Chat", + "chests": { + "prizeOddsText": "Possibilità di vincita", + "reduceWaitText": "Diminiusci Attesa", + "slotDescriptionText": "Questo spazio può tenere un forziere.\n\nOttieni casse giocando livelli nella campagna,\nclassificandoti nei tornei, e completando\nobiettivi.", + "slotText": "Slot Forziere ${NUM}", + "slotsFullWarningText": "ATTENZIONE: Tutti gli spazi per casse sono pieni.\nLe casse che otterrai in questa partita saranno perse.", + "unlocksInText": "Si Sblocca Tra" + }, "choosingPlayerText": "", + "claimText": "Ottieni", + "codesExplainText": "i codici sono forniti dallo sviluppatore per\nscoprire e correggere problemi all'account.", "completeThisLevelToProceedText": "Devi completare questo\nlivello per procedere!", "completionBonusText": "Competizione bonus", "configControllersWindow": { @@ -458,6 +477,7 @@ "titleText": "Configura il Touchscreen", "touchControlsScaleText": "Scala dei Comandi Touch" }, + "configureDeviceInSystemSettingsText": "${DEVICE} può essere configurato nelle Impostazioni di Sistema.", "configureItNowText": "Configurarlo adesso?", "configureText": "Configura", "connectMobileDevicesWindow": { @@ -509,7 +529,7 @@ "toRankedText": "Al prossimo livello", "totalText": "Totale", "tournamentInfoText": "Competi per punteggi alti con\naltri giocatori della tua lega.\n\nI premi sono assegnati ai giocatori con\ni punteggi più alti quando il tempo del torneo scade.", - "welcome1Text": "Benvenuto in ${LEAGUE}. Puoi migliorare il tuo\n livello lega guadagnando stelle, completando\n obbiettivi, e vincendo i trofei.", + "welcome1Text": "Benvenuto in ${LEAGUE}. Puoi migliorare il tuo\n livello lega guadagnando stelle, completando\n obiettivi, e vincendo i trofei.", "welcome2Text": "Puoi anche guadagnare biglietti con molte attività simili.\nI biglietti possono essere usato per sbloccare nuovi capitoli, mappe e\nmini-giochi, per entrare nei tornei ed altro.", "yourPowerRankingText": "La tua posizione assoluta" }, @@ -568,6 +588,7 @@ "demoText": "Demo", "denyText": "Nega", "deprecatedText": "Deprecato", + "descriptionText": "Descrizione", "desktopResText": "Risoluzione Nativa", "deviceAccountUpgradeText": "Attenzione:\nHai effettuato l'accesso con un profilo dispositivo (${NAME}$).\nI profili dispositivi verranno rimossi in un aggiornamento futuro.\nAggiornati ad un profilo V2 se desideri mantenere i tuoi progressi.", "difficultyEasyText": "Facile", @@ -578,6 +599,10 @@ "disableRemoteAppConnectionsText": "Disattiva connessione remota all'app", "disableXInputDescriptionText": "Permette l'uso di più di 4 pulsantiere, ma potrebbe anche non funzionare.", "disableXInputText": "Disabilita XInput", + "disabledText": "DISABILITATO", + "discardText": "Butta", + "discordFriendsText": "Cerchi altri con cui giocare?\nEntra nel nostro server Discord e fatti nuovi amici!", + "discordJoinText": "Entra nel server Discord", "doneText": "Fatto", "drawText": "Pareggio", "duplicateText": "Duplicato", @@ -585,7 +610,7 @@ "addGameText": "Aggiungi\nGioco", "cantOverwriteDefaultText": "Non puoi sovrascrivere la scaletta predefinita!", "cantSaveAlreadyExistsText": "Una scaletta con quel nome esiste già!", - "cantSaveEmptyListText": "Non puoi salvare una scaletta vuota!", + "cantSaveEmptyListText": "Non puoi salvare una playlist vuota!", "editGameText": "Modifica\nGioco", "gameListText": "Serie di Partite", "listNameText": "Nome Scaletta", @@ -612,6 +637,7 @@ "localProfileText": "(profilo locale)", "nameDescriptionText": "Nome del giocatore", "nameText": "Nome", + "profileAlreadyExistsText": "Esiste già un profilo con quel nome.", "randomText": "casuale", "titleEditText": "Modifica Profilo", "titleNewText": "Nuovo Profilo", @@ -651,6 +677,7 @@ "useMusicFolderText": "Cartella di Musica" }, "editText": "Modifica", + "enabledText": "Abilitato", "endText": "Fine", "enjoyText": "Buon Divertimento!", "epicDescriptionFilterText": "${DESCRIPTION} a rallentatore leggendario.", @@ -662,6 +689,8 @@ "errorText": "Errore", "errorUnknownText": "errore sconosciuto", "exitGameText": "Uscire da ${APP_NAME}?", + "expiredAgoText": "Scaduta ${T} fa", + "expiresInText": "Scade tra ${T}", "exportSuccessText": "'${NAME}' esportato", "externalStorageText": "Memoria Esterna", "failText": "Perso", @@ -698,6 +727,8 @@ "editText": "Modifica\nScaletta", "gameListText": "Lista delle serie di partite", "newText": "Nuova\nScaletta", + "pointsToWinText": "Punti Per Vincere", + "seriesLengthText": "Durata Serie", "showTutorialText": "Mostra Guida", "shuffleGameOrderText": "Ordine Partite Casuale", "titleText": "Personalizza Scalette ${TYPE}" @@ -726,6 +757,7 @@ "copyCodeConfirmText": "Codice copiato negli appunti!", "copyCodeText": "Copia il codice", "dedicatedServerInfoText": "Per risultati migliori, crea un server dedicato. Vedi bombsquadgame.com/server per scoprire come.", + "descriptionShortText": "Utilizza la finestra raduna per creare un party.", "disconnectClientsText": "Questo disconnetterà ${COUNT} giocatore/i\nnel tuo gruppo. Sei sicuro?", "earnTicketsForRecommendingAmountText": "I tuoi amici riceveranno ${COUNT} biglietti se proveranno il gioco\n(anche tu riceverai ${YOU_COUNT} biglietti per ogni amico che lo farà)", "earnTicketsForRecommendingText": "Condividi il gioco\nper biglietti gratis...", @@ -738,10 +770,10 @@ "friendHasSentPromoCodeText": "${COUNT} biglietti di ${APP_NAME} da ${NAME}", "friendPromoCodeAwardText": "Riceverai ${COUNT} biglietti ogni volta che viene usato.", "friendPromoCodeExpireText": "Questo codice scadrà in ${EXPIRE_HOURS} ore e funziona soltanto per nuovi giocatori.", - "friendPromoCodeInstructionsText": "Per usarlo, apri ${APP_NAME} e vai su \"Impostazioni->Avanzate->Inserisci Codice\".\nVisita bombsquadgame.com per i link di download per tutte le versioni supportate.", + "friendPromoCodeInstructionsText": "Per usarlo, apri ${APP_NAME} e vai su \"Impostazioni->Avanzate->Invia Informazioni\".\nVisita bombsquadgame.com per i link di download per tutte le versioni supportate.", "friendPromoCodeRedeemLongText": "Puó essere utilizzato per ${COUNT} biglietti gratis per un massimo di ${MAX_USES} persone.", "friendPromoCodeRedeemShortText": "Puó essere utilizzato per ${COUNT} biglietti nel gioco.", - "friendPromoCodeWhereToEnterText": "(in \"Impostazioni->Avanzate->Inserisci Codice\")", + "friendPromoCodeWhereToEnterText": "(in \"Impostazioni->Avanzate->Invia Informazioni\")", "getFriendInviteCodeText": "Ottieni un Codice di Invito", "googlePlayDescriptionText": "Invita giocatori Google Play nel tuo gruppo:", "googlePlayInviteText": "Invita", @@ -773,11 +805,12 @@ "manualYourLocalAddressText": "Indirizzo locale:", "nearbyText": "Locale", "noConnectionText": "", + "noPartiesAddedText": "Nessun Party Aggiunto", "otherVersionsText": "(altre versioni)", "partyCodeText": "Codice del Party", "partyInviteAcceptText": "Accetta", "partyInviteDeclineText": "Rifiuta", - "partyInviteGooglePlayExtraText": "(vedi la scheda 'Google Play' nella finestra 'Raduna')", + "partyInviteGooglePlayExtraText": "(vedi la scheda 'Google Play' nella finestra 'Raduna') ", "partyInviteIgnoreText": "Ignora", "partyInviteText": "${NAME} ti ha invitato\nad unirsi al suo party!", "partyNameText": "Nome Party", @@ -844,6 +877,12 @@ "youHaveShortText": "Hai ${COUNT}", "youHaveText": "Hai ${COUNT} biglietti" }, + "goldPass": { + "desc1InfTokensText": "Gettoni infiniti.", + "desc2NoAdsText": "Niente pubblicità.", + "desc3ForeverText": "Per sempre.", + "goldPassText": "Pass d'Oro" + }, "googleMultiplayerDiscontinuedText": "Mi dispiace, il servizio multiplayer di Google non è più disponibile.\nSto lavorando per sostituirlo il più velocemente possibile.\nFino a quando non troverò una soluzione, prova un altro metodo per connetterti.\n-Eric", "googlePlayPurchasesNotAvailableText": "Gli acquisti Google Play non sono disponibili.\nPotresti dover aggiornare lo store.", "googlePlayServicesNotAvailableText": "Google Play Services non è disponibile.\nAlcune funzionalità dell'app saranno disattivate.", @@ -853,16 +892,18 @@ "autoText": "Automatico", "fullScreenCmdText": "Schermo intero (Cmd-F)", "fullScreenCtrlText": "Schermo intero (Ctrl-F)", + "fullScreenText": "Schermo intero", "gammaText": "Gamma", "highText": "Alto", "higherText": "Più alto", "lowText": "Basso", + "maxFPSText": "FPS massimi", "mediumText": "Medio", "neverText": "Mai", "resolutionText": "Risoluzione", "showFPSText": "Mostra FPS", "texturesText": "Textures", - "titleText": "Grafiche", + "titleText": "Grafica", "tvBorderText": "Bordo della TV", "verticalSyncText": "Sincronizzazione verticale", "visualsText": "Visuali" @@ -920,6 +961,7 @@ "importText": "Importa", "importingText": "Importando...", "inGameClippedNameText": "Nel gioco ci sarà\n\"${NAME}\"", + "inboxText": "Posta", "installDiskSpaceErrorText": "ERRORE: Impossibile completare l'installazione. \nPotresti aver esaurito lo spazio sul tuo dispositivo. \nLibera un po' di spazio e prova di nuovo.", "internal": { "arrowsToExitListText": "Premi ${LEFT} o ${RIGHT} per uscire dalla serie", @@ -976,12 +1018,14 @@ "touchScreenJoinWarningText": "Ti sei unito al gioco con il touchscreen.\nSe è stato un errore, premi 'Menu->Lascia Gioco'.", "touchScreenText": "TouchScreen", "trialText": "prova", + "unableToCompleteTryAgainText": "Impossibile completare ciò al momento.\nPerfavore riprovare.", "unableToResolveHostText": "Errore: impossibile connettersi all'host", "unavailableNoConnectionText": "Non è al momento disponibile (dipende dalla tua connessione?)", "vrOrientationResetCardboardText": "Usa questo per ripristinare l'orientamento del VR.\nPer giocare avrai bisogno di un controller esterno.", "vrOrientationResetText": "Ripristina orientamento VR.", "willTimeOutText": "(se inattivo potrai riprendere il controllo)" }, + "inventoryText": "Inventario", "jumpBoldText": "SALTO", "jumpText": "Salta", "keepText": "Mantieni", @@ -1028,8 +1072,11 @@ "seasonEndsMinutesText": "La stagione finisce tra ${NUMBER} minuti.", "seasonText": "Stagione ${NUMBER}", "tournamentLeagueText": "Devi raggiungere la lega ${NAME} per partecipare a questo torneo.", - "trophyCountsResetText": "Il numero dei trofei verra azzerato la prossima stagione." + "trophyCountsResetText": "Il numero dei trofei verra azzerato la prossima stagione.", + "upToDateBonusDescriptionText": "I giocatori che utilizzano una versione recente del\ngioco otterranno un bonus del ${PERCENT}% qui.", + "upToDateBonusText": "Bonus Aggiornato" }, + "learnMoreText": "Scopri di più", "levelBestScoresText": "Miglior punteggio in ${LEVEL}", "levelBestTimesText": "Miglior tempo in ${LEVEL}", "levelFastestTimesText": "Tempo migliore su ${LEVEL}", @@ -1072,10 +1119,12 @@ "maxConnectionsText": "Connessioni massime", "maxPartySizeText": "Dimensione massima gruppo", "maxPlayersText": "Giocatori massimi", - "merchText": "Mercancía!", + "merchText": "Magliette!", "modeArcadeText": "Modalità Arcade", "modeClassicText": "Modalità Classica", "modeDemoText": "Modalità Demo", + "moreSoonText": "Di più in arrivo...", + "mostDestroyedPlayerText": "Giocatore più distrutto", "mostValuablePlayerText": "Giocatore Più Bravo", "mostViolatedPlayerText": "Giocatore Più Ucciso", "mostViolentPlayerText": "Giocatore Più Violento", @@ -1092,6 +1141,7 @@ "nameSuicideText": "${NAME} si è suicidato.", "nameText": "Nome", "nativeText": "Nativa", + "newExclaimText": "Novità!", "newPersonalBestText": "Nuovo record personale!", "newTestBuildAvailableText": "Una nuova versione beta è disponibile (${VERSION} build ${BUILD}).\nScaricala da ${ADDRESS}", "newText": "Nuovo", @@ -1103,13 +1153,17 @@ "noExternalStorageErrorText": "Nessun archiviatore esterno trovato su questo dispositivo", "noGameCircleText": "Errore: non hai effettuato il login su GameCircle", "noJoinCoopMidwayText": "Non puoi entrare in una partita cooperativa già iniziata.", + "noMessagesText": "Nessun messaggio.", + "noPluginsInstalledText": "Nessun Plugin Installato", "noProfilesErrorText": "Non hai un profilo giocatore, quindi sei bloccato con '${NAME}'.\nVai su Impostazioni > Profili giocatore per creare un profilo personale.", "noScoresYetText": "Ancora nessun punteggio.", + "noServersFoundText": "Nessun server individuato.", "noThanksText": "No Grazie", "noTournamentsInTestBuildText": "I punteggi del torneo di questo test build verranno ignorati", "noValidMapsErrorText": "Non sono state trovate mappe valide per questo tipo di gioco.", "notEnoughPlayersRemainingText": "Non ci sono più abbastanza giocatori: esci e inizia un'altra partita.", "notEnoughPlayersText": "Hai bisogno di almeno ${COUNT} giocatori per iniziare questa partita!", + "notEnoughTicketsText": "Non hai abbastanza biglietti fra", "notNowText": "Non ora", "notSignedInErrorText": "Per fare questo, devi accedere.", "notSignedInGooglePlayErrorText": "Per fare questo devi accedere a Google Play.", @@ -1122,6 +1176,9 @@ "onText": "Attiva", "oneMomentText": "Un Momento...", "onslaughtRespawnText": "${PLAYER} ritornerà all'ondata ${WAVE}", + "openMeText": "Aprimi!", + "openNowText": "Apri Ora", + "openText": "Apri", "orText": "${A} o ${B}", "otherText": "Altro", "outOfText": "(#${RANK} su ${ALL})", @@ -1178,7 +1235,11 @@ "pleaseWaitText": "Attendi...", "pluginClassLoadErrorText": "Errore nel caricamento di plugin classe '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Errore inizializzazione plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Impostazioni plugin", + "pluginsAutoEnableNewText": "Auto abilitazione nuovi plugins", "pluginsDetectedText": "nuovo/i plugin rilevato. Riavvia per attivarli, o configurali nelle impostazioni.", + "pluginsDisableAllText": "Disabilita tutti i plugins", + "pluginsEnableAllText": "Abilita tutti i plugins", "pluginsRemovedText": "${NUM} plugin non trovati.", "pluginsText": "Plugin", "practiceText": "Allenamento", @@ -1211,6 +1272,8 @@ "punchText": "Pugno", "purchaseForText": "Acquista per ${PRICE}", "purchaseGameText": "Acquista il gioco", + "purchaseNeverAvailableText": "Purtroppo, gli acquisti non sono disponibili su questa versione.\nProva ad accedere al tuo account su un'altra piattaforma e fare gli acquisti lì.", + "purchaseNotAvailableText": "Non disponibile per l'acquisto.", "purchasingText": "Acquisto in corso...", "quitGameText": "Uscire da ${APP_NAME}?", "quittingIn5SecondsText": "Uscendo in 5 secondi...", @@ -1253,6 +1316,7 @@ "version_mismatch": "Incompatibilità di versione.\nAssicurati che BombSquad e BombSquad Remote\nsiano alla stessa versione e riprova." }, "removeInGameAdsText": "Sblocca \"${PRO}\" nel negozio per rimuovere le pubblicità.", + "removeInGameAdsTokenPurchaseText": "PER UN TEMPO LIMITATO: Acquista QUALSIASI pacco di gettoni per rimuovere la pubblicità.", "renameText": "Rinomina", "replayEndText": "Fine Replay", "replayNameDefaultText": "Replay Ultima Partita", @@ -1273,7 +1337,9 @@ "revertText": "Ritorna", "runText": "Corri", "saveText": "Salva", - "scanScriptsErrorText": "Errore/i nella lettura degli script, guardare il log per i dettagli.", + "scanScriptsErrorText": "Errore/i nella lettura degli script. guardare il log per i dettagli.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} altri moduli necessitano di essere aggiornati per la api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} necessita di essere aggiornato per la api ${API}.", "scoreChallengesText": "Punteggi sfida", "scoreListUnavailableText": "Lista punteggi non disponibile.", "scoreText": "Punteggio", @@ -1284,6 +1350,7 @@ }, "scoreWasText": "(era ${COUNT})", "selectText": "Seleziona", + "sendInfoDescriptionText": "Invia le informazioni sullo stato dell'account e dell'applicazione allo sviluppatore.\nPrego di includere il proprio nome o il motivo dell'invio.", "seriesWinLine1PlayerText": "VINCE LA", "seriesWinLine1TeamText": "VINCE LA", "seriesWinLine1Text": "VINCE LA", @@ -1300,24 +1367,33 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(una semplice tastiera sullo schermo per editare testi)", - "alwaysUseInternalKeyboardText": "Usa Sempre La Tastiera Interna", + "alwaysUseInternalKeyboardText": "Usa sempre la tastiera interna", "benchmarksText": "Benchmarks & Prove Di Stress", + "devToolsText": "Strumenti di Sviluppo", "disableCameraGyroscopeMotionText": "Disabilita il movimento della visuale tramite giroscopio", "disableCameraShakeText": "Disabilita il tremolio della visuale", - "disableThisNotice": "(puoi disattivare questo messaggio su Impostazioni>Avanzate)", + "disableThisNotice": "(puoi disattivare questo messaggio su Impostazioni > Avanzate)", "enablePackageModsDescriptionText": "(abilita la possibilità di modding aggiuntivo ma disabilita il gioco in rete)", "enablePackageModsText": "Abilita Mod Dei Pacchetti Locali", "enterPromoCodeText": "Inserisci il Codice", "forTestingText": "Note: questi valori sono solo di prova e saranno cancellati uscendo dalla app.", "helpTranslateText": "Le traduzioni di ${APP_NAME} sono un contributo\ndella comunità. Se vuoi contribuire o correggere una\ntraduzione, segui il link qui sotto. Grazie in anticipo!", + "insecureConnectionsDescriptionText": "non è consigliato, ma potrebbe consentire\ndi giocare online da regioni o reti protette", + "insecureConnectionsText": "Usa connessioni non sicure", "kickIdlePlayersText": "Caccia i giocatori inattivi", "kidFriendlyModeText": "Modalità per bambini (violenza ridotta e altro)", "languageText": "Lingua", "moddingGuideText": "Manuale di personalizzazione", + "moddingToolsText": "Strumenti di Modding", "mustRestartText": "Devi riavviare il gioco per apportare questa modifica.", "netTestingText": "Collaudo Rete", "resetText": "Reset", + "sendInfoText": "Invia Informazioni", "showBombTrajectoriesText": "Mostra le traiettorie delle bombe", + "showDemosWhenIdleText": "Mostra demo quando inattivo", + "showDeprecatedLoginTypesText": "Mostra metodi di login obsoleti", + "showDevConsoleButtonText": "Mostra tasto console sviluppatore", + "showInGamePingText": "Mostra il ping in gioco", "showPlayerNamesText": "Mostra i nomi dei giocatori", "showUserModsText": "Apri cartella personalizzazioni", "titleText": "Avanzato", @@ -1325,8 +1401,8 @@ "translationFetchErrorText": "stato traduzione non disponibile", "translationFetchingStatusText": "controllo stato traduzione...", "translationInformMe": "Informami quando la mia lingua ha bisogno di aggiornamenti", - "translationNoUpdateNeededText": "la traduzione italiana è completa; woohoo!", - "translationUpdateNeededText": "** ci sono testi da tradurre!! **", + "translationNoUpdateNeededText": "La traduzione italiana è completa; woohoo!", + "translationUpdateNeededText": "** Ci sono testi da tradurre!! **", "vrTestingText": "Collaudo VR" }, "shareText": "Condividi", @@ -1336,6 +1412,9 @@ "signInWithGameCenterText": "Per utilizzare un account Game Center,\naccedi utilizzando l'app Game Center.", "singleGamePlaylistNameText": "Solo ${GAME}", "singlePlayerCountText": "Un giocatore", + "sizeLargeText": "Grande", + "sizeMediumText": "Medio", + "sizeSmallText": "Piccolo", "soloNameFilterText": "${NAME} Testa a Testa", "soundtrackTypeNames": { "CharSelect": "Selezione del personaggio", @@ -1361,6 +1440,7 @@ }, "spaceKeyText": "spazio", "statsText": "statistiche", + "stopRemindingMeText": "Non Ricordarmelo Più", "storagePermissionAccessText": "Richiede l'accesso alla memoria locale", "store": { "alreadyOwnText": "Hai già acquistato ${NAME}!", @@ -1412,6 +1492,8 @@ "storeText": "Negozio", "submitText": "Inoltra", "submittingPromoCodeText": "Inoltrando il Codice...", + "successText": "Fatto!", + "supportEmailText": "Se riscontri problemi con l'app,\nper favore scrivi a ${EMAIL}.", "teamNamesColorText": "Colore/Nome Team", "teamsText": "Squadre", "telnetAccessGrantedText": "Accesso a telnet abilitato", @@ -1422,6 +1504,7 @@ "testBuildValidatedText": "Build Di Prova Validata; Divertiti!", "thankYouText": "Grazie per il supporto! Goditi il gioco!!", "threeKillText": "TRIPLA UCCISIONE!!", + "ticketsDescriptionText": "I Biglietti si usano per sbloccare personaggi,\nmappe, minigiochi, ed altro nel negozio.\n\nI Biglietti si possono trovare nei forzieri e vincere\nnelle campagne, nei tornei, e con gli obiettivi trofeo.", "timeBonusText": "Bonus Tempo", "timeElapsedText": "Tempo trascorso", "timeExpiredText": "Tempo Scaduto", @@ -1432,10 +1515,24 @@ "tipText": "Consiglio", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Ottieni Gettoni", + "notEnoughTokensText": "Non hai abbastanza gettoni!", + "numTokensText": "${COUNT} Gettoni", + "openNowDescriptionText": "Hai gettoni sufficienti\nper aprire ora - non\nserve aspettare.", + "shinyNewCurrencyText": "La nuovissima valuta di BombSquad.", + "tokenPack1Text": "Pacco di Gettoni Mini", + "tokenPack2Text": "Pacco di Gettoni Medio", + "tokenPack3Text": "Pacco di Gettoni Grande", + "tokenPack4Text": "Pacco di Gettoni Enorme", + "tokensDescriptionText": "I gettoni si usano per accelerare lo sblocco dei forzieri\ne per altri acquisti di gioco o legati all'account.\n\nPuoi vincere gettoni nel gioco, o acquistali\ndai pacchetti. Oppure acquista un Pass Oro per ottenere\ngettoni infiniti senza più preoccupazioni.", + "youHaveGoldPassText": "Hai un Pass d'Oro.\nTutti gli acquisti di gettoni sono gratuiti.\nDivertiti!" + }, "topFriendsText": "Gli amici migliori", "tournamentCheckingStateText": "Controllo stato torneo in corso; attendere...", "tournamentEndedText": "Questo torneo è finito. Ne partirà un altro a breve.", "tournamentEntryText": "Partecipa al Torneo", + "tournamentFinalStandingsText": "Posizioni Finali", "tournamentResultsRecentText": "Risultati recenti del torneo", "tournamentStandingsText": "Classifica del torneo", "tournamentText": "Torneo", @@ -1509,6 +1606,18 @@ "Uber Onslaught": "Assalto Ultra", "Uber Runaround": "Girotondo Ultra" }, + "displayItemNames": { + "${C} Tickets": "${C} Biglietti", + "${C} Tokens": "${C} Gettoni", + "Chest": "Forziere", + "L1 Chest": "Forziere Lv.1", + "L2 Chest": "Forziere Lv.2", + "L3 Chest": "Forziere Lv.3", + "L4 Chest": "Forziere Lv.4", + "L5 Chest": "Forziere Lv.5", + "L6 Chest": "Forziere Lv.6", + "Unknown Chest": "Forziere Ignoto" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Per vincere, sii il prescelto per un determinato tempo.\nUccidi il prescelto per diventarlo.", "Bomb as many targets as you can.": "Bombarda più bersagli che puoi.", @@ -1614,6 +1723,7 @@ "Korean": "Koreano", "Malay": "Malese", "Persian": "Persiano", + "PirateSpeak": "Piratese", "Polish": "Polacco", "Portuguese": "Portoghese", "Romanian": "Rumeno", @@ -1688,6 +1798,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Individuato imbroglio: punteggi e premi sospesi per ${COUNT} giorni.", "Could not establish a secure connection.": "Impossibile stabilire una connessione sicura.", "Daily maximum reached.": "Limite massimo giornaliero raggiunto.", + "Daily sign-in reward": "Premio d'accesso giornaliero", "Entering tournament...": "Entrando nel torneo...", "Invalid code.": "Codice non valido.", "Invalid payment; purchase canceled.": "Pagamento non valido; acquisto annullato.", @@ -1697,21 +1808,26 @@ "Item unlocked!": "Oggetto sbloccato!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "Collegamento rifiutato. ${ACCOUNT} contiene\ndati importanti che verranno TUTTI PERSI.\nPuoi collegarlo nell'ordine opposto se preferisci\n(e perdere i dati di QUESTO account)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vuoi davvero collegare l'account ${ACCOUNT} a questo account?\nTutti i dati presenti in ${ACCOUNT} andranno persi.\nLa procedura non può essere annullata. Sei sicuro?", + "Longer streaks lead to better rewards.": "Le sequenze lunghe danno premi migliori.", "Max number of playlists reached.": "Numero massimo di playlist raggiunto.", "Max number of profiles reached.": "Numero massimo di profili raggiunto.", "Maximum friend code rewards reached.": "Numero massimo di richieste d'amicizia inviate", "Message is too long.": "Il messaggio è troppo lungo.", + "New tournament result!": "Nuovi risultati del torneo!", "No servers are available. Please try again soon.": "Nessun server disponibile,prova più tardi.", + "No slots available. Free a slot and try again.": "Nessuno slot disponibile. Liberane uno e riprova.", "Profile \"${NAME}\" upgraded successfully.": "Il profilo \"${NAME}\" è stato aggiornato con successo.", "Profile could not be upgraded.": "Il profilo non è potuto essere aggiornato.", "Purchase successful!": "Acquistato con successo!", - "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Ricevi ${COUNT} biglietti accedendo.\nTorna domani per ricevere ${TOMORROW_COUNT}.", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Ricevi ${COUNT} biglietti accedendo.\nTorna domani per riceverne ${TOMORROW_COUNT}.", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funzionalità server non è più supportata in questa versione del gioco;\nAggiornalo ad una nuova versione.", "Sorry, there are no uses remaining on this code.": "Spiacente, non ci sono altri utilizzi rimasti su questo codice.", "Sorry, this code has already been used.": "Spiacente, questo codice è già stato usato.", "Sorry, this code has expired.": "Spiacente, questo codice è scaduto.", "Sorry, this code only works for new accounts.": "Spiacente, questo codice funziona solo per nuovi account.", + "Sorry, this has expired.": "Spiacente, è scaduto.", "Still searching for nearby servers; please try again soon.": "Continuo a cercare dei server.Per favore prova più tardi.", + "Streak: ${NUM} days": "Sequenza: ${NUM} giorni", "Temporarily unavailable; please try again later.": "Al momento non disponibile; prova più tardi.", "The tournament ended before you finished.": "Il torneo è terminato prima che tu abbia finito.", "This account cannot be unlinked for ${NUM} days.": "Questo account non può essere scollegato per ${NUM} giorni.", @@ -1722,19 +1838,28 @@ "Tournaments require ${VERSION} or newer": "I tornei richiedono ${VERSION} o superiore", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Scollegare l'account ${ACCOUNT} da questo account?\nTutti i dati su ${ACCOUNT} andranno cancellati.\n(eccetto per i trofei in alcuni casi)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATTENZIONE: tentativi di hacking sono stati segnalati per il tuo account.\nGli account scoperti in tentativi di hacking saranno bannati. Gioca pulito.", + "Wait reduced!": "Tempo d'attesa ridotto!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Attenzione: Questa versione del gioco può accedere solo a vecchi dati account; potrebbero mancare o non essere aggiornati.\nPassa ad una versione più recente del gioco per visualizzare gli ultimi dati account.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Vuoi collegare il tuo account di dispositivo a questo?\n\nIl tuo account di dispositivo è ${ACCOUNT1}\nQuesto account è ${ACCOUNT2}\n\nQuesta operazione ti permetterà di conservare i tuoi progressi esistenti.\nAttenzione: l'operazione non può essere annullata!", "You already own this!": "È già tuo!", "You can join in ${COUNT} seconds.": "Potrai entrare in ${COUNT} secondi", "You don't have enough tickets for this!": "Non hai abbastanza biglietti per questo!", "You don't own that.": "Non lo possiedi", "You got ${COUNT} tickets!": "Hai ${COUNT} biglietti!", + "You got ${COUNT} tokens!": "Hai ottenuto ${COUNT} gettoni!", "You got a ${ITEM}!": "Hai ricevuto un ${ITEM}!", + "You got a chest!": "Hai ottenuto un forziere!", + "You got an achievement reward!": "Hai ottenuto un premio da un trofeo!", "You have been promoted to a new league; congratulations!": "Sei stato promosso a una nuova lega, Congratulazioni!", + "You lost a chest! (All your chest slots were full)": "Hai perso un forziere! (I tuoi slot forziere erano pieni)", + "You must update the app to view this.": "Aggiorna l'app per visualizzare.", "You must update to a newer version of the app to do this.": "Devi aggiornare a una versione nuova dell'app per poter fare questo.", "You must update to the newest version of the game to do this.": "Devi aggiornare ad una nuova versione del gioco per fare ciò.", "You must wait a few seconds before entering a new code.": "Devi aspettare qualche secondo prima di inserire un nuovo codice.", + "You placed #${RANK} in a tournament!": "Hai raggiunto #${RANK}° posto in un torneo!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Sei il numero ${RANK} dell'ultimo torneo. Grazie per aver giocato!", "Your account was rejected. Are you signed in?": "Il tuo account è stato rifiutato. Sei già iscritto?", + "Your ad views are not registering. Ad options will be limited for a while.": "Le visualizzazioni dei tuoi annunci non vengono registrate. Le opzioni degli annunci saranno limitate per un po'.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "La tua copia del gioco è stata modificata.\nPer favore, annulla le modifiche e riprova.", "Your friend code was used by ${ACCOUNT}": "Il tuo codice amico è stato usato da ${ACCOUNT}" }, @@ -1776,7 +1901,7 @@ "Short": "Breve", "Shorter": "Più breve", "Solo Mode": "Modalità Testa a Testa", - "Target Count": "Numero dì obbiettivi", + "Target Count": "Numero dì obiettivi", "Time Limit": "Tempo limite" }, "statements": { @@ -1888,11 +2013,14 @@ "toSkipPressAnythingText": "(tocca o premi qualsiasi pulsante per saltare la guida)" }, "twoKillText": "DOPPIA UCCISIONE!", + "uiScaleText": "Dimensione Interfaccia", "unavailableText": "non disponibile", + "unclaimedPrizesText": "Hai premi da riscattare!", "unconfiguredControllerDetectedText": "Rilevato controller non configurato:", "unlockThisInTheStoreText": "Deve essere sbloccato nel negozio", "unlockThisProfilesText": "Per creare più di ${NUM} profili, ti serve:", "unlockThisText": "Per sbloccare questo, hai bisogno di:", + "unsupportedControllerText": "Spiacente, il controller \"${NAME}\" non è supportato.", "unsupportedHardwareText": "Purtroppo, questo hardware non è supportato da questa versione del gioco.", "upFirstText": "Per primo:", "upNextText": "Fra poco nel ${COUNT}:", @@ -1900,12 +2028,16 @@ "upgradeText": "Aggiorna", "upgradeToPlayText": "Sblocca \"${PRO}\" nel negozio in-game per poter giocare a questo.", "useDefaultText": "Usa Predefinito", + "userSystemScriptsCreateText": "Crea Script di Sistema Utente", + "userSystemScriptsDeleteText": "Elimina Script di Sistema Utente", "usesExternalControllerText": "Questo gioco utilizza un controller esterno come input.", "usingItunesText": "Sto usando una app musicale per la colonna sonora...", "usingItunesTurnRepeatAndShuffleOnText": "Per favore, assicurati che la riproduzione casuale sia ATTIVA e che la ripetizione sia su TUTTO su iTunes.", "v2AccountLinkingInfoText": "Per collegare degli account V2, usa il tasto 'Gestisci Account'.", + "v2AccountRequiredText": "Questo richiede un account V2. Aggiorna il tuo account e riprova.", "validatingBetaText": "Sto convalidando la beta...", "validatingTestBuildText": "Convalida Build Di Prova...", + "viaText": "utilizzando", "victoryText": "Vittoria!", "voteDelayText": "Non puoi cominciare un'altra votazione per ${NUMBER} secondi", "voteInProgressText": "C'è già una votazione in corso.", @@ -1927,7 +2059,7 @@ "renameReplayButtonText": "Rinomina\nReplay", "renameReplayText": "Rinomina \"${REPLAY}\" in:", "renameText": "Rinomina", - "replayDeleteErrorText": "Errore cancellazione replay.", + "replayDeleteErrorText": "Errore eliminazione del replay.", "replayNameText": "Nome Replay", "replayRenameErrorAlreadyExistsText": "Esiste già un replay con questo nome.", "replayRenameErrorInvalidName": "Impossibile rinominare replay; nome invalido.", @@ -1981,5 +2113,6 @@ }, "yesAllowText": "Sì, permetti!", "yourBestScoresText": "I tuoi punteggi migliori", - "yourBestTimesText": "I tuoi tempi migliori" + "yourBestTimesText": "I tuoi tempi migliori", + "yourPrizeText": "Il tuo premio:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/korean.json b/dist/ba_data/data/languages/korean.json index 81b7c5aa..760d0d18 100644 --- a/dist/ba_data/data/languages/korean.json +++ b/dist/ba_data/data/languages/korean.json @@ -7,7 +7,9 @@ "campaignProgressText": "캠페인 진행 상황 [어려움]: ${PROGRESS}", "changeOncePerSeason": "한 시즌마다 바꿀수 있습니다.", "changeOncePerSeasonError": "다음 시즌으로 바뀔때까지 (${NUM} 일)기다려야 계정 이름을 바꿀수 있습니다.", + "createAnAccountText": "계정 만들기", "customName": "이름 맞춤설정", + "deleteAccountText": "계정 삭제", "googlePlayGamesAccountSwitchText": "다른 Google 계정을 전환하려면,\nGoogle Play 앱을 사용하세요", "linkAccountsEnterCodeText": "코드 입력", "linkAccountsGenerateCodeText": "코드 생성", @@ -25,14 +27,16 @@ "setAccountNameDesc": "당신 계정에 보여질 이름을 선택해주시오.\n연동된 계정 중 하나에서 이름을 사용하거나,\n또는 자기만의 독창적인 이름을 만들어서 사용할 수 있습니다.", "signInInfoText": "로그인해서 티켓을 수집하고 온라인으로 겨루며\n여러 기기에서 진행 상황을 공유하세요.", "signInText": "로그인", + "signInWithAnEmailAddressText": "이메일 주소로 로그인", "signInWithDeviceInfoText": "(자동 계정은 이 기기에서만 이용할 수 있습니다)", "signInWithDeviceText": "기기 계정으로 로그인", "signInWithGameCircleText": "Game Circle로 로그인", "signInWithGooglePlayText": "Google Play로 로그인", "signInWithTestAccountInfoText": "(이전 계정 유형, 앞의 기기 계정을 이용하세요)", "signInWithTestAccountText": "테스트 계정으로 로그인", + "signInWithText": "${SERVICE}로 로그인하기", "signInWithV2InfoText": "(모든 플랫폼에서 작동하는 계정입니다)", - "signInWithV2Text": "BombSquad 계정으로 로그인", + "signInWithV2Text": "${APP_NAME} 계정으로 로그인", "signOutText": "로그아웃", "signingInText": "로그인 중...", "signingOutText": "로그아웃 중...", @@ -335,9 +339,14 @@ "getMoreGamesText": "다른 게임 보기...", "titleText": "게임 추가" }, + "addToFavoritesText": "즐겨찾기에 추가하기", + "addedToFavoritesText": "즐겨찾기에 '${NAME}'을 추가했습니다.", + "allText": "모두", "allowText": "허용", "alreadySignedInText": "귀하의 계정은 다른 기기에서 로그인되었습니다. \n계정을 전환하거나 다른 기기에서 게임을 종료하고 \n다시 시도하십시오.", "apiVersionErrorText": "${NAME} 모듈을 불러올 수 없습니다; ${VERSION_USED} api 버전입니다; ${VERSION_REQUIRED} 버전이 필요합니다.", + "applyText": "적용", + "areYouSureText": "정말?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(헤드폰이 연결된 때에만 '자동'이 이 옵션을 활성화합니다)", "headRelativeVRAudioText": "머리 비례 VR 오디오", @@ -359,14 +368,23 @@ "boostText": "증가", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME}(은)는 앱 자체에 구성되어 있습니다.", "buttonText": "버튼", - "canWeDebugText": "BombSquad가 버그, 충돌 및 기본 사용 정보를\n자동으로 개발자에게 신고하도록 하시겠습니까?\n\n이 데이터에 개인 정보는 포함되지 않으며 게임이\n버그 없이 원활하게 실행되도록 하는 데 도움이 됩니다.", + "canWeDebugText": "${APP_NAME}가 버그, 충돌 및 기본 사용 정보를\n자동으로 개발자에게 신고하도록 하시겠습니까?\n\n이 데이터에 개인 정보는 포함되지 않으며 게임이\n버그 없이 원활하게 실행되도록 하는 데 도움이 됩니다.", "cancelText": "취소", "cantConfigureDeviceText": "죄송합니다만 ${DEVICE}(은)는 구성할 수 없습니다.", "challengeEndedText": "이 챌린지는 종료되었습니다.", "chatMuteText": "채팅 음소거", "chatMutedText": "채팅 음소거됨.", "chatUnMuteText": "채팅 음소거 해제", + "chests": { + "prizeOddsText": "상금 확률", + "reduceWaitText": "대기 시간 단축", + "slotDescriptionText": "이 슬롯은 상자를 보관할 수 있습니다.\n\n캠페인 레벨을 플레이하고,\n토너먼트에서 순위를 매기고,\n업적을 달성하여 상자를 획득하세요.", + "slotText": "상자 슬롯 ${NUM}", + "slotsFullWarningText": "경고: 모든 상자 슬롯이 찼습니다.\n이 게임에서 획득한 상자는 모두 사라지게 됩니다." + }, "choosingPlayerText": "<플레이어 선택>", + "claimText": "청구", + "codesExplainText": "계정 문제를 진단하고 수정하기 위해\n개발자가 코드를 제공합니다.", "completeThisLevelToProceedText": "계속 진행하려면 이 레벨을\n완료해야 합니다!", "completionBonusText": "완료 보너스", "configControllersWindow": { @@ -447,6 +465,7 @@ "swipeText": "스와이프", "titleText": "터치스크린 구성" }, + "configureDeviceInSystemSettingsText": "${DEVICE}는 시스템 설정 앱에서 구성할 수 있습니다.", "configureItNowText": "지금 구성하시겠습니까?", "configureText": "구성", "connectMobileDevicesWindow": { @@ -549,6 +568,7 @@ "demoText": "체험판", "denyText": "거부", "deprecatedText": "더 이상 사용되지 않음", + "descriptionText": "설명", "desktopResText": "데스크톱 해상도", "deviceAccountUpgradeText": "경고:\n 기기 계정(${NAME})으로 로그인하셨습니다.\n 기기 계정은 향후 업데이트에서 제거되기에\n 진행 상황을 유지하려면 V2 계정으로 업그레이드하세요.", "difficultyEasyText": "쉬움", @@ -559,6 +579,10 @@ "disableRemoteAppConnectionsText": "리모트 앱 연결 비활성화", "disableXInputDescriptionText": "4개 이상의 컨트롤러를 허용하지만 아마 잘 작동하지 않을 것입니다.", "disableXInputText": "엑스인풋 컨트롤러 비활성화", + "disabledText": "비활성화만", + "discardText": "버리기", + "discordFriendsText": "함께 플레이할 새로운 친구를 찾고 싶으신가요?\n디스코드에 가입하여 새로운 친구를 찾아보세요!", + "discordJoinText": "디스코드 가입", "doneText": "완료", "drawText": "무승부", "duplicateText": "복사", @@ -591,6 +615,7 @@ "localProfileText": "(로컬 프로필)", "nameDescriptionText": "플레이어 이름", "nameText": "이름", + "profileAlreadyExistsText": "해당 이름을 가진 프로필이 이미 존재합니다.", "randomText": "무작위", "titleEditText": "프로필 편집", "titleNewText": "새 프로필", @@ -626,6 +651,7 @@ "useMusicFolderText": "음악 파일 폴더" }, "editText": "편집", + "enabledText": "활성화만", "endText": "종료", "enjoyText": "즐기세요!", "epicDescriptionFilterText": "(에픽 슬로 모션) ${DESCRIPTION}.", @@ -637,6 +663,8 @@ "errorText": "오류", "errorUnknownText": "알 수 없는 오류", "exitGameText": "${APP_NAME}를 종료하시겠습니까?", + "expiredAgoText": "만료 ${T} 전", + "expiresInText": "${T} 남았습니다.", "exportSuccessText": "'${NAME}' 를 내보냈습니다.", "externalStorageText": "외부 저장소", "failText": "실패", @@ -671,6 +699,8 @@ "duplicateText": "플레이 목록\n복사", "editText": "플레이 목록\n편집", "newText": "새\n플레이 목록", + "pointsToWinText": "승리 포인트", + "seriesLengthText": "시리즈 길이", "showTutorialText": "튜토리얼 보기", "shuffleGameOrderText": "게임 순서 섞기", "titleText": "${TYPE} 플레이 목록 커스터마이징" @@ -696,6 +726,7 @@ "copyCodeConfirmText": "코드가 클립보드에 복사되었습니다.", "copyCodeText": "코드 복사", "dedicatedServerInfoText": "최선의 결과를 위해 전용 서버를 구축하세요. 자세한 사항은 bombsquadgame.com/server를 참조해주십시오.", + "descriptionShortText": "파티 모집 창을 이용해 파티를 구성하세요.", "disconnectClientsText": "파티 내의 플레이어 ${COUNT}명의 연결이\n끊어집니다. 괜찮습니까?", "earnTicketsForRecommendingAmountText": "친구들은 게임을 시도하면 티켓 ${COUNT}장을 받습니다\n(귀하는 각각의 친구에 대해서 ${YOU_COUNT}장을 받습니다)", "earnTicketsForRecommendingText": "게임을 공유하고\n무료 티켓을 받으세요...", @@ -708,10 +739,10 @@ "friendHasSentPromoCodeText": "${NAME} 님이 ${APP_NAME} 티켓 ${COUNT}장을 보냄", "friendPromoCodeAwardText": "코드가 사용될 때마다 귀하는 티켓 ${COUNT}장을 받습니다.", "friendPromoCodeExpireText": "이 코드는 ${EXPIRE_HOURS}시간 후 만료되며 신규 플레이어에게만 적용됩니다.", - "friendPromoCodeInstructionsText": "사용하려면 ${APP_NAME} 앱을 열고 '설정->고급->코드 입력'으로 이동합니다.\n지원되는 모든 플랫폼의 다운로드 링크는 bombsquadgame.com에서 확인하세요.", + "friendPromoCodeInstructionsText": "사용하려면 ${APP_NAME}을 열고 \"설정->고급->정보 보내기\"로 이동합니다.\n지원되는 모든 플랫폼의 다운로드 링크는 bombsquadgame.com을 참조하세요.", "friendPromoCodeRedeemLongText": "최대 ${MAX_USES}명의 사람이 무료 티켓 ${COUNT}장과 교환할 수 있습니다.", "friendPromoCodeRedeemShortText": "게임에서 티켓 ${COUNT}장과 교환할 수 있습니다.", - "friendPromoCodeWhereToEnterText": "('설정->고급->코드 입력')", + "friendPromoCodeWhereToEnterText": "(\"설정->고급->정보 보내기\")", "getFriendInviteCodeText": "친구 초대 코드 받기", "googlePlayDescriptionText": "Google Play 플레이어들을 파티에 초대하세요.", "googlePlayInviteText": "초대", @@ -743,6 +774,7 @@ "manualYourLocalAddressText": "귀하의 로컬 주소:", "nearbyText": "근처", "noConnectionText": "<연결 없음>", + "noPartiesAddedText": "추가한 파티 없음", "otherVersionsText": "(다른 버전)", "partyCodeText": "파티 코드", "partyInviteAcceptText": "수락", @@ -806,6 +838,12 @@ "youHaveShortText": "티켓 보유량: ${COUNT}", "youHaveText": "보유량: ${COUNT} 티켓" }, + "goldPass": { + "desc1InfTokensText": "무한한 토큰.", + "desc2NoAdsText": "광고 없음.", + "desc3ForeverText": "영원히.", + "goldPassText": "골든 패스" + }, "googleMultiplayerDiscontinuedText": "죄송하지만, 구글의 멀티플레이어 서비스는 더이상 이용할수가 없어요.\n지금 대체제에 가능한 빨리 작업중이에요.\n그 때까지는, 다른 접속 방법을 사용해주세요.\n-Eric", "googlePlayPurchasesNotAvailableText": "구매가 되지 않았습니다.\n아마 스토어 앱을 업데이트 해야 합니다.", "googlePlayServicesNotAvailableText": "Google Play 서비스를 사용할 수 없습니다.\n 일부 앱 기능이 비활성화될 수 있습니다.", @@ -814,10 +852,12 @@ "alwaysText": "언제나", "fullScreenCmdText": "전체 화면 (Cmd-F)", "fullScreenCtrlText": "전체 화면 (Ctrl-F)", + "fullScreenText": "전체화면", "gammaText": "감마", "highText": "높음", "higherText": "매우 높음", "lowText": "낮음", + "maxFPSText": "최대 FPS", "mediumText": "중간", "neverText": "안 함", "resolutionText": "해상도", @@ -878,6 +918,7 @@ "importText": "불러오기", "importingText": "불러오는 중...", "inGameClippedNameText": "게임 내에서는 다음과 같이 보여질 것입니다.\n\"${NAME}\"", + "inboxText": "받은 편지함", "installDiskSpaceErrorText": "오류: 설치를 완료할 수 없습니다.\n기기에 공간이 부족한 것 같습니다.\n공간을 확보한 후 다시 시도해보세요.", "internal": { "arrowsToExitListText": "목록에서 나가려면 ${LEFT} 또는 ${RIGHT}를 누르세요", @@ -932,12 +973,14 @@ "timeOutText": "(${TIME}초 후 시간 초과)", "touchScreenJoinWarningText": "터치스크린을 이용해 가입했습니다.\n실수로 그러신 경우 '메뉴->게임 나가기'를 누르세요.", "touchScreenText": "터치스크린", + "unableToCompleteTryAgainText": "지금은 완료할 수 없습니다.\n다시 시도해 주세요.", "unableToResolveHostText": "오류: 호스트를 확인할 수 없습니다.", "unavailableNoConnectionText": "이 기능은 현재 이용할 수 없습니다 (인터넷에 연결되지 않았습니까?)", "vrOrientationResetCardboardText": "이것을 이용해 VR 방향을 재설정합니다.\n게임을 플레이하려면 외부 컨트롤러가 필요합니다.", "vrOrientationResetText": "VR 방향이 재설정되었습니다.", "willTimeOutText": "(부재 중이면 시간 초과가 됩니다)" }, + "inventoryText": "인벤토리", "jumpBoldText": "점프", "jumpText": "점프", "keepText": "유지", @@ -984,8 +1027,11 @@ "seasonEndsMinutesText": "시즌은 ${NUMBER}분 후 종료됩니다.", "seasonText": "시즌 ${NUMBER}", "tournamentLeagueText": "이 토너먼트에 참가하려면 ${NAME} 리그에 도달해야 합니다.", - "trophyCountsResetText": "트로피 수는 다음 시즌에 초기화됩니다." + "trophyCountsResetText": "트로피 수는 다음 시즌에 초기화됩니다.", + "upToDateBonusDescriptionText": "최신 버전의 게임을 실행하면 플레이어는 여기에서 \n${PERCENT}%의 보너스를 받습니다.", + "upToDateBonusText": "최신 보너스" }, + "learnMoreText": "더 알아보기", "levelBestScoresText": "${LEVEL}의 최고 점수", "levelBestTimesText": "${LEVEL}의 최고 시간", "levelIsLockedText": "${LEVEL}(은)는 잠겼습니다.", @@ -1029,6 +1075,8 @@ "modeArcadeText": "아케이드 모드", "modeClassicText": "클래식 모드", "modeDemoText": "데모 모드", + "moreSoonText": "더 많은 내용이 곧 다가옵니다...", + "mostDestroyedPlayerText": "가장 많이 파괴된 플레이어", "mostValuablePlayerText": "가장 뛰어난 플레이어", "mostViolatedPlayerText": "가장 비참한 플레이어", "mostViolentPlayerText": "가장 난폭한 플레이어", @@ -1045,6 +1093,7 @@ "nameSuicideText": "${NAME} 님이 자살했습니다.", "nameText": "이름", "nativeText": "기본", + "newExclaimText": "신규!", "newPersonalBestText": "새 개인 최고 기록!", "newTestBuildAvailableText": "새 테스트 빌드가 나왔습니다! (${VERSION} 빌드 ${BUILD}).\n${ADDRESS}에서 다운로드 하세요", "newText": "새", @@ -1055,12 +1104,16 @@ "noContinuesText": "(계속 없음)", "noExternalStorageErrorText": "이 기기에서 외부 저장소를 찾지 못했습니다.", "noGameCircleText": "오류: GameCircle에 로그인되지 않았습니다", + "noMessagesText": "메시지 없음.", + "noPluginsInstalledText": "설치된 플러그인 없음", "noScoresYetText": "아직 점수 없음.", + "noServersFoundText": "서버를 찾을수 없음.", "noThanksText": "아니요", "noTournamentsInTestBuildText": "경고: 이 테스트 빌드의 토너먼트 점수는 기록되지 않습니다.", "noValidMapsErrorText": "이 게임 유형에 유효한 지도를 찾지 못했습니다.", "notEnoughPlayersRemainingText": "남은 플레이어가 충분하지 않습니다. 게임을 종료한 후 새로 시작하세요.", "notEnoughPlayersText": "이 게임을 시작하려면 ${COUNT}명 이상의 플레이어가 필요합니다!", + "notEnoughTicketsText": "티켓이 부족합니다!", "notNowText": "다음에", "notSignedInErrorText": "이 작업을 하려면 로그인해야 합니다.", "notSignedInGooglePlayErrorText": "이 작업을 하려면 Google Play로 로그인해야 합니다.", @@ -1073,6 +1126,9 @@ "onText": "켬", "oneMomentText": "잠시만요...", "onslaughtRespawnText": "${PLAYER} 님은 ${WAVE} 웨이브에서 부활합니다", + "openMeText": "나를 열어줘!", + "openNowText": "당장 열기", + "openText": "열기", "orText": "${A} 또는 ${B}", "otherText": "기타...", "outOfText": "(#${RANK} / ${ALL})", @@ -1124,7 +1180,11 @@ "pleaseWaitText": "잠시만 기다려 주십시오...", "pluginClassLoadErrorText": "플러그인(${PLUGIN})을 불러오는 도중에 오류가 생겼습니다. 오류 : ${ERROR}", "pluginInitErrorText": "플러그인(${PLUGIN})을 실행하는 도중에 오류가 생겼습니다. 오류 : ${ERROR}", + "pluginSettingsText": "플러그인 설정", + "pluginsAutoEnableNewText": "새 플러그인 자동 적용", "pluginsDetectedText": "새로운 플러그인이 감지되었습니다. 게임을 재시작 하거나 설정을 바꿔 주십시오.", + "pluginsDisableAllText": "모든 플러그인 해제하기", + "pluginsEnableAllText": "모든 플러그인 적용하기", "pluginsRemovedText": "${NUM} 플러그인을 더 이상 찾을 수 없습니다.", "pluginsText": "플러그인", "practiceText": "연습", @@ -1154,6 +1214,8 @@ "punchText": "펀치", "purchaseForText": "${PRICE}에 구입", "purchaseGameText": "게임 구입", + "purchaseNeverAvailableText": "죄송합니다. 이 빌드에서는 구매가 불가능합니다.\n다른 플랫폼에서 계정에 로그인하여 해당 플랫폼에서 구매를 시도해 보세요.", + "purchaseNotAvailableText": "해당 구매는 불가능합니다.", "purchasingText": "구입 중...", "quitGameText": "${APP_NAME}를 종료하시겠습니까?", "quittingIn5SecondsText": "5초 후 종료됩니다...", @@ -1195,6 +1257,7 @@ "version_mismatch": "버전이 일치하지 않습니다.\nBombSquad 및 BombSquad Remote가\n최신 버전인지 확인한 후 다시 시도하세요." }, "removeInGameAdsText": "게임 내 광고를 제거하려면 상점에서 \"${PRO}\"를 잠금 해제하세요.", + "removeInGameAdsTokenPurchaseText": "기간 한정 특가: 토큰 팩을 구매하면 게임 내 광고를 제거할 수 있습니다.", "renameText": "이름 바꾸기", "replayEndText": "다시 보기 종료", "replayNameDefaultText": "마지막 게임 다시 보기", @@ -1215,7 +1278,9 @@ "revertText": "되돌리기", "runText": "달리기", "saveText": "저장", - "scanScriptsErrorText": "스크립트를 검색하는 중 오류가 발생했습니다. 자세한 내용은 로그를 참조하십시오.", + "scanScriptsErrorText": "스크립트(들)을 검색하는 중 오류가 발생하였습니다. 자세한 내용은 로그를 확인하십시오.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 및 ${NUM}개의 기타 모듈을 ${API} API에 대해 업데이트를 해야 합니다.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH}는 api ${API}에 대해 업데이트해야 합니다.", "scoreChallengesText": "점수 챌린지", "scoreListUnavailableText": "점수 목록을 이용할 수 없습니다.", "scoreText": "점수", @@ -1226,8 +1291,9 @@ }, "scoreWasText": "(이전: ${COUNT})", "selectText": "선택", + "sendInfoDescriptionText": "계정 및 앱 상태 정보를 개발자에게 전송합니다.\n이름이나 전송 이유를 포함하세요.", "seriesWinLine1PlayerText": "님이 시리즈에서", - "seriesWinLine1TeamText": "님이 시리즈에서", + "seriesWinLine1TeamText": "팀이 시리즈에서", "seriesWinLine1Text": "님이 시리즈에서", "seriesWinLine2Text": "승리했습니다!", "settingsWindow": { @@ -1243,6 +1309,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(간편하고 사용하기 쉬운 텍스트 편집용 온스크린 키보드)", "alwaysUseInternalKeyboardText": "언제나 내부 키보드를 사용함", "benchmarksText": "벤치마크 및 스트레스 테스트", + "devToolsText": "개발자 도구", "disableCameraGyroscopeMotionText": "시야 자이로스코프 동작 비활성 하기", "disableCameraShakeText": "화면 진동 비활성하기", "disableThisNotice": "(고급설정에서 이 알림을 중지 할 수 있습니다)", @@ -1251,14 +1318,22 @@ "enterPromoCodeText": "코드 입력", "forTestingText": "참고: 이 값들은 테스트용으로 앱을 종료하면 없어집니다.", "helpTranslateText": "${APP_NAME}의 비영어권 번역은 커뮤니티에서 지원된\n결과입니다. 공헌하거나 번역을 교정하고 싶으면\n아래 링크를 이용하세요. 감사합니다!", + "insecureConnectionsDescriptionText": "권장하지는 않지만, 제한된 국가 또는 네트워크에서 온라인 플레이\n를 허용할 수 있습니다.", + "insecureConnectionsText": "보안이 취약한 연결 사용", "kickIdlePlayersText": "부재 중 플레이어 추방", "kidFriendlyModeText": "어린이 보호 모드 (폭력 순화 등)", "languageText": "언어", "moddingGuideText": "모딩 가이드", + "moddingToolsText": "모딩 도구", "mustRestartText": "이 설정이 적용되려면 게임을 다시 시작해야 합니다.", "netTestingText": "네트워크 테스트", "resetText": "재설정", + "sendInfoText": "정보 보내기", "showBombTrajectoriesText": "폭탄 궤적 표시", + "showDemosWhenIdleText": "유휴 상태일 때 데모 표시", + "showDeprecatedLoginTypesText": "더 이상 사용되지 않는 로그인 유형 표시", + "showDevConsoleButtonText": "개발자 콘솔 버튼 보이기", + "showInGamePingText": "인게임 핑 보이기", "showPlayerNamesText": "플레이어 이름 표시", "showUserModsText": "모드 폴더 표시", "titleText": "고급", @@ -1277,15 +1352,18 @@ "signInWithGameCenterText": "Game Center 계정을 이용하려면\nGame Center 앱으로 로그인하세요.", "singleGamePlaylistNameText": "${GAME}만", "singlePlayerCountText": "1 플레이어", + "sizeLargeText": "대형", + "sizeMediumText": "중간", + "sizeSmallText": "작음", "soloNameFilterText": "솔로 ${NAME}", "soundtrackTypeNames": { "CharSelect": "캐릭터 선택", "Chosen One": "선택된 자", - "Epic": "에픽 모드 게임", + "Epic": "에픽 모드 게임들", "Epic Race": "에픽 레이스", - "FlagCatcher": "깃발 탈환", + "FlagCatcher": "깃발 잡기", "Flying": "행복한 생각", - "Football": "축구", + "Football": "미식 축구", "ForwardMarch": "전진", "GrandRomp": "정복", "Hockey": "하키", @@ -1294,7 +1372,7 @@ "Menu": "메인 메뉴", "Onslaught": "맹습", "Race": "레이스", - "Scary": "킹 오브 더 힐", + "Scary": "언덕의 왕", "Scores": "점수 화면", "Survival": "제거", "ToTheDeath": "데스 매치", @@ -1350,6 +1428,8 @@ "storeText": "상점", "submitText": "제출", "submittingPromoCodeText": "코드 제출 중...", + "successText": "성공!", + "supportEmailText": "만약 앱에서 문제를 겪고있을경우,\n${EMAIL}로 연락해주세요", "teamNamesColorText": "팀 이름/색상...", "telnetAccessGrantedText": "텔넷 액세스가 활성화됨.", "telnetAccessText": "텔넷 액세스가 검색됨, 허용하시겠습니까?", @@ -1359,6 +1439,7 @@ "testBuildValidatedText": "테스트 빌드 확인 완료. 즐거운 시간 되세요!", "thankYouText": "지원해주셔서 감사합니다! 즐거운 시간 되세요!!", "threeKillText": "트리플 킬!!", + "ticketsDescriptionText": "티켓은 상점에서 캐릭터, 맵, 미니게임 등을 잠금 해제하는 데 사\n용할 수 있습니다.\n\n티켓은 캠페인, 토너먼트, 업적을 통해 획득한 상자에서 찾을 수 \n있습니다.", "timeBonusText": "시간 보너스", "timeElapsedText": "시간 경과", "timeExpiredText": "시간 종료", @@ -1369,10 +1450,23 @@ "tipText": "팁", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "토큰 얻기", + "notEnoughTokensText": "토큰이 부족합니다!", + "numTokensText": "${COUNT}개 토큰", + "shinyNewCurrencyText": "BombSquad의 반짝이는 새로운 화폐.", + "tokenPack1Text": "작은 토큰 팩", + "tokenPack2Text": "중간 토큰 팩", + "tokenPack3Text": "큰 토큰 팩", + "tokenPack4Text": "엄청 큰 토큰 팩", + "tokensDescriptionText": "토큰은 상자 잠금 해제 속도를 높이고\n다른 게임 및 계정 기능에 사용됩니다.\n\n게임에서 토큰을 얻거나\n팩으로 구매할 수 있습니다. 또는 무한한 토큰을 위해 골드 패스를 구매하면\n다시는 그 토큰에 대해서는 듣지 못할 겁니다.", + "youHaveGoldPassText": "골드 패스가 있습니다.\n모든 토큰 구매는 무료입니다.\n즐기세요!" + }, "topFriendsText": "절친들", "tournamentCheckingStateText": "토너먼트 상태를 확인 중입니다. 잠시 기다리세요...", "tournamentEndedText": "이 토너먼트는 종료되었습니다. 새 토너먼트가 곧 시작됩니다.", "tournamentEntryText": "토너먼트 참가", + "tournamentFinalStandingsText": "최종 순위", "tournamentResultsRecentText": "최근 토너먼트 결과", "tournamentStandingsText": "토너먼트 성적", "tournamentText": "토너먼트", @@ -1406,7 +1500,7 @@ "Spaz": "스파즈", "Taobao Mascot": "타오바오 마스코트", "Todd McBurton": "토드 맥버튼", - "Zoe": "조우", + "Zoe": "조", "Zola": "졸라" }, "coopLevelNames": { @@ -1428,6 +1522,18 @@ "Uber Onslaught": "슈퍼 맹습", "Uber Runaround": "슈퍼 행군" }, + "displayItemNames": { + "${C} Tickets": "${C} 티켓", + "${C} Tokens": "${C} 토큰", + "Chest": "상자", + "L1 Chest": "레벨 1 상자", + "L2 Chest": "레벨 2 상자", + "L3 Chest": "레벨 3 상자", + "L4 Chest": "레벨 4 상자", + "L5 Chest": "레벨 5 상자", + "L6 Chest": "레벨 6 상자", + "Unknown Chest": "알려지지 않은 상자" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "승리하려면 일정 시간 동안 선택된 자가 되세요.\n그 지위를 뺏으려면 선택된 자를 처치하세요.", "Bomb as many targets as you can.": "가능한 한 많은 목표에 폭탄을 던지세요.", @@ -1532,6 +1638,7 @@ "Korean": "한국어", "Malay": "말레이어", "Persian": "페르시아어", + "PirateSpeak": "해적의 말", "Polish": "폴란드어", "Portuguese": "포르투갈어", "Romanian": "루마니아어", @@ -1603,6 +1710,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "부정행위 사용이 감지되었습니다. ${COUNT}일 간 점수 및 상품이 중지됩니다.", "Could not establish a secure connection.": "보안 연결을 수립할 수 없습니다.", "Daily maximum reached.": "일일 한도에 도달했습니다.", + "Daily sign-in reward": "매일 로그인 보상", "Entering tournament...": "토너먼트에 참가 중...", "Invalid code.": "잘못된 코드.", "Invalid payment; purchase canceled.": "구매 무효화; 구매가 취소되었습니다.", @@ -1612,11 +1720,14 @@ "Item unlocked!": "아이템 잠금해제!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "연동 거부됨. ${ACCOUNT} 에 모두 지워질 \n매우 중요한 데이터가 있습니다.\n원한다면 반대 순서로 연동이 가능합니다\n(이 계정의 데이터가 지워지는 대신에)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "${ACCOUNT} 을 이 계정에 연동하시겠습니까?\n${ACCOUNT} 계정에 있는 모든 데이터가 삭제됩니다.\n이 동작은 번복할 수 없습니다. 확실합니까?", + "Longer streaks lead to better rewards.": "연속 기록이 길수록 보상도 더 좋습니다.", "Max number of playlists reached.": "최대 플레이 목록 수에 도달했습니다.", "Max number of profiles reached.": "최대 프로필 수에 도달했습니다.", "Maximum friend code rewards reached.": "최대의 친구 코드 보상에 도달했습니다.", "Message is too long.": "메시지가 너무 깁니다.", + "New tournament result!": "새로운 토너먼트 결과!", "No servers are available. Please try again soon.": "가능한 서버가 없습니다. 나중에 다시 시도해주십시오.", + "No slots available. Free a slot and try again.": "이용 가능한 슬롯이 없습니다. 슬롯을 비우고 다시 시도하세요.", "Profile \"${NAME}\" upgraded successfully.": "프로필 \"${NAME}\" 업그레이드 성공.", "Profile could not be upgraded.": "프로필을 업그레이드하지 못했습니다.", "Purchase successful!": "구매 성공!", @@ -1626,7 +1737,9 @@ "Sorry, this code has already been used.": "죄송합니다만 이 코드는 이미 사용되었습니다.", "Sorry, this code has expired.": "죄송합니다만 이 코드는 만료되었습니다.", "Sorry, this code only works for new accounts.": "죄송합니다만 이 코드는 새 계정에만 유효합니다.", + "Sorry, this has expired.": "죄송해요, 이건 만료됐어요.", "Still searching for nearby servers; please try again soon.": "아직 근처에 있는 서버를 찾는 중입니다; 나중에 다시 시도해주십시오.", + "Streak: ${NUM} days": "연속 기록: ${NUM}일", "Temporarily unavailable; please try again later.": "일시적으로 사용불가; 나중에 다시 시도하세요.", "The tournament ended before you finished.": "귀하가 완료하기 전에 토너먼트가 종료되었습니다.", "This account cannot be unlinked for ${NUM} days.": "이 계정은 ${NUM} 일 동안 연동 해제가 불가능합니다.", @@ -1637,19 +1750,27 @@ "Tournaments require ${VERSION} or newer": "토너먼트는 ${VERSION} 또는 그 보다 새로운 버전이 필요합니다.", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "이 계정에서 ${ACCOUNT} 의 연동을 해제하시겠습니까?\n${ACCOUNT} 에 있는 모든 데이터가 초기화됩니다.\n(일부 상황에서 도전과제 빼고는)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "경고: 당신 계정에 해킹 관련 경고가 전해졌습니다.\n해킹 중인 걸로 밝혀진 계정은 즉시 차단됩니다. 제발 게임만은 공정하게 합시다.", + "Wait reduced!": "대기 시간이 단축됐습니다!", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "귀하의 기기를 이 계정에 연동하시겠습니까?\n\n귀하의 기기 계정: ${ACCOUNT1}\n이 계정: ${ACCOUNT2}\n\n이로써 기존 진행 상황을 유지할 수 있습니다.\n경고: 이 작업은 취소할 수 없습니다!", "You already own this!": "이미 소유 중입니다!", "You can join in ${COUNT} seconds.": "${COUNT} 초 후에 참가할 수 있습니다.", "You don't have enough tickets for this!": "티켓이 충분하지 않습니다!", "You don't own that.": "이미 소유하지 않았습니다.", "You got ${COUNT} tickets!": "티켓 ${COUNT}장을 받았습니다!", + "You got ${COUNT} tokens!": "${COUNT}개의 토큰을 얻었습니다!", "You got a ${ITEM}!": "${ITEM}(을)를 받았습니다!", + "You got a chest!": "상자를 얻었습니다!", + "You got an achievement reward!": "업적 보상을 받았습니다!", "You have been promoted to a new league; congratulations!": "새 리그로 승격되었습니다. 축하합니다!", + "You lost a chest! (All your chest slots were full)": "상자를 하나 잃어버렸어요!(상자 슬롯이 모두 가득 찼어요)", + "You must update the app to view this.": "이 내용을 보려면 앱을 업데이트해야 합니다.", "You must update to a newer version of the app to do this.": "이 작업을 하려면 새 앱 버전으로 업데이트해야 합니다.", "You must update to the newest version of the game to do this.": "이 작업을 하려면 새로운 게임 버전으로 업데이트해야 합니다.", "You must wait a few seconds before entering a new code.": "새 코드를 입력하기 전에 수초 간 기다려야 합니다.", + "You placed #${RANK} in a tournament!": "토너먼트에서 #${RANK}를 달성했습니다!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "마지막 토너먼트에서 #${RANK}위에 랭크되었습니다. 플레이해주셔서 감사합니다!", "Your account was rejected. Are you signed in?": "계정이 거부되었습니다. 로그인 되어있으시나요?", + "Your ad views are not registering. Ad options will be limited for a while.": "광고 조회수가 올라가지 않습니다. 당분간은 광고가 제한됩니다.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "게임 사본이 수정되었습니다.\n변경 사항을 되돌린 후 다시 시도해주십시오.", "Your friend code was used by ${ACCOUNT}": "${ACCOUNT} 님이 친구 코드를 사용했습니다" }, @@ -1760,18 +1881,18 @@ "cpuBenchmarkText": "말도 안되는 속도로 튜토리얼을 실행 중(우선 CPU 속도를 테스트합니다)", "phrase01Text": "안녕하세요!", "phrase02Text": "${APP_NAME}에 환영합니다!", - "phrase03Text": "캐릭터를 컨트롤하는 팁을 몇 가지 알려드릴 게요.", - "phrase04Text": "${APP_NAME}의 많은 것이 물리학에 바탕을 두고 있어요.", + "phrase03Text": "캐릭터를 조작하는 팁을 몇 가지 알려드릴게요.", + "phrase04Text": "${APP_NAME}의 많은 것이 '물리학'에 바탕을 두고 있어요.", "phrase05Text": "예를 들어, 펀치를 날릴 때...", "phrase06Text": "...대미지는 주먹의 속도에 기반하죠.", "phrase07Text": "보셨죠? 움직이지 않으니 ${NAME} 님에게 거의 피해를 안 줘요.", - "phrase08Text": "이제 점프 및 회전을 해서 스피드를 더 올려보세요.", + "phrase08Text": "이제 점프와 회전을 해서 스피드를 더 올려볼게요.", "phrase09Text": "네, 훨씬 더 낫군요.", "phrase10Text": "달리는 것도 도움이 돼요.", "phrase11Text": "달리려면 아무 버튼이나 길게 누르세요.", "phrase12Text": "멋진 펀치를 날리려면 달리고 회전해보세요.", - "phrase13Text": "어이쿠, 저 ${NAME} 님에게 미안하군요.", - "phrase14Text": "깃발이나... 또는 ${NAME} 님 같은 물체를 집을 수 있어요.", + "phrase13Text": "이런, ${NAME} 님에게 미안하군요.", + "phrase14Text": "깃발이나... 또는 ${NAME} 님 같은 물체를 들어올릴 수 있어요.", "phrase15Text": "마지막으로 폭탄이 있군요.", "phrase16Text": "폭탄을 던지려면 연습이 필요해요.", "phrase17Text": "윽! 멋지게 던지지 못했군요.", @@ -1792,17 +1913,19 @@ "randomName3Text": "빌", "randomName4Text": "척", "randomName5Text": "필", - "skipConfirmText": "정말로 튜토리얼을 건너뛰세요? 눌러서 확인하세요.", + "skipConfirmText": "정말로 튜토리얼을 건너뛸건가요? 다시 눌러서 확인하세요.", "skipVoteCountText": "${COUNT}/${TOTAL} 건너뜀", "skippingText": "튜토리얼을 건너뛰는 중...", "toSkipPressAnythingText": "(튜토리얼을 건너뛰려면 아무거나 누르세요)" }, "twoKillText": "더블 킬!", + "uiScaleText": "Ui 크기", "unavailableText": "이용할 수 없음", "unconfiguredControllerDetectedText": "구성되지 않은 컨트롤러가 검색됨:", "unlockThisInTheStoreText": "상점에서 잠금 해제해야 합니다.", "unlockThisProfilesText": "${NUM}개 이상의 프로필을 만들기 위해, 다음 사항이 필요합니다. :", "unlockThisText": "잠금 해제 필요 사항:", + "unsupportedControllerText": "죄송합니다, 컨트롤러 \"${NAME}\" 은 지원되지 않습니다.", "unsupportedHardwareText": "죄송합니다만 이 하드웨어는 본 게임 빌드에 의해 지원되지 않습니다.", "upFirstText": "첫 번째:", "upNextText": "게임 ${COUNT}의 다음:", @@ -1810,11 +1933,15 @@ "upgradeText": "업그레이드", "upgradeToPlayText": "플레이하려면 상점에서 \"${PRO}\"를 잠금 해제하세요.", "useDefaultText": "기본값 사용", + "userSystemScriptsCreateText": "사용자 시스템 스크립트 생성", + "userSystemScriptsDeleteText": "사용자 시스템 스크립트 삭제", "usesExternalControllerText": "이 게임은 외부 컨트롤러를 입력용으로 사용합니다.", "usingItunesText": "사운트트랙에 음악 앱 사용 중...", "usingItunesTurnRepeatAndShuffleOnText": "iTunes에서 임의 재생이 켜져있고 반복은 모두로 되어 있는지 확인해주십시오.", "v2AccountLinkingInfoText": "V2 계정을 연결하려면 '계정 관리' 버튼을 누르세요.", + "v2AccountRequiredText": "여기에는 V2 계정을 필요로 합니다. 계정을 업그레이드하고 다시 시도하세요.", "validatingTestBuildText": "테스트 빌드 확인 중...", + "viaText": "통하여 로그인 함", "victoryText": "승리!", "voteDelayText": "${NUMBER} 초 동안 다른 투표를 시작할 수 없습니다.", "voteInProgressText": "투표가 이미 진행 중입니다.", @@ -1879,5 +2006,6 @@ }, "yesAllowText": "예, 허용합니다!", "yourBestScoresText": "내 최고 점수", - "yourBestTimesText": "내 최고 시간" + "yourBestTimesText": "내 최고 시간", + "yourPrizeText": "경품:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/malay.json b/dist/ba_data/data/languages/malay.json index 089a1b4b..ff2bef0b 100644 --- a/dist/ba_data/data/languages/malay.json +++ b/dist/ba_data/data/languages/malay.json @@ -5,9 +5,11 @@ "achievementProgressText": "Pencapaian: ${COUNT} daripada ${TOTAL}", "campaignProgressText": "Perkembangan Kempen [Susah]: ${PROGRESS}", "changeOncePerSeason": "Anda hanya boleh menukar ini sekali sahaja pada setiap musim.", - "changeOncePerSeasonError": "Anda mesti menunggu sehingga musim depan untuk menukarkannya lagi (${NUM} hari)", + "changeOncePerSeasonError": "Anda mesti menunggu sehingga musim seterusnya untuk menukarnya lagi (${NUM} hari)", + "createAnAccountText": "Buat Akaun", "customName": "Nama Tersuai", - "googlePlayGamesAccountSwitchText": "Jika anda ingin menggunakan akaun Google lain,\ngunakan apl Permainan Google Play untuk bertukar.", + "deleteAccountText": "Padamkan Akaun", + "googlePlayGamesAccountSwitchText": "Jika anda ingin menggunakan akaun Google lain,\ngunakan aplikasi Google Play Games untuk bertukar.", "linkAccountsEnterCodeText": "Masukkan Kod", "linkAccountsGenerateCodeText": "Hasilkan Kod", "linkAccountsInfoText": "(kongsi perkembangan melalui platform yang berbeza)", @@ -23,14 +25,16 @@ "setAccountNameDesc": "Pilih nama untuk dipaparkan untuk akaun anda.\nAnda boleh menggunakan nama itu dari salah satu akaun pautan anda \natau buat nama tersuai unik.", "signInInfoText": "Daftar masuk untuk dapatkan tiket, bersaing dalam talian,\ndan kongsi perkembangan melalui peranti.", "signInText": "Daftar Masuk", + "signInWithAnEmailAddressText": "Daftar masuk dengan e-mel", "signInWithDeviceInfoText": "(akaun automatik yang hanya tersedia untuk peranti ini)", "signInWithDeviceText": "Daftar masuk dengan akaun peranti", "signInWithGameCircleText": "Daftar masuk dengan Game Circle", "signInWithGooglePlayText": "Daftar masuk dengan Google Play", "signInWithTestAccountInfoText": "(jenis akaun warisan; gunakan akaun peranti untuk ke hadapan)", "signInWithTestAccountText": "Daftar masuk dengan akaun ujian", + "signInWithText": "Daftar masuk dengan ${SERVICE}", "signInWithV2InfoText": "(akaun yang berfungsi untuk semua platform)", - "signInWithV2Text": "Log masuk dengan akaun BombSquad", + "signInWithV2Text": "Daftar masuk dengan akaun ${APP_NAME}", "signOutText": "Daftar Keluar", "signingInText": "Mendaftar masuk...", "signingOutText": "Mendaftar keluar...", @@ -39,7 +43,7 @@ "unlinkAccountsInstructionsText": "Pilih akaun untuk nyahpaut", "unlinkAccountsText": "Nyahpaut Akaun", "unlinkLegacyV1AccountsText": "Nyahsambung Akaun Legacy (V1)", - "v2LinkInstructionsText": "Gunakan pautan ini untuk mencipta akaun atau daftar masuk", + "v2LinkInstructionsText": "Gunakan pautan ini untuk buat akaun baru atau daftar masuk.", "viaAccount": "(melalui akaun ${NAME})", "youAreSignedInAsText": "Anda didaftar masuk sebagai:" }, @@ -47,18 +51,18 @@ "achievementText": "Pencapaian", "achievements": { "Boom Goes the Dynamite": { - "description": "Pukul 3 musuh dengan TNT", - "descriptionComplete": "Memukul 3 musuh dengan TNT", - "descriptionFull": "Terajang 3 musuh dengan TNT di ${LEVEL}", - "descriptionFullComplete": "Penyepak 3 musuh dengan TNT di ${LEVEL}", - "name": "Letupan Dinamit" + "description": "Bunuh 3 orang jahat dengan TNT", + "descriptionComplete": "Membunuh 3 orang jahat dengan TNT", + "descriptionFull": "Bunuh 3 orang jahat dengan TNT di ${LEVEL}", + "descriptionFullComplete": "Membunuh 3 musuh dengan TNT di ${LEVEL}", + "name": "Haa Meletup Dinamit" }, "Boxer": { "description": "Menang tanpa menggunakan apa-apa bom", "descriptionComplete": "Memenangi tanpa menggunakan apa-apa bom", "descriptionFull": "Selesaikan ${LEVEL} tanpa menggunakan apa-apa bom", "descriptionFullComplete": "Menyelesaikan ${LEVEL} tanpa menggunakan apa-apa bom", - "name": "Burung apa, burung puyuh" + "name": "Peninju" }, "Dual Wielding": { "descriptionFull": "Sambungkan 2 alat kawalan (perkakasan atau aplikasi)", @@ -78,10 +82,10 @@ "name": "Free Loader" }, "Gold Miner": { - "description": "Lempang 6 musuh dengan periuk api", + "description": "Bunuh 6 orang jahat dengan periuk-api", "descriptionComplete": "Menerajangi 6 musuh dengan periuk api", "descriptionFull": "Lempang 6 musuh dengan periuk api di ${LEVEL}", - "descriptionFullComplete": "Terlempang 6 musuh dengan periuk api di ${LEVEL}", + "descriptionFullComplete": "Melempang 6 musuh dengan periuk api di ${LEVEL}", "name": "Pelombong Emas" }, "Got the Moves": { @@ -118,18 +122,18 @@ "name": "Ahli Sihir ${LEVEL}" }, "Mine Games": { - "description": "Lempang 3 musuh dengan periuk api", - "descriptionComplete": "Sepak 3 musuh dengan periuk api", + "description": "Sepak 3 musuh dengan periuk api", + "descriptionComplete": "Menyepak 3 musuh dengan periuk api", "descriptionFull": "Sepak 3 musuh dengan periuk api di ${LEVEL}", "descriptionFullComplete": "Menyepak 3 musuh dengan periuk api di ${LEVEL}", - "name": "Permainan Periuk Api" + "name": "Nah Bom Lantai" }, "Off You Go Then": { - "description": "Buang 3 musuh", + "description": "Buang/jatuhkan 3 orang jahat dari peta/tapak permainan", "descriptionComplete": "Membuang 3 orang jahat", - "descriptionFull": "Buang 3 musuh di ${LEVEL}", - "descriptionFullComplete": "Membuang 3 musuh ${LEVEL}", - "name": "Abang Aziz jatuh bot" + "descriptionFull": "Buang/jatuhkan 3 musuh dari peta/tapak permainan di ${LEVEL}", + "descriptionFullComplete": "Membuang 3 musuh di ${LEVEL}", + "name": "Gi Main Jauh-jauh" }, "Onslaught God": { "description": "Dapatkan 5000 mata", @@ -150,7 +154,7 @@ "descriptionComplete": "Mengalahkan semua serangan", "descriptionFull": "Kalahkan semua serangan di ${LEVEL}", "descriptionFullComplete": "Mengalahkan semua serangan di ${LEVEL}", - "name": "Berjaya ${LEVEL}" + "name": "Kemenangan ${LEVEL}" }, "Onslaught Wizard": { "description": "Skorkan 1000 mata", @@ -161,23 +165,23 @@ }, "Precision Bombing": { "description": "Menang tanpa sebarang kuasa tambahan", - "descriptionComplete": "Menang tanpa kuasa tambahan", - "descriptionFull": "Menangkan ${LEVEL} tanpa sebarang kuasa tambahan", - "descriptionFullComplete": "Menang ${LEVEL} tanpa kuasa tambahan", - "name": "Pengeboman tepat" + "descriptionComplete": "Memenangi tanpa sebarang kuasa tambahan", + "descriptionFull": "Menang ${LEVEL} tanpa sebarang kuasa tambahan", + "descriptionFullComplete": "Memenangi ${LEVEL} tanpa kuasa tambahan", + "name": "Pengeboman Tepat" }, "Pro Boxer": { "description": "Menang tanpa menggunakan bom", - "descriptionComplete": "Monang tanpa menggunakan bom", - "descriptionFull": "Lengkapkan ${LEVEL} tanpa menggunakan bom", - "descriptionFullComplete": "Selesai level ${LEVEL} tanpa menggunakan bom", + "descriptionComplete": "Memenangi tanpa menggunakan bom", + "descriptionFull": "Lengkapkan ${LEVEL} tanpa menggunakan sebarang bom", + "descriptionFullComplete": "Melengkapkan level ${LEVEL} tanpa menggunakan sebarang bom", "name": "Peninju Pro" }, "Pro Football Shutout": { "description": "Menang tanpa membiarkan penjahat mendapat markah", - "descriptionComplete": "Memonangi tanpa membiarkan penjahat mendapat markah", + "descriptionComplete": "Memenangi tanpa membiarkan penjahat mendapat markah", "descriptionFull": "Menangkan level ${LEVEL} tanpa membiarkan penjahat mendapat markah", - "descriptionFullComplete": "Menang ${LEVEL} tanpa membiarkan penjahat mendapat markah", + "descriptionFullComplete": "Memenangi ${LEVEL} tanpa membiarkan penjahat mendapat markah", "name": "${LEVEL} Menutup" }, "Pro Football Victory": { @@ -188,15 +192,15 @@ "name": "${LEVEL} Kemenangan" }, "Pro Onslaught Victory": { - "description": "Kalahkan semua tahap", - "descriptionComplete": "Telah mengalahkan semua gelombang", + "description": "Kalahkan semua tahap serangan", + "descriptionComplete": "Mengalahkan semua tahap serangan", "descriptionFull": "Kalahkan semua gelombang ${LEVEL}", "descriptionFullComplete": "Telah mengalahkan semua gelombang ${LEVEL}", "name": "${LEVEL} Kemenangan" }, "Pro Runaround Victory": { "description": "Lengkapkan semua gelombang", - "descriptionComplete": "Telah selesai semua gelombang", + "descriptionComplete": "Menyelesaikan semua serangan", "descriptionFull": "Lengkapkan semua gelombang pada ${LEVEL}", "descriptionFullComplete": "Telah selesai semua gelombang pada ${LEVEL}", "name": "pemenang ${LEVEL}" @@ -270,9 +274,9 @@ "name": "Pelempang Super" }, "TNT Terror": { - "description": "Letupkan 6 orang jahat dengan TNT", - "descriptionComplete": "6 orang jahat telah diletupkan dengan TNT", - "descriptionFull": "Letupkan 6 orang jahat dengan TNT di ${LEVEL}", + "description": "Bunuh 6 orang jahat dengan TNT", + "descriptionComplete": "Membunuh 6 orang jahat dengan TNT", + "descriptionFull": "Bunuh 6 orang jahat dengan TNT di ${LEVEL}", "descriptionFullComplete": "6 orang jahat telah diletupkan dengan TNT di ${LEVEL}", "name": "Ta an ta" }, @@ -292,7 +296,7 @@ "description": "Hentikan setiap orang jahat", "descriptionComplete": "Telah berjaya mengentikan setiap orang jahat", "descriptionFull": "Hentikan setiap orang jahat di ${LEVEL}", - "descriptionFullComplete": "Berjaya menghentikan setiap orang jahat di ${LEVEL}", + "descriptionFullComplete": "Menghentikan setiap orang jahat di ${LEVEL}", "name": "Dinding" }, "Uber Football Shutout": { @@ -332,9 +336,14 @@ "getMoreGamesText": "Dapatkan Lebih Banyak Permainan...", "titleText": "Tambahkan Permainan" }, + "addToFavoritesText": "Tambah pada Kegemaran", + "addedToFavoritesText": "'${NAME}' ditambah pada Kegemaran", + "allText": "Semua", "allowText": "Benarkan", "alreadySignedInText": "Akaun anda didaftar masuk dari peranti lain;\nsila tukar akaun atau tutupkan permainan pada\nperanti itu dan cuba lagi.", "apiVersionErrorText": "Tidak dapat memuatkan modul ${NAME}; ia menyasarkan versi api ${VERSION_USED}; kami memerlukan ${VERSION_REQUIRED}.", + "applyText": "Memohon", + "areYouSureText": "Adakah awak pasti?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Automatik\" menghidupkan ini apabila fon kepala dimasukkan)", "headRelativeVRAudioText": "Audio VR Set-Kelapa Relatif", @@ -356,14 +365,24 @@ "boostText": "Tingkatkan", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} dapat ditatarajah di aplikasinya", "buttonText": "butang", - "canWeDebugText": "Adakah anda mahu BombSquad melaporkan pepijat, kerosakan, dan\nmaklumat penggunaan asas kepada pembangun secara automatik?\n\nData ini tidak mengandungi maklumat peribadi dan membantu\npermainan selalu berjalan dengan lancar dan bebas pepijat.", + "canWeDebugText": "Adakah anda mahu ${APP_NAME} melaporkan secara automatik pepijat, ranap sistem \ndan maklumat penggunaan asas kepada pembangun?\n \nData ini tidak mengandungi maklumat peribadi dan membantu \npermainan selalu berjalan lancar dan bebas pepijat.", "cancelText": "Batal", "cantConfigureDeviceText": "Maaf, ${DEVICE} tidak dapat diatur.", "challengeEndedText": "Cabaran ini telah tamat", "chatMuteText": "Senyapkan Perbualan", "chatMutedText": "Perbualan Disenyapkan", "chatUnMuteText": "Nyahsenyapkan Perbualan", + "chests": { + "prizeOddsText": "Peluang Hadiah", + "reduceWaitText": "Kurangkan Tunggu", + "slotDescriptionText": "Slot ini boleh memuatkan peti.\n\nPeroleh peti dengan bermain peringkat kempen,\nmenempatkan dalam kejohanan, dan melengkapkan\npencapaian.", + "slotText": "Slot Peti ${NUM}", + "slotsFullWarningText": "AMARAN: Semua slot peti anda penuh.\nMana-mana peti yang anda perolehi dalam permainan ini akan hilang.", + "unlocksInText": "Dibuka Dalam" + }, "choosingPlayerText": "", + "claimText": "Tuntut", + "codesExplainText": "Kod disediakan oleh pembangun untuk\nmendiagnosis dan membaiki masalah akaun.", "completeThisLevelToProceedText": "Anda mesti menyelasaikan\nperingkat ini untuk teruskan!", "completionBonusText": "Bonus Penyelesaian", "configControllersWindow": { @@ -408,54 +427,55 @@ "pressAnyButtonText": "Tekan mana-mana butang...", "pressLeftRightText": "Tekan kiri atau kanan...", "pressUpDownText": "Tekan bawah atau atas...", - "runButton1Text": "Butang Jalankan 1", - "runButton2Text": "Butang Jalankan 2", - "runTrigger1Text": "Jalankan Pencetus 1", - "runTrigger2Text": "Jalankan Pencetus 2", + "runButton1Text": "Butang Lari 1", + "runButton2Text": "Butang Lari 2", + "runTrigger1Text": "Pencetus Larian 1", + "runTrigger2Text": "Pencetus Larian 2", "runTriggerDescriptionText": "(pencetus analog membolehkan anda berlari pada kelajuan yang berbeza)", - "secondHalfText": "Gunakan ini untuk mengkonfigurasi pengawal kedua\ndalam peranti, 2-pengawal-dalam-1 yang\nmuncul sebagai pengawal tunggal.", - "secondaryEnableText": "Dayakan", - "secondaryText": "Pengawal Kedua", + "secondHalfText": "Gunakan ini untuk mengkonfigurasi pengawal kedua\ndalam peranti, 2-alat kawalan-dalam-1 yang\nmuncul sebagai alat kawalan tunggal.", + "secondaryEnableText": "Aktifkan", + "secondaryText": "Alat Kawalan Kedua", "startButtonActivatesDefaultDescriptionText": "(matikan ini jika butang mula anda lebih kepada butang 'menu')", "startButtonActivatesDefaultText": "Butang Mula Mengaktifkan Widget Biasa", - "titleText": "Setup Pengawal", - "twoInOneSetupText": "Persediaan Pengawal 2-dalam-1", - "uiOnlyDescriptionText": "(halang pengawal ini daripada menyertai permainan)", - "uiOnlyText": "Had kepada Penggunaan Menu", + "titleText": "Penetap Alat Kawalan", + "twoInOneSetupText": "Penetap Alat Kawalan 2-dalam-1", + "uiOnlyDescriptionText": "(menghalang alat kawalan ini daripada menyertai permainan)", + "uiOnlyText": "Hadkan kepada Penggunaan Menu sahaja", "unassignedButtonsRunText": "Semua Butang yang Tidak Ditugaskan Dijalankan", "unsetText": "", "vrReorientButtonText": "Butang VR Reorient" }, "configKeyboardWindow": { "configuringText": "Mengkonfigurasi ${DEVICE}", - "keyboard2NoteText": "Nota: kebanyakan papan kekunci boleh mendaftarkan beberapa tekanan kekunci dalam\nsesuatu masa, jadi papan kekunci kedua mungkin boleh berfungsi dengan lebih baik\njika terdapat papan kekunci berasingan yang dilampirkan untuk mereka gunakan.\nAmbil perhatian bahawa anda masih perlu memberikan kunci unik kepada\ndua pemain walaupun dalam kes itu." + "keyboard2NoteText": "Nota: kebanyakan papan kekunci hanya boleh mengesan beberapa tekanan kekunci sahaja dalam\nsesuatu masa, jadi papan kekunci kedua mungkin boleh berfungsi dengan lebih baik\njika terdapat papan kekunci berasingan yang dilampirkan untuk mereka gunakan.\nAmbil perhatian bahawa anda masih perlu memberikan kunci unik kepada\ndua pemain walaupun dalam kes itu." }, "configTouchscreenWindow": { "actionControlScaleText": "Skala Kawalan Aksi", "actionsText": "Aksi", "buttonsText": "butang", "dragControlsText": "< seret kawalan untuk ubah kedudukan >", - "joystickText": "kayu ria", - "movementControlScaleText": "Skala Kawalan Gerakan", + "joystickText": "Kayu Bedik (Joystick)", + "movementControlScaleText": "Skala Kawalan Pergerakan", "movementText": "Pergerakan", "resetText": "Tetap Semula", - "swipeControlsHiddenText": "Sembunyikan Ikon Sapu", - "swipeInfoText": "Gaya kawalan 'sapu' sangat sedikit digunakan tapi ia\nmembuatkan lebih senang bermain tanpa melihat kawalan", - "swipeText": "sapu", + "swipeControlsHiddenText": "Sembunyikan Ikon Kawalan Yang Mengggunakan Seret", + "swipeInfoText": "Gaya kawalan 'seret' mungkin susah untuk dibiasakan tapi ia\nmembuatkan lebih senang bermain tanpa melihat pada kawalan.", + "swipeText": "seret", "titleText": "Atur Skrin Sentuhan" }, + "configureDeviceInSystemSettingsText": "${DEVICE} boleh diatur di aplikasi Tetapan Sistem.", "configureItNowText": "Aturnya sekarang?", "configureText": "Atur", "connectMobileDevicesWindow": { "amazonText": "Amazon AppStore", "appStoreText": "App Store", - "bestResultsText": "Untuk hasil terbaik, anda memerlukan rangkaian Wi-Fi yang bebas lambat.\nAnda boleh mengurangkan kelambatan Wi-Fi dengan mematikan peranti wayarles,\ndengan bermain berdekatan dengan penghala Wi-Fi anda, dan dengan menyambungkan\nhos permainan ke rangkaian melalui ethernet.", - "explanationText": "Untuk menggunakan telefon pintar atau tablet sebagai alat kawalan tanpa\nwayar, pasang aplikasi \"${REMOTE_APP_NAME}\" padanya. Banyak peranti boleh\nsambung ke satu permainan ${APP_NAME} melalui Wi-Fi, dan percuma!", - "forAndroidText": "Untuk Android:", - "forIOSText": "Untuk iOS:", + "bestResultsText": "Untuk hasil terbaik, anda memerlukan rangkaian Wi-Fi yang bebas lambat.\nAnda boleh mengurangkan kelambatan Wi-Fi dengan mematikan peranti tanpa wayar lain (peranti lain yang guna Wi-Fi),\ndengan bermain berdekatan dengan router/pengahala Wi-Fi anda, dan dengan menyambungkan\nhos permainan ke rangkaian melalui ethernet.", + "explanationText": "Untuk menggunakan telefon pintar atau tablet sebagai alat kawalan tanpa\nwayar, pasang aplikasi \"${REMOTE_APP_NAME}\" padanya. Banyak peranti boleh\nsambung ke satu permainan ${APP_NAME} melalui Wi-Fi, dan ianya percuma!", + "forAndroidText": "untuk Android:", + "forIOSText": "untuk iOS:", "getItForText": "Dapatkan ${REMOTE_APP_NAME} bagi iOS di Apple App Store\natau untuk Android di Google Play Store atau Amazon Appstore", "googlePlayText": "Google Play", - "titleText": "Menggunakan Peranti Mudah Alih sebagai Pengawal:" + "titleText": "Menggunakan Peranti Mudah Alih (telefon pintar/tablet) sebagai Alat Kawalan:" }, "continuePurchaseText": "Teruskan untuk ${PRICE}?", "continueText": "Teruskan", @@ -465,17 +485,17 @@ "activenessInfoText": "Pengganda ini meningkat pada hari apabila anda\nbermain dan jatuh pada hari apabila anda tidak.", "activityText": "Aktiviti", "campaignText": "Kempen", - "challengesInfoText": "Dapat hadiah apabila melengkapkan permainan mini.\n\nHadiah dan tahap kesukaran meningkat\nsetiap kali cabaran selesai dan\nberkurangan apabila tamat tempoh atau dilucuthakkan.", + "challengesInfoText": "Dapat hadiah apabila melengkapkan permainan mini.\n\nHadiah dan tahap kesukaran meningkat\nsetiap kali satu cabaran diselesaikan dan\nberkurangan pabila satu tamat tempoh atau dilucuthakkan.", "challengesText": "Cabaran", - "currentBestText": "Yang Terbaik", + "currentBestText": "Yang Terbaik Semasa", "customText": "Ubah suai", "entryFeeText": "Kemasukan", "forfeitConfirmText": "Hilang cabaran ini?", - "forfeitNotAllowedYetText": "Cabaran ini tidak boleh diketepikan lagi.", + "forfeitNotAllowedYetText": "Cabaran ini belum boleh diketepikan lagi.", "forfeitText": "Mengalah", "multipliersText": "Pengganda", "nextChallengeText": "Cabaran Seterusnya", - "nextPlayText": "Main Seterusnya", + "nextPlayText": "Permainan Seterusnya", "ofTotalTimeText": "daripada ${TOTAL}", "playNowText": "Main sekarang", "pointsText": "Mata", @@ -494,19 +514,19 @@ "toRankedText": "Untuk Peringkat", "totalText": "jumlah", "tournamentInfoText": "Bersaing untuk markah tinggi dengan\npemain lain dalam liga anda.\n\nHadiah diberikan kepada markah tertinggi\npemain apabila masa kejohanan tamat.", - "welcome1Text": "Selamat datang ke ${LEAGUE}. Anda boleh memperbaiki\nkedudukan liga dengan memperoleh penarafan bintang, melengkapkan\npencapaian, dan memenangi trofi dalam kejohanan.", - "welcome2Text": "Anda juga boleh mendapatkan tiket daripada banyak aktiviti yang sama.\nTiket boleh digunakan untuk membuka kunci aksara baharu, peta dan\npermainan mini, untuk menyertai kejohanan dan banyak lagi.", - "yourPowerRankingText": "Kedudukan Terhebat Anda:" + "welcome1Text": "Selamat datang ke ${LEAGUE}. Anda boleh memperbaikkan\nkedudukan liga dengan memperoleh penarafan bintang, melengkapkan\npencapaian, dan memenangi trofi dalam kejohanan.", + "welcome2Text": "Anda juga boleh mendapatkan tiket daripada banyak aktiviti yang sama.\nTiket boleh digunakan untuk membuka kunci aksara(karakter) baharu, peta dan\npermainan mini, untuk menyertai kejohanan dan banyak lagi.", + "yourPowerRankingText": "Kedudukan Kuasa Anda:" }, - "copyConfirmText": "Disalin ke papan keratan.", + "copyConfirmText": "Dah disalin ke papan keratan (clipboard).", "copyOfText": "Salinan ${NAME}", - "copyText": "Salinan", - "createEditPlayerText": "", - "createText": "Cipta", + "copyText": "Salin", + "createEditPlayerText": "", + "createText": "Buat", "creditsWindow": { "additionalAudioArtIdeasText": "Audio Tambahan, Hasil Kerja Awal, dan Idea oleh ${NAME}", "additionalMusicFromText": "Muzik tambahan dari ${NAME}", - "allMyFamilyText": "Seluruh kawan dan keluarga saya yang tolong main uji", + "allMyFamilyText": "Semua kawan dan keluarga saya yang tolong uji permainan", "codingGraphicsAudioText": "Aturcara, Grafik, dan Audio oleh ${NAME}", "languageTranslationsText": "Penerjemah Bahasa:", "legalText": "Sah:", @@ -518,58 +538,63 @@ "specialThanksText": "Terima Kasih Banyak kepada:", "thanksEspeciallyToText": "Terima kasih terutamanya kepada ${NAME}", "titleText": "Penghargaan ${APP_NAME}", - "whoeverInventedCoffeeText": "Sesiapa yang buatkan kopi" + "whoeverInventedCoffeeText": "Sesiapapun yang buat kopi" }, "currentStandingText": "Kedudukan semasa anda adalah #${RANK}", "customizeText": "Ubahsuai...", - "deathsTallyText": "${COUNT} meninggal", - "deathsText": "Meninggal", - "debugText": "nyahpep..izzat", + "deathsTallyText": "${COUNT} kematian", + "deathsText": "Kematian", + "debugText": "nyahpepijat (debug)", "debugWindow": { - "reloadBenchmarkBestResultsText": "Nota: adalah disyorkan agar anda menetapkan Tetapan->Grafik->Tekstur kepada 'Tinggi' semasa menguji ini.", + "reloadBenchmarkBestResultsText": "Nota: Disyorkan untuk anda menetapkan Tetapan->Grafik->Tekstur kepada 'Tinggi' semasa menguji ni.", "runCPUBenchmarkText": "Jalankan Penanda Aras CPU", "runGPUBenchmarkText": "Jalankan Penanda Aras GPU", "runMediaReloadBenchmarkText": "Jalankan Penanda Aras Muat Semula Media", "runStressTestText": "Jalankan ujian tekanan", "stressTestPlayerCountText": "Kiraan Pemain", - "stressTestPlaylistDescriptionText": "Ujian Tekanan Senarai Main", - "stressTestPlaylistNameText": "Nama Senarai Main", - "stressTestPlaylistTypeText": "Jenis Senarai Main", + "stressTestPlaylistDescriptionText": "Ujian Tekanan Senarai Permainan", + "stressTestPlaylistNameText": "Nama Senarai Permainan", + "stressTestPlaylistTypeText": "Jenis Senarai Permainan", "stressTestRoundDurationText": "Tempoh Pusingan", "stressTestTitleText": "Ujian Tekanan", "titleText": "Penanda Aras & Ujian Tekanan", "totalReloadTimeText": "Jumlah masa muat semula: ${TIME} (lihat log untuk butiran)" }, - "defaultGameListNameText": "Senarai Main ${PLAYMODE} biasa", - "defaultNewGameListNameText": "Senarai Main ${PLAYMODE} Saya", + "defaultGameListNameText": "Senarai Permain ${PLAYMODE} Biasa", + "defaultNewGameListNameText": "Senarai Permainan ${PLAYMODE} Saya", "deleteText": "Buang", "demoText": "Demo", "denyText": "Nafikan", "deprecatedText": "Ditamatkan", - "desktopResText": "Desktop Res", - "deviceAccountUpgradeText": "Amaran:\nAnda telah log masuk dengan akaun peranti (${NAME}).\nAkaun peranti akan dialih keluar dalam kemas \nkini akan datang.", + "descriptionText": "Keterangan", + "desktopResText": "Resolusi Desktop", + "deviceAccountUpgradeText": "Amaran:\nAnda telah log masuk dengan akaun peranti (${NAME}).\nAkaun peranti akan dibuang dalam kemas kini (update) yang akan datang.\nNaik taraf kepada akaun V2 kalau anda mahu simpan kemajuan/data permainan (progress) anda.", "difficultyEasyText": "Mudah", "difficultyHardOnlyText": "Mod Susah Sahaja", "difficultyHardText": "Susah", - "difficultyHardUnlockOnlyText": "Tahap ini hanya dapat dibuka dalam mod sukar.\nAdakah anda mempunyai apa yang diperlukan!?!?!", - "directBrowserToURLText": "Sila arahkan pelayar web ke URL berikut:", - "disableRemoteAppConnectionsText": "Lumpuhkan Sambungan Apl Jauh", - "disableXInputDescriptionText": "Membenarkan lebih daripada 4 pengawal tetapi mungkin tidak berfungsi juga.", + "difficultyHardUnlockOnlyText": "Tahap ini hanya dapat dibuka dalam mod susah.\nAdakah anda rasa anda cukup berani dan cekap untuknya!?!?!", + "directBrowserToURLText": "Sila arahkan pelayar web (Web-browser) ke URL berikut:", + "disableRemoteAppConnectionsText": "Matikan Sambungan Aplikasi-Alat-Kawalan", + "disableXInputDescriptionText": "Membenarkan lebih daripada 4 alat kawalan tetapi mungkin tidak berfungsi juga.", "disableXInputText": "Lumpuhkan XInput", + "disabledText": "Dimatikan", + "discardText": "Buang", + "discordFriendsText": "Mahu seseorang untuk bermain bersama?\nSertai Discord kami dan cari rakan baharu!", + "discordJoinText": "Sertai Discord", "doneText": "Selesai", "drawText": "Seri", - "duplicateText": "Pendua", + "duplicateText": "Gandakan", "editGameListWindow": { "addGameText": "Tambah\nPermainan", - "cantOverwriteDefaultText": "Tidak boleh menulis ganti senarai main biasa!", + "cantOverwriteDefaultText": "Tidak boleh ubah suai senarai permainan biasa!", "cantSaveAlreadyExistsText": "Senarai main dengan nama itu sudah ada!", - "cantSaveEmptyListText": "Tidak dapat menyimpan senarai main kosong!", - "editGameText": "Sunting\nPermainan", - "listNameText": "Nama Senarai Main", + "cantSaveEmptyListText": "Tidak dapat menyimpan senarai main yang kosong!", + "editGameText": "Sunting (Edit) \nPermainan", + "listNameText": "Nama Senarai Permainan", "nameText": "Nama", "removeGameText": "Buang\nPermainan", "saveText": "Simpan senarai", - "titleText": "Editor Senarai Main" + "titleText": "Editor/Penyunting Senarai Permainan" }, "editProfileWindow": { "accountProfileInfoText": "Profil istimewa ini mempunyai nama\ndan ikon berdasarkan akaun anda.\n\n${ICONS}\n\nBuat profil tersuai untuk menggunakan\nnama yang berbeza atau ikon tersuai.", @@ -578,27 +603,28 @@ "characterText": "watak", "checkingAvailabilityText": "Menyemak ketersediaan untuk \"${NAME}\"...", "colorText": "warna", - "getMoreCharactersText": "Dapatkan Lebih Banyak Watak...", + "getMoreCharactersText": "Dapatkan Lebih Banyak Watak/Karakter...", "getMoreIconsText": "Dapatkan Lebih Banyak Ikon...", "globalProfileInfoText": "Profil pemain global dijamin nama\nunik di seluruh dunia. Ia juga termasuk ikon tersuai.", "globalProfileText": "(profil global)", "highlightText": "sorotan", "iconText": "ikon", - "localProfileInfoText": "Profil pemain tempatan tidak mempunyai ikon dan namanya\ntidak dijamin unik. Tingkatkan ke profil global\nuntuk menempah nama unik dan menambahkan ikon sesuai.", + "localProfileInfoText": "Profil pemain tempatan tidak mempunyai ikon dan namanya\ntidak dijamin unik. Naik taraf ke profil global\nuntuk menempah nama unik dan menambahkan ikon tersuai.", "localProfileText": "(profil lokal)", "nameDescriptionText": "Nama Pemain", "nameText": "Nama", + "profileAlreadyExistsText": "Profil dengan nama itu dah ada.", "randomText": "rawak", "titleEditText": "Sunting profil", - "titleNewText": "Profil Baru", - "unavailableText": "\"${NAME}\" tidak tersedia; cuba nama lain.", + "titleNewText": "Profil Baharu", + "unavailableText": "\"${NAME}\" tidak tersedia (dah ada orang pakai); cuba nama lain.", "upgradeProfileInfoText": "Ini akan menyimpan nama pemain anda di seluruh dunia\ndan membolehkan anda memberikan ikon khusus kepadanya.", "upgradeToGlobalProfileText": "Naik taraf kepada Profil Global" }, "editSoundtrackWindow": { "cantDeleteDefaultText": "Anda tidak boleh memadamkan runut bunyi terbiasa.", "cantEditDefaultText": "Tidak boleh mengedit runut bunyi biasa. Duplikasikan nya atau buat yang baharu.", - "cantOverwriteDefaultText": "Tidak dapat menulis ganti runut bunyi biasa", + "cantOverwriteDefaultText": "Tidak dapat menu ganti default soundtrack", "cantSaveAlreadyExistsText": "Lagu dengan nama itu sudah wujud!", "defaultGameMusicText": "", "defaultSoundtrackNameText": "Runut Bunyi Biasa", @@ -623,6 +649,7 @@ "useMusicFolderText": "Folder Fail Muzik" }, "editText": "Sunting", + "enabledText": "Dihidupkan", "endText": "Tamatkan", "enjoyText": "Nikmatilah!", "epicDescriptionFilterText": "${DESCRIPTION} dalam gerakan perlahan epik", @@ -634,6 +661,8 @@ "errorText": "Ralat", "errorUnknownText": "ralat tidak diketahui", "exitGameText": "Keluar daripada ${APP_NAME}?", + "expiredAgoText": "Tamat tempoh ${T} yang lalu", + "expiresInText": "Tamat tempoh dalam ${T}", "exportSuccessText": "'${NAME}' dieksport.", "externalStorageText": "Storan Luaran", "failText": "Gagal", @@ -652,9 +681,9 @@ "fireTVRemoteWarningText": "* Untuk pengalaman yang lebih baik,\ngunakan Game Controllers atau pasang\naplikasi '${REMOTE_APP_NAME}' pada\ntelefon atau tablet anda.", "firstToFinalText": "Yang pertama untuk ${COUNT} pusingan akhir", "firstToSeriesText": "Siri Pertama kepada-${COUNT}.", - "fiveKillText": "KENTUT BERLIMA!!!", + "fiveKillText": "MEMBUNUH LIMA!!!", "flawlessWaveText": "Pusingan Sempurna!", - "fourKillText": "KENTUT BERAMAI-RAMAI!!!", + "fourKillText": "MEBUNUH EMPAT!!!", "friendScoresUnavailableText": "Skor rakan tidak tersedia.", "gameCenterText": "GameCenter", "gameCircleText": "GameCircle", @@ -668,6 +697,8 @@ "duplicateText": "Pendua\nSenarai main", "editText": "Sunting\nSenarai main", "newText": "Senarai Main\nBaru", + "pointsToWinText": "Mata Untuk Menang", + "seriesLengthText": "Panjang Siri", "showTutorialText": "Tunjukkan Cara-cara", "shuffleGameOrderText": "Pesanan Permainan Rombak", "titleText": "Ubahsuai Senarai Main ${TYPE}" @@ -693,6 +724,7 @@ "copyCodeConfirmText": "Kod telah disalin.", "copyCodeText": "Salin Kod", "dedicatedServerInfoText": "Untuk pengalaman yang lebih baik, tetapkan pelayan berdedikasi. Lihat di bombsquadgame.com/server untuk mengetahui caranya.", + "descriptionShortText": "Gunakan tetingkap berkumpul untuk memasang parti.", "disconnectClientsText": "Ini akan memutuskan sambungan ${COUNT} pemain\ndi parti anda. Anda pasti?", "earnTicketsForRecommendingAmountText": "Rakan anda akan menerima ${COUNT} tiket jika mereka cuba main\n(anda akan menerima ${YOU_COUNT} tiket untuk setiap yang cuba)", "earnTicketsForRecommendingText": "Kongsi permainan\nuntuk tiket percuma...", @@ -705,10 +737,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tiket daripada ${NAME}", "friendPromoCodeAwardText": "Anda akan menerima ${COUNT} tiket setiap kali kod digunakan.", "friendPromoCodeExpireText": "Kod akan tamat tempoh dalam ${EXPIRE_HOURS} jam dan cuma berfungsi untuk pemain baru.", - "friendPromoCodeInstructionsText": "Untuk gunakan kod, buka ${APP_NAME} dan pergi ke \"Tetapan->Lanjutan->Masukkan Kod\".\nLihat di bombsquadgame.com untuk pautan muat turun untuk semua platform yang disokong.", + "friendPromoCodeInstructionsText": "Untuk menggunakan kod, buka ${APP_NAME} dan pergi ke \"Tetapan->Lanjutan->Hantar Maklumat\".\nLihat ke bombsquadgame.com untuk pautan muat turun untuk semua platform yang disokong.", "friendPromoCodeRedeemLongText": "Ia boleh ditebus untuk ${COUNT} tiket percuma oleh sebanyak ${MAX_USES} orang.", "friendPromoCodeRedeemShortText": "Ia boleh ditebus untuk ${COUNT} tiket di dalam permainan.", - "friendPromoCodeWhereToEnterText": "(tebus di \"Tetapan->Lanjutan->Masukkan Kod\")", + "friendPromoCodeWhereToEnterText": "(dalam \"Tetapan->Lanjutan->Hantar Maklumat\")", "getFriendInviteCodeText": "Dapatkan Kod Jemputan Rakan", "googlePlayDescriptionText": "Jemput pemain Google Play ke parti anda:", "googlePlayInviteText": "Jemput", @@ -740,6 +772,7 @@ "manualYourLocalAddressText": "Alamat tempatan anda", "nearbyText": "Berdekatan", "noConnectionText": "", + "noPartiesAddedText": "Tiada Parti Yang Ditambah", "otherVersionsText": "(versi lain)", "partyCodeText": "Kod Permainan", "partyInviteAcceptText": "Terima", @@ -803,6 +836,12 @@ "youHaveShortText": "anda mempunyai ${COUNT} tiket", "youHaveText": "anda mempunyai ${COUNT} tiket" }, + "goldPass": { + "desc1InfTokensText": "Token tak terhingga.", + "desc2NoAdsText": "Tiada iklan.", + "desc3ForeverText": "Selama-lamanya.", + "goldPassText": "Pas Emas" + }, "googleMultiplayerDiscontinuedText": "Maaf, perkhidmatan berbilang pemain Google tidak lagi tersedia.\nSaya sedang mencari pengganti secepat mungkin.\nSementara itu, sila cuba kaedah sambungan lain.\n-Eric", "googlePlayPurchasesNotAvailableText": "Pembelian Google Play tidak tersedia.\nAnda mungkin perlu mengemas kini apl kedai anda.", "googlePlayServicesNotAvailableText": "Perkhidmatan Google Play tidak tersedia.\nSesetengah fungsi apl mungkin dilumpuhkan.", @@ -811,10 +850,12 @@ "alwaysText": "Sentiasa", "fullScreenCmdText": "Skrin penuh (Cmd-F)", "fullScreenCtrlText": "Skrin penuh (Ctrl-F)", + "fullScreenText": "Skrin Penuh", "gammaText": "Gamma", "highText": "Tinggi", "higherText": "Lebih tinggi", "lowText": "Rendah", + "maxFPSText": "Maksimum FPS", "mediumText": "Sederhana", "neverText": "Tidak pernah", "resolutionText": "Resolusi", @@ -844,9 +885,9 @@ "powerupBombNameText": "Bom Bertiga", "powerupCurseDescriptionText": "Anda mungkin mahu elakkan diri\ndaripada ini... atau tidak?", "powerupCurseNameText": "Sumpah", - "powerupHealthDescriptionText": "Pulihkan nyawa penuh.\nAnda mungkin tidak terfikir.", + "powerupHealthDescriptionText": "Penuhkan bar nyawa.\nMesti xleh teka an? An?", "powerupHealthNameText": "Pek Rawatan", - "powerupIceBombsDescriptionText": "Lebih lemah daripada bom biasa\ntapi membekukan musuh anda\ndan terutamanya memecahkan.", + "powerupIceBombsDescriptionText": "Lebih lemah daripada bom biasa\ntapi membekukan musuh dan\nsenang dipecahkan.", "powerupIceBombsNameText": "Bom Ais", "powerupImpactBombsDescriptionText": "Lemah sikit daripada bom biasa,\ntapi ia letup bila dihentam.", "powerupImpactBombsNameText": "Bom Pencetus", @@ -856,7 +897,7 @@ "powerupPunchNameText": "Sarung Tangan Tinju", "powerupShieldDescriptionText": "Menyerap kerosakan\njadi jangan takut.", "powerupShieldNameText": "Perlindungan Tenaga", - "powerupStickyBombsDescriptionText": "Melekat di mana sahaja ia kena.\nMenghasilkan keseronokan.", + "powerupStickyBombsDescriptionText": "Melekat di mana sahaja ia kena.\nBoleh jadi lawak.", "powerupStickyBombsNameText": "Bom Melekit", "powerupsSubtitleText": "Sudah tentu; tiada permainan yang selesai tanpa kuasa tambahan", "powerupsText": "Kuasa Tambahan", @@ -869,15 +910,16 @@ }, "holdAnyButtonText": "", "holdAnyKeyText": "", - "hostIsNavigatingMenusText": "- ${HOST} sedang melayari menu -", - "importPlaylistCodeInstructionsText": "Gunakan kod berikut untuk import senarai main ini mana-mana:", + "hostIsNavigatingMenusText": "- ${HOST} tengah mungkin tengah pilih² game macam bos -", + "importPlaylistCodeInstructionsText": "Gunakan kod berikut untuk import senarai permainan ini mana-mana:", "importPlaylistSuccessText": "Senarai main ${TYPE} '${NAME}' diimport", "importText": "Import", "importingText": "Mengimport...", "inGameClippedNameText": "dalam permainan dilihat\n\"${NAME}\"", + "inboxText": "Peti masuk", "installDiskSpaceErrorText": "RALAT: Tidak dapat menyelesaikan pemasangan.\nAnda mungkin kehabisan storan pada peranti anda.\nKosongkan sikit ruang dan cuba lagi.", "internal": { - "arrowsToExitListText": "tekan ${LEFT} atau ${RIGHT} untuk terkeluar senarai", + "arrowsToExitListText": "tekan ${LEFT} atau ${RIGHT} untuk keluar senarai", "buttonText": "butang", "cantKickHostError": "Anda tidak boleh menendang penganjur.", "chatBlockedText": "${NAME} disekat beburak selamo ${TIME} saat.", @@ -929,12 +971,14 @@ "timeOutText": "(masa tamat dalam ${TIME} saat)", "touchScreenJoinWarningText": "Anda telah bergabung dengan skrin sentuh.\nJika ini satu kesilapan, ketik 'Menu->Tinggalkan Permainan' dengannya.", "touchScreenText": "Skrin-Sesentuh", + "unableToCompleteTryAgainText": "Tidak dapat menyelesaikan ini sekarang.\nSila cuba lagi.", "unableToResolveHostText": "Ralat: tidak dapat menyelesaikan hos.", "unavailableNoConnectionText": "Ini tidak tersedia pada masa ini (tiada sambungan internet?)", "vrOrientationResetCardboardText": "Gunakan ini untuk menetapkan semula orientasi VR.\nUntuk bermain permainan, anda memerlukan pengawal lain.", "vrOrientationResetText": "Tetapan semula orientasi VR.", "willTimeOutText": "(tamat masa jika terbiar)" }, + "inventoryText": "Inventori", "jumpBoldText": "LOMPAT", "jumpText": "Lompat", "keepText": "Simpan", @@ -942,29 +986,29 @@ "keyboardChangeInstructionsText": "Tekan dua kali \"spacebar\" untuk menukar papan kekunci.", "keyboardNoOthersAvailableText": "Tiada papan kekunci lain tersedia.", "keyboardSwitchText": "Menukar papan kekunci kepada \"${NAME}\".", - "kickOccurredText": "${NAME} telah diterajang.", - "kickQuestionText": "Tendang ${NAME}?", - "kickText": "Terajang", - "kickVoteCantKickAdminsText": "Admin tidak boleh ditendang.", - "kickVoteCantKickSelfText": "Anda tidak boleh menendang diri sendiri.", + "kickOccurredText": "${NAME} telah dikeluarkan.", + "kickQuestionText": "Keluarkan ${NAME}?", + "kickText": "Keluarkan", + "kickVoteCantKickAdminsText": "Admin tidak boleh dikeluarkan.", + "kickVoteCantKickSelfText": "Anda tidak boleh mengeluarkan diri sendiri.", "kickVoteFailedNotEnoughVotersText": "Tidak cukup pemain untuk undian.", - "kickVoteFailedText": "Undi sepakan gagal.", - "kickVoteStartedText": "Undian sepakan telah dimulakan untuk ${NAME}.", - "kickVoteText": "Undi untuk Menendang", - "kickVotingDisabledText": "Undian sepakan dilumpuhkan.", + "kickVoteFailedText": "Undian mengeluarkan gagal.", + "kickVoteStartedText": "Undian mengeluarkan telah dimulakan untuk ${NAME}.", + "kickVoteText": "Undi untuk Mengeluarkan", + "kickVotingDisabledText": "Undian mengeluarkan dilumpuhkan.", "kickWithChatText": "Taip ${YES} dalam sembang untuk ya dan ${NO} untuk tidak.", - "killsTallyText": "${COUNT} meninggal", - "killsText": "Meninggal", + "killsTallyText": "${COUNT} membunuh", + "killsText": "Membunuh", "kioskWindow": { "easyText": "Senang", - "epicModeText": "Mod Epik", + "epicModeText": "Mode Epik", "fullMenuText": "Menu Penuh", "hardText": "Susah", "mediumText": "Sederhana", "singlePlayerExamplesText": "Contoh Pemain Tunggal / Koperasi", "versusExamplesText": "Contoh Perbandingan" }, - "languageSetText": "Bahasa ditetapkan ke \"${LANGUAGE}\"", + "languageSetText": "Bahasa sekarang \"${LANGUAGE}\"", "lapNumberText": "Pusingan ${CURRENT}/${TOTAL}", "lastGamesText": "( ${COUNT} permainan terakhir)", "leaderboardsText": "Papan pendahulu", @@ -981,8 +1025,11 @@ "seasonEndsMinutesText": "Musim tamat dalam ${NUMBER} minit.", "seasonText": "Musim ${NUMBER}", "tournamentLeagueText": "Anda mesti mencapai liga ${NAME} untuk menyertai kejohanan ini.", - "trophyCountsResetText": "Kiraan trofi akan ditetapkan semula musim depan." + "trophyCountsResetText": "Kiraan trofi akan ditetapkan semula musim depan.", + "upToDateBonusDescriptionText": "Pemain yang menjalankan versi terbaru\npermainan menerima bonus ${PERCENT}% di sini.", + "upToDateBonusText": "Bonus Terkini" }, + "learnMoreText": "Ketahui lebih lanjut", "levelBestScoresText": "Markah terbaik pada ${LEVEL}", "levelBestTimesText": "Masa terbaik di ${LEVEL}", "levelIsLockedText": "${LEVEL} dikunci.", @@ -1026,23 +1073,26 @@ "modeArcadeText": "Mod arked", "modeClassicText": "Mod Klasik", "modeDemoText": "Demo Mode", + "moreSoonText": "Lagi Akan Datang...", + "mostDestroyedPlayerText": "Pemain Paling Musnah", "mostValuablePlayerText": "Pemain yang amat berharga", - "mostViolatedPlayerText": "Pemain yang Amat Melanggar", + "mostViolatedPlayerText": "Pemain Paling Banyak Mati", "mostViolentPlayerText": "Pemain Paling Ganas", "moveText": "Bergerak", - "multiKillText": "${COUNT}-Meninggal!!", + "multiKillText": "${COUNT}-Membunuh!!", "multiPlayerCountText": "${COUNT} pemain", "mustInviteFriendsText": "Nota: anda mesti menjemput rakan masuk\npanel \"${GATHER}\" atau lampirkan\npengawal untuk bermain berbilang pemain.", "nameBetrayedText": "${NAME} mengkhianati ${VICTIM}.", - "nameDiedText": "${NAME} ninggal.", - "nameKilledText": "${NAME} meng ninggal ${VICTIM}.", + "nameDiedText": "${NAME} mati.", + "nameKilledText": "${NAME} membunuh ${VICTIM}.", "nameNotEmptyText": "Nama tidak boleh kosong!", "nameScoresText": "Markah ${NAME}!", - "nameSuicideKidFriendlyText": "${NAME} ter ninggal.", - "nameSuicideText": "${NAME} mening gal.", + "nameSuicideKidFriendlyText": "${NAME} secara tidak sengaja mati.", + "nameSuicideText": "${NAME} membunuh diri.", "nameText": "Nama", "nativeText": "Asal", - "newPersonalBestText": "Markah sendiri baharu!", + "newExclaimText": "Baru!", + "newPersonalBestText": "Terbaik peribadi baru!", "newTestBuildAvailableText": "Binaan ujian yang lebih baharu tersedia! (${VERSION} bina ${BUILD}).\nDapatkannya di ${ADDRESS}", "newText": "Baru", "newVersionAvailableText": "Versi ${APP_NAME} yang lebih baharu tersedia! (${VERSION})", @@ -1052,12 +1102,16 @@ "noContinuesText": "(tidak boleh bersambung)", "noExternalStorageErrorText": "Tiada storan luaran ditemui pada peranti ini", "noGameCircleText": "Ralat: tidak log masuk ke GameCircle", + "noMessagesText": "Tiada mesej.", + "noPluginsInstalledText": "Tiada Pemalam Yang Dipasang", "noScoresYetText": "Tiada markah lagi.", + "noServersFoundText": "Tiada pelayan yang ditemui.", "noThanksText": "Tak Terimo Kasih, Yo", "noTournamentsInTestBuildText": "AMARAN: Markah kejohanan daripada binaan ujian ini akan diabaikan.", "noValidMapsErrorText": "Tiada peta yang sah ditemui untuk jenis permainan ini.", "notEnoughPlayersRemainingText": "Tidak cukup pemain yang tinggal; keluar dan mulakan permainan baharu.", "notEnoughPlayersText": "Anda memerlukan sekurang-kurangnya ${COUNT} pemain untuk memulakan permainan ini!", + "notEnoughTicketsText": "Ticket tidak mencukupi!", "notNowText": "Bukan sekarang", "notSignedInErrorText": "Anda mesti log masuk untuk melakukan ini.", "notSignedInGooglePlayErrorText": "Anda mesti log masuk dengan Google Play untuk melakukan ini.", @@ -1070,6 +1124,9 @@ "onText": "Hidup", "oneMomentText": "Tunggu Seketika...", "onslaughtRespawnText": "${PLAYER} akan muncul semula dalam gelombang ${WAVE}", + "openMeText": "Buka Saya!", + "openNowText": "Buka Sekarang", + "openText": "Buka", "orText": "${A} atau ${B}", "otherText": "Lain-lain...", "outOfText": "(#${RANK} daripada ${ALL})", @@ -1121,7 +1178,11 @@ "pleaseWaitText": "Sila tunggu...", "pluginClassLoadErrorText": "Ralat memuatkan kelas pemalam '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Ralat semasa memulakan pemalam '${PLUGIN}': ${ERROR}", - "pluginsDetectedText": "Pemalam baharu dikesan. Mulakan semula untuk mengaktifkannya, atau konfigurasikannya dalam tetapan.", + "pluginSettingsText": "Tetapan Pemalam", + "pluginsAutoEnableNewText": "Auto Dayakan Pemalam Baru", + "pluginsDetectedText": "Pemalam(s) baharu dikesan. Mulakan semula untuk mengaktifkannya, atau konfigurasikannya dalam tetapan.", + "pluginsDisableAllText": "Nyahdayakan Semua Pemalam", + "pluginsEnableAllText": "Dayakan Semua Pemalam", "pluginsRemovedText": "${NUM} pemalam tidak ditemui lagi.", "pluginsText": "Bahan Tambahan", "practiceText": "Latihan", @@ -1151,6 +1212,8 @@ "punchText": "Lempeng", "purchaseForText": "Beli dengan harga ${PRICE}", "purchaseGameText": "Permainan Belian", + "purchaseNeverAvailableText": "Maaf, pembelian tidak tersedia pada binaan ini.\nCuba log masuk ke akaun anda di platform lain dan buat pembelian dari sana.", + "purchaseNotAvailableText": "Pembelian ini tidak tersedia.", "purchasingText": "Membeli...", "quitGameText": "Blah ${APP_NAME}?", "quittingIn5SecondsText": "Berhenti dalam 5 saat...", @@ -1192,6 +1255,7 @@ "version_mismatch": "Versi tidak sepadan.\nPastikan BombSquad dan BombSquad Remote\nadalah verisi terkini dan cuba lagi." }, "removeInGameAdsText": "Buka kunci \"${PRO}\" di kedai untuk mengalih keluar iklan dalam permainan.", + "removeInGameAdsTokenPurchaseText": "TAWARAN MASA TERHAD: Beli SEBARANG pek token untuk mengalih keluar iklan dalam permainan.", "renameText": "Namakan semula", "replayEndText": "Tamatkan Rakaman ulang", "replayNameDefaultText": "Main Ulang Permainan Terakhir", @@ -1212,7 +1276,9 @@ "revertText": "Kembalikan", "runText": "Lari", "saveText": "Simpan", - "scanScriptsErrorText": "Ralat mengimbas skrip; lihat log untuk butiran.", + "scanScriptsErrorText": "Ralat(s) mengimbas skrip; Lihat log untuk butiran.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} dan ${NUM} modul yang lain perlu dikemaskinikan untuk API ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} perlu dikemaskinikan untuk API ${API}.", "scoreChallengesText": "Cabaran Skor", "scoreListUnavailableText": "Senarai skor tidak tersedia.", "scoreText": "Markah", @@ -1223,6 +1289,7 @@ }, "scoreWasText": "(telah ${COUNT})", "selectText": "Pilih", + "sendInfoDescriptionText": "Menghantar maklumat keadaan akaun dan apl kepada pembangun.\nSila sertakan nama atau sebab anda untuk menghantar.", "seriesWinLine1PlayerText": "MEMENANGI", "seriesWinLine1TeamText": "MEMENANGI", "seriesWinLine1Text": "MENANGKAN", @@ -1238,24 +1305,33 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(papan kekunci skrin yang ringkas dan mesra)", - "alwaysUseInternalKeyboardText": "Gunakan Papan Kekunci Dalaman", + "alwaysUseInternalKeyboardText": "Gunakan papan kekunci dalaman", "benchmarksText": "Penanda Aras & Ujian Tekanan", - "disableCameraGyroscopeMotionText": "Lumpuhkan Pergerakan Giroskop Kamera", - "disableCameraShakeText": "Lumpuhkan Goncangan Kamera", + "devToolsText": "Alat Pembangun", + "disableCameraGyroscopeMotionText": "Tutup pergerakan giroskop kamera", + "disableCameraShakeText": "Tutup goncangan kamera", "disableThisNotice": "(anda boleh mematikan pemberitahuan ini di tetapan lanjutan)", "enablePackageModsDescriptionText": "(menghidupkan kecekapan mod tambahan tapi mematikan permainan rangkaian)", "enablePackageModsText": "Hidupkan Pakej Mod Tempatan", "enterPromoCodeText": "Masukkan Kod", "forTestingText": "Peringatan: nilai ini hanya untuk ujian dan akan hilang apabila aplikasi ditutup.", "helpTranslateText": "terjemahan ${APP_NAME} selain Inggeris adalah usaha sokongan\nkomuniti. Jika anda ingin membantu menyumbang atau memperbetulkan \nterjemahan, sila ke pautan di bawah. Terima kasih!", - "kickIdlePlayersText": "Keluarkan Pemain yang Duduk Diam", + "insecureConnectionsDescriptionText": "tidak disyorkan, tetapi mungkin membenarkan permainan\ndalam talian daripada negara atau rangkaian terhad", + "insecureConnectionsText": "Gunakan sambungan yang tidak selamat", + "kickIdlePlayersText": "Tendang pemain terbiar", "kidFriendlyModeText": "Mod Mesra (kurangkan kekerasan, dll)", "languageText": "Bahasa", "moddingGuideText": "Panduan Menge-mod", - "mustRestartText": "Anda perlu memula semula permainan untuk dapat berkesan.", + "moddingToolsText": "Alat Modding", + "mustRestartText": "Anda perlu tutup dan buka semula game ni kalau nak bende ni berfungsi.", "netTestingText": "Ujian Rangkaian", "resetText": "Tetap Semula", + "sendInfoText": "Hantar Maklumat", "showBombTrajectoriesText": "Tunjukkan Trajektori Bom", + "showDemosWhenIdleText": "Tunjukkan demo apabila melahu", + "showDeprecatedLoginTypesText": "Tunjukkan jenis log masuk yang ditamatkan", + "showDevConsoleButtonText": "Tunjukkan butang konsol pembangun", + "showInGamePingText": "Tunjukkan ping dalam permainan", "showPlayerNamesText": "Tunjukkan Nama Pemain", "showUserModsText": "Tunjukkan Pelipat Mod", "titleText": "Lanjutan", @@ -1263,8 +1339,8 @@ "translationFetchErrorText": "status terjemahan tidak tersedia", "translationFetchingStatusText": "memeriksa status terjemahan...", "translationInformMe": "Beritahu saya apabila bahasa saya perlu dikemaskini", - "translationNoUpdateNeededText": "bahasa semasa telah dikemaskini; sting aku yahoo", - "translationUpdateNeededText": "** bahasa semasa perlu dikemaskini **", + "translationNoUpdateNeededText": "Bahasa semasa adalah terkini; woohoo!", + "translationUpdateNeededText": "** Bahasa semasa memerlukan kemas kini!! **", "vrTestingText": "Cubaan VR" }, "shareText": "Kongsi", @@ -1274,6 +1350,9 @@ "signInWithGameCenterText": "Untuk menggunakan akaun Game Center,\nlog masuk dengan aplikasi Game Center.", "singleGamePlaylistNameText": "Cuma ${GAME}", "singlePlayerCountText": "1 pemain", + "sizeLargeText": "Besar", + "sizeMediumText": "Sederhana", + "sizeSmallText": "Kecil", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Pemilihan watak", @@ -1299,9 +1378,10 @@ }, "spaceKeyText": "space", "statsText": "Statistik", + "stopRemindingMeText": "Berhenti Mengingatkan Saya", "storagePermissionAccessText": "Ini memerlukan akses storan", "store": { - "alreadyOwnText": "Anda telah memiliki ${NAME}!", + "alreadyOwnText": "Anda dah ada ${NAME}!", "bombSquadProNameText": "${APP_NAME} Pro", "bombSquadProNewDescriptionText": "• Buang iklan dan timbulan pembelian\n• Membuka kunci lebih banyak tetapan permainan\n• Juga termasuk:", "buyText": "Beli", @@ -1311,15 +1391,15 @@ "freeBombSquadProText": "BombSquad kini percuma, tapi sejak anda membelinya secara sah anda menerima\npenaiktarafan BombSquad Pro dan ${COUNT} tiket sebagai tanda terima kasih.\nNikmatilah ciri-ciri baru, dan terima kasih atas sokongan anda!\n- Eric", "holidaySpecialText": "Istimewa Cuti Perayaan", "howToSwitchCharactersText": "(pergi ke \"${SETTINGS} -> ${PLAYER_PROFILES}\" untuk urus & ubahsuai watak)", - "howToUseIconsText": "(cipta profil pemain global (di tetingkap akaun) untuk gunakan ini)", + "howToUseIconsText": "(cipta profil pemain global (di window akaun) untuk gunakan ini)", "howToUseMapsText": "(gunakan peta ini di senarai main pasukan/bebas untuk semua anda)", "iconsText": "Ikon", "loadErrorText": "Tidak dapat memuatkan halaman.\nSila periksa sambungan internet.", - "loadingText": "memuat", + "loadingText": "loading jap", "mapsText": "Peta", - "miniGamesText": "Permainan Kecil", + "miniGamesText": "Permainan Tambahan", "oneTimeOnlyText": "(satu masa sahaja)", - "purchaseAlreadyInProgressText": "Pembelian item ini dalam pembelian.", + "purchaseAlreadyInProgressText": "Pembelian item tengah dalam proses.", "purchaseConfirmText": "Beli ${ITEM}?", "purchaseNotValidError": "Pembelian tidak sah.\nHubungi ${EMAIL} jika ini disebabkan ralat.", "purchaseText": "Beli", @@ -1346,6 +1426,8 @@ "storeText": "Kedai", "submitText": "Hantar", "submittingPromoCodeText": "Mengemukakan Kod...", + "successText": "Berjaya!", + "supportEmailText": "Jika anda mengalami masalah dengan apl ini, sila\nhantar e-mel kepada ${EMAIL}.", "teamNamesColorText": "Nama/Warna Pasukan...", "telnetAccessGrantedText": "Akses telnet diaktifkan.", "telnetAccessText": "Akses telnet dikesan; benarkan?", @@ -1354,26 +1436,41 @@ "testBuildValidateErrorText": "Tidak dapat mengesahkan binaan ujian. (tiada sambungan net?)", "testBuildValidatedText": "Binaan Ujian Disahkan; Sting aku yahoo!", "thankYouText": "Terima kasih atas sokongan anda! Nikmati permainan!!", - "threeKillText": "PELEPASAN GAS TIGA KALI!!", + "threeKillText": "PEMBUNUHAN TIGA KALI GANDA!!", + "ticketsDescriptionText": "Tiket boleh digunakan untuk membuka kunci aksara,\npeta, permainan kecil dan banyak lagi di kedai.\n\nTiket boleh didapati di peti yang dimenangi\nkempen, kejohanan dan pencapaian.", "timeBonusText": "Bonus Masa", "timeElapsedText": "Masa Berlalu", "timeExpiredText": "Masa Tamat", - "timeSuffixDaysText": "${COUNT}h", - "timeSuffixHoursText": "${COUNT}j", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", "timeSuffixMinutesText": "${COUNT}m", "timeSuffixSecondsText": "${COUNT}s", "tipText": "Tip", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Dapatkan Token", + "notEnoughTokensText": "Tidak mencukupi token!", + "numTokensText": "${COUNT} Token", + "openNowDescriptionText": "Anda mempunyai cukup token untuk\nmembuka ini sekarang - anda tidak\nperlu menunggu.", + "shinyNewCurrencyText": "Mata wang baharu berkilat BombSquad.", + "tokenPack1Text": "Pek Token Kecil", + "tokenPack2Text": "Pek Token Sederhana", + "tokenPack3Text": "Pek Token Besar", + "tokenPack4Text": "Pek Token Jumbo", + "tokensDescriptionText": "Token digunakan untuk mempercepatkan buka kunci peti\ndan untuk ciri permainan dan akaun lain.\n\nAnda boleh memenangi token dalam permainan atau membelinya\ndalam pek. Atau beli Pas Emas untuk\ntoken tak terhingga dan tidak pernah mendengar tentangnya lagi.", + "youHaveGoldPassText": "Anda mempunyai Pas Emas.\nSemua pembelian token adalah percuma.\nNikmati!" + }, "topFriendsText": "Rakan Karib", "tournamentCheckingStateText": "Memeriksa keadaan kejohanan; sila tunggu...", "tournamentEndedText": "Kejohanan ini telah berakhir. Yang baru akan dimulakan tidak lama lagi.", "tournamentEntryText": "Kemasukan Kejohanan", + "tournamentFinalStandingsText": "Kedudukan Akhir", "tournamentResultsRecentText": "Keputusan Kejohanan Terkini", "tournamentStandingsText": "Kedudukan Kejohanan", "tournamentText": "Kejohanan", "tournamentTimeExpiredText": "Masa Kejohanan Tamat", - "tournamentsDisabledWorkspaceText": "Kejohanan dilumpuhkan apabila ruang kerja aktif.\nUntuk mendayakan semula kejohanan, lumpuhkan ruang kerja anda dan mulakan semula.", + "tournamentsDisabledWorkspaceText": "Kejohanan dilumpuhkan apabila ruang kerja aktif.\nUntuk buka semula kejohanan, tutup ruang kerja anda dan tutup-bukak semula game ni.", "tournamentsText": "Kejohanan", "translations": { "characterNames": { @@ -1424,10 +1521,22 @@ "Uber Onslaught": "Berserang Urban", "Uber Runaround": "Lari padang Urban" }, + "displayItemNames": { + "${C} Tickets": "${C} Tiket", + "${C} Tokens": "${C} Token", + "Chest": "Peti", + "L1 Chest": "L1 Peti", + "L2 Chest": "L2 Peti", + "L3 Chest": "L3 Peti", + "L4 Chest": "L4 Peti", + "L5 Chest": "L5 Peti", + "L6 Chest": "L6 Peti", + "Unknown Chest": "Peti tidak diketahui" + }, "gameDescriptions": { - "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah orang yang terpilih untuk masa yang lama untuk menang.\nLawan untuk terpilih.", + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah orang yang terpilih untuk masa yang lama untuk menang.\nBunuh orang terpilih untuk menjadinya.", "Bomb as many targets as you can.": "Bom seberapa banyak sasaran yang anda boleh.", - "Carry the flag for ${ARG1} seconds.": "Bawa bendera selama ${ARG1} saat.", + "Carry the flag for ${ARG1} seconds.": "Pegang bendera selama ${ARG1} saat.", "Carry the flag for a set length of time.": "Bawa bendera untuk jangka masa yang ditetapkan.", "Crush ${ARG1} of your enemies.": "Hancurkan ${ARG1} lawan anda.", "Defeat all enemies.": "Kalahkan semua lawan.", @@ -1435,13 +1544,13 @@ "Final glorious epic slow motion battle to the death.": "Pertempuran gerakan perlahan epik terakhir yang terkoncat hingga mati.", "Gather eggs!": "Kumpul tolo!", "Get the flag to the enemy end zone.": "Dapatkan bendera ke zon hujung musuh.", - "How fast can you defeat the ninjas?": "Seberapa pantas anda boleh mengalahkan ninja?", - "Kill a set number of enemies to win.": "Sepak segerombolan musuh untuk memenangi.", - "Last one standing wins.": "Kedudukan terakhir menang.", - "Last remaining alive wins.": "Kemenangan terakhir yang masih ada.", - "Last team standing wins.": "Kedudukan pasukan terakhir menang.", - "Prevent enemies from reaching the exit.": "Elakkan musuh daripada sampai ke pintu keluar.", - "Reach the enemy flag to score.": "Sampai ke bendera musuh untuk menerima mata.", + "How fast can you defeat the ninjas?": "Seberapa pantas mana anda boleh mengalahkan semua ninja?", + "Kill a set number of enemies to win.": "Bunuh beberapa set musuh untuk menang.", + "Last one standing wins.": "Yang terakhir bertahan menang.", + "Last remaining alive wins.": "Yang terakhir bertahan menang.", + "Last team standing wins.": "Pasukan terakhir bertahan menang.", + "Prevent enemies from reaching the exit.": "Halang musuh daripada sampai ke pintu keluar.", + "Reach the enemy flag to score.": "Sentuh bendera musuh untuk menjaringkan gol.", "Return the enemy flag to score.": "Kembalikan bendera musuh untuk menerima mata.", "Run ${ARG1} laps.": "Telah berlari ${ARG1} pusingan.", "Run ${ARG1} laps. Your entire team has to finish.": "Lari pusingan ${ARG1}. Mesti semua ahli pasukan sudah selesai.", @@ -1456,21 +1565,21 @@ "Secure all ${ARG1} flags.": "Lindungi semua bendera ${ARG1}.", "Secure all flags on the map to win.": "Lindungi semua bendera pada peta untuk menang.", "Secure the flag for ${ARG1} seconds.": "Selamatkan bendera dalam ${ARG1} saat", - "Secure the flag for a set length of time.": "Selamatkan bendera untuk jangka masa yang ditetapkan.", + "Secure the flag for a set length of time.": "Lindungi bendera dalam jangka masa yang ditetapkan.", "Steal the enemy flag ${ARG1} times.": "Curi bendera musuh ${ARG1} kali.", - "Steal the enemy flag.": "Curi bendera lawan.", + "Steal the enemy flag.": "Curi bendera pihak lawan.", "There can be only one.": "Hanya boleh ada satu.", "Touch the enemy flag ${ARG1} times.": "Sentuh bendera musuh sebanyak ${ARG1} kali.", "Touch the enemy flag.": "Sentuh bendera musuh.", "carry the flag for ${ARG1} seconds": "membawa bendera selama ${ARG1} saat", - "kill ${ARG1} enemies": "lempang musuh ${ARG1}", - "last one standing wins": "yang terakhir menang", - "last team standing wins": "pasukan terakhir berdiri menang", + "kill ${ARG1} enemies": "Bunuh ${ARG1} musuh", + "last one standing wins": "yang terakhir bertahan menang", + "last team standing wins": "pasukan terakhir bertahan menang", "return ${ARG1} flags": "kembalikan bendera ${ARG1}.", "return 1 flag": "pulangkan 1 bendera", - "run ${ARG1} laps": "pusingan ke ${ARG1} larian", + "run ${ARG1} laps": "lari sebanyak ${ARG1} pusingan", "run 1 lap": "lari 1 pusingan", - "score ${ARG1} goals": "menjaringkan ${ARG1} gol.", + "score ${ARG1} goals": "menjaringkan ${ARG1} gol", "score ${ARG1} touchdowns": "skor ${ARG1} pendaratan", "score a goal": "menjaringkan gol", "score a touchdown": "skorkan gol", @@ -1497,7 +1606,7 @@ "Race": "Perlumbaan", "Runaround": "Berlarian", "Target Practice": "Praktis Sasaran", - "The Last Stand": "Yang Terakhir" + "The Last Stand": "Yang Terakhir Berdiri" }, "inputDeviceNames": { "Keyboard": "Papan kekunci", @@ -1506,19 +1615,20 @@ "languages": { "Arabic": "Bahasa Arab", "Belarussian": "Bahasa Belarus", - "Chinese": "Bahasa Cina", - "ChineseTraditional": "Bahasa Tradisional Cina", + "Chinese": "Bahasa Cina (Dimudahkan) ", + "ChineseSimplified": "Bahasa Cina - Dimudahkan", + "ChineseTraditional": "Bahasa Cina - Tradisional", "Croatian": "Bahasa Kroatia", "Czech": "Bahasa Czech", "Danish": "Bahasa Denmark", "Dutch": "Bahasa Belanda", "English": "Bahasa Inggeris", "Esperanto": "Bahasa Esperanto", - "Filipino": "Filipina", + "Filipino": "Bahasa Filipina", "Finnish": "Bahasa Finland", "French": "Bahasa Perancis", "German": "Bahasa Jerman", - "Gibberish": "Karut", + "Gibberish": "Bahasa Mengarut/Tah Ape-ape", "Greek": "Bahasa Yunani", "Hindi": "Bahasa Hindi", "Hungarian": "Bahasa Hungari", @@ -1528,13 +1638,18 @@ "Korean": "Bahasa Korea", "Malay": "Melayu", "Persian": "Bahasa Farsi", + "PirateSpeak": "Bahasa Lanun", "Polish": "Bahasa Poland", "Portuguese": "Bahasa Portugis", + "PortugueseBrazil": "Bahasa Portugis Brazil", + "PortuguesePortugal": "Bahasa Portugis Portugal", "Romanian": "Bahasa Romania", "Russian": "Bahasa Rusia", "Serbian": "Bahasa Serbia", "Slovak": "Bahasa Slovak", "Spanish": "Bahasa Sepanyol", + "SpanishLatinAmerica": "Spanyol - Latin Amerika", + "SpanishSpain": "Bahasa Spanyol - Spain", "Swedish": "Bahasa Sweden", "Tamil": "Bahasa Tamil", "Thai": "Bahasa Thai", @@ -1551,7 +1666,7 @@ }, "mapsNames": { "Big G": "G Besar", - "Bridgit": "Jambatan", + "Bridgit": "Jambatan Sultan Abdul Halim Muadzam Shah (Cetak rompak punye)", "Courtyard": "Halaman Mahkamah", "Crag Castle": "Istana Batu", "Doom Shroom": "Cendawan Malapetaka", @@ -1560,7 +1675,7 @@ "Hockey Stadium": "Stadium Hoki", "Lake Frigid": "Tasik Beku", "Monkey Face": "Muka Monyet", - "Rampage": "Amukan", + "Rampage": "Huru-harawan", "Roundabout": "Bulatan", "Step Right Up": "Langkah Ke Atas", "The Pad": "Lapang", @@ -1581,14 +1696,14 @@ "Time Held": "Masa Dijalankan" }, "serverResponses": { - "A code has already been used on this account.": "Kod telah digunakan pada akaun ini.", + "A code has already been used on this account.": "Suatu kod telah digunakan pada akaun ini.", "A reward has already been given for that address.": "Ganjaran telah pun diberikan untuk alamat itu.", "Account linking successful!": "Pemautan akaun berjaya!", "Account unlinking successful!": "Penyahpautan akaun berjaya!", "Accounts are already linked.": "Akaun sudah dipautkan.", "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Paparan iklan mengacau tidak dapat disahkan.\nSila pastikan anda menjalankan versi permainan yang rasmi dan terkini.", "An error has occurred; (${ERROR})": "Ralat telah berlaku; (${ERROR})", - "An error has occurred; please contact support. (${ERROR})": "Ralat telah berlaku; sila hubungi sokongan. (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ralat telah berlaku; sila hubungi bantuan. (${ERROR})", "An error has occurred; please contact support@froemling.net.": "Ralat telah berlaku; sila hubungi support@froemling.net.", "An error has occurred; please try again later.": "Ralat telah berlaku; sila cuba sebentar lagi.", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Adakah anda pasti mahu memautkan akaun ini?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nPerkara ini tidak boleh diubah semula .!", @@ -1599,6 +1714,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Penipuan dikesan; markah dan hadiah digantung selama ${COUNT} hari.", "Could not establish a secure connection.": "Tidak dapat mewujudkan sambungan selamat.", "Daily maximum reached.": "Maksimum harian dicapai.", + "Daily sign-in reward": "Ganjaran log masuk harian", "Entering tournament...": "Memasuki kejohanan...", "Invalid code.": "Kod tidak sah.", "Invalid payment; purchase canceled.": "Pembayaran tidak sah; pembelian dibatalkan.", @@ -1608,11 +1724,14 @@ "Item unlocked!": "Item dibuka!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "MEMAUT DITOLAK. ${ACCOUNT} mengandungi\ndata penting yang akan KESEMUANYA HILANG.\nAnda boleh memaut dalam susunan yang bertentangan jika anda mahu\n(dan akan menghilangan data akaun INI sebagai ganti)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Pautkan akaun ${ACCOUNT} ke akaun ini?\nSemua data sedia ada pada ${ACCOUNT} akan hilang.\nPerkara ini tidak boleh diubah. Adakah anda pastis?", + "Longer streaks lead to better rewards.": "Coretan yang lebih panjang membawa kepada ganjaran yang lebih baik.", "Max number of playlists reached.": "Bilangan maksimum senarai main dicapai.", "Max number of profiles reached.": "Bilangan profil maksimum dicapai.", "Maximum friend code rewards reached.": "Ganjaran kod rakan telah maksimum dicapai.", "Message is too long.": "Mesej terlalu panjang.", + "New tournament result!": "Keputusan kejohanan baharu!", "No servers are available. Please try again soon.": "Tiada pelayan tersedia. Nanti cuba lagi, sebentar lagi.", + "No slots available. Free a slot and try again.": "Tiada slot tersedia. Kosongkan slot dan cuba lagi.", "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" berjaya dinaik taraf.", "Profile could not be upgraded.": "Profil tidak dapat ditingkatkan.", "Purchase successful!": "Pembelian berjaya!", @@ -1622,7 +1741,9 @@ "Sorry, this code has already been used.": "Maaf, kod ini telah digunakan.", "Sorry, this code has expired.": "Maaf, kod ini telah tamat tempoh.", "Sorry, this code only works for new accounts.": "Maaf, kod ini hanya berfungsi untuk akaun baharu.", + "Sorry, this has expired.": "Maaf, ini telah tamat tempoh.", "Still searching for nearby servers; please try again soon.": "Masih mencari pelayan berdekatan; sila cuba lagi nanti.", + "Streak: ${NUM} days": "Rentetan: ${NUM} hari", "Temporarily unavailable; please try again later.": "Tidak tersedia buat sementara waktu; sila cuba sebentar lagi.", "The tournament ended before you finished.": "Kejohanan tamat sebelum anda tamat.", "This account cannot be unlinked for ${NUM} days.": "Akaun ini tidak boleh dinyahpautkan selama ${NUM} hari.", @@ -1633,19 +1754,28 @@ "Tournaments require ${VERSION} or newer": "Kejohanan memerlukan ${VERSION} atau lebih baharu", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Nyahpaut ${ACCOUNT} daripada akaun ini?\nSemua data pada ${ACCOUNT} akan ditetapkan semula.\n(kecuali untuk pencapaian dalam kes tertentu)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "AMARAN: aduan penggodaaman telah dikeluarkan terhadap akaun anda.\nAkaun yang didapati menggodam akan diharamkan. Tolong main adil.", + "Wait reduced!": "Tunggu dikurangkan!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Amaran: Versi permainan ini terhad kepada data akaun lama; beberapa perkara mungkin kelihatan hilang atau tidak terkini.\nSila naik taraf ke versi permainan yang lebih baharu untuk melihat data akaun terkini anda.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Adakah anda ingin memautkan akaun peranti anda ke akaun ini?\n\nAkaun peranti anda ialah ${ACCOUNT1}\nAkaun ini ialah ${ACCOUNT2}\n\nIni akan membolehkan anda mengekalkan data sedia ada anda.\nAmaran: ini tidak boleh dibaiki semula!", "You already own this!": "Anda sudah memiliki ini!", "You can join in ${COUNT} seconds.": "Anda boleh menyertai dalam ${COUNT} saat.", "You don't have enough tickets for this!": "Anda tidak mempunyai tiket yang mencukupi untuk ini!", "You don't own that.": "Anda tidak memilikinya.", "You got ${COUNT} tickets!": "Anda mendapat ${COUNT} tiket!", + "You got ${COUNT} tokens!": "Anda mendapat ${COUNT} token!", "You got a ${ITEM}!": "Anda mendapat ${ITEM}!", + "You got a chest!": "Anda mendapat peti!", + "You got an achievement reward!": "Anda mendapat ganjaran pencapaian!", "You have been promoted to a new league; congratulations!": "Anda telah dinaikkan pangkat ke liga baharu; tahniah!", + "You lost a chest! (All your chest slots were full)": "Anda kehilangan peti! (Semua slot peti anda penuh)", + "You must update the app to view this.": "Anda mesti mengemas kini aplikasi untuk melihat ini.", "You must update to a newer version of the app to do this.": "Anda mesti mengemas kini kepada versi apl yang lebih baharu untuk melakukan ini.", "You must update to the newest version of the game to do this.": "Anda mesti mengemas kini kepada versi terbaharu permainan untuk melakukan ini.", "You must wait a few seconds before entering a new code.": "Anda mesti menunggu beberapa saat sebelum memasukkan kod baharu.", + "You placed #${RANK} in a tournament!": "Anda meletakkan #${RANK} dalam kejohanan!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Anda menduduki #${RANK} dalam kejohanan terakhir. Terima kasih kerana bermain!", "Your account was rejected. Are you signed in?": "Akaun anda telah ditolak. Adakah anda telah log masuk?", + "Your ad views are not registering. Ad options will be limited for a while.": "Iklan anda tak dapat masuk. Butang/pilihan untuk melihat iklan akan terhad buat sementara waktu.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Salinan permainan anda telah diubah suai.\nSila kembalikan sebarang perubahan dan cuba lagi.", "Your friend code was used by ${ACCOUNT}": "Kod rakan anda telah digunakan oleh ${ACCOUNT}" }, @@ -1666,10 +1796,10 @@ "Chosen One Gets Shield": "Yang Terpilih Dapat Perisai", "Chosen One Time": "Masa Bagi Yg Terpilih", "Enable Impact Bombs": "Dayakan Bom Kesan", - "Enable Triple Bombs": "Dayakan Triple Bombs", - "Entire Team Must Finish": "Seluruh Pasukan Mesti Selesai", + "Enable Triple Bombs": "Bolehkan Triple Bombs", + "Entire Team Must Finish": "Seluruh Pasukan Mesti Habiskan", "Epic Mode": "Mod Epik", - "Flag Idle Return Time": "Tandakan Masa Pulang Terbiar", + "Flag Idle Return Time": "Masa Bendera Auto Pulang", "Flag Touch Return Time": "Tandakan Masa Pulang Sentuh", "Hold Time": "Tahan Masa", "Kills to Win Per Player": "Memukul untuk Menang Setiap Pemain", @@ -1702,15 +1832,15 @@ "Red": "Merah" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Pukulan lari-lompat-putaran yang tepat pada masanya boleh menyepak dalam satu pukulan\ndan mendapat penghormatan sepanjang hayat daripada rakan-rakan anda.", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Aksi lari-lompat-putaran-tumbuk! yang tepat pada masanya boleh mnghapuskan dalam satu pukulan\ndan mendapat penghormatan sepanjang hayat daripada rakan-rakan anda.", "Always remember to floss.": "Jangan lupa untuk floss.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Buat profil pemain untuk diri sendiri dan rakan anda\ndengan penampilan pilihan anda dan bukannya menggunakan nama secara rawak.", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Kotak sumpahan mengubah anda menjadi bom masa yang berdetik.\nSatu-satunya ubat adalah dengan mengambil pek kesihatan.", - "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Rupa mereka berbeza, tetapi kebolehan watak adalah sama,\njadi pilih sahaja yang mana satu yang paling anda sukai.", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Tolong jangan sombong dengan perisai tenaga itu; anda masih boleh tercampak dari tebing.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Rupa mereka berbeza, tetapi kebolehan watak adalah hampir sama,\njadi pilih sahaja yang mana satu yang paling anda sukai.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Tolong jangan sombong dengan perisai tenaga tu; anda masih boleh tercampak dari tebing.", "Don't run all the time. Really. You will fall off cliffs.": "Jangan berlari sepanjang masa. Den koba ni. Anda akan jatuh dari tebing.", "Don't spin for too long; you'll become dizzy and fall.": "Jangan berputar terlalu lama; anda akan menjadi pening dan jatuh.", - "Hold any button to run. (Trigger buttons work well if you have them)": "Tahan sebarang butang untuk dijalankan. (Butang pencetus berfungsi dengan baik jika anda memilikinya)", + "Hold any button to run. (Trigger buttons work well if you have them)": "Tahan sebarang butang untuk lari. (Butang pencetus berfungsi dengan baik jika anda memilikinya)", "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Tahan mana-mana butang untuk dijalankan. Anda akan berjalan lebih cepat\ntetapi tidak akan menjadi lebih baik, jadi hati-hati dengan tebing.", "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Bom ais tidak begitu kuat, tetapi ia membeku\nsesiapa sahaja yang mereka pukul, menyebabkan mereka terdedah kepada kehancuran.", "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jika seseorang mengangkat anda, tumbuk mereka dan mereka akan melepaskannya.\nIni juga berfungsi dalam kehidupan sebenar.", @@ -1728,39 +1858,39 @@ "Jump just as you're throwing to get bombs up to the highest levels.": "Lompat semasa anda melontar untuk melontarkan bom sehingga ke tahap tertinggi.", "Land-mines are a good way to stop speedy enemies.": "Periuk api adalah cara yang baik untuk menghentikan musuh yang pantas.", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Banyak benda boleh diangkat dan dilempar termasuk pemain lain. Melambung\nlawan anda dari tebing boleh menjadi strategi yang berkesan dan memuaskan emosi.", - "No, you can't get up on the ledge. You have to throw bombs.": "Tidak, anda tidak boleh bangun di atas belebas. Anda perlu baling bom.", - "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Pemain boleh menyertai dan keluar di tengah-tengah kebanyakan permainan,\ndan anda juga boleh pasang dan cabut pengawal dengan cepat.", + "No, you can't get up on the ledge. You have to throw bombs.": "Tidak, anda tidak boleh panjat ke atas tapak tu. Anda perlu baling bom.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Pemain boleh menyertai dan keluar di tengah-tengah kebanyakan permainan,\ndan anda juga boleh pasang dan cabut alat kawalan dengan cepat.", "Practice using your momentum to throw bombs more accurately.": "Berlatih menggunakan momentum anda untuk melontar bom dengan lebih tepat.", - "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Tumbukan lebih merosakkan lebih cepat penumbuk anda bergerak,\njadi cuba berlari, melompat dan berputar seperti orang tak siuman.", - "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Berlari ke sana ke mari sebelum melontar bom\nuntuk 'whiplash' dan membuangnya lebih jauh.", - "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Keluarkan sekumpulan musuh dengan\nmelancarkan bom berhampiran kotak TNT.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Tumbukan jadi lagi kuat lebih cepat penumbuk anda bergerak,\njadi cuba berlari, melompat dan berputar seperti orang gila.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Berlari kebelakang dan kedepan sebelum baling bom\nuntuk 'whiplash' dan membalingnya lebih jauh.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Kalahkan sekumpulan musuh dengan\nmelancarkan bom berhampiran kotak TNT.", "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Kepala adalah kawasan yang paling terdedah, jadi bom melekit\nkepada orang biasanya bermaksud game-over.", "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Tahap ini tidak pernah berakhir, tetapi skor tinggi di sini\nakan memberi anda penghormatan kekal di seluruh dunia.", - "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kekuatan lontaran adalah berdasarkan arah yang anda tuju.\nUntuk melemparkan sesuatu, jangan tuju ke sebarang arah.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kekuatan lontaran adalah berdasarkan arah yang anda tuju.\nUntuk melemparkan sesuatu dengan lembut di depan anda, jangan tuju ke sebarang arah.", "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Bosan dengan runut bunyi? Gantikan dengan pilihan anda sendiri!\nLihat Tetapan->Audio->Runut Bunyi", - "Try 'Cooking off' bombs for a second or two before throwing them.": "Cuba 'Memasak' bom selama satu atau dua saat sebelum melontarkannya.", - "Try tricking enemies into killing eachother or running off cliffs.": "Cuba menipu musuh untuk memukul satu sama lain atau melarikan diri dari tebing.", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Cuba 'didihkan' bom selama satu atau dua saat dulu sebelum baling.", + "Try tricking enemies into killing eachother or running off cliffs.": "Cuba memperdayakan musuh untuk membunuh satu sama lain atau berlari sampai jatuh tebing.", "Use the pick-up button to grab the flag < ${PICKUP} >": "Gunakan butang ambil untuk mengambil bendera < ${PICKUP} >", "Whip back and forth to get more distance on your throws..": "Bergerak ke sana ke mari untuk mendapatkan lebih jarak pada lontaran anda..", - "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Anda boleh 'membidik' pukulan anda dengan berputar ke kiri atau kanan.\nIni berguna untuk mengetuk orang jahat dari tepi atau menjaringkan gol dalam hoki.", - "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Anda boleh menilai bila bom akan meletup berdasarkan\nwarna percikan api dari fiusnya: kuning..oren..merah..BOOM.", - "You can throw bombs higher if you jump just before throwing.": "Anda boleh melontar bom lebih tinggi jika anda melompat sebelum melontar.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Anda menerima kesakitan apabila anda terhantuk kepala anda pada sesuatu,\njadi cuba untuk tidak memeningkan kepala anda.", - "Your punches do much more damage if you are running or spinning.": "Tumbukan anda menghasilkan lebih banyak kesakitan jika anda berlari atau berputar." + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Anda boleh 'membidik/aim' pukulan anda dengan berputar ke kiri atau kanan.\nIni berguna untuk mengetuk orang jahat dari tepi atau menjaringkan gol dalam hoki.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Anda boleh menilai bila bom akan meletup berdasarkan\nwarna percikan api dari sumbunya: kuning..oren..merah..BOOOO000M.", + "You can throw bombs higher if you jump just before throwing.": "Anda boleh baling bom lebih tinggi kalau anda lompat sebelum melontar.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Anda menerima kesakitan/damage apabila anda terhantuk kepala anda pada sesuatu,\njadi cuba untuk tidak hantukkan kepala anda.", + "Your punches do much more damage if you are running or spinning.": "Tumbukan anda memberikan lebih banyak kesakitan/damage jika anda berlari atau berputar." } }, - "trophiesRequiredText": "Ini memerlukan sekurang-kurangnya ${NUMBER} trofi.", + "trophiesRequiredText": "Ini memerlukan sekurang-kurangnya ${NUMBER} piala.", "trophiesText": "Piala", "trophiesThisSeasonText": "Trofi Musim Ini", "tutorial": { "cpuBenchmarkText": "Menjalankan tutorial pada kelajuan menggelikan (menguji kelajuan CPU)", - "phrase01Text": "Hi lombu", + "phrase01Text": "Hai awak! Ye, awak!", "phrase02Text": "Selamat datang ke ${APP_NAME}!", "phrase03Text": "Berikut ialah beberapa petua untuk mengawal watak anda:", "phrase04Text": "Banyak perkaro dalam ${APP_NAME} berasaskan FIZIK.", "phrase05Text": "Contohnya, apabila anda menumbuk,..", "phrase06Text": "..kerosakan adalah berdasarkan kelajuan penumbuk anda.", - "phrase07Text": "Nampak taak? Kami tidak bergerak, jadi hampir tidak mencederakan ${NAME}.", + "phrase07Text": "Nampak taak? Kite tidak bergerak, jadi hampir tidak mencederakan ${NAME}.", "phrase08Text": "Sekarang mari melompat dan berputar untuk mendapatkan lebih kelajuan.", "phrase09Text": "Aah, itu lebih baik.", "phrase10Text": "Berlari juga membantu.", @@ -1775,12 +1905,12 @@ "phrase19Text": "Melompat membantu anda melontar lebih tinggi.", "phrase20Text": "\"Sebat\" bom anda untuk lontaran lebih lama.", "phrase21Text": "Mengangar bom anda boleh menjadi rumit.", - "phrase22Text": "Iyam.", + "phrase22Text": "Aduhai.", "phrase23Text": "Cuba \"memasak\" fius selama satu atau dua saat.", "phrase24Text": "Sting aku! Elok dimasak.", "phrase25Text": "Dah, itu sahaja.", "phrase26Text": "Sekarang pergi selamatkan abang Aziz, dekat bot!", - "phrase27Text": "Ingat latihan anda, dan jangan tingal solat lima waktu", + "phrase27Text": "Ingat latihan anda, dan jangan tinggal solat lima waktu", "phrase28Text": "...selamat maju jaya...", "phrase29Text": "Semoga berjaya!", "randomName1Text": "Syed", @@ -1788,17 +1918,20 @@ "randomName3Text": "Ilham", "randomName4Text": "Abang Irfan", "randomName5Text": "Jasini", - "skipConfirmText": "Taknak tengok tutorial? Ketik atau tekan untuk mengesahkan.", + "skipConfirmText": "Taknak tengok tutorial? Tekan untuk mengesahkan.", "skipVoteCountText": "${COUNT}/${TOTAL} langkau undi", "skippingText": "ponteng tutorial...", "toSkipPressAnythingText": "(ketik atau tekan apa-apa untuk melangkau tutorial)" }, - "twoKillText": "KENTUT BERGANDA!", + "twoKillText": "PEMBUNUHAN BERGANDA!", + "uiScaleText": "Skala UI", "unavailableText": "tidak ada", - "unconfiguredControllerDetectedText": "Pengawal tidak dikonfigurasikan dikesan:", - "unlockThisInTheStoreText": "Mangga mesti dibuka kunci di kedai.", + "unclaimedPrizesText": "Anda mempunyai hadiah yang belum dituntut!", + "unconfiguredControllerDetectedText": "Alat kawalan tidak dikonfigurasikan dikesan:", + "unlockThisInTheStoreText": "Ini mesti dibuka kunci di kedai.", "unlockThisProfilesText": "Untuk membuat lebih daripada ${NUM} profil, anda memerlukan:", "unlockThisText": "Untuk membuka kunci ini, anda memerlukan:", + "unsupportedControllerText": "Maaf, alat kawalan \"${NAME}\" tidak disokong.", "unsupportedHardwareText": "Maaf, perkakasan ini tidak disokong oleh binaan permainan ini.", "upFirstText": "Bangun dahulu:", "upNextText": "Seterusnya dalam permainan ${COUNT}:", @@ -1806,10 +1939,14 @@ "upgradeText": "Naik Taraf", "upgradeToPlayText": "Buka kunci \"${PRO}\" dalam gedung di dalam permainan untuk mainkan ini.", "useDefaultText": "Gunakan seperti Biasa", + "userSystemScriptsCreateText": "Cipta Skrip Sistem Pengguna", + "userSystemScriptsDeleteText": "Padam Skrip Sistem Pengguna", "usesExternalControllerText": "Permainan ini menggunakan pengawal luaran untuk input.", "usingItunesText": "Menggunakan Apl Muzik untuk runut bunyi...", "v2AccountLinkingInfoText": "Untuk memautkan akaun V2, gunakan butang 'Urus Akaun'.", + "v2AccountRequiredText": "Ini memerlukan akaun V2. Tingkatkan akaun anda dan cuba lagi.", "validatingTestBuildText": "Mengesahkan Binaan Ujian...", + "viaText": "melalui", "victoryText": "Kemenangan!", "voteDelayText": "Anda tidak boleh memulakan undian lain selama ${NUMBER} saat", "voteInProgressText": "Undian sedang dijalankan.", @@ -1820,28 +1957,28 @@ "waitingForPlayersText": "menunggu pemain menyertai...", "waitingInLineText": "Menunggu dalam barisan (parti penuh)...", "watchAVideoText": "Tonton Video", - "watchAnAdText": "Tengok iklan Adabi", + "watchAnAdText": "Tonton iklan", "watchWindow": { "deleteConfirmText": "Padamkan \"${REPLAY}\"?", "deleteReplayButtonText": "Padam\nMain semula", - "myReplaysText": "Tayangan Ulang Saya", - "noReplaySelectedErrorText": "Tiada Main Ulang Dipilih", + "myReplaysText": "Tayangan Ulangan Saya", + "noReplaySelectedErrorText": "Tiada Tayangan Ulangan Dipilih", "playbackSpeedText": "Kelajuan Main Semula: ${SPEED}", - "renameReplayButtonText": "Namakan\nMain semula", + "renameReplayButtonText": "Namakan\nTayangan Ulangan", "renameReplayText": "Namakan semula \"${REPLAY}\" kepada:", "renameText": "Namakan semula", "replayDeleteErrorText": "Ralat memadamkan ulang tayang.", - "replayNameText": "Nama Main Semula", + "replayNameText": "Nama Tayangan Ulangan", "replayRenameErrorAlreadyExistsText": "Tayangan semula dengan nama itu sudah wujud.", - "replayRenameErrorInvalidName": "Tidak boleh menamakan semula main semula; nama tidak sah.", - "replayRenameErrorText": "Ralat menamakan main semula.", - "sharedReplaysText": "Main Semula Dikongsi", + "replayRenameErrorInvalidName": "Tidak boleh menamakan semula tayangan; nama tidak sah.", + "replayRenameErrorText": "Ralat menamakan tayangan permainan.", + "sharedReplaysText": "Tayangan Permainan Yang Dikongsi", "titleText": "Tonton", - "watchReplayButtonText": "Tonton\nMain Semula" + "watchReplayButtonText": "Tonton Tayangan\nPermainan" }, - "waveText": "Gelombang musuh", + "waveText": "Serangan", "wellSureText": "Baiklah!", - "whatIsThisText": "Apakah Ini?", + "whatIsThisText": "Abende ni?", "wiimoteLicenseWindow": { "titleText": "Hak Cipta DarwiinRemote" }, @@ -1859,7 +1996,7 @@ }, "winsPlayerText": "${NAME} Menang!", "winsTeamText": "${NAME} Menang!", - "winsText": "${NAME} Monang!", + "winsText": "${NAME} Menang!", "workspaceSyncErrorText": "Ralat menyegerakkan ${WORKSPACE}. Lihat log untuk butiran.", "workspaceSyncReuseText": "Tidak dapat menyegerakkan ${WORKSPACE}. Menggunakan semula versi disegerakkan sebelumnya.", "worldScoresUnavailableText": "Markah dunia tidak tersedia.", @@ -1874,5 +2011,6 @@ }, "yesAllowText": "Ya, Benarkan!", "yourBestScoresText": "Markah Terbaik Anda", - "yourBestTimesText": "Masa Terbaik Anda" + "yourBestTimesText": "Masa Terbaik Anda", + "yourPrizeText": "Hadiah anda:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/persian.json b/dist/ba_data/data/languages/persian.json index 9e2396cc..d35d6413 100644 --- a/dist/ba_data/data/languages/persian.json +++ b/dist/ba_data/data/languages/persian.json @@ -1,14 +1,16 @@ { "accountSettingsWindow": { - "accountNameRules": "نام نمی‌تواند اموجی (شکلک) یا نویسه‌ های ویژه داشته باشد", + "accountNameRules": "نام حساب کاربری نمیتونه شکلک و نویسه های ویژه داشته باشه جیگر", "accountProfileText": "(مشخصات حساب)", - "accountsText": "پروفایل ها", + "accountsText": "حساب ها", "achievementProgressText": "${TOTAL}/${COUNT} :دستاوردها", "campaignProgressText": "${PROGRESS} :[سخت]‎ پیشروی در بازی اصلی", - "changeOncePerSeason": ".فقط یک‌بار در هر فصل می‌توانید این مورد را تغییر دهید", - "changeOncePerSeasonError": "(روز تا فصل بعد‎ ${NUM}) برای تغییر این گزینه باید تا فصل بعد صبر کنید", + "changeOncePerSeason": ".فقط یه‌ بار در هر فصل می‌تونی این مورد رو تغییر بدی", + "changeOncePerSeasonError": "(روز تا فصل بعد‎ ${NUM}) برای تغییر مجدد این گزینه باید تا فصل بعد صبر کنی", + "createAnAccountText": "یک حساب کاربری ایجاد کنید", "customName": "نام سفارشی", - "googlePlayGamesAccountSwitchText": "اگه میخوای اکانت گوگلت رو استفاده کنی\nاستفاده کن اکانت گوگل پلی بازی های دیگت رو", + "deleteAccountText": "حذف حساب کاربری", + "googlePlayGamesAccountSwitchText": "اگه میخوای از حساب های مختلف گوگل استفاده کنی از بازی های گوگل برای عوض کردن استفاده کن", "linkAccountsEnterCodeText": "کد را وارد کنید", "linkAccountsGenerateCodeText": "ایجاد کد", "linkAccountsInfoText": "(به اشتراک گذاری پیشروی بین دستگاه‌های مختلف)", @@ -16,341 +18,348 @@ "linkAccountsInstructionsText": "برای اتصال دو حساب، در یکی از\nآن ها کدی ایجاد کرده \nو آن را در دیگری وارد کنید.\nپیشرفت ها و موجودی ترکیب خواهد شد.\nحساب را وصل کنید ${COUNT} شما می توانید.\n!توجه : فقط حساب هایی را وصل کنید که برای\n شماست\nاگر شما حساب دیگری را وصل کنید، شما توانایی این را ندارید که در یک زمان بازی کنید!\nاین عمل برگشت پذیر نیست، پس \nدقت کنید!", "linkAccountsText": "متصل کردن حساب ها", "linkedAccountsText": ":حساب های متصل شده", - "manageAccountText": "تنظیمات حساب کاربری", - "nameChangeConfirm": "تغییر کند؟‎ ${NAME} آیا نام شما به", - "resetProgressConfirmNoAchievementsText": "همهٔ پیشروی‌های شما در بخش همکاری و بالاترین امتیازات\nشما پاک خواهد شد. (به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", - "resetProgressConfirmText": "همهٔ پیشروی‌ها در بخش همکاری، دستاوردها\n.و امتیازات بالای شما پاک خواهد شد\n(به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", + "manageAccountText": "مدیریت حساب", + "nameChangeConfirm": "تغییر کند؟‎ ${NAME} نام شما به", + "resetProgressConfirmNoAchievementsText": "همهٔ پیشروی‌های شما در بخش همکاری و امتیازات\nشما پاک خواهد شد. (به استثنای بلیط های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", + "resetProgressConfirmText": "همهٔ پیشروی‌ها در بخش همکاری، دستاوردها\n.و امتیازات بالای شما پاک خواهد شد\n(بلیط های شما تحت تاثیر قرار نخواهد گرفت)\nاین کار برگشت‌ پذیر نیست. آیا مطمئنید؟", "resetProgressText": "بازنشانی پیشروی", - "setAccountName": "تنظیم نام حساب", + "setAccountName": "تنظیم نام اکانت", "setAccountNameDesc": "نامی که می‌خواهید برای این حساب نمایش داده شود را انتخاب کنید\nمی‌توانید از یکی از نام‌های حساب‌های وصل‌شده استفاده کنید\nیا یک نام جدید بسازید", - "signInInfoText": "به حسابتان وصل شوید تا بلیت جمع کنید، آنلاین رقابت کنید \n.و پیشرفت خود را با دیگران به اشتراک بگذارید", + "signInInfoText": "به حسابتان وصل شوید تا بلیت جمع کنید، آنلاین رقابت کنید \n.و پیشرفت خود را در دستگاه ها به اشتراک بگذارید", "signInText": "ورود به حساب", + "signInWithAnEmailAddressText": "ورود با ایمیل", "signInWithDeviceInfoText": "(یک حساب خودکار فقط از این دستگاه در دسترس می‌باشد)", - "signInWithDeviceText": "وصل شدن با حساب دستگاه", + "signInWithDeviceText": "وصل شدن با اکانت دستگاه", "signInWithGameCircleText": "وصل شدن از طریق حوزهٔ بازی", - "signInWithGooglePlayText": "ورود با حساب بازی‌های گوگل", + "signInWithGooglePlayText": "ورود با اکانت گوگل پلی", "signInWithTestAccountInfoText": "(حساب میراثی؛ از حساب‌های دستگاه برای پیشروی استفاده می‌کند)", "signInWithTestAccountText": "ورود با حساب آزمایشی", - "signInWithV2InfoText": "یک حساب کاربری که بر روی تمام سیستم عامل ها کار می کند", - "signInWithV2Text": "ورود به سیستم با حساب بمب اسکواد", + "signInWithText": "با ${SERVICE} وارد شوید", + "signInWithV2InfoText": "یک حساب که روی همه سیستم عامل ها کار میکنه", + "signInWithV2Text": "ورود به سیستم با حساب ${APP_NAME}", "signOutText": "خروج از حساب", - "signingInText": "در حال اتصال…", + "signingInText": "در حال ورود...", "signingOutText": "در حال خروج…", "ticketsText": "${COUNT} :بلیت‌ها", - "titleText": "حساب", + "titleText": "حساب کاربری", "unlinkAccountsInstructionsText": "یک حساب را برای جداسازی انتخاب کنید", "unlinkAccountsText": "جداسازی حساب‌ها", - "unlinkLegacyV1AccountsText": "لغو پیوند حساب‌های قدیمی (V1)", + "unlinkLegacyV1AccountsText": "(V1) لغو پیوند حساب‌های قدیمی", "v2LinkInstructionsText": "استفاده از این لینک برای ایجاد یک حساب کاربری و یا ورود به سیستم.", "viaAccount": "(${NAME} از طریق حساب)", - "youAreSignedInAsText": ":با این حساب وصل شده‌اید" + "youAreSignedInAsText": ":با این اکانت وصل شدی" }, - "achievementChallengesText": "چالش‌های دستاورددار", + "achievementChallengesText": "چالش‌های دستاورد دار", "achievementText": "دستاورد", "achievements": { "Boom Goes the Dynamite": { - "description": ".نابود کن TNT سه حریف را با", - "descriptionComplete": "!نابود کردی TNT سه حریف را با", - "descriptionFull": "از بین ببر TNT با ${LEVEL} سه حریف را در", - "descriptionFullComplete": "از بین بردی TNT با ${LEVEL} سه حریف را در", + "description": "⁦از بین ببر TNT ۳ حریف رو با", + "descriptionComplete": "⁦از بین بردی TNT ۳ حریف رو با", + "descriptionFull": "⁦از بین ببر TNT در ${LEVEL} ۳ حریف رو با", + "descriptionFullComplete": "‎از بین بردی TNT در ${LEVEL} ۳ حریف رو با", "name": "!ترکوندی" }, "Boxer": { - "description": "بدون استفاده از هیچ بمبی برنده شو", + "description": "بدون استفاده از بمب برنده شو", "descriptionComplete": "بدون استفاده از بمب برنده شدی", "descriptionFull": "را بدون استفاده از هیچ بمبی کامل کن ${LEVEL} مرحلهٔ", - "descriptionFullComplete": "را بدون استفاده از بمب کامل کردی ${LEVEL} مرحلهٔ", - "name": "مشت‌زن" + "descriptionFullComplete": "${LEVEL} رو بدون استفاده از بمب کامل کردی", + "name": "بوکسر" }, "Dual Wielding": { - "descriptionFull": "(‏دو دستهٔ بازی وصل کن ‏(سخت‌افزاری یا نرم‌افزاری", - "descriptionFullComplete": "(دو دستهٔ بازی وصل کردی (سخت‌افزار یا نرم‌افزار", - "name": "دوگانه اداره کردن" + "descriptionFull": "(واقعی یا مجازی) ‏۲ دسته به بازی وصل کن", + "descriptionFullComplete": "(واقعی یا مجازی) ۲ دسته به بازی وصل کردی", + "name": "دوتایی" }, "Flawless Victory": { - "description": "بدون ضربه خوردن برنده شو", - "descriptionComplete": "بدون ضربه خوردن برنده شدی", - "descriptionFull": "را بدون ضربه خوردن برنده شو ${LEVEL} مرحلهٔ", - "descriptionFullComplete": "را بدون ضربه خوردن برنده شدی ${LEVEL} مرحلهٔ", + "description": "بدون هیچ آسیبی برنده شو", + "descriptionComplete": "بدون هیچ آسیبی برنده شدی", + "descriptionFull": "${LEVEL} رو بدون هیچ آسیبی برنده شو", + "descriptionFullComplete": "${LEVEL} رو بدون هیچ آسیبی برنده شدی", "name": "پیروزی بی‌نقص" }, "Free Loader": { - "descriptionFull": "یک بازی به سبک تک به تک را با ۲+ بازیکن شروع کن", - "descriptionFullComplete": "یک بازی تک به تک را با ۲+ بازیکن شروع کردی", - "name": "بارگذار رایگان" + "descriptionFull": "یه بازی تک‌به‌تک رو با +۲ بازیکن راه بنداز", + "descriptionFullComplete": "یه بازی تک‌به‌تک رو با +۲ بازیکن راه انداختی", + "name": "تک‌به‌تک‌باز" }, "Gold Miner": { - "description": "شش حریف را با مین زمینی نابود کن", - "descriptionComplete": "شش حریف را با مین زمینی نابود کردی", - "descriptionFull": "با مین زمینی از بین ببر ${LEVEL} شش حریف را در مرحلهٔ", - "descriptionFullComplete": "با مین زمینی نابود کردی ${LEVEL} شش حریف را در مرحلهٔ", - "name": "مین‌گذار حرفه‌ای" + "description": "۶ حریف رو با مین زمینی از بین ببر", + "descriptionComplete": "۶ حریف رو با مین زمینی از بین بردی", + "descriptionFull": "۶ حریف رو در ${LEVEL} با مین زمینی از بین ببر", + "descriptionFullComplete": "۶ حریف رو در ${LEVEL} با مین زمینی از بین بردی", + "name": "مین‌گذار طلایی" }, "Got the Moves": { "description": "بدون استفاده از مشت یا بمب برنده شو", - "descriptionComplete": "بدون استفاده از هیچ مشت یا بمبی برنده شدی", - "descriptionFull": "را بدون مشت یا بمب برنده شو ${LEVEL} بازی", - "descriptionFullComplete": "را بدون مشت یا بمب برنده شدی ${LEVEL} بازی", - "name": "عجب حرکتی" + "descriptionComplete": "بدون استفاده از مشت یا بمب برنده شدی", + "descriptionFull": "${LEVEL} رو بدون مشت یا بمب برنده شو", + "descriptionFullComplete": "${LEVEL} رو بدون مشت یا بمب برنده شدی", + "name": "حرکت خفنی زدی" }, "In Control": { - "descriptionFull": "(یک دستهٔ بازی وصل کن (سخت‌افزاری یا نرم‌افزاری", - "descriptionFullComplete": "(یک دستهٔ بازی وصل کردی (سخت‌افزار یا نرم‌افزار", - "name": "تحت کنترل" + "descriptionFull": "(واقعی یا مجازی) یه دسته به بازی وصل کن", + "descriptionFullComplete": "(واقعی یا مجازی) یه دسته به بازی وصل کردی", + "name": "دسته‌باز" }, "Last Stand God": { "description": "‏۱۰۰۰ امتیاز بگیر", "descriptionComplete": "‏۱۰۰۰ امتیاز گرفتی‏", - "descriptionFull": "‏۱۰۰۰ امتیاز بگیر ${LEVEL} در مرحلهٔ", - "descriptionFullComplete": "‏۱۰۰۰ امتیاز گرفتی‏ ${LEVEL} در مرحلهٔ", - "name": "${LEVEL} سَرور" + "descriptionFull": "‏در ${LEVEL} ۱۰۰۰ امتیاز بگیر", + "descriptionFullComplete": "‏در ${LEVEL} ۱۰۰۰ امتیاز گرفتی", + "name": "خدای ${LEVEL}" }, "Last Stand Master": { "description": "‏۲۵۰ امتیاز بگیر", "descriptionComplete": "‏۲۵۰ امتیاز گرفتی", - "descriptionFull": "‏۲۵۰ امتیاز بگیر ${LEVEL} در مرحلهٔ", - "descriptionFullComplete": "‏۲۵۰ امتیاز گرفتی ${LEVEL} در مرحلهٔ", - "name": "${LEVEL} استاد" + "descriptionFull": "‏در ${LEVEL} ۲۵۰ امتیاز بگیر", + "descriptionFullComplete": "‏در ${LEVEL} ۲۵۰ امتیاز گرفتی", + "name": "استاد ${LEVEL}" }, "Last Stand Wizard": { "description": "‏۵۰۰ امتیاز بگیر", "descriptionComplete": "‏۵۰۰ امتیاز گرفتی", - "descriptionFull": "‏۵۰۰ امتیاز بگیر ${LEVEL} در مرحلهٔ", - "descriptionFullComplete": "‏۵۰۰ امتیاز گرفتی ${LEVEL} در مرحلهٔ", - "name": "${LEVEL} جادوگر" + "descriptionFull": "‏در ${LEVEL} ۵۰۰ امتیاز بگیر", + "descriptionFullComplete": "‏در ${LEVEL} ۵۰۰ امتیاز گرفتی", + "name": "جادوگر ${LEVEL}" }, "Mine Games": { - "description": "سه حریف را با مین زمینی از بین ببر", - "descriptionComplete": "سه حریف را با مین زمینی از بین بردی", - "descriptionFull": "با مین از بین ببر ${LEVEL} سه حریف را در مرحلهٔ", - "descriptionFullComplete": "با مین از بین بردی ${LEVEL} سه حریف را در مرحلهٔ", - "name": "بازی با مین" + "description": "۳ حریف رو با مین زمینی از بین ببر", + "descriptionComplete": "۳ حریف رو با مین زمینی از بین بردی", + "descriptionFull": "۳ حریف رو در ${LEVEL} با مین زمینی از بین ببر", + "descriptionFullComplete": "۳ حریف رو در ${LEVEL} با مین زمینی از بین بردی‎", + "name": "بازی‌های مین" }, "Off You Go Then": { - "description": "سه حریف رو از زمین بنداز بیرون", - "descriptionComplete": "سه حریف رو از نقشه انداختی پایین", - "descriptionFull": "از نقشه بنداز پایین${LEVEL}سه حریف رو در مرحله ی", - "descriptionFullComplete": "از نقشه انداختی پایین ${LEVEL} سه حریف رو در مرحله ی", - "name": "حالا میتونی بری" + "description": "۳ حریف رو از نقشه بیرون بنداز", + "descriptionComplete": "۳ حریف رو از نقشه بیرون انداختی", + "descriptionFull": "۳ حریف رو در ${LEVEL} از نقشه بیرون بنداز", + "descriptionFullComplete": "۳ حریف رو در ${LEVEL} از نقشه بیرون انداختی", + "name": "حالا می‌تونی بری" }, "Onslaught God": { - "description": "پنج هزار امتیاز بگیر", - "descriptionComplete": "پنج هزار امتیاز گرفتی", - "descriptionFull": "بگیر${LEVEL}پنج هزار امتیاز در مرحله ی", - "descriptionFullComplete": "گرفتی${LEVEL}پنج هزار امتیاز در مرحله ی", - "name": "${LEVEL} خدا" + "description": "۵۰۰۰ امتیاز بگیر", + "descriptionComplete": "۵۰۰۰ امتیاز گرفتی", + "descriptionFull": "در ${LEVEL} ۵۰۰۰ امتیاز بگیر", + "descriptionFullComplete": "در ${LEVEL} ۵۰۰۰ امتیاز گرفتی", + "name": "خدای ${LEVEL}" }, "Onslaught Master": { - "description": "پونصد امتیاز بگیر", - "descriptionComplete": "پونصد امتیاز گرفتی", - "descriptionFull": "بگیر ${LEVEL} پونصد امتیاز در مرحله ی", - "descriptionFullComplete": "گرفتی ${LEVEL} پونصد امتیاز در مرحله ی", - "name": "${LEVEL} استاد" + "description": "۵۰۰ امتیاز بگیر", + "descriptionComplete": "۵۰۰ امتیاز گرفتی", + "descriptionFull": "در ${LEVEL} ۵۰۰ امتیاز بگیر", + "descriptionFullComplete": "در ${LEVEL} ۵۰۰ امتیاز گرفتی", + "name": "استاد ${LEVEL}" }, "Onslaught Training Victory": { - "description": "تمام موج ها را بگذران", - "descriptionComplete": "تمام موج ها را گذراندی", - "descriptionFull": "بگذران ${LEVEL} تمام موج ها رو در مرحله ی", - "descriptionFullComplete": "گذراندی ${LEVEL} تمام موج ها رو در مرحله ی", - "name": "${LEVEL} پیروزی" + "description": "همه‌ی موج‌ها رو شکست بده", + "descriptionComplete": "همه‌ی موج‌ها رو شکست دادی", + "descriptionFull": "همه‌ی موج‌های ${LEVEL} رو شکست بده", + "descriptionFullComplete": "همه‌ی موج‌های ${LEVEL} رو شکست دادی", + "name": "پیروزی در ${LEVEL}" }, "Onslaught Wizard": { - "description": "هزار امتیاز بگیر", - "descriptionComplete": "هزار امتیاز گرفتی", - "descriptionFull": "بگیر ${LEVEL} هزار امتیاز در مرحله ی", - "descriptionFullComplete": "گرفتی ${LEVEL} هزار امتیاز در مرحله ی", - "name": "${LEVEL} جادوگر" + "description": "۱۰۰۰ امتیاز بگیر", + "descriptionComplete": "۱۰۰۰ امتیاز گرفتی", + "descriptionFull": "در ${LEVEL} ۱۰۰۰ امتیاز بگیر", + "descriptionFullComplete": "در ${LEVEL} ۱۰۰۰ امتیاز گرفتی", + "name": "جادوگر ${LEVEL}" }, "Precision Bombing": { - "description": "بدون گرفتن هیچ جعبه ای برنده شو", - "descriptionComplete": "بدون گرفتن هیچ جعبه ای برنده شدی", - "descriptionFull": "رو بدون گرفتن جعبه برنده شو ${LEVEL} مرحله ی", - "descriptionFullComplete": "رو بدون گرفتن جعبه برنده شدی ${LEVEL} مرحله ی", - "name": "بمب اندازی دقیق" + "description": "بدون گرفتن هیچ قدرتی برنده شو", + "descriptionComplete": "بدون گرفتن هیچ قدرتی برنده شدی", + "descriptionFull": "${LEVEL} رو بدون گرفتن هیچ قدرتی برنده شو", + "descriptionFullComplete": "${LEVEL} رو بدون گرفتن هیچ قدرتی برنده شدی", + "name": "بمب‌باران دقیق" }, "Pro Boxer": { - "description": "بدون استفاده از هر بمبی برنده شو", - "descriptionComplete": "بدون استفاده از هر بمبی برنده شدی", - "descriptionFull": "رو بدون استفاده از هر بمبی تمام کن ${LEVEL} مرحله ی", - "descriptionFullComplete": "رو بدون استفاده از هر بمبی تمام کردی ${LEVEL} مرحله", + "description": "بدون استفاده از هیچ بمبی برنده شو", + "descriptionComplete": "بدون استفاده از هیچ بمبی برنده شدی", + "descriptionFull": "${LEVEL} رو بدون استفاده از هیچ بمبی کامل کن", + "descriptionFullComplete": "${LEVEL} رو بدون استفاده از هیچ بمبی کامل کردی", "name": "مشت‌زن حرفه‌ای" }, "Pro Football Shutout": { - "description": "بدون اینکه اجازه بدی حریف امتیاز بگیره برنده شو", - "descriptionComplete": "بدون اینکه اجازه بدی حریف امتیاز بگیره برنده شدی", - "descriptionFull": "اجازه نده حریف امتیاز بگیره و برنده شو ${LEVEL} در مرحله", - "descriptionFullComplete": "اجازه ندادی حریف امتیاز بگیره و برنده شدی ${LEVEL} در مرحله", - "name": "${LEVEL} امتیاز ندادن" + "description": "بدون اینکه بزاری حریف امتیاز بگیره، برنده شو", + "descriptionComplete": "بدون اینکه بزاری حریف امتیاز بگیره، برنده شدی", + "descriptionFull": "در ${LEVEL} بدون اینکه بزاری حریف امتیاز بگیره، برنده شو", + "descriptionFullComplete": "در ${LEVEL} بدون اینکه بزاری حریف امتیاز بگیره، برنده شدی", + "name": "دوازه‌بسته در ${LEVEL}" }, "Pro Football Victory": { "description": "برنده شو", - "descriptionComplete": "! برنده شدی", - "descriptionFull": "برنده شو ${LEVEL} در مرحله", - "descriptionFullComplete": "برنده شدی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "descriptionComplete": "برنده شدی", + "descriptionFull": "در ${LEVEL} برنده شو", + "descriptionFullComplete": "در ${LEVEL} برنده شدی", + "name": "پیروزی در ${LEVEL}" }, "Pro Onslaught Victory": { - "description": "همه ی موج ها را بگذران", - "descriptionComplete": "همه ی موج ها را گذراندی", - "descriptionFull": "همه ی موج ها را بگذران ${LEVEL} در مرحله", - "descriptionFullComplete": "همه ی موج ها را گذراندی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "description": "همه‌ی موج‌ها رو شکست بده", + "descriptionComplete": "همه‌ی موج‌ها رو شکست دادی", + "descriptionFull": "همه‌ی موج‌های ${LEVEL} رو شکست بده", + "descriptionFullComplete": "همه‌ی موج‌های ${LEVEL} رو شکست دادی", + "name": "پیروزی در ${LEVEL}" }, "Pro Runaround Victory": { - "description": "همه ی موج ها را بگذران", - "descriptionComplete": "همه ی موج ها را گذراندی", - "descriptionFull": "همه ی موج ها را بگذران ${LEVEL} در مرحله", - "descriptionFullComplete": "همه ی موج ها را گذراندی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "description": "همه‌ی موج‌ها رو کامل کن", + "descriptionComplete": "همه‌ی موج‌ها رو کامل کردی", + "descriptionFull": "همه‌ی موج‌های ${LEVEL} رو کامل کن", + "descriptionFullComplete": "همه‌ی موج‌های ${LEVEL} رو کامل کردی", + "name": "پیروزی در ${LEVEL}" }, "Rookie Football Shutout": { - "description": "برنده شو و اجازه نده حریف امتیاز بگیره", - "descriptionComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره", - "descriptionFull": "برنده شو و اجازه نده حریف امتیاز بگیره ${LEVEL} در مرحله", - "descriptionFullComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره ${LEVEL} در مرحله", - "name": "${LEVEL} بدون امتیاز دادن" + "description": "بدون اینکه بزاری حریف امتیاز بگیره، برنده شو", + "descriptionComplete": "بدون اینکه بزاری حریف امتیاز بگیره، برنده شدی", + "descriptionFull": "در ${LEVEL} بدون اینکه بزاری حریف امتیاز بگیره، برنده شو", + "descriptionFullComplete": "در ${LEVEL} بدون اینکه بزاری حریف امتیاز بگیره، برنده شدی", + "name": "دروازه‌بسته در ${LEVEL}" }, "Rookie Football Victory": { "description": "برنده شو", "descriptionComplete": "برنده شدی", - "descriptionFull": "برنده شو ${LEVEL} در مرحله", - "descriptionFullComplete": "برنده شدی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "descriptionFull": "در ${LEVEL} برنده شو", + "descriptionFullComplete": "در ${LEVEL} برنده شدی", + "name": "پیروزی در ${LEVEL}" }, "Rookie Onslaught Victory": { - "description": "همه ی موج ها را بگذران", - "descriptionComplete": "همه ی موج ها را گذراندی", - "descriptionFull": "همه ی موج ها را بگذران ${LEVEL} در مرحله", - "descriptionFullComplete": "همه ی موج ها را گذراندی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "description": "همه‌ی موج‌ها رو شکست بده", + "descriptionComplete": "همه‌ی موج‌ها رو شکست دادی", + "descriptionFull": "همه‌ی موج‌های ${LEVEL} رو شکست بده", + "descriptionFullComplete": "همه‌ی موج‌های ${LEVEL} رو شکست دادی", + "name": "پیروزی در ${LEVEL}" }, "Runaround God": { - "description": "دو هزار امتیاز بگیر", - "descriptionComplete": "دو هزار امتیاز گرفتی", - "descriptionFull": "دو هزار امتیاز بگیر ${LEVEL} در مرحله", - "descriptionFullComplete": "دو هزار امتیاز گرفتی ${LEVEL} در مرحله", - "name": "${LEVEL} خدا" + "description": "۲۰۰۰ امتیاز بگیر", + "descriptionComplete": "۲۰۰۰ امتیاز گرفتی", + "descriptionFull": "در ${LEVEL} ۲۰۰۰ امتیاز بگیر", + "descriptionFullComplete": "در ${LEVEL} ۲۰۰۰ امتیاز گرفتی", + "name": "خدای ${LEVEL}" }, "Runaround Master": { - "description": "پانصد امتیاز بگیر", - "descriptionComplete": "پانصد امتیاز گرفتی", - "descriptionFull": "پونصد امتیاز بگیر ${LEVEL} در مرحله", - "descriptionFullComplete": "پونصد امتیاز گرفتی ${LEVEL} در مرحله", - "name": "${LEVEL} استاد" + "description": "۵۰۰ امتیاز بگیر", + "descriptionComplete": "۵۰۰ امتیاز گرفتی", + "descriptionFull": "در ${LEVEL} ۵۰۰ امتیاز بگیر", + "descriptionFullComplete": "در ${LEVEL} ۵۰۰ امتیاز گرفتی", + "name": "استاد ${LEVEL}" }, "Runaround Wizard": { - "description": "هزار امتیاز بگیر", - "descriptionComplete": "هزار امتیاز گرفتی", - "descriptionFull": "هزار امتیاز بگیر ${LEVEL} در مرحله", - "descriptionFullComplete": "هزار امتیاز گرفتی ${LEVEL} در مرحله", - "name": "${LEVEL} جادوگر" + "description": "۱۰۰۰ امتیاز بگیر", + "descriptionComplete": "۱۰۰۰ امتیاز گرفتی", + "descriptionFull": "در ${LEVEL} ۱۰۰۰ امتیاز بگیر", + "descriptionFullComplete": "در ${LEVEL} ۱۰۰۰ امتیاز گرفتی", + "name": "جادوگر ${LEVEL}" }, "Sharing is Caring": { - "descriptionFull": "بازی را با یک دوست به اشتراک بگذار", - "descriptionFullComplete": "بازی را با یک دوست به اشتراک گذاشتی", - "name": "به اشتراک‌گذاشتن یه‌جور مراقبت است" + "descriptionFull": "بازی رو با یکی از دوستات به اشتراک بگذار", + "descriptionFullComplete": "بازی رو با دوستت به اشتراک گذاشتی", + "name": "بازی با دوستا می‌چسبه" }, "Stayin' Alive": { - "description": "بدون از بین‌رفتن برنده‌شو", - "descriptionComplete": "بدون از بین‌رفتن برنده شدی", - "descriptionFull": "بدون از بین رفتن شو ${LEVEL} در مرحله", - "descriptionFullComplete": "بدون از بین رفتن برنده شدی ${LEVEL} در مرحله", + "description": "بدون از بین رفتن برنده شو", + "descriptionComplete": "بدون از بین رفتن برنده شدی", + "descriptionFull": "در ${LEVEL} بدون از بین رفتن شو", + "descriptionFullComplete": "در ${LEVEL} بدون از بین رفتن برنده شدی", "name": "زنده ماندن" }, "Super Mega Punch": { - "description": "فقط با یک مشت، یکی رو نابود کن", - "descriptionComplete": "فقط با یک مشت، یه نفرو کشتی", - "descriptionFull": "فقط با یک مشت، یه نفر رو نابود کن ${LEVEL} در مرحله", - "descriptionFullComplete": "فقط با یک مشت، یه نفر رو کشتی ${LEVEL} در مرحله", - "name": "مشت فوق‌العاده" + "description": "با یه مشت حریف رو از بین ببر", + "descriptionComplete": "با یه مشت حریف رو از بین بردی", + "descriptionFull": "در ${LEVEL} با یه مشت حریف رو از بین ببر", + "descriptionFullComplete": "در ${LEVEL} با یه مشت حریف رو از بین بردی", + "name": "مشت خیلی فوق‌العاده" }, "Super Punch": { "description": "با یک مشت، نصف جون یه نفر رو ببر", "descriptionComplete": "با یک مشت، نصف جون یه نفر رو بردی", - "descriptionFull": "با یک مشت، نصف جون یه نفر رو ببر ${LEVEL} در مرحله", - "descriptionFullComplete": "با یک مشت، نصف جون یه نفر رو بردی ${LEVEL} در مرحله", + "descriptionFull": "در ${LEVEL} با یه مشت نصف جون حریف رو بگیر", + "descriptionFullComplete": "در ${LEVEL} با یه مشت نصف جون حریف رو گرفتی", "name": "مشت فوق‌العاده" }, "TNT Terror": { - "description": "نابود کنTNT شش حریف رو با", - "descriptionComplete": "نابود کردی TNT شش حریف رو با", - "descriptionFull": "نابود کن TNT شش حریف رو با ${LEVEL} در مرحله", - "descriptionFullComplete": "نابود کردی TNT شش حریف رو با ${LEVEL} در مرحله", + "description": "⁦از بین ببر TNT ۶ حریف رو با", + "descriptionComplete": "⁦از بین بردی TNT ۶ حریف رو با", + "descriptionFull": "⁦از بین ببر TNT در ${LEVEL} ۶ حریف رو با", + "descriptionFullComplete": "⁦از بین بردی TNT در ${LEVEL} ۶ حریف رو با", "name": "TNT وحشت" }, "Team Player": { - "descriptionFull": "یه بازی تیمی با چهارتا از دوستات شروع کن", - "descriptionFullComplete": "یه بازی تیمی با چهارتا از دوستات شروع کردی", + "descriptionFull": "یه بازی تیمی رو با +۴ بازیکن راه بنداز", + "descriptionFullComplete": "یه بازی تیمی رو با +۴ بازیکن راه انداختی", "name": "بازیکن تیم" }, "The Great Wall": { - "description": "جلوی تک تک حریف ها رو بگیر", - "descriptionComplete": "جلوی تک تک حریف ها رو گرفتی", - "descriptionFull": "جلوی تک تک حریف ها رو بگیر ${LEVEL} در مرحله", - "descriptionFullComplete": "جلوی تک تک حریف ها رو گرفتی ${LEVEL} در مرحله", + "description": "جلوی تک‌تک حریف‌ها رو بگیر", + "descriptionComplete": "جلوی تک‌تک حریف‌ها رو گرفتی", + "descriptionFull": "در ${LEVEL} جلوی تک‌تک حریف‌ها رو بگیر", + "descriptionFullComplete": "در ${LEVEL} جلوی تک‌تک حریف‌ها رو گرفتی", "name": "دیوار بزرگ" }, "The Wall": { "description": "جلوی تک تک حریف ها رو بگیر", "descriptionComplete": "جلوی تک تک حریف ها رو گرفتی", - "descriptionFull": "جلوی تک تک حریف ها رو بگیر ${LEVEL} در مرحله", - "descriptionFullComplete": "جلوی تک تک حریف ها رو بگیر ${LEVEL} در مرحله", + "descriptionFull": "در ${LEVEL} جلوی تک‌تک حریف‌ها رو بگیر", + "descriptionFullComplete": "در ${LEVEL} جلوی تک‌تک حریف‌ها رو گرفتی", "name": "دیوار" }, "Uber Football Shutout": { - "description": "برنده شو و اجازه نده حریف امتیاز بگیره", - "descriptionComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره", - "descriptionFull": "برنده شو و اجازه نده حریف امتیاز بگیره ${LEVEL} در مرحله", - "descriptionFullComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره ${LEVEL} در مرحله", - "name": "${LEVEL} بدون امتیاز دادن" + "description": "بدون اینکه بزاری حریف امتیاز بگیره، برنده شو", + "descriptionComplete": "بدون اینکه بزاری حریف امتیاز بگیره، برنده شدی", + "descriptionFull": "در ${LEVEL} بدون اینکه بزاری حریف امتیاز بگیره، برنده شو", + "descriptionFullComplete": "در ${LEVEL} بدون اینکه بزاری حریف امتیاز بگیره، برنده شدی", + "name": "دروازه‌بسته در ${LEVEL}" }, "Uber Football Victory": { "description": "برنده شو", "descriptionComplete": "برنده شدی", "descriptionFull": "برنده شو ${LEVEL} در مرحله", - "descriptionFullComplete": "برنده شدی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "descriptionFullComplete": "در ${LEVEL} برنده شدی", + "name": "پیروزی در ${LEVEL}" }, "Uber Onslaught Victory": { - "description": "تمام موج ها رو بگذران", - "descriptionComplete": "تمام موج ها رو گذراندی", - "descriptionFull": "تمام موج ها رو بگذران ${LEVEL} در مرحله", - "descriptionFullComplete": "تمام موج ها رو گذراندی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "description": "همه‌ی موج‌ها رو شکست بده", + "descriptionComplete": "همه‌ی موج‌ها رو شکست دادی", + "descriptionFull": "همه‌ی موج‌های ${LEVEL} رو شکست بده", + "descriptionFullComplete": "همه‌ی موج‌های ${LEVEL} رو شکست دادی", + "name": "پیروزی در ${LEVEL}" }, "Uber Runaround Victory": { - "description": "همه ی موج ها رو بگذران", - "descriptionComplete": "همه ی موج ها رو گذرونی", - "descriptionFull": "همه ی موج ها رو بگذران ${LEVEL} در مرحله", - "descriptionFullComplete": "همه ی موج ها رو گذروندی ${LEVEL} در مرحله", - "name": "${LEVEL} پیروزی" + "description": "همه‌ی موج‌ها رو کامل کن", + "descriptionComplete": "همه‌ی موج‌ها رو کامل کردی", + "descriptionFull": "همه‌ی موج‌های ${LEVEL} رو کامل کن", + "descriptionFullComplete": "همه‌ی موج‌های ${LEVEL} رو کامل کردی", + "name": "پیروزی در ${LEVEL}" } }, - "achievementsRemainingText": "دستاورد های باقیمانده:", + "achievementsRemainingText": ":دستاوردهای باقی‌مانده", "achievementsText": "دستاوردها", "achievementsUnavailableForOldSeasonsText": "ببخشید، دستاوردهای مخصوص فصل گذشته در دسترس نیستند", - "activatedText": "${THING} فعال شد.", + "activatedText": "⁦.فعال شد ${THING}", "addGameWindow": { - "getMoreGamesText": "...بازی های بیشتر", + "getMoreGamesText": "بازی‌های بیشتر…", "titleText": "افزودن بازی" }, + "addToFavoritesText": "افزودن به مورد علاقه‌ها", + "addedToFavoritesText": "اضافه شد '${NAME}' به مورد علاقه ها", + "allText": "همه", "allowText": "اجازه دادن", "alreadySignedInText": "این حساب کاربری توسط یک دستگاه دیگر در حال استفاده می باشد.\nلطفا از حساب کاربری دیگری استفاده کنید یا بازی را \nدر بقیه دستگاه هایتان ببندید و دوباره امتحان کنید.", "apiVersionErrorText": "نیاز داریم ${VERSION_REQUIRED} است. به ورژن ${VERSION_USED} بالا نمی آید. هدفش ${NAME} مدل", + "applyText": "اعمال کردن", + "areYouSureText": "مطمئنی؟", "audioSettingsWindow": { - "headRelativeVRAudioInfoText": "(به صورت اتوماتیک فعال شود وقتی که هدفون متصل است)", + "headRelativeVRAudioInfoText": "(به صورت خودکار فعال شود وقتی که هدفون متصل است)", "headRelativeVRAudioText": "(صدای واقعیت مجازی(مخصوص هدفون", "musicVolumeText": "صدای موسیقی", "soundVolumeText": "صدای بازی", - "soundtrackButtonText": "تراک های موسیقی", + "soundtrackButtonText": "موسیقی‌متن", "soundtrackDescriptionText": "(موسیقی مورد نظر خود را برای هنگام بازی تعیین کنید)", "titleText": "صدا" }, "autoText": "خودکار", "backText": "بازگشت", "banThisPlayerText": "این بازیکن را محروم کن", - "bestOfFinalText": "${COUNT} برترین های نهایی از", - "bestOfSeriesText": "${COUNT} برترین های مجموعه از", + "bestOfFinalText": "‎بازی - نهایی ${COUNT} برترین در", + "bestOfSeriesText": ":‎بازی ${COUNT} برترین در", "bestRankText": "است #${RANK} برترین رتبه ی شما", "bestRatingText": "است ${RATING} بهترین امتیاز شما", "bombBoldText": "بمب", @@ -358,25 +367,35 @@ "boostText": "تقویت", "bsRemoteConfigureInAppText": "در خود برنامه تنظیم شده است ${REMOTE_APP_NAME} برنامه", "buttonText": "دکمه", - "canWeDebugText": "آیا مایلید که بازی، اتوماتیک خرابی ها \nو باگ ها را به نویسنده ی بازی گزارش دهد ؟\n\nداده ای که فرستاده میشود حاوی هیچ یک از\n اطلاعات شخصی شما نیست و باعث میشود بازی روان تر شود", + "canWeDebugText": "آیا مایلید که ${APP_NAME} اتوماتیک خرابی ها \nو باگ ها را به نویسنده ی بازی گزارش دهد ؟\n\nداده ای که فرستاده میشود حاوی هیچ یک از\n اطلاعات شخصی شما نیست و باعث میشود بازی روان تر شود", "cancelText": "لغو", "cantConfigureDeviceText": "قابل تنظیم نیست ${DEVICE} متاسفانه دستگاه", "challengeEndedText": "این چالش به پایان رسیده است", - "chatMuteText": "گفتگو رو بیصدا کن", - "chatMutedText": "گفتگو بیصدا شد", + "chatMuteText": "گفتگو رو بی‌صدا کن", + "chatMutedText": "گفتگو بی‌صدا شد", "chatUnMuteText": "گفتگو رو صدادار کن", + "chests": { + "prizeOddsText": "جایزه خفن", + "reduceWaitText": "کاهش انتظار", + "slotDescriptionText": "این مکان می تواند یک صندوق را نگه دارد\n\nبا بازی سطوح کمپین،\nقرار گرفتن در مسابقات و تکمیل\nدستاوردها صندوق بدست آورید", + "slotText": "محل صندوق ${NUM}", + "slotsFullWarningText": "هشدار: تمام محل های صندوق شما پر است.\n هر صندوق ای که در این بازی به دست آورید از بین خواهد رفت", + "unlocksInText": "باز می کند" + }, "choosingPlayerText": "<انتخاب بازیکن>", + "claimText": "دریافت", + "codesExplainText": "کدها توسط توسعه دهنده ارائه می شوند\n مشکلات حساب را تشخیص و تصحیح کنید.", "completeThisLevelToProceedText": "برای ادامه باید این مرحله را تمام کنید", "completionBonusText": "پاداش به اتمام رساندن", "configControllersWindow": { - "configureControllersText": "تنظیم دسته ها", + "configureControllersText": "پیکربندی دسته‌ها", "configureKeyboard2Text": "تنظیمات کیبورد بازیکن دوم", "configureKeyboardText": "تنظیمات کیبورد", - "configureMobileText": "گوشی همراه به‌عنوان دستهٔ بازی", - "configureTouchText": "تنظیمات صفحه لمسی", + "configureMobileText": "گوشی به‌عنوان دسته‌ی بازی", + "configureTouchText": "پیکربندی صفحه‌ی لمسی", "ps3Text": "PS3 دسته", - "titleText": "دسته ها", - "wiimotesText": "Wii دسته", + "titleText": "دسته‌ها", + "wiimotesText": "ها Wiimote", "xbox360Text": "Xbox 360 دسته" }, "configGamepadSelectWindow": { @@ -387,7 +406,7 @@ "configGamepadWindow": { "advancedText": "پیشرفته", "advancedTitleText": "تنظیمات پیشرفته ی دسته", - "analogStickDeadZoneDescriptionText": "این گزینه را فعال کنید اگر بازیکن شما بی خودی حرکت میکند", + "analogStickDeadZoneDescriptionText": "(این گزینه را فعال کنید اگر بازیکن شما بی خودی تکان میخورد)", "analogStickDeadZoneText": "دکمه ی آنالوگ منطقه ی مرگ و میر", "appliesToAllText": "(بر همه دسته ها از این نوع اعمال میشود)", "autoRecalibrateDescriptionText": "(این گزینه را فعال کنید اگر بازیکن شما با تمام سرعت نمیدود)", @@ -437,16 +456,17 @@ "actionControlScaleText": "اندازه ی دکمه ها", "actionsText": "اعمال", "buttonsText": "کلید ها", - "dragControlsText": "<دکمه ها را بکشید و موقعیتشان را تعیین کنید>", + "dragControlsText": "⁦< دکمه‌ها را بکشید و موقعیتشان را تعیین کنید >", "joystickText": "دکمه ی حرکت", "movementControlScaleText": "اندازه ی دکمه ی حرکت", "movementText": "حرکت", - "resetText": "بازگرداندن", + "resetText": "بازنشانی", "swipeControlsHiddenText": "مخفی کردن دکمه ی حرکت", "swipeInfoText": "کمی طول میکشد به این نوع حرکت عادت کنید\nولی راحت باشید و بدون نگاه کردن به آن بازی کنید", "swipeText": "حرکت جاروبی", "titleText": "پیکربندی صفحه لمسی" }, + "configureDeviceInSystemSettingsText": "${DEVICE} می‌تواند در سیستم تنظیمات برنامه پیکربندی شود.", "configureItNowText": "همین الآن تنظیم شود ؟", "configureText": "پیکربندی", "connectMobileDevicesWindow": { @@ -454,7 +474,7 @@ "appStoreText": "فروشگاه برنامه", "bestResultsScale": 0.65, "bestResultsText": "برای بهترین نتایج شما به یک شبکه وای‌فای بدون لَگ نیاز دارید\nبرای رفع لگ می‌توانید بقیه دستگاه‌های متصل به وای‌فای را خاموش کنید\nیا نزدیک مودم بازی کنید و یا با شبکه محلی به شبکه وصل شوید و میزبان\nبازی را مستقیماً وصل کنید", - "explanationText": "برای استفاده کردن از یک گوشی هوشمند یا تبلت به عنوان دسته ی بی سیم\nرا بر روی آن نصب کنید. هر تعداد دلخواه گوشی ${REMOTE_APP_NAME} برنامه\nتوسط وای فای به صورت رایگان وصل شوند ${APP_NAME} به برنامه", + "explanationText": "برای استفاده از یک گوشی هوشمند یا تبلت به‌عنوان دسته‌ی بی‌سیم\nبرنامه‌ی ${REMOTE_APP_NAME} را بر روی آن نصب کنید. هر تعداد دلخواه گوشی\nمی‌توانند به ${APP_NAME} روی وای‌فای به‌صورت رایگان وصل شوند.", "forAndroidText": "برای اندروید", "forIOSText": "iOS برای", "getItForText": "را برای آی‌اواس از فروشگاه برنامه‌های اپل ${REMOTE_APP_NAME} برنامهٔ\nیا برای اندروید از فروشگاه گوگل پلی و یا فروشگاه برنامهٔ آمازون دریافت کنید.", @@ -468,7 +488,7 @@ "activenessAllTimeInfoText": "بر روی رده‌بندی کلی اِعمال نمی‌شود.", "activenessInfoText": "این افزاینده در روزهایی که بازی می‌کنید افزایش می‌یابد\nو در روزهایی که بازی نمی‌کنید کاهش می‌یابد.", "activityText": "فعالیت", - "campaignText": "عملیات", + "campaignText": "پیشروی", "challengesInfoText": "برای کامل کردن مینی‌بازی‌ها جایزه بگیرید.\n\nهرگاه چالشی را انجام می‌دهید، جایزه‌ها و\nسختی مراحل افزایش می‌یابد و هرگاه چالشی\nباطل شود یا به هدر رود، کاهش می‌یابد.", "challengesText": "چالش‌ها", "currentBestText": "بهترین امتیاز کنونی", @@ -485,9 +505,9 @@ "pointsText": "امتیازات", "powerRankingFinishedSeasonUnrankedText": "(فصل بدون رده‌بندی پایان یافته)", "powerRankingNotInTopText": "(نفر برتر نیستید ${NUMBER} بین)", - "powerRankingPointsEqualsText": "= امتیاز ${NUMBER}", + "powerRankingPointsEqualsText": "⁦= امتیاز ${NUMBER}", "powerRankingPointsMultText": "(x ${NUMBER} امتیاز)", - "powerRankingPointsText": "امتیاز ${NUMBER}", + "powerRankingPointsText": "⁦امتیاز ${NUMBER}", "powerRankingPointsToRankedText": "(امتیاز ${REMAINING} از ${CURRENT})", "powerRankingText": "رتبه‌بندی قدرت", "prizesText": "جایزه‌ها", @@ -496,7 +516,7 @@ "skipWaitText": "توقف انتظار", "timeRemainingText": "زمان باقی‌مانده", "toRankedText": "تا رتبه‌بندی شوید", - "totalText": "در مجموع", + "totalText": "⁦مجموع", "tournamentInfoText": "بر سر امتیاز بیشتر با بازیکنان در\nلیگ خود رقابت کنید.\n\nهنگامی که زمان مسابقه تمام شود، جایزه به\nنفرات برتر با امتیازهای بالا داده می‌شود.", "welcome1Text": "خوش آمدید. شما می‌توانید ${LEAGUE} به لیگ\nبا گرفتن امتیاز، کامل کردن دستاوردها یا گرفتن جام\n.در مسابقات رتبهٔ خود را بهبود بخشید", "welcome2Text": "همچنین می‌توانید از راه‌های مشابه بلیت جمع‌آوری کنید.\nبلیت‌ها می‌توانند برای باز کردن بازیکنان جدید، نقشه‌ها، مینی‌بازی‌ها یا برای ورود در مسابقه‌ها و موارد\nبیشتر مورد استفاده قرار گیرند.", @@ -510,32 +530,32 @@ "creditsWindow": { "additionalAudioArtIdeasText": "${NAME} صداهای افزوده، کارهای هنری و ایده‌های ابتدایی توسط", "additionalMusicFromText": "${NAME} موسیقی‌های افزوده از", - "allMyFamilyText": "همهٔ دوستان و خانواده‌ام که با بازی نسخهٔ آزمایشی کمک کردند", + "allMyFamilyText": "همه‌ی دوستان و خانواده‌ام که با بازی نسخه‌ی آزمایشی کمک کردند", "codingGraphicsAudioText": "${NAME} کدگذاری، گرافیک و صدا توسط", - "languageTranslationsText": "مترجمان زبان‌ها:", + "languageTranslationsText": "⁦ترجمه‌گران⁦:", "legalText": "حقوقی:", - "publicDomainMusicViaText": "${NAME} موسیقی خاصهٔ مردم از", - "softwareBasedOnText": "میباشد ${NAME} این نرم افزار در بخش هایی الهام گرفته از", - "songCreditText": "اجرا شده و ${PERFORMER} توسط ${TITLE} آهنگ\n.می باشد ${COMPOSER}تنظیم شده و نوشته ی${ARRANGER}انتشار یافته، توسط${PUBLISHER}توسط\n${SOURCE} ادب و مهربانی", + "publicDomainMusicViaText": "${NAME} موسیقی دامنه‌عمومی از", + "softwareBasedOnText": "⁦می‌باشد ${NAME} این نرم‌افزار در بخش‌هایی الهام‌گرفته از", + "songCreditText": "⁦اجرا شده و ${PERFORMER} ⁦توسط ${TITLE} آهنگ\n.⁦می‌باشد ${COMPOSER} ⁦تنظیم شده و نوشته‌ی ${ARRANGER} ⁦انتشار یافته، توسط ${PUBLISHER} توسط\n${SOURCE} ادب و مهربانی", "soundAndMusicText": "صدا & آهنگ:", - "soundsText": "(${SOURCE})صداها :", - "specialThanksText": "تشکر ویژه:", - "thanksEspeciallyToText": "${NAME} تشکر مخصوص از", - "titleText": "${APP_NAME} درباره", + "soundsText": "⁦صداها (${SOURCE}):", + "specialThanksText": "سپاس ویژه:", + "thanksEspeciallyToText": "${NAME} سپاس ویژه از", + "titleText": "درباره‌ی ${APP_NAME}", "whoeverInventedCoffeeText": "هر کسی که قهوه را اختراع کرد!" }, "currentStandingText": "است #${RANK} رتبه ی کنونی شما", "customizeText": "...سفارشی کردن", - "deathsTallyText": "مرگ ${COUNT}", - "deathsText": "مرگ و میرها", + "deathsTallyText": "⁦مرگ ${COUNT}", + "deathsText": "مرگ‌ها", "debugText": "رفع اشكال", "debugWindow": { "reloadBenchmarkBestResultsText": "تذکر: توصیه میشود که در قسمت تنظیمات>گرافیک، کیفیت بافت را آخر ببرید در هنگام تست این", - "runCPUBenchmarkText": "را بسنجید CPU عملکرد", + "runCPUBenchmarkText": "CPU اجرای سنجش", "runGPUBenchmarkText": "را بسنجید GPU عملکرد", - "runMediaReloadBenchmarkText": "بارگذاری رسانه را بسنجید", + "runMediaReloadBenchmarkText": "اجرای سنجش بارگذاری رسانه", "runStressTestText": "اجرای تست استرس", - "stressTestPlayerCountText": "شمارش بازیکن", + "stressTestPlayerCountText": "شمار بازیکنان", "stressTestPlaylistDescriptionText": "لیست بازی تست استرس", "stressTestPlaylistNameText": "نام لیست بازی", "stressTestPlaylistTypeText": "نوع لیست بازی", @@ -544,12 +564,13 @@ "titleText": "معیارها و تست‌های استرس", "totalReloadTimeText": "مجموع زمان بارگذاری: ${TIME} (برای جزئیات گزارش را مشاهده کنید)" }, - "defaultGameListNameText": "به صورت پیشفرض ${PLAYMODE} لیست بازی", - "defaultNewGameListNameText": "من ${PLAYMODE} لیست بازی", - "deleteText": "پاک کن", + "defaultGameListNameText": "⁦پیش‌فرض ⁦${PLAYMODE}⁦ لیست", + "defaultNewGameListNameText": "⁦من ⁦${PLAYMODE}⁦ لیست", + "deleteText": "پاک کردن", "demoText": "نسخه آزمایشی", "denyText": "نپذیرفتن", "deprecatedText": "ناراحت شد", + "descriptionText": "شرح", "desktopResText": "رزولوشن دسکتاپ", "deviceAccountUpgradeText": "هشدار:\nشما با حساب کاربری دستگاه ثبت نام کرده اید (${NAME}).\nدر بروزرسانی های آینده حساب کاربری دستگاه حذف خواهد شد.\nبه حساب کاربری نسخه 2 بروزرسانی کنید اگر می خواهید روند را ادامه دهید.", "difficultyEasyText": "آسان", @@ -560,9 +581,13 @@ "disableRemoteAppConnectionsText": "غیر فعال کردن ارتباطات از راه دور برنامه", "disableXInputDescriptionText": "اجازه می‌دهد به بیش از 4 کنترل کننده اما ممکن است کار نکند.", "disableXInputText": "غیرفعال کردن ورودی ایکس", + "disabledText": "غیرفعال", + "discardText": "دور انداختن", + "discordFriendsText": "دنبال آدم‌های جدید می‌گردید تا با آنها بازی کنید؟\nبه دیسکورد ما بپیوندید و دوستان جدید پیدا کنید!", + "discordJoinText": "پیوستن به دیسکورد", "doneText": "انجام شد", - "drawText": "برابر", - "duplicateText": "تکراری", + "drawText": "مساوی", + "duplicateText": "روگرفتن", "editGameListWindow": { "addGameText": "افزودن\nبازی", "cantOverwriteDefaultText": "نمیشه لیست پیشفرض رو بازنویسی کرد", @@ -577,27 +602,28 @@ }, "editProfileWindow": { "accountProfileInfoText": "این نمایۀ ویژه دارای یک نام\n.و تندیس بر اساس حسابتان است\n\n${ICONS}\n\nنمایه‌های سفارشی بسازید تا از نام‌ها\n.و تندیس‌های مختلف استفاده کرده باشید", - "accountProfileText": "(نمایهٔ حساب)", + "accountProfileText": "(نمایه‌ی حساب)", "availableText": ".در دسترس میباشد \"${NAME}\" نام", "characterText": "بازیکن", "checkingAvailabilityText": "...\"${NAME}\" بررسی برای در دسترس بودن نام", "colorText": "رنگ", - "getMoreCharactersText": "...بازیکن های بیشتر", + "getMoreCharactersText": "بازیکن‌های بیشتر...", "getMoreIconsText": "... تندیس های بیشتر", "globalProfileInfoText": "ضمانت می‌شود که نمایه‌های جهانی بازیکنان، نام‌های یکتا\n.دارند. همچنین یک تندیس سفارشی ضمیمهٔ آن‌ها است", - "globalProfileText": "(نمایهٔ جهانی)", + "globalProfileText": "(نمایه‌ی جهانی)", "highlightText": "بخش درخشان", "iconText": "تندیس", "localProfileInfoText": "نمایه‌های محلی بازیکنان تندیس ندارند و ضمانت نمی‌شود\nکه نام آن‌ها یکتا باشد. نمایه را جهانی کنید تا\n.نامی یکتا و تندیسی سفارشی داشته باشید", - "localProfileText": "(نمایهٔ محلی)", + "localProfileText": "(نمایه‌ی محلی)", "nameDescriptionText": "نام بازیکن", "nameText": "نام", + "profileAlreadyExistsText": "نمایه ای با این نام از قبل وجود دارد.", "randomText": "تصادفی", "titleEditText": "ویرایش نمایه", - "titleNewText": "نمایهٔ جدید", - "unavailableText": ".در دسترس نمی‌باشد؛ نامی دیگر امتحان کنید «${NAME}» نام", - "upgradeProfileInfoText": "این کار نام بازیکن شما را در جهان ذخیره میکند\n.و اجازه میدهد که تندیسی سفارشی به آن دهید", - "upgradeToGlobalProfileText": "ارتقا به نمایهٔ جهانی" + "titleNewText": "نمایه‌ی جدید", + "unavailableText": ".⁦در دسترس نمی‌باشد. نامی دیگر امتحان کنید \"${NAME}\"", + "upgradeProfileInfoText": "این کار نام بازیکن شما را جهانی رزرو می‌کند\n.و اجازه می‌دهد که تندیسی سفارشی به آن بدهید", + "upgradeToGlobalProfileText": "ارتقا به نمایه‌ی جهانی" }, "editSoundtrackWindow": { "cantDeleteDefaultText": "نمیتوانید صدای پیشفرض را حذف کنید", @@ -627,23 +653,26 @@ "useMusicFolderText": "پوشه ی فایل های موسیقی" }, "editText": "ویرایش", + "enabledText": "فعال", "endText": "پایان", "enjoyText": "لذت ببرید", - "epicDescriptionFilterText": "در حماسهٔ حرکت آهسته ${DESCRIPTION}", - "epicNameFilterText": "${NAME} حماسهٔ", + "epicDescriptionFilterText": "‎${DESCRIPTION}‎ در حرکت آهسته‌ی‏‏ حماسی", + "epicNameFilterText": "⁦حماسی ⁦${NAME}⁦", "errorAccessDeniedText": "دسترسی رد شد", "errorDeviceTimeIncorrectText": "ساعت گوشی‌تان ${HOURS} ساعت خطا دارد.\nممکن است مشکل به‌وجود بیاید.\nلطفاً ساعت و منطقه زمانی گوشی‌تان را بررسی کنید.", "errorOutOfDiskSpaceText": "حافظه جا ندارد", "errorSecureConnectionFailText": "قادر به ایجاد اتصال ابری امن نیست. عملکرد شبکه ممکن است خراب شود.", "errorText": "خطا", "errorUnknownText": "خطای ناشناخته", - "exitGameText": "؟${APP_NAME} خروج از", + "exitGameText": "خروج از ${APP_NAME}؟", + "expiredAgoText": "‎پیش منقضی شد ${T}‎", + "expiresInText": "‎دیگر منقضی می‌شود ‎${T}‎", "exportSuccessText": "منتقل شد ${NAME}", "externalStorageText": "حافظه ی خارجی", "failText": "باختی", "fatalErrorText": ".اوه اوه؛ فایلی خراب یا گم شده\nلطفا برنامه را از اول نصب کنید یا\n.در تماس باشید ${EMAIL} برای کمک با", "fileSelectorWindow": { - "titleFileFolderText": "یه فایل یا پوشه را انتخاب نمایید", + "titleFileFolderText": "یک فایل یا پوشه را انتخاب نمایید", "titleFileText": "یک فایل انتخاب نمایید", "titleFolderText": "یک پوشه انتخاب نمایید", "useThisFolderButtonText": "استفاده از این پوشه" @@ -652,69 +681,72 @@ "finalScoreText": "امتیاز نهایی", "finalScoresText": "امتیازهای نهایی", "finalTimeText": "زمان نهایی", - "finishingInstallText": "...در حال اتمام نصب؛ یه لحظه", + "finishingInstallText": "در حال اتمام نصب؛ یه لحظه...", "fireTVRemoteWarningText": "برای یک تجربه ی بهتر، از دسته ها*\n'${REMOTE_APP_NAME}' یا برنامه\nبر روی گوشی های هوشمند یا تبلت\n.خود استفاده کنید", - "firstToFinalText": "فینال ${COUNT} اولین در", - "firstToSeriesText": "مجموعه ${COUNT} اولین در", - "fiveKillText": "!!پنج نفر رو کشتی", + "firstToFinalText": "‎نهایی ${COUNT} اول تا", + "firstToSeriesText": "‎مجموعه‌بازی ${COUNT} اول تا", + "fiveKillText": "!!!پنج نفر رو کشتی", "flawlessWaveText": "!یک موج بدون عیب", "fourKillText": "!!چهار نفر رو نابود کردی", "friendScoresUnavailableText": "امتیاز دوستان در دسترس نیست", "gameCenterText": "مرکز بازی", "gameCircleText": "GameCircle", - "gameLeadersText": "نفر برتر بازی ${COUNT}", + "gameLeadersText": "${COUNT} پیشتازان بازی", "gameListWindow": { "cantDeleteDefaultText": "نمیتوانید لیست بازی پیش فرض را حذف کنید", - "cantEditDefaultText": "نمیتوانید لیست بازی پیش فرض را دست کاری کنید. آن را کپی کنید یا یه لیست جدید بسازید", + "cantEditDefaultText": "نمی‌توانید لیست بازی پیش‌فرض را دست کاری کنید. آن را کپی کنید یا یک لیست جدید بسازید.", "cantShareDefaultText": "شما نمیتونید لیست بازی پیش فرض رو به اشتراک بگذارید", "deleteConfirmText": "؟ \"${LIST}\" حذف", "deleteText": "حذف\nلیست بازی", "duplicateText": "کپی کردن\nلیست بازی", "editText": "ویرایش\nلیست بازی", "newText": "لیست بازی\nجدید", + "pointsToWinText": "امتیاز برای برنده شدن", + "seriesLengthText": "طول مجموعه‌بازی", "showTutorialText": "نمایش آموزش", - "shuffleGameOrderText": "ترتیب تصادفی بازی ها", - "titleText": "${TYPE} تنظیم لیست های" + "shuffleGameOrderText": "ترتیب تصادفی بازی‌ها", + "titleText": "سفارشی‌سازی لیست‌های ${TYPE}" }, "gameSettingsWindow": { "addGameText": "افزودن بازی" }, - "gamesToText": "${LOSECOUNT} بازی به ${WINCOUNT}", + "gamesToText": "${LOSECOUNT}⁦ بازی به ${WINCOUNT}", "gatherWindow": { "aboutDescriptionLocalMultiplayerExtraText": "فراموش نکنید: هردستگاه در یک گروه میتواند بیشتر\n.از یک بازیکن داشته باشد اگر به اندازه ی کافی دسته دارید", - "aboutDescriptionText": ".از این صفحات برای تشکیل یک گروه استفاده کنید\n\nگروه به شما این امکان را میدهد که بازی ها و مسابقات\n.را با دوستانتان بر روی گوشی های متفاوت بازی کنید\n\nدر گوشه ی بالای سمت راست استفاده کنید ${PARTY}از دکمه ی\n.تا با گروه چت و تعامل کنید\n(را هنگامی که در منو هستید فشار دهید${BUTTON} با دسته، دکمه ی)", + "aboutDescriptionText": ".از این زبانه‌ها برای تشکیل یک پارتی استفاده کنید\n\nپارتی به شما این امکان را می‌دهد که بازی‌ها و مسابقات\n.را با دوستانتان بر روی گوشی‌های متفاوت بازی کنید\n\n⁦در گوشه‌ی بالای سمت راست استفاده کنید ${PARTY} از دکمه‌ی\n.تا با پارتی چت و تعامل کنید\n(⁦را هنگامی که در منو هستید فشار دهید ${BUTTON} با دسته، دکمه‌ی)", "aboutText": "درباره", - "addressFetchErrorText": "<خطا در اتصال به آدرس>", - "appInviteMessageText": "${APP_NAME}بلیط فرستاده در برنامه ی ${COUNT}برای شما ${NAME}", + "addressFetchErrorText": "⁦<خطا در اتصال به آدرس>", + "appInviteMessageText": "${APP_NAME}بلیت فرستاده در برنامه ی ${COUNT}برای شما ${NAME}", "appInviteSendACodeText": "برایشان یه کد ارسال کن", "appInviteTitleText": "${APP_NAME} دعوت به", "bluetoothAndroidSupportText": "(کار میکنه با هر دستگاه اندرویدی که از بلوتوث پشتیبانی میکنه)", "bluetoothDescriptionText": "میزبان/مهمان شدن یک گروه با بلوتوث :", "bluetoothHostText": "میزبانی با بلوتوث", - "bluetoothJoinText": "ملحق شدن با بلوتوث", + "bluetoothJoinText": "پیوستن با بلوتوث", "bluetoothText": "بلوتوث", "checkingText": "...در حال چک کردن", "copyCodeConfirmText": "کد در کلیپ بورد کپی شد.", "copyCodeText": "کپی کردن کد", - "dedicatedServerInfoText": "برای نتیجه بهتر،یه سرور اختصاصی بزنید.به سایت زیر برین bombsquadgame.com/serverتا بفهمین چطوری", + "dedicatedServerInfoText": ".‎را ببینید bombsquadgame.com/server برای نتیجه‌ی بهتر، یک سرور اختصاصی بالا بیاورید. برای یاد گرفتن چگونگی کار", + "descriptionShortText": "از بخش شبکه با دوستان برای تشکیل پارتی استفاده کنید.", "disconnectClientsText": "بازیکن را از ${COUNT} این کار ارتباط\nبازی قطع میکند. مطمئنید؟", "earnTicketsForRecommendingAmountText": ".بلیط خواهند گرفت اگر این بازی را امتحان کنند ${COUNT} دوستانتان\n(بلیط به ازای هر کدامشان میگیرید${YOU_COUNT}و شما هم)", "earnTicketsForRecommendingText": "به اشتراک گذاری بازی\nبرای بلیط های رایگان", "emailItText": "ایمیلش کن", "favoritesSaveText": "ذخیره به‌عنوان مورد علاقه", "favoritesText": "مورد علاقه‌ها", - "freeCloudServerAvailableMinutesText": "سرور ابری رایگان بعدی در عرض ${MINUTES} دقیقه در دسترس است.", + "freeCloudServerAvailableMinutesText": ".‎دقیقه‌ی دیگر در دسترس است ${MINUTES} سرور ابری رایگان بعدی", "freeCloudServerAvailableNowText": "!سرور ابری رایگان در دسترس است", "freeCloudServerNotAvailableText": ".سرورهای ابری رایگان در دسترس نیست", "friendHasSentPromoCodeText": "${NAME}از طرف ${APP_NAME}بلیطِ بازی ${COUNT}", "friendPromoCodeAwardText": ".بلیط خواهید گرفت هر بار که استفاده شود${COUNT}شما", "friendPromoCodeExpireText": ".ساعت منقضی میشود و تنها بر روی بازیکنان جدید کار میکند${EXPIRE_HOURS}این کد در", - "friendPromoCodeInstructionsText": ".را باز کنید و به قسمت تنظیمات>پیشرفته>وارد کردن کد بروید${APP_NAME}برای استفاده از کد، برنامه\n.سر بزنید تا لینک دانلود بازی برای سیستم عامل های مختلف بازی را بگیرید BombSquadgame.com به سایت", + "friendPromoCodeInstructionsText": ".را باز کنید و به قسمت تنظیمات>پیشرفته>فرستادن اطلاعات بروید${APP_NAME}برای استفاده از کد، برنامه\n.سر بزنید تا لینک دانلود بازی برای سیستم عامل های مختلف بازی را بگیرید BombSquadgame.com به سایت", "friendPromoCodeRedeemLongText": ".بلیط رایگان به دست آورند${COUNT}نفر میتوانند از این کد استفاده کنند تا${MAX_USES}", "friendPromoCodeRedeemShortText": ".بلیط در بازی بگیرید${COUNT}با این کد میتوانید", - "friendPromoCodeWhereToEnterText": "(در بخش تنظیمات>پیشرفته>وارد کردن کد)", + "friendPromoCodeWhereToEnterText": "(\"در \"تنظیمات > پیشرفته > فرستادن اطلاعات)", "getFriendInviteCodeText": "گرفتن کد برای دعوت دوستان", - "googlePlayDescriptionText": ":دعوت از بازیکنان گوگل پلی برای ملحق شدن به گروه شما", + "googlePlayDescriptionText": ":دعوت از بازیکنان گوگل پلی برای پیوستن به پارتی شما", "googlePlayInviteText": "دعوت", "googlePlayReInviteText": "بازیکن از گوگل پلی در گروه شما هستند${COUNT}\n.که ارتباط‌شان قطع می‌شود اگر یک دعوت جدید را شروع کنید\n.آن ها را هم در دعوت جدید، ضمیمه کنید", "googlePlaySeeInvitesText": "دیدن دعوت ها", @@ -724,56 +756,57 @@ "hostingUnavailableText": "میزبانی در دسترس نیست", "inDevelopmentWarningText": ":تذکر\n\n.بازی شبکه‌ای یک ویژگی جدید و درحال گسترشه\nاکنون شدیداً توصیه می‌شود همه بازیکنان\n.در یک شبکه وای‌فای مشترک باشند", "internetText": "اینترنت", - "inviteAFriendText": "رفیقات این بازی رو ندارند؟ دعوتشون کن\n.بلیط رایگان بگیرند${COUNT}بیان بازی کننده و", + "inviteAFriendText": "دوستات این بازی رو ندارند؟ دعوتشون کن\n.تا بلیت رایگان دریافت کنند${COUNT} بیان بازی کنن و", "inviteFriendsText": "دعوت دوستان", - "joinPublicPartyDescriptionText": "پیوستن به سرور های عمومی", - "localNetworkDescriptionText": "به یک سرور دیگر از طریق LAN , Bluetooth , etc بپیوندید", + "joinPublicPartyDescriptionText": "پیوستن به یک سرور عمومی", + "localNetworkDescriptionText": "(.وای‌فای، بلوتوث، و غیره) به یه پارتی نزدیکت وصل شو", "localNetworkText": "شبکه محلی", - "makePartyPrivateText": "گروه من رو از عمومی خارج کن", - "makePartyPublicText": "گروه بازی من رو عمومی کن", - "manualAddressText": "آدرس", + "makePartyPrivateText": "پارتی من را خصوصی کن", + "makePartyPublicText": "پارتی من را عمومی کن", + "manualAddressText": "نشانی", "manualConnectText": "وصل شدن", - "manualDescriptionText": ":ملحق شدن به یک گروه با آدرس", + "manualDescriptionText": ":پیوستن به یک پارتی با نشانی", "manualJoinSectionText": "پیوستن با نشانی", - "manualJoinableFromInternetText": ":کسی میتوانداز طریق اینترنت به شما ملحق شود؟", + "manualJoinableFromInternetText": "⁦کسی می‌تواند از طریق اینترنت به شما ملحق شود؟:", "manualJoinableNoWithAsteriskText": "خیر*", "manualJoinableYesText": "بلی", - "manualRouterForwardingText": "را به آدرس محلی بفرستد${PORT} برای حل این مشکل، روتر خود را تنظیم کنید تا یو دی پی پورت", + "manualRouterForwardingText": "⁦را به نشانی محلی شما بفرستد UDP ${PORT} ‏*برای حل این مشکل، روتر خود را تنظیم کنید تا درگاه", "manualText": "بطور دستی", - "manualYourAddressFromInternetText": ":آدرس شما در اینترنت", - "manualYourLocalAddressText": ":آدرس محلی شما", + "manualYourAddressFromInternetText": "⁦نشانی شما در اینترنت:", + "manualYourLocalAddressText": "⁦نشانی محلی شما:", "nearbyText": "افراد نزدیک", "noConnectionText": "<اتصال برقرار نیست>", + "noPartiesAddedText": "هیچ پارتی‌ای اضافه نشده‌است", "otherVersionsText": "(نسخه های دیگر)", - "partyCodeText": "کد گروه", + "partyCodeText": "کد پارتی", "partyInviteAcceptText": "پذیرفتن", "partyInviteDeclineText": "نپذیرفتن", "partyInviteGooglePlayExtraText": "(صفحه گوگل‌پلی را در صفحه \"شبکه با دوستان\" ببینید)", "partyInviteIgnoreText": "نادیده گرفتن", "partyInviteText": "شما را دعوت کرده${NAME} \nتا به گروهشان ملحق شوید", - "partyNameText": "نام گروه", - "partyServerRunningText": ".سرور گروه شما در حال اجراست", + "partyNameText": "نام پارتی", + "partyServerRunningText": ".سرور پارتی شما در حال اجراست", "partySizeText": "اندازه دسته", "partyStatusCheckingText": "در حال چک کردن وضعیت...", "partyStatusJoinableText": "گروه شما حالا دیگه از طریق اینترنت قابل اتصال برای بقیه است.", "partyStatusNoConnectionText": "عدم توانایی برقراری ارتباط با سرور", "partyStatusNotJoinableText": "گروه شما قابل اتصال از طریق اینترنت نیست", - "partyStatusNotPublicText": "گروه بازی شما در اینترنت عمومی نیست", + "partyStatusNotPublicText": "پارتی شما عمومی نیست", "pingText": "پینگ", "portText": "درگاه", "privatePartyCloudDescriptionText": ".گروه‌های خصوصی بر روی سرورهای ابری اختصاصی اجرا می شوند; و نیازی به پیکربندی روتر/مودم نیست", - "privatePartyHostText": "میزبانی گروه خصوصی", - "privatePartyJoinText": "ملحق شدن به سرور خصوصی", + "privatePartyHostText": "میزبانی پارتی خصوصی", + "privatePartyJoinText": "پیوستن به سرور خصوصی", "privateText": "خصوصی", "publicHostRouterConfigText": "این ممکن است نیاز به پیکربندی انتقال پورت در روتر شما داشته باشد. برای یک گزینه آسانتر ، یک سرور خصوصی برگزار کنید.", "publicText": "عمومی", "requestingAPromoCodeText": "...درخواست یک کد", "sendDirectInvitesText": "ارسال دعوت مستقیم", "shareThisCodeWithFriendsText": ":اشتراک این کد با دوستان", - "showMyAddressText": "آدرس من رو نشون بده", + "showMyAddressText": "نشانی من رو نشون بده", "startHostingPaidText": "${COST} میزبانی اکنون برای", "startHostingText": "میزبان", - "startStopHostingMinutesText": "شما می توانید میزبانی رایگان را برای ${MINUTES}  دقیقه دیگر شروع کرده و متوقف کنید.", + "startStopHostingMinutesText": ".‎‎دقیقه‌ی دیگر شروع کرده و متوقف کنید ‎${MINUTES} می‌توانید میزبانی رایگان را تا", "stopHostingText": "میزبانی را متوقف کنید", "titleText": "شبکه با دوستان", "wifiDirectDescriptionBottomText": "داشته باشند حتماً میتونید ازش استفاده کنندWi-Fi Direct اگر دستگاه هاتون قابلیت\nو به یکدیگر وصل شوند.وقتی که دستگاه ها بهم وصل شدند میتوانید اینجا در صفحه ی\nشبکه محلی گروه تشکیل دهید.دقیقاً مثل وصل شدن از طریق وای فای معمولی\n\n.هم میزبان شود${APP_NAME}میزبان میشود درWi-Fi Directبرای گرفتن بهترین نتیجه،کسی که در", @@ -797,7 +830,7 @@ "ticketPack4Text": "پک خیلی بزرگ بلیط", "ticketPack5Text": "پک ماموتی بلیط", "ticketPack6Text": "پک نهایی بلیط", - "ticketsFromASponsorText": "در ازای ${COUNT} بلیت\nیک آگهی ببینید", + "ticketsFromASponsorText": "در ازای ${COUNT} بلیط\nیک آگهی ببینید", "ticketsText": "بلیط${COUNT}", "titleText": "بلیط بگیرید", "unavailableLinkAccountText": ".ببخشید،خرید به وسیله ی این دستگاه در دسترس نمیباشد\nمیتوانید حسابتان بر روی این دستگاه را به حسابی در دستگاهی\n.دیگر متصل کنید و آنجا خرید خود را انجام دهید", @@ -807,6 +840,12 @@ "youHaveShortText": "دارید ${COUNT} شما", "youHaveText": ".بلیط دارید ${COUNT} شما" }, + "goldPass": { + "desc1InfTokensText": "توکن بی‌نهایت", + "desc2NoAdsText": "بدون تبلیغات", + "desc3ForeverText": "برای همیشه", + "goldPassText": "گلد پس" + }, "googleMultiplayerDiscontinuedText": "متأسفیم ، سرویس چند نفره Google دیگر در دسترس نیست.\nمن در اسرع وقت در حال جایگزینی هستم.\nتا آن زمان ، لطفاً روش اتصال دیگری را امتحان کنید.", "googlePlayPurchasesNotAvailableText": "خرید های گوگل‌پلی در دسترس نیستند.\nاحتمالا باید برنامه‌ی استور خود را بروز‌رسانی کنید.", "googlePlayServicesNotAvailableText": ".سرویس گوگل پلی در دسترس نیست\n.بعضی عملکرد های برنامه ممکن غیرفعال باشند", @@ -815,10 +854,12 @@ "alwaysText": "همیشه", "fullScreenCmdText": "تمام صفحه (Cmd-F)", "fullScreenCtrlText": "تمام صفحه (Ctrl-F)", + "fullScreenText": "تمام‌صفحه", "gammaText": "گاما", "highText": "زیاد", "higherText": "بالاتر", "lowText": "کم", + "maxFPSText": "حداکثر FPS", "mediumText": "معمولی", "neverText": "هرگز", "resolutionText": "رزولوشن", @@ -830,20 +871,20 @@ "visualsText": "کیفیت تصویر" }, "helpWindow": { - "bombInfoText": "- بمب -\nقوی تر از مشته امامیتونه\n.برای خودتون هم خطرناک باشه\nدر بهترین زمان ممکن قبل از اینکه\n.در دست خودتون بترکه، پرتش بدید", - "canHelpText": "میتونه به شما کمک کنه${APP_NAME}", - "controllersInfoText": "بازی کنید و یا${APP_NAME}میتوانید توسط شبکه با دوستانتان\n.روی یک دستگاه بازی کنید اگر به اندازه ی کافی دسته دارید\nاز این تنوع پشتیبانی میکند؛ شما حتی میتوانید${APP_NAME}\nاز گوشی های هوشمند به عنوان دسته استفاده کنید از طریق برنامه\n.برای اطلاعات بیشتر به تنظیمات>کنترلرها بروید.${REMOTE_APP_NAME}", + "bombInfoText": "⁦- بمب -\nقوی‌تر از مشته، ولی می‌تونه\nبرای خودتون هم خطرناک باشه.\nدر بهترین زمان ممکن قبل از اینکه\nتوی دست خودتون بترکه، پرتش کنید.", + "canHelpText": "${APP_NAME} می‌تونه کمک کنه.", + "controllersInfoText": "می‌تونی روی یه شبکه یا اگه به اندازه کافی دسته\nدارید، روی یه دستگاه با دوستات ${APP_NAME} بازی کنی.\n${APP_NAME} از کنترلرهای مختلفی پشتیبانی می‌کنه. حتی می‌تونی گوشی رو\nبه‌عنوان دسته از طریق برنامه‌ی ${REMOTE_APP_NAME} استفاده کنی.\nبرای اطلاعات بیشتر تنظیمات -> کنترلرها رو ببینید.", "controllersInfoTextRemoteOnly": "شما میتونید ${APP_NAME} رو همراه دوستانتان به صورت اینترنتی ، یا\nبا استفاده از نرم‌افزار '${REMOTE_APP_NAME}' گوشیتون رو\nبه دسته بازی تبدیل کنید تا همه با هم در یک گوشی بازی کنید.", "controllersText": "کنترلرها", - "controlsSubtitleText": ":شما چندتا حرکت اساسی داره ${APP_NAME} بازیکن", + "controlsSubtitleText": "کاراکتر ${APP_NAME} شما چندتا حرکت اساسی داره:", "controlsText": "کنترل‌ها", "devicesInfoText": "نسخه وی آر ${APP_NAME} میتونه با شبکه با\n نسخه معمولی بازی کنه، پس تلفن یا تبلت \nیا کامپیوتر اضافیتونو آماده کنید و بازیو شروع کنید.\n حتی وقتی بخواین فقط کاری کنین که چن نفر از \nبیرون بتونن بازیو تماشا کنن هم بکار میاد.", "devicesText": "دستگاه‌ها", - "friendsGoodText": "داشتن چنتا ازینا خیلی خوبه. ${APP_NAME} حالش بیشتره وقتی با چن نفر\nبازی بشه و میتونه همزمان تا 8 نفر ساپورت کنه که این قضیه ما رو میبره سمت:", + "friendsGoodText": "داشتن چندتا از اینا خوبه. ${APP_NAME} حالش بیشتره وقتی با چند نفر\nبازی بشه و می‌تونه همزمان تا ۸ نفر رو پشتیبانی کنه که این قضیه ما رو می‌بره به سمت:", "friendsText": "دوستان", - "jumpInfoText": "پرش\nبرای پریدن ازاین دکمه کمک بگیرید\n همچنین پریدن قبل از پرتاب بمب و\nهمزمان بامشت بسیار در بازی بکارمیره", + "jumpInfoText": "⁦- پرش -\nپرش برای عبور از شکاف‌های کوچیک،\nپرتاب کردن چیزها به بالاتر، و برای \nبیان احساس شادی استفاده می‌شه.", "orPunchingSomethingText": "یا بهش مشت بزنی یا از یه بلندی پرتش کنی و توی راه که داره پرت میشه با یه بمب چسبونکی بترکونیش.", - "pickUpInfoText": "بلند کردن\nمیتونید هر فرد یا بمب یا هر چیزی رو\nاز زمین بلند و پرتاب کنید,حتی \nمیتونید بازیکنان رو از زمین بیرون بندازین", + "pickUpInfoText": "⁦- بلند کردن -\nپرچم، دشمن یا هر چیزی رو\nمی‌تونید از زمین بلند و پرتاب کنید.\nواسه انداختنش دوباره دکمه رو باید بزنید.", "powerupBombDescriptionText": "به شما اجازه پرتاب هر بار سه بمب\nرو پشت سر هم همزمان میده", "powerupBombNameText": "سه بمب", "powerupCurseDescriptionText": "بهتره اینو نگیرین چون طی چند ثانیه اگه\nبه جعبه درمان نرسین منفجر میشین", @@ -861,31 +902,32 @@ "powerupShieldDescriptionText": "سپر محافظ دورتون قرار میگیره\nو ضربه وانفجار ها روتون کم اثر میشه", "powerupShieldNameText": "سپر محافظ", "powerupStickyBombsDescriptionText": "این بمب ها رو به سمت هر چی پرتاب \nکنی میچسبن به اون تا لحظه ی انفجار", - "powerupStickyBombsNameText": "بمب های چسبنده", - "powerupsSubtitleText": "البته هیچ بازی کامل نیست بدون استفاده از بسته های ویژه", - "powerupsText": "بسته های ویژه", - "punchInfoText": "مشت\nبرا ضربه به حریف از این کلید \nاستفاده کنید ضربه مشت های قوی تر\nهمزمان با پرش و سرعت و چرخش هستن", - "runInfoText": "حرکت\nبرا حرکت از جهت های جوی استیک استفاده کنید و برای حرکت سریع تر میتونید جهت ها رو همزمان با یک کلید دیگه بکار ببرید\nبرای پرتاب بمب ها به مسافت بیشتر همزمان با حرکت قابل انجامه ضربه مشت ها همزمان با حرکت هم موثرتر هستن", + "powerupStickyBombsNameText": "بمب چسبنده", + "powerupsSubtitleText": ":البته هیچ بازی‌ای کامل نیست بدون استفاده از نیروزاها", + "powerupsText": "نیروزاها", + "punchInfoText": "⁦- مشت -\nبه هر اندازه که توی مشت زدن بیشتر\nبچرخید و حرکت کنید، ضربه مشتتون قوی‌تره.\nپس موقع مشت زدن بپرید و بچرخید و بدویید.", + "runInfoText": "‎- ⁦حرکت -\n.هر دکمه‌ای رو برای دویدن می‌تونی نگه داری. البته یادت نره که دکمه‌ی جهت رو هم در کنارش بگیری\n.دویدن شما رو سریع‌تر به یه جایی می‌رسونه، اما چرخیدن رو سخت می‌کنه. پس مراقب صخره‌ها باش", "someDaysText": "بعضی روزا دوس داری مشت بزنی یه جایی. یا یه چیزیو بزنی بترکونی.", - "titleText": "${APP_NAME} راهنمایی", - "toGetTheMostText": "To get the most out of this game, you'll need:", - "welcomeText": "!خوش آمدید ${APP_NAME} به" + "titleText": "راهنمای ${APP_NAME}", + "toGetTheMostText": ":برای اینکه بیشترین لذت را از این بازی ببرید، به این موردها نیاز دارید", + "welcomeText": "به ${APP_NAME} خوش آمدید!" }, "holdAnyButtonText": "<نگه داشتن هر دکمه>", "holdAnyKeyText": "<نگه داشتن هر کلید>", - "hostIsNavigatingMenusText": "- ${HOST} مدیر تغییر منو ها در بازیست -", + "hostIsNavigatingMenusText": "- مدیر تغییر منوها در بازی است ⁦${HOST}⁦ -", "importPlaylistCodeInstructionsText": "از کدی که در ادامه است برای وارد کردن این لیست بازی در جای دیگر استفاده کنید:", "importPlaylistSuccessText": "لیست بازی شد ${TYPE} وارد '${NAME}'", "importText": "وارد کردن", "importingText": "...وارد کردن", "inGameClippedNameText": "نام درون بازیتان خواهد بود\n\"${NAME}\"", + "inboxText": "پیام‌ها", "installDiskSpaceErrorText": "خطا: قادر به تکمیل نصب نیست\nممکنه مربوط به فضای ذخیره دستگاه شما باشه\nچک کنید و مجددا امتحان کنید", "internal": { "arrowsToExitListText": "برای خروج از لیست ${LEFT} یا ${RIGHT} فشار دهید", "buttonText": "دکمه", "cantKickHostError": ".شما نمیتوانید میزبان را بیرون کنید", "chatBlockedText": ".ثانیه مسدود شد ${TIME} برای ${NAME} چت", - "connectedToGameText": "متصل شد '${NAME}'", + "connectedToGameText": "⁦متصل شد '${NAME}'", "connectedToPartyText": "${NAME} پیوستن به", "connectingToPartyText": "در حال اتصال", "connectionFailedHostAlreadyInPartyText": "ارتباط ناموفق: میزبان در بخش دیگریست", @@ -899,8 +941,8 @@ "controllerDisconnectedTryAgainText": "قطع اتصال شد. لطفا تلاش کنید برای اتصال ازنو ${CONTROLLER}", "controllerForMenusOnlyText": ".این کنترلر نمی‌تواند در بازی مورد استفاده قرار بگیرد. استفاده فقط برای پیمایش در منوها", "controllerReconnectedText": "دوباره متصل شد ${CONTROLLER}", - "controllersConnectedText": "کنترولر متصل شد ${COUNT}", - "controllersDetectedText": "کنترولر شناسایی شد ${COUNT}", + "controllersConnectedText": "⁦کنترلر متصل شد ${COUNT}", + "controllersDetectedText": "⁦کنترلر شناسایی شد ${COUNT}", "controllersDisconnectedText": "قطع اتصال شد ${COUNT}", "corruptFileText": "Corrupt file(s) detected. Please try re-installing, or email ${EMAIL}", "errorPlayingMusicText": "خطای موزیک بازی:${MUSIC}", @@ -916,29 +958,31 @@ "invitationsSentText": "دعوت نامه ارسال شد ${COUNT}", "joinedPartyInstructionsText": "فردی به گروه شما پیوسته\nبرید به بازی و بازی را شروع کنید", "keyboardText": "صفحه‌کلید", - "kickIdlePlayersKickedText": "بعلت غیرفعال بودن ${NAME} خروج", + "kickIdlePlayersKickedText": "به علت غیرفعال بودن ${NAME} خروج", "kickIdlePlayersWarning1Text": "${NAME} will be kicked in ${COUNT} seconds if still idle.", "kickIdlePlayersWarning2Text": "(شما می توانید اینو خاموش کنید در تنظیمات -> پیشرفته)", - "leftGameText": "خارج شد '${NAME}'", - "leftPartyText": "پارتی رو ترک کرد ${NAME}", + "leftGameText": ".⁦خارج شد '${NAME}'", + "leftPartyText": ".⁦پارتی رو ترک کرد ⁦${NAME}⁦", "noMusicFilesInFolderText": "پوشه حاوی هیچ فایل موسیقی نیست.", "playerJoinedPartyText": "به گروه بازی پیوست ${NAME}", - "playerLeftPartyText": "${NAME} گروه رو ترک کرد", + "playerLeftPartyText": ".⁦پارتی رو ترک کرد ⁦${NAME}⁦", "rejectingInviteAlreadyInPartyText": "رد کردن دعوت (already in a party)", "serverRestartingText": "سرور در حال شروع مجدد است. لطفا چند لحظه دیگر مجددا متصل شوید", "serverShuttingDownText": ".سرور درحال بسته شدن است", "signInErrorText": "خطای ورود به سیستم", - "signInNoConnectionText": "ورود ناموفق بود اتصال به اینترنت در دسترسه؟", + "signInNoConnectionText": "ورود ناموفق بود. اتصال به اینترنت برقراره؟", "telnetAccessDeniedText": "خطا: کاربر از دسترسی به شبکه خارج شد", "timeOutText": "(times out in ${TIME} seconds)", "touchScreenJoinWarningText": "You have joined with the touchscreen.\nIf this was a mistake, tap 'Menu->Leave Game' with it.", "touchScreenText": "صفحه لمسی", + "unableToCompleteTryAgainText": "در حال حاضر نمی توان این را تکمیل کرد.\n لطفا دوباره امتحان کنید.", "unableToResolveHostText": "مشکل:توانایی حل مشکل میزبان وجود ندارد", "unavailableNoConnectionText": "در دسترس نیست. اتصال به اینترنت برقرار است آیا؟", "vrOrientationResetCardboardText": "برای تنظیم مجدد جهت گیری VR از این استفاده کنید.\nبرای بازی کردن به یک کنترلر خارجی نیاز دارید.", "vrOrientationResetText": "تنظیم مجدد VR.", "willTimeOutText": "(زمان تموم میشه اگه بیکار بود)" }, + "inventoryText": "موجودی", "jumpBoldText": "پرش", "jumpText": "پرش", "keepText": "نگه داشتن", @@ -949,7 +993,7 @@ "kickOccurredText": ".بیرون انداخته شد ${NAME}", "kickQuestionText": "بیرون انداخته شود؟ ${NAME}", "kickText": "بیرون انداختن", - "kickVoteCantKickAdminsText": "نمیشود ادمین ها رو اخراج کنید", + "kickVoteCantKickAdminsText": "نمیشه ادمین ها رو اخراج کنی", "kickVoteCantKickSelfText": "نمیشه خودت رو اخراج کنی اسکل", "kickVoteFailedNotEnoughVotersText": ".بازیکنان برای رای گیری کافی نیستند", "kickVoteFailedText": ".رای گیری برای بیرون انداختن ناموفق", @@ -957,8 +1001,8 @@ "kickVoteText": "رای برای بیرون انداختن", "kickVotingDisabledText": ".رأی گیری غیرفعاله", "kickWithChatText": "را برای نه تایپ کن ${NO} را برای بله و ${YES} در چت", - "killsTallyText": "${COUNT} کشته ها", - "killsText": "کشته ها", + "killsTallyText": "⁦شکار ${COUNT}", + "killsText": "شکارها", "kioskWindow": { "easyText": "آسان", "epicModeText": "حرکت آهسته", @@ -968,25 +1012,28 @@ "singlePlayerExamplesText": "Single Player / Co-op Examples", "versusExamplesText": "Versus Examples" }, - "languageSetText": "زبان فعلی: ${LANGUAGE}", - "lapNumberText": "${TOTAL}/${CURRENT} دور", + "languageSetText": "زبان کنونی: ${LANGUAGE}", + "lapNumberText": "${CURRENT}/${TOTAL} دور", "lastGamesText": "(بازی آخر ${COUNT})", - "leaderboardsText": "مدیران", + "leaderboardsText": "تابلوی امتیازات", "league": { "allTimeText": "همیشه", "currentSeasonText": "(${NUMBER}) فصل جاری", - "leagueFullText": "${NAME} لیگ", + "leagueFullText": "لیگ ${NAME}", "leagueRankText": "رتبه لیگ", "leagueText": "لیگ", "rankInLeagueText": "#${RANK}, ${NAME} League${SUFFIX}", - "seasonEndedDaysAgoText": ".روز پیش پایان یافت ${NUMBER} فصل", - "seasonEndsDaysText": ".روز دیگر پایان می‌یابد ${NUMBER} فصل", - "seasonEndsHoursText": ".ساعت دیگر پایان می‌یابد ${NUMBER} فصل", - "seasonEndsMinutesText": ".دقیقهٔ دیگر پایان می‌یابد ${NUMBER} فصل", + "seasonEndedDaysAgoText": "⁦.روز پیش پایان یافت ${NUMBER} فصل", + "seasonEndsDaysText": "⁦.روز دیگر پایان می‌یابد ${NUMBER} فصل", + "seasonEndsHoursText": "⁦.ساعت دیگر پایان می‌یابد ${NUMBER} فصل", + "seasonEndsMinutesText": "⁦.دقیقه‌ی دیگر پایان می‌یابد ${NUMBER} فصل", "seasonText": "${NUMBER} فصل", "tournamentLeagueText": ".برسید ${NAME} برای ورود به این مسابقه، باید به لیگ", - "trophyCountsResetText": ".جوایز در فصل بعد بازنشانی می‌شوند" + "trophyCountsResetText": ".جوایز در فصل بعد بازنشانی می‌شوند", + "upToDateBonusDescriptionText": "بازیکنانی نسخه اخیر را اجرا می کنند بازی در اینجا جایزه دریافت می کند ${PERCENT}%", + "upToDateBonusText": "پاداش به‌روز بودن" }, + "learnMoreText": "بیشتر بدانید", "levelBestScoresText": "${LEVEL} بهترین امتیاز در", "levelBestTimesText": "${LEVEL} بهترین زمان در", "levelIsLockedText": ".قفل است ${LEVEL}", @@ -995,10 +1042,10 @@ "levelUnlockedText": "!قفل مرحله باز شد", "livesBonusText": "پاداش تعداد جان ها", "loadingText": "در حال بارگزاری", - "loadingTryAgainText": "…در حال بارگذاری؛ چند لحظهٔ دیگر دوباره امتحان کنید", + "loadingTryAgainText": "در حال بارگذاری؛ چند لحظه‌ی دیگر دوباره امتحان کنید…", "macControllerSubsystemBothText": "(هر دو (توصیه نمی‌شود", "macControllerSubsystemClassicText": "معمولی", - "macControllerSubsystemDescriptionText": "(موقعی سعی کنید این را عوض کنید که کنترلر شما درست کار نمیکند.)", + "macControllerSubsystemDescriptionText": "(زمانی سعی کنید این را عوض کنید که کنترلر شما درست کار نمیکند.)", "macControllerSubsystemMFiNoteText": ".ساخته شده برای کنترلر آی‌اواِس/مک تشخیص داده شد\n شما شاید بخواهید این‌ها رو در تنظیمات فعال کنید", "macControllerSubsystemMFiText": "ساخته شده برای ای او اس و مک", "macControllerSubsystemTitleText": "پشتیبانی کنترل کننده", @@ -1010,7 +1057,7 @@ "exitGameText": "خروج از بازی", "exitToMenuText": "خروج به منو؟", "howToPlayText": "روش بازی", - "justPlayerText": "(فقط ${NAME})", + "justPlayerText": "(⁦${NAME}⁦ فقط)", "leaveGameText": "ترک کردن بازی", "leavePartyConfirmText": "واقعا میخوای دسته رو ترک کنی؟", "leavePartyText": "ترک دسته", @@ -1019,9 +1066,9 @@ "settingsText": "تنظیمات" }, "makeItSoText": "درستش کن", - "mapSelectGetMoreMapsText": "رفتن به زمین‌های بازیِ بیشتر...", - "mapSelectText": "انتخاب . . .", - "mapSelectTitleText": "${GAME} نقشه", + "mapSelectGetMoreMapsText": "دریافت نقشه‌های بیشتر...", + "mapSelectText": "انتخاب…", + "mapSelectTitleText": "نقشه‌ی ${GAME}", "mapText": "نقشه", "maxConnectionsText": "حداکثر اتصالات", "maxPartySizeText": "حداکثر فضای پارتی", @@ -1030,22 +1077,25 @@ "modeArcadeText": "حالت بازی", "modeClassicText": "حالت کلاسیک", "modeDemoText": "حالت نمایشی", + "moreSoonText": "...موارد بیشتر به زودی", + "mostDestroyedPlayerText": "نابود شده ترین بازیکن", "mostValuablePlayerText": "ارزشمندترین بازیکن", - "mostViolatedPlayerText": "پُراشتباه‌ترین بازیکن", + "mostViolatedPlayerText": "پراشتباه‌ترین بازیکن", "mostViolentPlayerText": "خشن‌ترین بازیکن", "moveText": "انتقال", - "multiKillText": "! !${COUNT} ازبین بردن.", - "multiPlayerCountText": "بازیکن ${COUNT}", - "mustInviteFriendsText": "توجه:\nشما باید دعوت کنید از دوستان درصفحه اصلی از قسمت\n\"${GATHER}\"", - "nameBetrayedText": ".خیانت کرد ${VICTIM} به ${NAME}", - "nameDiedText": ".از بین رفت ${NAME}", - "nameKilledText": ".را از بین برد ${VICTIM} ${NAME}", + "multiKillText": "!!!⁦شکار ${COUNT}", + "multiPlayerCountText": "⁦بازیکن ${COUNT}", + "mustInviteFriendsText": "توجه: برای بازی چندنفره باید از\n\"${GATHER}\" دوستانتان در پنل \nدعوت یا به بازی دسته وصل کنید.", + "nameBetrayedText": ".⁦خیانت کرد ⁦${VICTIM}⁦ ⁦به ⁦${NAME}⁦", + "nameDiedText": ".⁦از بین رفت ⁦${NAME}⁦", + "nameKilledText": ".⁦را از بین برد ⁦${VICTIM}⁦ ⁦،${NAME}⁦", "nameNotEmptyText": "!نام نمی‌تواند خالی باشد", - "nameScoresText": "!موفق شد ${NAME}", - "nameSuicideKidFriendlyText": ".بیرون افتاد ${NAME}", - "nameSuicideText": ".خودکشی کرد ${NAME}", + "nameScoresText": "⁦!موفق شد ⁦${NAME}⁦", + "nameSuicideKidFriendlyText": ".⁦بیرون افتاد ⁦${NAME}⁦", + "nameSuicideText": ".⁦خودکشی کرد ⁦${NAME}⁦", "nameText": "نام", "nativeText": "بومی", + "newExclaimText": "!جدید", "newPersonalBestText": "!رکورد قبلیتو شکستی", "newTestBuildAvailableText": "(${BUILD} نسخهٔ ${VERSION}) !نسخهٔ آزمایشی جدیدتری دردسترس است\n${ADDRESS} :از این نشانی دریافت کنید", "newText": "جدید", @@ -1056,12 +1106,16 @@ "noContinuesText": "(ادامه ندارد)", "noExternalStorageErrorText": "محل ذخیره سازی در این دستگاه یافت نشد", "noGameCircleText": "GameCircleخطا: وارد نشدید به", + "noMessagesText": "هیچ پیامی فعلا نیست", + "noPluginsInstalledText": "متاسفانه افزونه ها نصب نشده", "noScoresYetText": "هیچ امتیازی نیست", + "noServersFoundText": "سروری یافت نشد.", "noThanksText": "نه مرسی", "noTournamentsInTestBuildText": ".هشدار: امتیازات مسابقه از این نسخهٔ آزمایشی نادیده گرفته می‌شوند", "noValidMapsErrorText": "هیچ نقشه معتبری برای این نوع بازی یافت نشد.", "notEnoughPlayersRemainingText": "بازیکنان باقیمانده کافی نیستند خارج بشید و دوباره یه بازی جدید رو شروع کنید", "notEnoughPlayersText": "!بازیکن نیاز دارید ${COUNT} برای شروع بازی حداقل به", + "notEnoughTicketsText": "بلیط کافی ندارید!", "notNowText": "حالا نه", "notSignedInErrorText": ".برای انجام این کار باید وارد شوید", "notSignedInGooglePlayErrorText": "برا استفاده از این مورد شما باید به گوگل‌پلی وارد شوید", @@ -1073,10 +1127,13 @@ "okText": "تایید", "onText": "روشن", "oneMomentText": "یک لحظه...", - "onslaughtRespawnText": "${PLAYER} will respawn in wave ${WAVE}", + "onslaughtRespawnText": "⁦زنده می‌شود ${WAVE} ⁦در موج ⁦${PLAYER}⁦", + "openMeText": "!بازم کن", + "openNowText": "همین حالا باز کنید", + "openText": "باز کنید", "orText": "${A} یا ${B}", "otherText": "دیگر...", - "outOfText": "(#${RANK} از ${ALL})", + "outOfText": "(${ALL} ⁦از #${RANK})", "ownFlagAtYourBaseWarning": "پرچم شما باید در پایگاه خودتان باشد تا امتیاز کسب کنید.", "packageModsEnabledErrorText": "شبکه‌بازی دردسترس نیست. بروبه تظیمات》 تنظیمات پیشرفته و تیک پکیج محلی رو وردار", "partyWindow": { @@ -1084,7 +1141,7 @@ "emptyText": "هیچکس نیست", "hostText": "(میزبان)", "sendText": "ارسال", - "titleText": "گروه شما" + "titleText": "پارتی شما" }, "pausedByHostText": "(مکث شده توسط میزبان)", "perfectWaveText": "! عالی کار کردی", @@ -1093,57 +1150,57 @@ "coopText": "چند نفره", "freeForAllText": "تک به تک", "multiTeamText": "چند تیم", - "singlePlayerCoopText": "بازی با کامپیوتر", + "singlePlayerCoopText": "بازی تک‌نفره / چندنفره", "teamsText": "بازی تیمی" }, "playText": "شروع بازی", "playWindow": { - "oneToFourPlayersText": "حداکثر ۴ بازیکن", + "oneToFourPlayersText": "۱ تا ۴ بازیکن", "titleText": "شروع بازی", - "twoToEightPlayersText": "حداکثر ۸ بازیکن" + "twoToEightPlayersText": "۲ تا ۸ بازیکن" }, - "playerCountAbbreviatedText": "بازیکن ${COUNT}", - "playerDelayedJoinText": ".در دور بعد وارد می‌شود ${PLAYER}", + "playerCountAbbreviatedText": "(⁦نفره ${COUNT})", + "playerDelayedJoinText": ".⁦در دور بعد وارد می‌شود ⁦${PLAYER}⁦", "playerInfoText": "اطلاعات بازیکن", - "playerLeftText": ".بازی را ترک کرد ${PLAYER}", + "playerLeftText": ".⁦بازی را ترک کرد ⁦${PLAYER}⁦", "playerLimitReachedText": "محدودیت بازکن به ${COUNT} رسیده; عضو جدید مجاز نیست.", "playerProfilesWindow": { - "cantDeleteAccountProfileText": "شما نمی‌توانید نمایهٔ مربوط به حساب‌کاربری را حذف کنید.", + "cantDeleteAccountProfileText": "نمی‌توانید نمایه‌ی مربوط به حساب کاربری را حذف کنید.", "deleteButtonText": "حذف\nنمایه", "deleteConfirmText": "؟'${PROFILE}' حذف", "editButtonText": "ویرایش\nنمایه", - "explanationText": "نام سفارشی بازیکن حاضر در این حساب کاربری", - "newButtonText": "نمایهٔ\nجدید", + "explanationText": "(نام‌ها و شخصیت‌های سفارشی این حساب)", + "newButtonText": "نمایه‌ی\nجدید", "titleText": "نمایه‌های بازیکن" }, "playerText": "بازیکن", "playlistNoValidGamesErrorText": "این لیست حاوی هیچ بازی معتبری نیست", "playlistNotFoundText": "لیست بازی یافت نشد", - "playlistText": "لیست پخش", - "playlistsText": "لیست بازی ها", - "pleaseRateText": "خوشتان آمده، لطفاً چند لحظه‌ای وقت بگذارید و ${APP_NAME} اگر از\nآن را رتبه‌بندی کنید یا مروری بر آن بنویسید. این کار بازخوردهای مفیدی\n.را به همراه دارد و به پشتیبانی از توسعه‌ها در آینده کمک خواهد کرد\n\n!با تشکر\nاریک—", + "playlistText": "لیست بازی", + "playlistsText": "لیست بازی‌ها", + "pleaseRateText": "اگر از ${APP_NAME} خوشتان آمده، لطفاً چند لحظه‌ای وقت بگذارید و\nآن را رتبه‌بندی کنید یا مروری بر آن بنویسید. این کار بازخوردهای مفیدی\n.را به همراه دارد و به پشتیبانی از توسعه‌ها در آینده کمک خواهد کرد\n\n!با تشکر\nاریک—", "pleaseWaitText": "…لطفاً صبر کنید", "pluginClassLoadErrorText": "${ERROR} :«${PLUGIN}» خطا در بارگیری دسته‌بندی افزونهٔ", "pluginInitErrorText": "${ERROR} :«${PLUGIN}» خطا در راه‌اندازی افزونهٔ", - "pluginSettingsText": "تنظیمات پلاگین", - "pluginsAutoEnableNewText": "فعال کردن خودکار افزونه های جدید", + "pluginSettingsText": "تنظیمات افزونه", + "pluginsAutoEnableNewText": "فعال کردن خودکار افزونه‌های جدید", "pluginsDetectedText": "افزونه(ها)ی جدید شناسایی شد. آن‌ها را در تنظیمات فعال، یا پیکربندی کنید.", - "pluginsDisableAllText": "غیرفعال کردن همه افزونه ها", - "pluginsEnableAllText": "فعال کردن همه افزونه ها", + "pluginsDisableAllText": "غیرفعال کردن همه‌ی افزونه‌ها", + "pluginsEnableAllText": "فعال کردن همه‌ی افزونه‌ها", "pluginsRemovedText": "${NUM} افزونه دیگر یافت نمی‌شود.", "pluginsText": "افزونه‌ها", "practiceText": "تمرین", - "pressAnyButtonPlayAgainText": "…فشردن هر دکمه‌ای برای بازی دوباره", - "pressAnyButtonText": "…فشردن هر دکمه‌ای برای ادامه", - "pressAnyButtonToJoinText": "…پیوستن با فشردن هر دکمه‌ای", - "pressAnyKeyButtonPlayAgainText": "…فشردن هر کلیدی/دکمه‌ای برای بازی دوباره", - "pressAnyKeyButtonText": "…فشردن هر کلیدی/دکمه‌ای برای ادامه", + "pressAnyButtonPlayAgainText": "فشردن هر دکمه‌ای برای بازی دوباره…", + "pressAnyButtonText": "فشردن هر دکمه‌ای برای ادامه…", + "pressAnyButtonToJoinText": "پیوستن با فشردن هر دکمه‌ای…", + "pressAnyKeyButtonPlayAgainText": "فشردن هر کلیدی/دکمه‌ای برای بازی دوباره…", + "pressAnyKeyButtonText": "فشردن هر کلیدی/دکمه‌ای برای ادامه…", "pressAnyKeyText": "…کلیدی را فشار دهید", - "pressJumpToFlyText": "** روی پرش مکرراً ضربه بزنید تا پرواز کنید **", + "pressJumpToFlyText": "⁦** روی پرش پیاپی بزن تا پرواز کنی **", "pressPunchToJoinText": "…برای پیوستن دکمهٔ مشت را فشار دهید", - "pressToOverrideCharacterText": "را فشار دهید ${BUTTONS} برای انتخاب کاراکتر", - "pressToSelectProfileText": "را فشار دهید ${BUTTONS} برای انتخاب بازیکن", - "pressToSelectTeamText": "را فشار دهید ${BUTTONS} برای انتخاب تیم", + "pressToOverrideCharacterText": "⁦برای انتخاب کاراکتر ${BUTTONS} را فشار دهید", + "pressToSelectProfileText": "⁦را فشار دهید ${BUTTONS} برای انتخاب بازیکن", + "pressToSelectTeamText": "⁦را فشار دهید ${BUTTONS} برای انتخاب تیم", "promoCodeWindow": { "codeText": "کد", "enterText": "ورود" @@ -1152,6 +1209,7 @@ "ps3ControllersWindow": { "macInstructionsText": "Switch off the power on the back of your PS3, make sure\nBluetooth is enabled on your Mac, then connect your controller\nto your Mac via a USB cable to pair the two. From then on, you\ncan use the controller's home button to connect it to your Mac\nin either wired (USB) or wireless (Bluetooth) mode.\n\nOn some Macs you may be prompted for a passcode when pairing.\nIf this happens, see the following tutorial or google for help.\n\n\n\n\nPS3 controllers connected wirelessly should show up in the device\nlist in System Preferences->Bluetooth. You may need to remove them\nfrom that list when you want to use them with your PS3 again.\n\nAlso make sure to disconnect them from Bluetooth when not in\nuse or their batteries will continue to drain.\n\nBluetooth should handle up to 7 connected devices,\nthough your mileage may vary.", "ouyaInstructionsText": "To use a PS3 controller with your OUYA, simply connect it with a USB cable\nonce to pair it. Doing this may disconnect your other controllers, so\nyou should then restart your OUYA and unplug the USB cable.\n\nFrom then on you should be able to use the controller's HOME button to\nconnect it wirelessly. When you are done playing, hold the HOME button\nfor 10 seconds to turn the controller off; otherwise it may remain on\nand waste batteries.", + "ouyaInstructionsTextScale": 0.74, "pairingTutorialText": "آموزش تصویری جفت‌شدن", "titleText": ":${APP_NAME} در PS3 استفاده از کنترلر" }, @@ -1159,6 +1217,8 @@ "punchText": "مشت", "purchaseForText": "خرید برای ${PRICE}", "purchaseGameText": "خرید بازی", + "purchaseNeverAvailableText": ".با عرض پوزش، خرید در این نسخه در دسترس نیست\n.سعی کنید در پلتفرم دیگری وارد حساب خود شوید و از آنجا خرید کنید", + "purchaseNotAvailableText": ".این خرید در دسترس نیست", "purchasingText": "…در حال خرید", "quitGameText": "؟${APP_NAME} خروج از", "quittingIn5SecondsText": "…ترک در ۵ ثانیه", @@ -1166,17 +1226,17 @@ "randomText": "تصادفی", "rankText": "رتبه", "ratingText": "امتیاز", - "reachWave2Text": "برای ثبت امتیاز به دور دوم برسید", + "reachWave2Text": "برای گرفتن رتبه به موج ۲ برسید.", "readyText": "آماده", "recentText": "اخیر", "remoteAppInfoShortText": ".خیلی جذاب تره وقتی با دوستانتون بازی می کنید ${APP_NAME} بازی\nکافیه چند تا دسته ی بازی به دستگاهتون وصل کنید یا\nرا روی گوشی و تبلت های دیگر نصب کنید تا ${REMOTE_APP_NAME} برنامه ی\n.به عنوان دسته برای بازی استفاده شوند", "remote_app": { - "app_name": "BombSquad کنترولر مخصوص", + "app_name": "دسته‌مجازی بمب‌اسکواد", "app_name_short": "BSRemote", "button_position": "مکان دکمه", "button_size": "اندازه دکمه", "cant_resolve_host": "میزبان را نمی‌توان یافت.", - "capturing": "گرفتن…", + "capturing": "...در حال گرفتن", "connected": ".متصل شد", "description": "از گوشی یا تبلتتان به‌عنوان دستهٔ بازی برای بمب‌اسکواد استفاده کنید.\nتا ۸ دستگاه می‌توانند به‌صورت هم‌زمان برای جنون حماسهٔ محلی چندنفره روی یک تی‌وی یا تبلت متصل شوند.", "disconnected": "قطع اتصال از سرور", @@ -1197,14 +1257,15 @@ "searching": "جستجو برای بازی‌های فعال", "searching_caption": "بر روی نام یک بازی برای پیوستن به آن ضربه بزنید.\nاطمینان حاصل کنید که شما در شبکه وای فای همان بازی هستید.", "start": "شروع", - "version_mismatch": "عدم تطابق نسخه‌ها\nاطمینان حاصل کنید که بمب‌اسکوار و کنترولر\nآخرین ورژن باشن و دوباره امتحان کنید" + "version_mismatch": "عدم تطابق نسخه‌ها.\nاطمینان حاصل کنید که بمب‌اسکواد و دسته‌مجازی\nآخرین نسخه باشند و دوباره امتحان کنید." }, "removeInGameAdsText": "بازی را در فروشگاه بخرید تا تبلیغات حذف شوند «${PRO}» نسخهٔ", + "removeInGameAdsTokenPurchaseText": "پیشنهاد زمان محدود: هر بسته توکن را برای حذف تبلیغات درون بازی خریداری کنید", "renameText": "تغییر نام", "replayEndText": "پایان بازپخش", "replayNameDefaultText": "بازپخش بازی اخیر", "replayReadErrorText": "خطا در خواندن فایل بازپخش", - "replayRenameWarningText": "عبارت «${REPLAY}» را تغییر دهید، اگر می‌خواهید بعد از یک بازی آن را از دست ندهید. در غیر این صورت بازنویسی می‌شود.", + "replayRenameWarningText": "⁦.را تغییر دهید، اگر می‌خواهید بعد از یک بازی آن را از دست ندهید؛ وگرنه بازنویسی می‌شود \"${REPLAY}\"", "replayVersionErrorText": "با عرض پوزش این بازبخش در ورژن مختلفیاز بازی ایجاد شده\n است و نمیتوان مورد استفاده قرار گیرد", "replayWatchText": "دیدن بازبخش بازی", "replayWriteErrorText": "خطا در نوشتن فایل بازپخش.", @@ -1220,7 +1281,9 @@ "revertText": "بازگشت", "runText": "دویدن", "saveText": "ذخیره", - "scanScriptsErrorText": "اسکریپت ها در حال بررسی خطا ها است؛ برای جزئیات لوگ را ببینید", + "scanScriptsErrorText": "اسکریپت ها در حال بررسی خطا ها است؛ برای جزئیات لاگ را ببینید", + "scanScriptsMultipleModulesNeedUpdatesText": ".⁦به‌روزرسانی شوند api ${API} ⁦ماژول دیگر باید برای ${NUM} ⁦و ${PATH}", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} باید برای api ${API} به‌روزرسانی شود.", "scoreChallengesText": "امتیاز چالش", "scoreListUnavailableText": ".لیست امتیازات در دسترس نیست", "scoreText": "امتیاز", @@ -1231,10 +1294,11 @@ }, "scoreWasText": "(بود ${COUNT})", "selectText": "انتخاب", - "seriesWinLine1PlayerText": "برنده", - "seriesWinLine1TeamText": "برنده", - "seriesWinLine1Text": "برنده", - "seriesWinLine2Text": "مجموعه بازی", + "sendInfoDescriptionText": ".اطلاعات اکانت و حالت برنامه را به سازنده می‌فرستد\n.لطفاً نام خود یا دلیل فرستادن را بیان کنید", + "seriesWinLine1PlayerText": "برنده‌ی", + "seriesWinLine1TeamText": "برنده‌ی", + "seriesWinLine1Text": "برنده‌ی", + "seriesWinLine2Text": "!مجموعه‌بازی", "settingsWindow": { "accountText": "حساب", "advancedText": "پیشرفته", @@ -1245,35 +1309,43 @@ "titleText": "تنظیمات" }, "settingsWindowAdvanced": { - "alwaysUseInternalKeyboardDescriptionText": "(یه صفحه‌کلید ساده و خوش‌دست بر روی صفحهٔ نمایش برای ویرایش متنی)", - "alwaysUseInternalKeyboardText": "همیشه از صفحه‌کلید داخلی استفاده شود", + "alwaysUseInternalKeyboardDescriptionText": "(یه کی‌بورد ساده و خوش‌دست برای نوشتن)", + "alwaysUseInternalKeyboardText": "همیشه از کی‌بورد داخلی استفاده شود", "benchmarksText": "معیار و تست استرس", + "devToolsText": "ابزارهای توسعه", "disableCameraGyroscopeMotionText": "غیرفعال کردن حرکت ژیروسکوپ دوربین", "disableCameraShakeText": "غیرفعال کردن لرزش دوربین", - "disableThisNotice": "(شما میتوانید این اخطار را در تنظیمات یشرفته خاموش کنید)", + "disableThisNotice": "(می‌تونید این اخطار رو در تنظیمات پیشرفته خاموش کنید)", "enablePackageModsDescriptionText": "(فعالسازی قابلیت مد اکسترا اما شبکه بازی غیر فعال میشود)", "enablePackageModsText": "فعالسازی پکیج مد محلی", "enterPromoCodeText": "وارد کردن کد", - "forTestingText": "توجه: این تغیرات برای آزمایش کردن هستند و هنگام خروج به حال اول باز میگردند", - "helpTranslateText": "ترجمه‌های غیرانگلیسی ${APP_NAME} تلاشی است که\nتوسط انجمن پشتیبانی می‌شود. اگر مایل به کمک یا تصحیح\nترجمه هستید، پیوند زیر را دنبال کنید. پیشاپیش متشکرم!", + "forTestingText": "توجه: این تغیرات برای آزمایش هستند و هنگام خروج از بین می‌روند.", + "helpTranslateText": "ترجمه‌های غیرانگلیسی ${APP_NAME} تلاشی است که\nتوسط جامعه پشتیبانی می‌شود. اگر مایل به کمک یا تصحیح\n!ترجمه هستید، پیوند زیر را دنبال کنید. پیشاپیش سپاس‌گزارم", + "insecureConnectionsDescriptionText": "توصیه نمی شود، اما ممکن است از طرف کشورها یا\nشبکه‌های محدودشده اجازه‌ی بازی آنلاین را بدهد", + "insecureConnectionsText": "استفاده از اتصال‌های ناپایدار", "kickIdlePlayersText": "بیرون انداختن بازیکنان غیرفعال", "kidFriendlyModeText": "حالت دوستانه برای کودکان. خشونت کم", "languageText": "زبان", "moddingGuideText": "راهنمای برنامه‌نویسان", + "moddingToolsText": "اصلاح کردن ابزار", "mustRestartText": "برای اعمال تغییرات باید بازی را دوباره راه اندازی کنید", "netTestingText": "تست شبکه", - "resetText": "باز گرداندن", + "resetText": "بازنشانی", + "sendInfoText": "فرستادن اطلاعات", "showBombTrajectoriesText": "نمایش خط سیر بمب", - "showInGamePingText": "نمایش پینگ در بازی", + "showDemosWhenIdleText": "نمایش دموها هنگام بیکاری", + "showDeprecatedLoginTypesText": "نمایش انواع ورودهای منسوخ", + "showDevConsoleButtonText": "نمایش دکمه‌ی کنسول توسعه", + "showInGamePingText": "نمایش پینگ درون بازی", "showPlayerNamesText": "نمایش نام بازیکنان", - "showUserModsText": "نمایش پوشهٔ سبک بازی‌ها", + "showUserModsText": "نمایش پوشه‌ی افزونه‌های بازی", "titleText": "پیشرفته", - "translationEditorButtonText": "${APP_NAME} ویرایشگر زبان", + "translationEditorButtonText": "ویرایشگر زبان ${APP_NAME}", "translationFetchErrorText": "وضعیت ترجمه در دسترس نیست", "translationFetchingStatusText": "چک کردن وضعیت ترجمه ...", "translationInformMe": "!وقتی زبان من به‌روزرسانی نیاز داشت، خبرم کن", - "translationNoUpdateNeededText": "!زبان کنونی به‌روز است؛ ووهو", - "translationUpdateNeededText": "! زبان فعلی نیاز به به روز رسانی دارد", + "translationNoUpdateNeededText": "!زبان کنونی به‌روز است. ایول به ولت", + "translationUpdateNeededText": "!زبان کنونی نیاز به به‌روزرسانی دارد", "vrTestingText": "VR تست" }, "shareText": "اشتراک‌گذاری", @@ -1281,11 +1353,14 @@ "showText": "نمایش", "signInForPromoCodeText": "برای اثر گذاری کد ها باید با یک حساب کاربری وارد شوید", "signInWithGameCenterText": "برای استفاده از حسابی که در یک گیم سنتر دارید,\nبا برنامه گیم سنتر خود وارد شوید.", - "singleGamePlaylistNameText": "${GAME} فقط", + "singleGamePlaylistNameText": "⁦${GAME}⁦ فقط", "singlePlayerCountText": "1 بازیکن", + "sizeLargeText": "بزرگ", + "sizeMediumText": "متوسط", + "sizeSmallText": "کوچک", "soloNameFilterText": "رو در رو ${NAME}", "soundtrackTypeNames": { - "CharSelect": "انتخاب کارکتر", + "CharSelect": "انتخاب شخصیت", "Chosen One": "انتخاب شده", "Epic": "بازی قدرت", "Epic Race": "مسابقه حرکت آهسته", @@ -1308,6 +1383,7 @@ }, "spaceKeyText": "فاصله", "statsText": "آمار", + "stopRemindingMeText": "به من یادآوری نکن", "storagePermissionAccessText": "به اجازه شما برای دسترسی به حافظه نیاز دارد", "store": { "alreadyOwnText": "!را در اختیار دارید ${NAME} شما", @@ -1315,22 +1391,22 @@ "bombSquadProNameText": "حرفه ای ${APP_NAME}", "bombSquadProNewDescriptionText": ".تبلیغات داخل بازی حذف میشود\n.بیشتر تنظیمات بازی باز میشوند\n:همچنین شامل", "buyText": "خرید", - "charactersText": "شخصیت ها", + "charactersText": "شخصیت‌ها", "comingSoonText": "...به زودی", "extrasText": "دیگر", "freeBombSquadProText": "جوخه بمب حالا مجانیه، ولی چون شما زمانی خریدینش که پولی بود؛ ما داریم\nشمارو به جوخه بمب پرو ارتقا میدیم و ${COUNT} بلیط بعنوان تشکر برای شما.\nاز امکانات جدید لذت ببرید. از شما بابت پشتیبانی و دلگرمی تان ممنونیم!\n-اریک", "holidaySpecialText": "ویژه‌ی تعطیلات", - "howToSwitchCharactersText": "(برو به \"${SETTINGS} -> ${PLAYER_PROFILES}\" برای ایجاد و شخصی‌سازی شخصیت‌ها)", - "howToUseIconsText": "(ایجاد نمایه‌های جهانی از قسمت پنجرهٔ حساب برای استفاده در این مورد)", - "howToUseMapsText": "(از این نقشه‌ها میتونید تو بازی‌های تیمی و تک‌به‌تکی خودتون استفاده کنید)", + "howToSwitchCharactersText": "(⁦برو \"${SETTINGS} -> ${PLAYER_PROFILES}\" برای ایجاد و شخصی‌سازی شخصیت‌ها به)", + "howToUseIconsText": "((در بخش حساب کاربری) برای استفاده از این‌ها نمایه‌های جهانی ایجاد کنید)", + "howToUseMapsText": "(از این نقشه‌ها می‌تونید توی بازی‌های تیمی و تک‌به‌تک خودتون استفاده کنید)", "iconsText": "نشانه‌ها", "loadErrorText": "لود شدن صفحه ناموفق بود\nاتصال اینترنت رو چک کنید", "loadingText": "در حال بارگزاری", - "mapsText": "نقشه ها", - "miniGamesText": "تک بازی‌های کوچک", + "mapsText": "نقشه‌ها", + "miniGamesText": "بازی‌های کوچک", "oneTimeOnlyText": "(فقط یک بار)", "purchaseAlreadyInProgressText": "این مورد قبلا سفارش داده شده", - "purchaseConfirmText": "را بخرید ؟ ${ITEM} واقعا می خواهید", + "purchaseConfirmText": "واقعا می‌خواهید ${ITEM} ⁦را بخرید؟", "purchaseNotValidError": ". سفارش معتبر نیست\n. ایمیل بزنید ${EMAIL} اگر مشکلی دارید به", "purchaseText": "خرید", "saleBundleText": "فروش بسته نرم‌افزاری!", @@ -1347,7 +1423,7 @@ "storeDescriptionText": "8 بازیکن حزب جنون بازی!\n\nدوستان خود (یا رایانه) را در مسابقات مینی بازی‌های انفجاری مانند: پرچم، هاکی و حرکت آهسته\n\nکنترل ساده و پشتیبانی گسترده می‌توان تا حداکثر 8 نفر برای ورود به بازی اقدام کند؛ شما حتی می‌توانید دستگاه‌های تلفن‌همراه خود را به عنوان کنترل از طریق برنامه رایگان BombSquadremote استفاده کنید!\n\nبمب‌اندازی از راه دور!\n\nwww.froemling.net/bombsquad را برای اطلاعات بیشتر چک کنید.", "storeDescriptions": { "blowUpYourFriendsText": "بازیکن دوستات رو بترکون 😁", - "competeInMiniGamesText": "رقابت در بازی‌های کوچک بویژه مسابقه پرواز.", + "competeInMiniGamesText": "رقابت در بازی‌های کوچک به یژه مسابقه پرواز.", "customize2Text": "سفارشی کردن شخصیت‌ها، بازی‌های کوچک، و حتی موسیقی‌های متن .", "customizeText": "شما می تونید شخصیت‌ها رو شخصی‌سازی کنید و به سلیقه خودتون لیست‌بازی درست کنید", "sportsMoreFunText": "ورزش ها سرگرم کننده تر میشن با انفجار", @@ -1356,29 +1432,46 @@ "storeText": "فروشگاه", "submitText": "ثبت", "submittingPromoCodeText": "...ثبت کردن کد", + "successText": "!موفقیت آمیز بود", + "supportEmailText": "اگر با هر گونه مشکلی مواجه هستید\n برنامه، لطفاً به ${EMAIL} ایمیل بزنید.", "teamNamesColorText": "نام/رنگ تیم...", "telnetAccessGrantedText": "شبکه ی در دسترس فعال", "telnetAccessText": "شبکه راه دور دردسترس است اجازه میدید؟", "testBuildErrorText": "این نسخه دیگر فعال نیست، لطفا نسخه جدید را بررسی کنید", - "testBuildText": "آزمایش ساخت", + "testBuildText": "ساخت آزمایشی", "testBuildValidateErrorText": "قادر به تأیید نسخه نیست (اتصال برقره نشد؟)", "testBuildValidatedText": "نسخه معتبر است؛ لذت ببرید.!", "thankYouText": "تشکر بخاطر حمایت از ما ! از بازی لذت ببرید", "threeKillText": "نابود کردن همزمان سه نفر", + "ticketsDescriptionText": "بلیت‌ها برای بازگشایی شخصیت‌ها، نقشه‌ها، بازی‌های\nکوچک و موارد دیگر در فروشگاه به کار می‌روند. \n\nبلیت‌ها در صندوق‌هایی که از کمپین‌ها، مسابقات\nو دستاوردها برنده شده‌اید، یافت می‌شوند.", "timeBonusText": "پاداش سرعت عمل", - "timeElapsedText": "زمان سپری شده", + "timeElapsedText": "زمان گذشته", "timeExpiredText": "زمان تمام شده", - "timeSuffixDaysText": "روز ${COUNT}", - "timeSuffixHoursText": "ساعت ${COUNT}", - "timeSuffixMinutesText": "دقیقه ${COUNT}", - "timeSuffixSecondsText": "ثانیه ${COUNT}", + "timeSuffixDaysText": "ر${COUNT}", + "timeSuffixHoursText": "س${COUNT}", + "timeSuffixMinutesText": "د${COUNT}", + "timeSuffixSecondsText": "ث${COUNT}", "tipText": "نکته", "titleText": "بمب‌اسکواد", - "titleVRText": "BombSquad VR", + "titleVRText": "بمب اسکواد نسخه واقعیت‌مجازی", + "tokens": { + "getTokensText": "دریافت توکن", + "notEnoughTokensText": "توکن های شما کافی نیست !", + "numTokensText": "⁦توکن ${COUNT}", + "openNowDescriptionText": "شما به اندازه کافی نشانه دارید\nاکنون این را باز کنید - اگر نکنید\nباید صبر کرد", + "shinyNewCurrencyText": "ارز های جدید بمب اسکواد", + "tokenPack1Text": "بسته توکن کوچک", + "tokenPack2Text": "بسته توکن متوسط", + "tokenPack3Text": "بسته توکن بزرگ", + "tokenPack4Text": "بسته توکن جامبو", + "tokensDescriptionText": "توکن‌ها برای سرعت بخشیدن به باز کردن قفل صندوق و برای \n.دیگر ویژگی‌های بازی و حساب کاربری به کار می‌روند\n\nمی‌توانید توکن‌ها را در بازی برنده شوید یا آن‌ها را در بسته‌ها\nخریداری کنید. یا یک گلدپس برای توکن‌های بی‌نهایت\n.بخرید و دیگر در خرج آن‌ها مشکلی نداشته باشید", + "youHaveGoldPassText": ".شما یک گلد پس دارید\n.تمامی خریدهای توکن رایگان است\n!لذت ببرید" + }, "topFriendsText": "بالاترین امتیاز دوستان", "tournamentCheckingStateText": "چک کردن وضعیت مسابقات؛ لطفا صبر کنید", "tournamentEndedText": "این دوره از مسابقات به پایان رسیده است دوره جدیدی بزودی آغاز خواهد شد", "tournamentEntryText": "ورودیِ مسابقات", + "tournamentFinalStandingsText": "جدول رده بندی نهایی", "tournamentResultsRecentText": "آخرین نتایج مسابقات", "tournamentStandingsText": "جدول رده بندی مسابقات", "tournamentText": "جام حذفی", @@ -1388,7 +1481,7 @@ "translations": { "characterNames": { "Agent Johnson": "مامور جانسون", - "B-9000": "B-9000", + "B-9000": "بات.۹۰۰۰", "Bernard": "برنارد", "Bones": "اسکلت", "Butch": "بوچ", @@ -1408,7 +1501,7 @@ "Pixel": "پیکسل", "Sammy Slam": "سامی کشتی‌گیر", "Santa Claus": "بابا نوئل", - "Snake Shadow": "سایه ی مار", + "Snake Shadow": "سایه‌ی مار", "Spaz": "اسپاز", "Taobao Mascot": "تائوبائو", "Todd": "تاد", @@ -1418,110 +1511,123 @@ "Zola": "زولا" }, "coopLevelNames": { - "${GAME} Training": "${GAME} محل تمرین", - "Infinite ${GAME}": "بی پایان ${GAME}", + "${GAME} Training": "تمرین ${GAME}", + "Infinite ${GAME}": "${GAME} بی‌پایان", "Infinite Onslaught": "نبرد بی‌پایان", - "Infinite Runaround": "دوره بی نهایت", + "Infinite Runaround": "دور بی‌پایان", "Onslaught Training": "نبرد مبتدی", - "Pro ${GAME}": "حرفه ای ${GAME}", + "Pro ${GAME}": "${GAME} حرفه‌ای", "Pro Football": "فوتبال حرفه‌ای", - "Pro Onslaught": "حمله ی سخت", + "Pro Onslaught": "هجوم سخت", "Pro Runaround": "نگهبان خروج", "Rookie ${GAME}": "${GAME} قدرت", "Rookie Football": "مبارز فوتبال", "Rookie Onslaught": "میدان مبارزه", "The Last Stand": "آخرین مقاومت", - "Uber ${GAME}": "${GAME} بازی", - "Uber Football": "فوتبال حرفه‌ای", + "Uber ${GAME}": "${GAME} خفن", + "Uber Football": "فوتبال خفن", "Uber Onslaught": "هجوم", "Uber Runaround": "ایست بازرسی" }, + "displayItemNames": { + "${C} Tickets": "⁦بلیت ${C}", + "${C} Tokens": "⁦توکن ${C}", + "Chest": "صندوق", + "L1 Chest": "صندوق ۱", + "L2 Chest": "صندوق ۲", + "L3 Chest": "صندوق ۳", + "L4 Chest": "صندوق ۴", + "L5 Chest": "صندوق ۵", + "L6 Chest": "صندوق ۶", + "Unknown Chest": "صندوق ناشناخته" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "یکی از بهترین ها برای پیروزی در زمان بازی است.\nیکی را انتخاب کنید و از بین ببرید تا به آن تبدیل شوید.", - "Bomb as many targets as you can.": "هدف ها را با بمب بزن", - "Carry the flag for ${ARG1} seconds.": "ثانیه${ARG1}حمل و نگهداری پرچم برای", - "Carry the flag for a set length of time.": "حمل و حفاظت از پرچم برای برای یک زمان معین", - "Crush ${ARG1} of your enemies.": "بار از حریف ${ARG1} پیروز شدن", - "Defeat all enemies.": "همه ی حریف ها را شکست بده", - "Dodge the falling bombs.": "از بمب ها جاخالی بده", - "Final glorious epic slow motion battle to the death.": "نبرد در حرکت آهسته", - "Gather eggs!": "تخم مرغ ها رو جمع کن", - "Get the flag to the enemy end zone.": "بردن پرچم به منطقه پایانی حریف", - "How fast can you defeat the ninjas?": "با چه سرعتی میتونید نینجاها رو شکست بدید؟", - "Kill a set number of enemies to win.": "ازبین بردن تعدادی ازحریف ها برای بردن", - "Last one standing wins.": "آخرین کسی که موند برنده س", - "Last remaining alive wins.": "تاریخ و زمان آخرین برنده زنده باقی مانده", - "Last team standing wins.": "آخرین تیمی که می‌مونه تو بازی برنده‌س", - "Prevent enemies from reaching the exit.": "جلوگیری از خروج حریف", - "Reach the enemy flag to score.": "رسیدن به پرچم دشمن", - "Return the enemy flag to score.": "برداشتن پرچم دشمن برای امتیاز گرفتن", - "Run ${ARG1} laps.": "دور ${ARG1} حرکت", - "Run ${ARG1} laps. Your entire team has to finish.": "دور ,کل تیم ${ARG1} حرکت", - "Run 1 lap.": "یک دور", - "Run 1 lap. Your entire team has to finish.": "یک دور کل تیم به خط پایان برسند", - "Run real fast!": "!حرکت واقعا سریع", - "Score ${ARG1} goals.": "گل ${ARG1}زدن", - "Score ${ARG1} touchdowns.": "بار ${ARG1}عبور پرچم ازخط", - "Score a goal.": "گل بزنید", - "Score a touchdown.": "امتیاز پرش", - "Score some goals.": "امتیاز برخی گل ها", - "Secure all ${ARG1} flags.": "پرچم ${ARG1}مال خودکردن همه", - "Secure all flags on the map to win.": "حفاظت از تمام پرچم ها. در نقشه", - "Secure the flag for ${ARG1} seconds.": "ثانیه ${ARG1} حفاظت از پرچم برای", - "Secure the flag for a set length of time.": "حفاظت از پرچم در مدت زمان معین", - "Steal the enemy flag ${ARG1} times.": "بار ${ARG1} ربودن پرچم حریف", - "Steal the enemy flag.": "ربودن پرچم حریف", - "There can be only one.": "صاحب پرچم فقط میتونه یه نفر باشه", - "Touch the enemy flag ${ARG1} times.": "${ARG1} بار لمس پرچم دشمن", - "Touch the enemy flag.": "لمس پرچم دشمن", - "carry the flag for ${ARG1} seconds": "ثانیه${ARG1}حمل و نگهداری پرچم برای", - "kill ${ARG1} enemies": "حریف ${ARG1} ازبین بردن", - "last one standing wins": "آخرین کسی که موند برنده س", - "last team standing wins": "آخرین تیمی که می‌مونه روصحنه برنده‌س", - "return ${ARG1} flags": "پرچم ${ARG1} بدست آوردن", - "return 1 flag": "بدست آوردن 1 پرچم", - "run ${ARG1} laps": "دور ${ARG1} حرکت", - "run 1 lap": "یک دور", - "score ${ARG1} goals": "گل ${ARG1}زدن", - "score ${ARG1} touchdowns": "بار ${ARG1}عبور پرچم ازخط", + "Bomb as many targets as you can.": ".هدف‌ها را با بمب بزنید", + "Carry the flag for ${ARG1} seconds.": ".⁦ثانیه پرچم رو حمل کن ${ARG1} برای", + "Carry the flag for a set length of time.": ".برای یک زمان معین پرچم را حمل کنید", + "Crush ${ARG1} of your enemies.": "⁦.تا از دشمن‌ها رو له کن${ARG1}", + "Defeat all enemies.": ".همه‌ی دشمن‌ها را شکست بدهید", + "Dodge the falling bombs.": ".از بمب‌ها جاخالی بدهید", + "Final glorious epic slow motion battle to the death.": ".نبرد نهایی با شکوه حرکت آهسته‌ی حماسی تا پای مرگ", + "Gather eggs!": "!تخم‌مرغ‌ها را جمع کنید", + "Get the flag to the enemy end zone.": ".پرچم را به منطقه‌ی انتهایی دشمن برسانید", + "How fast can you defeat the ninjas?": "با چه سرعتی می‌توانید نینجاها را شکست دهید؟", + "Kill a set number of enemies to win.": ".تعداد معینی از دشمنان را برای برنده شدن از بین ببرید", + "Last one standing wins.": ".آخرین نفری که مونده برنده‌ست", + "Last remaining alive wins.": ".آخرین نفری که زنده می‌ماند، برنده است", + "Last team standing wins.": ".آخرین تیمی که می‌مونه برنده‌ست", + "Prevent enemies from reaching the exit.": ".از خروج دشمن جلوگیری کنید", + "Reach the enemy flag to score.": ".پرچم دشمن را برای گرفتن امتیاز لمس کنید", + "Return the enemy flag to score.": ".پرچم دشمن را بربایید تا امتیاز بگیرید", + "Run ${ARG1} laps.": ".⁦دور بدو ${ARG1}", + "Run ${ARG1} laps. Your entire team has to finish.": ".⁦دور بدو. کل تیم باید به خط پایان برسه ${ARG1}", + "Run 1 lap.": ".⁦دور بدو 1", + "Run 1 lap. Your entire team has to finish.": ".⁦دور بدو. کل تیم باید به خط پایان برسد 1", + "Run real fast!": "!تخت گاز بدوید", + "Score ${ARG1} goals.": ".تا گل بزن${ARG1}", + "Score ${ARG1} touchdowns.": ".⁦بار از خط رد کن ${ARG1} پرچم رو", + "Score a goal.": ".گل بزن", + "Score a touchdown.": ".امتیاز بگیر", + "Score some goals.": "تعدادی گل بزنید.", + "Secure all ${ARG1} flags.": ".⁦پرچم رو تصاحب کن ${ARG1} همه‌ی", + "Secure all flags on the map to win.": ".در نقشه همه‌ی پرچم‌ها را از آن خود کنید تا برنده شوید", + "Secure the flag for ${ARG1} seconds.": ".⁦ثانیه از پرچم محافظت کن ${ARG1} برای", + "Secure the flag for a set length of time.": ".برای زمان معینی از پرچم محافظت کنید", + "Steal the enemy flag ${ARG1} times.": ".⁦بار بربا ${ARG1} پرچم دشمن رو", + "Steal the enemy flag.": "پرچم دشمن را بربایید.", + "There can be only one.": ".فقط یه نفر صاحب پرچمه", + "Touch the enemy flag ${ARG1} times.": "⁦.بار لمس کن ${ARG1} پرچم دشمن رو", + "Touch the enemy flag.": ".پرچم دشمن را لمس کنید", + "carry the flag for ${ARG1} seconds": "⁦ثانیه پرچم را حمل کنید ${ARG1} برای", + "kill ${ARG1} enemies": "⁦⁦دشمن را از بین ببرید ${ARG1}", + "last one standing wins": "آخرین نفری که مانده برنده است", + "last team standing wins": "آخرین تیمی که می‌ماند برنده است", + "return ${ARG1} flags": "⁦پرچم به دست بیاورید ${ARG1}", + "return 1 flag": "⁦پرچم به دست بیاورید 1", + "run ${ARG1} laps": "⁦⁦دور بدوید ${ARG1}", + "run 1 lap": "⁦دور بدوید 1", + "score ${ARG1} goals": "⁦⁦گل بزنید ${ARG1}", + "score ${ARG1} touchdowns": "⁦بار از خط رد کنید ${ARG1} پرچم را", "score a goal": "گل بزنید", - "score a touchdown": "امتیاز یک پرش", - "secure all ${ARG1} flags": "پرچم ${ARG1}مال خودکردن همه", - "secure the flag for ${ARG1} seconds": "ثانیه ${ARG1} حفاظت از پرچم برای", - "touch ${ARG1} flags": "پرچم ${ARG1}لمس", - "touch 1 flag": "لمس 1 پرچم" + "score a touchdown": "امتیاز بگیرید", + "secure all ${ARG1} flags": "⁦پرچم را از آن خود کنید ${ARG1} همه‌ی", + "secure the flag for ${ARG1} seconds": "⁦ثانیه از پرچم محافظت کنید ${ARG1} برای", + "touch ${ARG1} flags": "⁦بار لمس کنید ${ARG1} پرچم را", + "touch 1 flag": "⁦بار لمس کنید 1 پرچم را" }, "gameNames": { "Assault": "لمس پرچم", "Capture the Flag": "تسخیر پرچم", - "Chosen One": "فرد منتخب", - "Conquest": "قدرت نمایی", + "Chosen One": "برگزیده", + "Conquest": "فتح", "Death Match": "نبرد مرگبار", - "Easter Egg Hunt": "شکار تخم‌مرغ عید پاک", + "Easter Egg Hunt": "شکار ایستر اگ", "Elimination": "استقامت", "Football": "فوتبال آمریکایی", "Hockey": "هاکی", "Keep Away": "دور نگه داشتن", "King of the Hill": "پادشاه تپه", - "Meteor Shower": "بمباران", + "Meteor Shower": "بمب‌باران", "Ninja Fight": "نبرد با نینجاها", "Onslaught": "مبارزه", - "Race": "مسابقهٔ دو", + "Race": "مسابقه‌ی دو", "Runaround": "مانع", "Target Practice": "تمرین بمب‌اندازی", "The Last Stand": "دفاع آخر" }, "inputDeviceNames": { - "Keyboard": "صفحه‌کلید", - "Keyboard P2": "p2 صفحه‌کلید" + "Keyboard": "کی‌بورد", + "Keyboard P2": "کی‌بورد ب۲" }, "languages": { "Arabic": "عربی", "Belarussian": "بلاروسی", - "Chinese": "چینی ساده شده", - "ChineseTraditional": "چینی سنتی", + "Chinese": "چینی - ساده شده", + "ChineseSimplified": "چینی - ساده شده", + "ChineseTraditional": "چینی - سنتی", "Croatian": "کرواتی", - "Czech": "چک", + "Czech": "چکی", "Danish": "دانمارکی", "Dutch": "هلندی", "English": "انگلیسی", @@ -1534,19 +1640,24 @@ "Greek": "یونانی", "Hindi": "هندی", "Hungarian": "مجارستانی", - "Indonesian": "اندونزی", + "Indonesian": "اندونزیایی", "Italian": "ایتالیایی", "Japanese": "ژاپنی", "Korean": "کره‌ای", "Malay": "مالایی", - "Persian": "فارسی‎", + "Persian": "⁦فارسی‎", + "PirateSpeak": "سومالیایی", "Polish": "لهستانی", "Portuguese": "پرتغالی", + "PortugueseBrazil": "پرتغالی - برزیل", + "PortuguesePortugal": "Portuguese - Portugal", "Romanian": "رومانیایی", "Russian": "روسی", "Serbian": "صربستانی", - "Slovak": "اسلواک", + "Slovak": "اسلواکی", "Spanish": "اسپانیایی", + "SpanishLatinAmerica": "اسپانیایی - آمریکای لاتین", + "SpanishSpain": "اسپانیایی - اسپانیا", "Swedish": "سوئدی", "Tamil": "تامیلی", "Thai": "تایلندی", @@ -1562,26 +1673,26 @@ "Silver": "نقره" }, "mapsNames": { - "Big G": "بزرگ G", - "Bridgit": "بریدگیت", + "Big G": "⁦بزرگ⁦ G", + "Bridgit": "پل میانی", "Courtyard": "حیاط", "Crag Castle": "قلعه پرتگاه", "Doom Shroom": "رستاخیز", "Football Stadium": "استادیوم فوتبال", - "Happy Thoughts": "پرواز", + "Happy Thoughts": "رویای شیرین", "Hockey Stadium": "استادیوم هاکی", - "Lake Frigid": "یخبندان", + "Lake Frigid": "دریاچه‌ی یخ‌زده", "Monkey Face": "صورت میمون", "Rampage": "خشم", - "Roundabout": "میدان", + "Roundabout": "میدان نبرد", "Step Right Up": "پایدار", "The Pad": "رینگ", "Tip Top": "تیپ تاپ", - "Tower D": "برج دی", - "Zigzag": "زیگ زاگ" + "Tower D": "⁦برج D", + "Zigzag": "زیگ‌زاگ" }, "playlistNames": { - "Just Epic": "فقط حرکت آهسته", + "Just Epic": "فقط حماسی", "Just Sports": "فقط ورزشی" }, "scoreNames": { @@ -1599,42 +1710,49 @@ "Account unlinking successful!": "قطع شدن حساب با موفقیت انجام شد", "Accounts are already linked.": "حساب‌ها قبلا مرتبط شده‌اند", "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "نمای آگهی تأیید نمی شود\nلطفا مطمئن باشید که نسخه رسمی و به روز بازی را اجرا می کنید", - "An error has occurred; (${ERROR})": "متاسفانه یک مشکل رخ داده ؛ (${ERROR})", + "An error has occurred; (${ERROR})": "(${ERROR}) متاسفانه مشکلی رخ داده؛", "An error has occurred; please contact support. (${ERROR})": "یک مشکل رخ داده! لطفا با پشتیبانی تماس بگیرید؛ (${ERROR})", - "An error has occurred; please contact support@froemling.net.": ".تماس بگیرید support@froemling.net خطایی رخ داده است. لطفاً با", + "An error has occurred; please contact support@froemling.net.": ".ای‌میل بزنید support@froemling.net خطایی رخ داده است. لطفن به", "An error has occurred; please try again later.": ".خطایی رخ داده است. لطفاً بعداً تلاش کنید", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "آیا مطمئن هستید که می‌خواهید این حساب‌ها را به هم متصل کنید؟\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n!این کار برگشت‌پذیر نیست", "BombSquad Pro unlocked!": "!نسخهٔ حرفه‌ای باز شد", "Can't link 2 accounts of this type.": ".نمی‌توان دو حساب از این نوع را پیوند داد", "Can't link 2 diamond league accounts.": "نمی‌توان حساب دو لیگ الماس را پیوند داد.", "Can't link; would surpass maximum of ${COUNT} linked accounts.": "پیوند نمی‌شود; حداکثر از ${COUNT} پیوند پشتیبانی می‌شود.", - "Cheating detected; scores and prizes suspended for ${COUNT} days.": "تقلب تشخیص داده شد; امتیازات و جوایز برای ${COUNT} روز تعلیق شد.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "⁦.روز تعلیق شد ${COUNT} تقلب شناسایی شد؛ امتیازها و جایزه‌ها برای", "Could not establish a secure connection.": "نمیتوان یک اتصال امن ایجاد کرد", - "Daily maximum reached.": "به حداکثر روزانه رسیده است", - "Entering tournament...": "ورود به مسابقات ...", + "Daily maximum reached.": "به حداکثر ارقام روزانه رسیدید", + "Daily sign-in reward": "پاداش ورود روزانه", + "Entering tournament...": "ورود به مسابقات...", + "Higher streaks lead to better rewards.": "رگه های بالاتر منجر به پاداش بهتر می شود.", "Invalid code.": "کد نامعتبر", - "Invalid payment; purchase canceled.": "پرداخت با خطا مواجه شد؛ خرید لغو شد", - "Invalid promo code.": "کد نامعتبر است.", + "Invalid payment; purchase canceled.": "پرداخت نامعتبر؛ خرید لغو شد.", + "Invalid promo code.": "کد دعوتی نامعتبر است.", "Invalid purchase.": "خرید نا معتبر", "Invalid tournament entry; score will be ignored.": "ورود مسابقات نامعتبر است؛ نمره نادیده گرفته می شود.", "Item unlocked!": "!مورد باز شد", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "پیوند کردن ممنوع شد ${ACCOUNT} شامل\nداده های قابل توجهی که می توانند از دست بدهند.\nشما می توانید در صورت مخالفت پیوست کنید اگر دوست دارید\n(و در عوض داده های این حساب را از دست می دهید)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "را به این حساب پیوند دهید؟ ${ACCOUNT} آیا مایلید که حساب کاربری \n.از بین خواهد رفت ${ACCOUNT} تمام اطلاعات روی حساب\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", + "Longer streaks lead to better rewards.": "دوره‌های طولانی‌تر ورود روزانه به بازی منجر به پاداش‌های بهتر می‌شود.", "Max number of playlists reached.": "تعداد بازی ها به حداکثر رسیده است", "Max number of profiles reached.": ".تعداد نمایه‌ها به حداکثر رسیده است", "Maximum friend code rewards reached.": ".حداکثر جایزه کد ارسالی برای دوستان دریافت شد", "Message is too long.": "پیام خیلی طولانی است", + "New tournament result!": "نتیجه مسابقات جدید!", "No servers are available. Please try again soon.": "هیچ سروری در دسترس نیست. لطفا به زودی دوباره امتحان کنید", + "No slots available. Free a slot and try again.": "محل صندوقی موجود نیست. یک محل صندوق ی آزاد کنید و دوباره امتحان کنید.", "Profile \"${NAME}\" upgraded successfully.": ".با موفقیت ارتقا یافت «${NAME}» نمایهٔ", "Profile could not be upgraded.": ".نمایه نمی‌تواند ارتقا یابد", "Purchase successful!": "خرید با موفقیت انجام شد", - "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "بدست آمده ${COUNT} بلیت برای ورود به سیستم.\nفردا برگرد برای دریافت ${TOMORROW_COUNT}.", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": ".تا بلیت برای ورود به برنامه دریافت کردی${COUNT}\n.تا دوباره سر بزن${TOMORROW_COUNT} فردا برای دریافت", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "این نسخه از بازی دیگر توسط سرور پشتیبانی نمی شود.\nلطفا از جدید ترین نسخه بازی استفاده کنید.", "Sorry, there are no uses remaining on this code.": "با عرض پوزش, این کد دیگر کاربرد ندارد", "Sorry, this code has already been used.": "با عرض پوزش، این کد قبلا استفاده شده است.", "Sorry, this code has expired.": "متاسفانه این کد منقضی شده", "Sorry, this code only works for new accounts.": "با عرض وزش پوزش, این کد فقط برا حساب کاربری جدید کاربرد داره", + "Sorry, this has expired.": "متاسفانه درخواست منقضی شده.", "Still searching for nearby servers; please try again soon.": "هنوز سرورهای اطراف را جستجو می کنید. لطفا به زودی دوباره امتحان کنید", + "Streak: ${NUM} days": "‎روز ${NUM} دوره‌ی ورود روزانه:", "Temporarily unavailable; please try again later.": "در حال حاضر این گذینه موجود نمی باشد؛لطفا بعدا امتحان کنید", "The tournament ended before you finished.": "مسابقات به پایان رسید قبل از اینکه شما به پایان برسید.", "This account cannot be unlinked for ${NUM} days.": "این حساب برای مدت ${NUM} روز قابل جداسازی نیست!", @@ -1645,19 +1763,28 @@ "Tournaments require ${VERSION} or newer": "تورنومنت ها به${VERSION}جدید تر یا حرفه ای نیاز دارند", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "آیا مایلبد حساب ${ACCOUNT} را از حساب خودتان جداسازی کنید؟\nتمام اطلاعات حساب ${ACCOUNT} بازنویسی خواهد شد.\n(به جز بعضی از افتخارات کسب شده)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "اخطار: شکایت هایی مبنی بر استفاده شما از ابزار های تقلب به دست ما رسیده!\nدر صورت تکرار حساب کاربری شما مسدود خواهد شد! لطفا جوانمردانه بازی کنید.", + "Wait reduced!": "انتظار کاهش یافت", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "هشدار: این نسخه از بازی به داده های حساب قدیمی محدود شده است. ممکن است چیزهایی گم شده یا قدیمی به نظر برسند\nلطفا برای مشاهده آخرین اطلاعات حساب خود به نسخه جدیدتر بازی ارتقا دهید", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "می‌خواهید دستگاه‌تون رو به این دستگاه متصل کنید؟\n\nحساب دستگاهی شما ${ACCOUNT1}\nاین حساب ${ACCOUNT2}\n\nاین مشکلی توی سیو و پیشرفت شما ایجاد نمیکنه.\nاخطار: بعدا نمی‌تونید پشیمون بشید!", "You already own this!": "قبلا اینو گرفتی", - "You can join in ${COUNT} seconds.": ".ثانیه ${COUNT} شما میتوانید متصل شوید در", + "You can join in ${COUNT} seconds.": ".‎ثانیه‌ی دیگر می‌توانید بپیوندید ${COUNT} تا", "You don't have enough tickets for this!": "شما بلیط کافی برای این ندارید", "You don't own that.": ".اون مال شما نیست", "You got ${COUNT} tickets!": "! تا بلیط گرفتی ${COUNT}", + "You got ${COUNT} tokens!": "!تا توکن گرفتی ${COUNT}", "You got a ${ITEM}!": "! گرفتی ${ITEM} یه دونه", + "You got a chest!": "!یه صندوق گرفتی", + "You got an achievement reward!": "!یه پاداش دستاورد گرفتی", "You have been promoted to a new league; congratulations!": "شما به یک لیگ جدید ارتقا داده‌اید؛ تبریک می‌گوییم!", + "You lost a chest! (All your chest slots were full)": "یک صندوق از دست دادی! (همه محل های صندوق شما پر بود)", + "You must update the app to view this.": "برای دیدن این بخش باید بازی را بروزرسانی کنید", "You must update to a newer version of the app to do this.": "برای انجام این کار شما باید بازی را به روز رسانی کنید", "You must update to the newest version of the game to do this.": "برای انجام این کار باید از آخرین نسخه بازی استفاده کنید.", "You must wait a few seconds before entering a new code.": "شما باید چند ثانیه قبل از وارد کردن یک کد جدید صبر کنید.", + "You placed #${RANK} in a tournament!": "شما #${RANK} را در یک تورنمنت قرار دادید!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "! شدید . ممنون که شرکت کردید ${RANK} شما در آخرین مسابقه رتبه ی", "Your account was rejected. Are you signed in?": "حساب شما رد شده است. آیا وارد حساب خود شده اید؟", + "Your ad views are not registering. Ad options will be limited for a while.": "بازدیدهای تبلیغاتی شما ثبت نمی شود. گزینه های تبلیغاتی برای مدتی محدود خواهد بود.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "نسخه بازی شما دستکاری شده است.\nلطفا تغییرات رو به حالت اول برگردونید و دوباره امتحان کنید.", "Your friend code was used by ${ACCOUNT}": "کد دوست شما استفاده شده توسط ${ACCOUNT}" }, @@ -1675,56 +1802,56 @@ "Balance Total Lives": "مجموعِ جانِ باقيمانده", "Bomb Spawning": "بازسازی بمب", "Chosen One Gets Gloves": "دستکش بکس برای مالک پرچم", - "Chosen One Gets Shield": "قرار دادن سپر برای مالک پرچم", + "Chosen One Gets Shield": "دادن سپر به مالک پرچم", "Chosen One Time": "انتخاب زمان", "Enable Impact Bombs": "فعالسازی تاثیر بمب ها", "Enable Triple Bombs": "فعال کردن بمب سه گانه", "Entire Team Must Finish": "کل تیم باید نابود بشن", "Epic Mode": "حرکت آهسته", - "Flag Idle Return Time": "پرچم زمان بازگشت بیدرنگ", + "Flag Idle Return Time": "زمان بازگشت پرچم رهاشده", "Flag Touch Return Time": "زمان بازگشت لمس پرچم", "Hold Time": "زمان نگه داشتن", - "Kills to Win Per Player": "هرکی بیشتر نابود کنه", - "Laps": "دور ها", + "Kills to Win Per Player": "تعداد کشته برای پیروز شدن", + "Laps": "دورها", "Lives Per Player": "تعداد جان برای بازیکن", "Long": "طولانی", "Longer": "خیلی طولانی", - "Mine Spawning": "مین گذاری", + "Mine Spawning": "کاشت مین", "No Mines": "بدون مین", "None": "هيچ", "Normal": "معمولی", "Pro Mode": "حالت حرفه ای", - "Respawn Times": "زمان برگشت بازیکن مرده", - "Score to Win": "امتیاز بگیر تا برنده شی", + "Respawn Times": "زمان دوباره زنده شدن", + "Score to Win": "تعداد امتیاز برای برنده شدن", "Short": "کوتاه", - "Shorter": "کوتاه تر", - "Solo Mode": "حالت انفرادی", + "Shorter": "خیلی کوتاه", + "Solo Mode": "حالت تکی", "Target Count": "تعداد هدف", "Time Limit": "محدودیت زمانی" }, "statements": { - "${TEAM} is disqualified because ${PLAYER} left": "بازی‌رو ترک کرد ${PLAYER} ردصلاحیت شد چون ${TEAM}", - "Killing ${NAME} for skipping part of the track!": "! از بین رفت چون جِرزنی کرد ${NAME}", - "Warning to ${NAME}: turbo / button-spamming knocks you out.": "هشدار به ${NAME}: توربو/اسپم دادن شما را مسدود میکند" + "${TEAM} is disqualified because ${PLAYER} left": "⁦بازی را ترک کرد ⁦${PLAYER}⁦ ⁦رد صلاحیت شد چون ⁦${TEAM}⁦", + "Killing ${NAME} for skipping part of the track!": "!⁦به‌خاطر جرزنی از بین رفت ⁦${NAME}⁦", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": ".⁦توربو/اسپم دادن شما را مسدود می‌کند :⁦${NAME}⁦ هشدار به" }, "teamNames": { - "Bad Guys": "تیم حریف", + "Bad Guys": "آدم بد ها", "Blue": "آبی", - "Good Guys": "تیم خودی", + "Good Guys": "آدم خوب ها", "Red": "قرمز" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "یه مشت جهشی پرشی چرخشی با زمان بندی درست ، با یه ضربه حریف رو نابود میکنه\n! از این حرکتا بزن بعدش برا دوستات تعریف کن", - "Always remember to floss.": "حرفه‌ای باش، بَرنده باش..", - "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "برای خودت و دوستات نمایه بساز تا مجبور نشی\n.از «بازیکنان تصادفی» خودِ بازی استفاده کنی", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "یه مشت جهشی-پرشی-چرخشی با زمان بندی درست، با یه ضربه حریف رو نابود میکنه\nاز این حرکتا بزن بعدش برا دوستات تعریف کن", + "Always remember to floss.": "...حرفه ای باش، برنده باش", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "برای خودت و دوستات پروفایل بساز تا مجبور نشی\n.از اسم های شانسی خودِ بازی استفاده کنی", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "جعبه ی مرگ تو رو تبدیل به یه بمب ساعتی می کنه\nاگه می خوای زنده بمونی باید سریع یه جعبه درمان بگیری", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "تمام کارکتر های بازی دارای توانایی های یکسانی هستند بنابراین شما فقط کافیه\nنزدیکترین کارکتر به شخصیت خودتون رو انتخاب و پیکربندی کنید", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "فکر میکنی با گرفتن ضد ضربه شکست ناپذیر میشی ؟ اگه از زمین پرت بشی پایین چی ؟", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "فکر میکنی با گرفتن شیلد شکست ناپذیر میشی ؟ اگه از زمین پرت بشی پایین چی ؟", "Don't run all the time. Really. You will fall off cliffs.": "تمام وقت درطول بازی با سرعت حرکت نکنید ممکنه از صخره پرت بشید", "Don't spin for too long; you'll become dizzy and fall.": "زیاد به دور خودت نچرخ؛ سرگیجه می‌گیری و می‌افتی.", "Hold any button to run. (Trigger buttons work well if you have them)": "هر دکمه رو با زدن روش کار میکنه همه دکمه ها بدرستی کار میکنه اگه صحیح زده بشن", "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "موقع حرکت یه دکمه رو همزمان نگهدار مثلا مشت رو تا سرعت حرکت بیشتر شه\nاما توی سرعت زیاد مراقب پایین افتادن از صخره باش", - "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "بمب های یخی برا نابودی خیلی قدرتمند نیستن ولی نزدیک هر کی منفجر بشه منجمد میشه \n اگه نمیخواید منجمد و آسیب پذیر بشوید نزدیک این بمب ها نمونید", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "بمب های یخی برا نابودی خیلی قدرتمند نیستن ولی نزدیک هر کی منفجر بشه منجمد میشه \n اگه نمیخواید منجمد و آسیب پذیر بشید نزدیک این بمب ها نمونید", "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "اگه کسی شما رو از زمین بلند کرد با مشت و پرش و کشیدن اجازه \nحرکت بهش ندید تا رها بشید", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "اگر روی کنترلرها کوتاه هستید، برنامه '${REMOTE_APP_NAME}' را نصب کنید\nبر روی دستگاه های تلفن همراه خود را میتوان به عنوان کنترلر استفاده کنید.", "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "اگر بمب چسبنده ای به شما چسبید به اطراف بپرید و بچرخید\n😅کار دیگری از شما بر نمی‌آید", @@ -1732,7 +1859,7 @@ "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "اگه یه جعبه نابودگر رو به اشتباه گرفتین کارتون تمومه مگه اینکه ظرف چند\nثانیه یه جعبه ی درمان گیر بیارید", "If you stay in one place, you're toast. Run and dodge to survive..": "اگه فقط توی یه مکان ثابت بمونید کباب میشید پس بهتره مرتب توی زمین تحرک داشته باشی", "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "اگر تعداد زیادی از بازیکنان در حال رفت و آمد هستند، بازیکنان \"بیروت انداختن بازیکنان غیرفعال\" را روشن کنید\nتحت تنظیمات در صورتی که کسی فراموش می‌کندپیش از خروج از بازی ترک بازی را بزند.", - "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "اگر دستگاه شما بیش از حد گرم می شود یا شما می خواهید برای حفظ قدرت باتری،\nکم کنید \"کیفیت\" یا \"وضوح تصویر\" رو در تنظیمات> گرافیک", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "اگر دستگاه شما بیش از حد گرم می شود یا شما می خواهید برای حفظ قدرت باتری،\n\"کیفیت\" یا \"وضوح تصویر\" رو در تنظیمات> گرافیک\nکم کنید", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "اگر دیدید که نرخ فریم تصویر کمی متلاطم است کاهش بدید رزولوشن \nیا کیفیت تصویر رو در تنظیمات گرافیک بازی", "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "توی بازی رساندن پرچم ، باید پرچم تیم شما همون جا باقی بمونه\nاگه تیم حریف پرچم تیم شما رو برداشت باید از دستش کش بری", "In hockey, you'll maintain more speed if you turn gradually.": "روی زمین های یخی ، یه دفعه چرخیدن خیلی از سرعت بازیکن کم میکنه", @@ -1757,7 +1884,7 @@ "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "شما می تونید مشت های خودتون رو به جهت مشخصی وارد کنید با چرخیدن به چپ و راست\nاین کار برای پرت کردن دشمنان از لبه ی زمین به پایین یا امتیاز گرفت در هاکی موثره", "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "با دیدن رنگ جرقه ی بمب میشه فهمید چه موقع منفجر میشه\n!!!! زرد ... نارنجی ... قرمز ... بوم", "You can throw bombs higher if you jump just before throwing.": "شما می‌تونید بمب‌هاتون رو دورتر پرتاب کنید اگه همزمان با یه پرش به موقع باشه", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "شما آسیب می بینید زمانی که سرتون به چیزی برخورد میکنه پس بیشر احتیاط کنید\nزمانی هم که چیزی به سمتتون پرتاب میشه", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "اگه سرت به جایی برخورد کنه آسیب میبینی،\n .پس سعی کن سرت به جایی نخوره", "Your punches do much more damage if you are running or spinning.": "مشت هاتون موثر تر خواهند بود اگر هنگام حرکت سریع و یا چرخش وارد بشن" } }, @@ -1767,79 +1894,86 @@ "tutorial": { "cpuBenchmarkText": "آموزش اجرای بهتر بازی در بدترین وضعیت سرعت بازی در درجه اول تست سرعت پردازنده", "phrase01Text": "!سلام جیگر", - "phrase02Text": "! خوش آمدی ${APP_NAME} به", - "phrase03Text": ". قبل از شروع ، یک سری آموزش ها هست که باید ببینی", - "phrase04Text": "متکی به اعمال فیزیکی اند ${APP_NAME} چیزای زیادی در", - "phrase05Text": "... مثلا وقتی با مشت میفتی به جون یه نفر", - "phrase06Text": "! این جوری حتی خون از دماغش نمیاد", - "phrase07Text": "... چجوری برات دلقک بازی در میاره ${NAME} نگاه کن", - "phrase08Text": ".باید حالشو بگیری ! پرش و چرخش قدرت مشت رو بیشتر می کنه", - "phrase09Text": "! آهان ! حالا شد", - "phrase10Text": ".دویدن هم موثره", - "phrase11Text": "برای دویدن باید یه دکمه ی دلخواه رو فشار بدی و نگه داری", - "phrase12Text": "! دویدن و چرخیدن باعث میشه که فکش بیاد پایین", - "phrase13Text": "اومد پایین ؟ ${NAME} دیدی چطوری فک", - "phrase14Text": "${NAME} خیلی چیزها رو میشه بلند کرد و پرت کرد . یعنی پرچم یا بازیکنهای دیگه مثل", - "phrase15Text": "! حالا وقت بمبارون کردنه", - "phrase16Text": "بمب انداختن یه کم تمرین لازم داره", - "phrase17Text": "این چه طرز بمب انداختنه ؟", - "phrase18Text": "اگه حرکت کنی بمب دورتر پرت میشه", - "phrase19Text": "اگه بپری بمب بیشتر پرت میشه", - "phrase20Text": "! اگه به صورت شلاقی بمب پرت کنی که دیگه هیچی ... نمی دونی تا کجا میره", - "phrase21Text": "این که چه موقع پرتش کنی خیلی مهمه", - "phrase22Text": "!!! بوم", - "phrase23Text": "قبل از انداختن بمب یه کم نگهش دار ... تا به محض این که به هدف رسید بترکه", - "phrase24Text": "باریکلا ! به این میگن انفجار", - "phrase25Text": "دیدی اصلا سخت نبود ؟", - "phrase26Text": "حالا دیگه مثل یه ببر قوی شدی", - "phrase27Text": "این آموزش ها رو به یاد داشته باش، و مطمئن باش که زنده برمی‌گردی!", - "phrase28Text": "! ببینم چند مرده حلاجی پهلوون", - "phrase29Text": "! خدا قوت", - "randomName1Text": "فرد", - "randomName2Text": "هری", - "randomName3Text": "بیل", - "randomName4Text": "چاک", - "randomName5Text": "فیل", - "skipConfirmText": ".واقعا از آموزش رد می‌شی ؟ هر کلیدی رو بزن تا رد بشیم", + "phrase02Text": "به ${APP_NAME} خوش اومدی!", + "phrase03Text": "چندتا آموزش واسه کنترل بازیکنت آوردم:", + "phrase04Text": "بیشتر چیزها توی ${APP_NAME} بر پایه‌ی فیزیک هستن.", + "phrase05Text": "...مثلا وقتی که مشت می‌زنی", + "phrase06Text": "…هر چی سرعت حرکتت بیشتر باشه، ضربه‌ت قوی‌تره.", + "phrase07Text": "می‌بینی؟ چون ثابت وایسادی ضربه‌ت به ${NAME} زیاد آسیب نمی‌رسونه.", + "phrase08Text": ".باید حالشو بگیری! حالا باید بپری و بچرخی تا سرعت بگیری", + "phrase09Text": ".آهان، حالا بهتر شد", + "phrase10Text": ".دویدن هم کارسازه", + "phrase11Text": "برای دویدن یه دکمه رو نگه دار و حرکت کن.", + "phrase12Text": "اگه می‌خوای یه مشت خفن بزنی که فکش بیاد پایین، باید بدویی و بچرخی.", + "phrase13Text": "اوخ! بابت اینکه فکت اومد پایین ببخشید ${NAME} جان.", + "phrase14Text": "خیلی چیزها رو می‌شه برداشت و پرتاب کرد. مثل پرچم... یا ${NAME}", + "phrase15Text": "نوبتیم باشه، نوبت بمب‌هاست.", + "phrase16Text": "بمب انداختن یه کم تمرین لازم داره.", + "phrase17Text": "اوخ اوخ! اصلا پرتاب خوبی نبود.", + "phrase18Text": "حرکت کردن باعث می‌شه تا بتونی دورتر پرتاب کنی.", + "phrase19Text": "پریدن باعث می‌شه تا بمب بیشتر ارتفاع بگیره.", + "phrase20Text": "اگه موقع پرتاب بچرخی که بیشتر پرت می‌شه ولی ممکنه ندونی کجا فرود میاد.", + "phrase21Text": "زمان‌بندی برای پرتاب بمب می‌تونه چالشی باشه.", + "phrase22Text": "لعنتی.", + "phrase23Text": "قبل از انداختن بمب یکم صبر کن تا فیتیله‌ش بسوزه و بعد پرتابش کن.", + "phrase24Text": "هورا! کتلت شد.", + "phrase25Text": "خب، این هم از این.", + "phrase26Text": "حالا مثل یه ببر همه رو نابود کن.", + "phrase27Text": "این آموزش‌ها رو به یاد داشته باش، و مطمئن باش که زنده برمی‌گردی!", + "phrase28Text": "…خب، شاید زنده برگردی…", + "phrase29Text": "به هر حال موفق باشی!", + "randomName1Text": "فریدون", + "randomName2Text": "حشمت", + "randomName3Text": "برزو", + "randomName4Text": "جلال", + "randomName5Text": "سیروس", + "skipConfirmText": ".واقعا میخوای از آموزش رد بشی؟ هر کلیدی رو بزن تا رد بشیم", "skipVoteCountText": "نفر خواستار رد شدن از آموزش هستند ${TOTAL} نفر از ${COUNT}", - "skippingText": "از آموزش می گذریم", - "toSkipPressAnythingText": "هر کلیدی را بزنید تا از آموزش خارج شوید" + "skippingText": "رد شدن از آموزش...", + "toSkipPressAnythingText": "(برای رد شدن از آموزش می‌تونید روی هر چیزی بزنید)" }, - "twoKillText": "نابودی دونفر همزمان", - "unavailableText": "چیزی در دسترس نیست", - "unconfiguredControllerDetectedText": ":کنترول پیکربندی نشده شناسایی شد", + "twoKillText": "دو نفرو با هم کشتی!", + "uiScaleText": "UI مقیاس", + "unavailableText": "در دسترس نیست", + "unclaimedPrizesText": "شما جایزه های بی ادعایی دارید", + "unconfiguredControllerDetectedText": ":کنترلر پیکربندی نشده شناسایی شد", "unlockThisInTheStoreText": ". این مورد باید در فروشگاه باز شود", - "unlockThisProfilesText": "برای ایجاد بیش از ${NUM} پروفال٫ احتیاج به این موارد دارید:", + "unlockThisProfilesText": "برای ایجاد بیش از ${NUM} پروفایل٫ احتیاج به این موارد دارید:", "unlockThisText": ": برا باز کردن قفل این شما نیاز دارید که", - "unsupportedHardwareText": "با عرض پوزش، این سخت افزار توسط این ساخت بازی پشتیبانی نمی شود.", - "upFirstText": "برای بار اول :", - "upNextText": "${COUNT} بعدی در بازی", + "unsupportedControllerText": "متاسفانه کنترلر \"${NAME}\" پشتیبانی نمی‌شود.", + "unsupportedHardwareText": "با عرض پوزش، این سخت افزار توسط این بازی پشتیبانی نمی شود.", + "upFirstText": "⁦بازی اول⁦:", + "upNextText": "⁦${COUNT} ⁦در ادامه در بازی⁦:", "updatingAccountText": "... در حال به‌روزرسانی حساب", "upgradeText": "ارتقا", - "upgradeToPlayText": "بازی را خریداری کنید تا این گزینه فعال شود ${PRO} نسخه ی", + "upgradeToPlayText": "بازی را از فروشگاه خریداری کنید تا این قابلیت فعال شود. ${PRO} نسخه ی", "useDefaultText": "استفاده از پیش فرض", + "userSystemScriptsCreateText": "ایجاد اسکریپت‌های سیستمی کاربر", + "userSystemScriptsDeleteText": "حذف اسکریپت‌های سیستمی کاربر", "usesExternalControllerText": "این بازی از یک کنترلر خارجی برای ورودی استفاده می کند.", - "usingItunesText": "استفاده از برنامه ی موسیقی برای موسیقی متن", + "usingItunesText": "استفاده از برنامه ی موسیقی برای موسیقی متن...", "usingItunesTurnRepeatAndShuffleOnText": "مطمین شید که شافل روشن است و تکرار کنید همه رو در آیتونز", "v2AccountLinkingInfoText": "برای پیوند دادن حساب‌های V2، از دکمه «مدیریت حساب» استفاده کنید.", + "v2AccountRequiredText": "این به یک حساب V2 نیاز داره !. حسابتو ارتقا بده دوباره امتحان کن.", "validatingTestBuildText": "... در حال بررسی حالت آزمایشی", - "victoryText": "! برنده شدی", - "voteDelayText": ".ثانیه رای گیری کنید ${NUMBER} شما نمیتوانید به مدت", - "voteInProgressText": ".یک رای گیری در حال انجام است", - "votedAlreadyText": ".شما رای داده اید", - "votesNeededText": ".رای نیاز است ${NUMBER}", - "vsText": "علیه", - "waitingForHostText": "ادامه بدهد ${HOST} صبر می کنیم تا", + "viaText": "از طریق", + "victoryText": "پیروز شدی!", + "voteDelayText": ".ثانیه رای گیری کنی ${NUMBER} نمیتونی به مدت", + "voteInProgressText": "یه رای گیری داره انجام میشه.", + "votedAlreadyText": "تو که رای دادی.", + "votesNeededText": ".رای لازمه ${NUMBER}", + "vsText": "در برابر", + "waitingForHostText": "( ادامه بده ${HOST} صبر کن تا)", "waitingForPlayersText": "...انتظار برای پیوستن بازیکنان", - "waitingInLineText": "در صف انتظار(پارتی تکمیل است) ...", + "waitingInLineText": "در صف انتظار (پارتی تکمیل است) ...", "watchAVideoText": "یک ویدئو ببینید", - "watchAnAdText": "تبلیغ ببین", + "watchAnAdText": "یه تبلیغ ببینید", "watchWindow": { "deleteConfirmText": "حذف شود؟\"${REPLAY}\"", "deleteReplayButtonText": "حذف\nبازبخش", - "myReplaysText": "بازی‌های ضبط‌شدهٔ من", + "myReplaysText": "بازی‌های ضبط‌شده‌ی من", "noReplaySelectedErrorText": "بازپخشی انتخاب نشده", - "playbackSpeedText": "سرعت باز پخش:${SPEED}", + "playbackSpeedText": "${SPEED} :سرعت پخش", "renameReplayButtonText": "تغییرنام\nبازبخش", "renameReplayText": ":به \"${REPLAY}\"تغییر نام", "renameText": "تغییر نام", @@ -1856,7 +1990,7 @@ "wellSureText": "! حتما", "whatIsThisText": "این چیه؟", "wiimoteLicenseWindow": { - "titleText": "DarwiinRemote Copyright" + "titleText": "کشیدن حق برداشت کنترلر" }, "wiimoteListenWindow": { "listeningText": "گوش دادن به Wiimotes ...", @@ -1868,18 +2002,18 @@ "listenText": "گوش بده", "macInstructionsText": "اطمینان حاصل کنید که رشته خود خاموش است و بلوتوث را فعال کنید\nدر مک خود را، و سپس دکمه \"گوش دهید\". پشتیبانی Wiimote می توانید\nیک کمی پوسته پوسته، بنابراین شما ممکن است باید سعی کنید چند بار\nقبل از شما یک اتصال.\nبلوتوث باید به 7 دستگاه های متصل رسیدگی کردن،\nهر چند مسافت پیموده شده شما ممکن است متفاوت باشد.\n\nBombSquad پشتیبانی از Wiimotes اصلی، Nunchuks،\nو کنترل کلاسیک.\nجدیدتر رشته از راه دور علاوه در حال حاضر بیش از حد کار\nاما با فایل پیوست است.", "thanksText": "تشکر از تیم ناظر\nبرای ایجاد این امکان", - "titleText": "Wiimote Setup" + "titleText": "راه اندازی ویم‌اوت" }, - "winsPlayerText": "${NAME} برنده شد", - "winsTeamText": "${NAME} برنده شد", - "winsText": "${NAME} برنده شد", + "winsPlayerText": "!⁦برنده شد ⁦⁦${NAME}⁦⁦", + "winsTeamText": "!⁦برنده شد ⁦⁦${NAME}⁦⁦", + "winsText": "!⁦برنده شد ⁦⁦${NAME}⁦⁦", "workspaceSyncErrorText": "خطا در همگام‌سازی ${WORKSPACE}. برای جزئیات به لاگ مراجعه کنید.", "workspaceSyncReuseText": "نمی‌توان ${WORKSPACE} را همگام‌سازی کرد. استفادهٔ مجدد از نسخهٔ همگام‌سازی‌شده قبلی.", "worldScoresUnavailableText": "امتیاز های جهانی قابل دسترس نیستند.", "worldsBestScoresText": "بهترین امتیازهای جهانی", "worldsBestTimesText": "بهترین زمان های جهانی", "xbox360ControllersWindow": { - "getDriverText": "درایور", + "getDriverText": "دریافت درایور", "macInstructions2Text": "برای استفاده از کنترلرها به صورت بی سیم، شما همچنین باید گیرنده را دریافت کنید\nXbox 360 Wireless Controller for Windows می آید.\nیک گیرنده به شما اجازه می دهد تا تا 4 کنترل کننده را وصل کنید.\n\nمهم: گیرنده های شخص ثالث با این راننده کار نخواهند کرد؛\nاطمینان حاصل کنید که گیرنده شما \"مایکروسافت\" را در آن می گوید، نه \"XBOX 360\".\nمایکروسافت این را به طور جداگانه به فروش نمی رساند، بنابراین شما باید آن را دریافت کنید\nیک همراه با کنترلر و یا دیگری جستجو بی.\n\nاگر این مفید را پیدا کنید، لطفا کمک مالی به آن بدهید\nتوسعه دهنده راننده در سایت خود.", "macInstructionsText": "برای استفاده از کنترلر Xbox 360، باید نصب کنید\nدرایور Mac موجود در لینک زیر است.\nبا کنترلر های سیمی و بی سیم کار می کند.", "macInstructionsTextScale": 0.8, @@ -1887,6 +2021,7 @@ "titleText": "${APP_NAME}:استفاده از کنترولر های ایکس باکس با" }, "yesAllowText": "!بله, اجازه داده میشود", - "yourBestScoresText": "بهترین امتیاز شما", - "yourBestTimesText": "بهترین زمان شما" + "yourBestScoresText": "بهترین امتیازات شما", + "yourBestTimesText": "بهترین زمان شما", + "yourPrizeText": ":جایزه شما" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/piratespeak.json b/dist/ba_data/data/languages/piratespeak.json new file mode 100644 index 00000000..dd7d5acf --- /dev/null +++ b/dist/ba_data/data/languages/piratespeak.json @@ -0,0 +1,2015 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Arrrcount nammes carrnnot containn Peter Pan faces orrr otherrr special charraracters.", + "accountProfileText": "(ARRRccount Prrrofile)", + "accountsText": "Arrrrrcounts", + "achievementProgressText": "Arrrchivements: ${COUNT} out of ${TOTAL}", + "campaignProgressText": "Campaign Prrrrrogresss [Harrrrrd]: ${PROGRESS}", + "changeOncePerSeason": "Pirate can only change this once perrr season arrrr.", + "changeOncePerSeasonError": "Yer sure to bay over til' the season rolls over, Arg! (${NUM} days)", + "createAnAccountText": "Crrreate an Ship", + "customName": "Make yer own name", + "deleteAccountText": "Delete Account", + "googlePlayGamesAccountSwitchText": "You want to use me Google acounttt?\nYou bettterrr use Google Play Games!", + "linkAccountsEnterCodeText": "Put in Cipherrr, will ya?", + "linkAccountsGenerateCodeText": "Grrrab the Chiperrr", + "linkAccountsInfoText": "(To boast yer exploits in town, and acrross different platforrms, and acrross yer frens)", + "linkAccountsInstructionsNewText": "To link two pirates, generrrate a code on the first\nand enterrr that code on the second. Data from the\nsecond account will then be shared between both pirates.\n(The first pirate will get alzheimer)\n\nYer can link up to ${COUNT} pirrrates. (yarrr)\n\nSINK ME! If a pirate links to another, yer can't\ndance with Jack Ketch together! (Which son of a biscuit\neater made up this lie?)", + "linkAccountsInstructionsText": "Err, to bundle two rekconings, grab a cipherrr on one\nof the consoole 'en push in the chyper on the other.\nErrrnings and golds gotta be merged.\nYerr could bundle to ${COUNT} reckonings, captain.\n\nBe safe out therrrre; things can't be 'err reverted!", + "linkAccountsText": "Bundle 'dem Rekconings", + "linkedAccountsText": "Reckonings bundled:", + "manageAccountText": "Marnage Arrrrcount", + "nameChangeConfirm": "Charrrnge your arrcount nammme to ${NAME}?", + "resetProgressConfirmNoAchievementsText": "This will rrreset your co-op prrrogressss and\nlocal high-scorrrres (but not your playing caards).\nThis cannot be undone. Are you sure captain?", + "resetProgressConfirmText": "This will rrreset your co-op prrrogressss,\narrrchievements, and local high-scorrres\n(but not yourrr tickets). This cannot\nbe undone. Arrrre you surrre captain?", + "resetProgressText": "Rrreset Prrrogressss", + "setAccountName": "Set Arrrcount Namme", + "setAccountNameDesc": "Select the name to display forrr yourrr \naccounts. Pirate can use the name frrrom one\n of yourrr linked accounts orrr crrreate unique custom name arrr.", + "signInInfoText": "Sign in to collect caards, compete with battle ships,\nand share prrrogressss across yer devices.", + "signInText": "Sign in, matey!", + "signInWithAnEmailAddressText": "Signnn innn with an eeemail addddresssssssr", + "signInWithDeviceInfoText": "(an automatic 'you' only available frrom this plastic thing you'rre holding right therre)", + "signInWithDeviceText": "Sign in to the pirate ship with device arrcount", + "signInWithGameCircleText": "Sail with yer Game Circle", + "signInWithGooglePlayText": "Set sail with Google Play", + "signInWithTestAccountInfoText": "(ye ole' account type; here on out use yer device account)", + "signInWithTestAccountText": "Sign in with test account arrr.", + "signInWithText": "Avast ye! Be accompanied by ${SERVICE}, ye scallywags!", + "signInWithV2InfoText": "(Arrrrcounts that there works on any of yer ships arrrrr!)", + "signInWithV2Text": "Just enter with yer ${APP_NAME} account there arrr!", + "signOutText": "Leaving the sloop!", + "signingInText": "Signing in to the pirate ship!", + "signingOutText": "Signing out from the pirate ship!", + "testAccountWarningOculusText": "Warning: you are signing in with a \"test\" account.\nThis will be replaced with \"real\" accounts later this\nyear which will offer ticket purchasing and other features.\n\n\nFor now you'll have to earn all tickets in-game.", + "ticketsText": "yer playing cards: ${COUNT}", + "titleText": "Arrrcount", + "unlinkAccountsInstructionsText": "Set a pirate to walk the plank", + "unlinkAccountsText": "Unlink ye ole Accounts", + "unlinkLegacyV1AccountsText": "Get rrrrid of those old arrrcounts!", + "v2LinkInstructionsText": "Get this link as a ‘yer creation of accounts or enter in arrr!!!", + "viaAccount": "(by-way-of pirate ${NAME})", + "youAreSignedInAsText": "You be the pirate ship being:" + }, + "achievementChallengesText": "Arrrrchievement Challenges", + "achievementText": "Doubloon", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Kill 3 bad scurvy dogs with tnt", + "descriptionComplete": "Got 3 knaves off the deck with a powder box", + "descriptionFull": "Clear 3 knaves off ${LEVEL} usin' a powderr box", + "descriptionFullComplete": "Clearred 3 knaves off ${LEVEL} usin' a powderr box", + "name": "Fire In Th’ Box" + }, + "Boxer": { + "description": "Beat all these buckos without any powderrr", + "descriptionComplete": "Victorrrious with no blassts", + "descriptionFull": "Complete ${LEVEL} without usin' any powderrr, no kornswoggle 'ere!", + "descriptionFullComplete": "Completed ${LEVEL} without usin' any powderrr, no kornswoggle 'ere!", + "name": "Boxrrr" + }, + "Dual Wielding": { + "descriptionFull": "Connnect 2 contrrrollerrrs (harrrdwarre or app)", + "descriptionFullComplete": "Ye’ave Connnected 2 contrrrollerrrs (harrrdwarre or app)", + "name": "Up For A Briny Duel" + }, + "Flawless Victory": { + "description": "Win without bein’ busted off by those stinky scurvies", + "descriptionComplete": "Wonn without bein’ busted off by those stinky scurvies", + "descriptionFull": "Win that ${LEVEL} thing without bein’ busted off by those stinky scurvies", + "descriptionFullComplete": "Win that ${LEVEL} thing without bein’ busted off by those stinky scurvies, all hands hoay for this handsome pirate", + "name": "Handsomely Won" + }, + "Free Loader": { + "descriptionFull": "Kick off a Fight-Outrageously game with 2+ joiners arrr!!!", + "descriptionFullComplete": "Emerged a Fight-Outrageously game with 2+ joiners arrr!!!", + "name": "A Carrier Fer Nothing" + }, + "Gold Miner": { + "description": "Rekt 6 bad guys wirrth land-mines", + "descriptionComplete": "Ye’ rekt 6 bad guys wirrth land-mines", + "descriptionFull": "Rekt 6 bad guys wirrth land-mines on ${LEVEL}", + "descriptionFullComplete": "Ye’ rekt 6 bad guys wirrth land-mines on ${LEVEL}", + "name": "Treasure Minerrrr" + }, + "Got the Moves": { + "description": "Win without fistfight some scaliwags or firing th’ hole", + "descriptionComplete": "Won without fistfight some scaliwags or firing th’ hole", + "descriptionFull": "Win ${LEVEL} without fistfight some scaliwags or firing th’ hole", + "descriptionFullComplete": "Won ${LEVEL} without fistfight some scaliwags or firing th’ hole", + "name": "Aye Aye I Got It" + }, + "In Control": { + "descriptionFull": "Ye connect a cutlass, can it be sharp or broken, tar!", + "descriptionFullComplete": "Blimey! me have cutlass like ye!", + "name": "Puppeteerrrr" + }, + "Last Stand God": { + "description": "Get 1,000 doubloons", + "descriptionComplete": "Ye' got 1,000 doubloons", + "descriptionFull": "Get 1,000 doubloons on ${LEVEL}", + "descriptionFullComplete": "Ye' got yer' 1,000 doubloons on ${LEVEL}", + "name": "${LEVEL} Cap'ain" + }, + "Last Stand Master": { + "description": "Get the damn 250 dbs", + "descriptionComplete": "Ye' got yer' 250 doubloons", + "descriptionFull": "Get 250 doubloons on ${LEVEL}", + "descriptionFullComplete": "Ye' got 250 doubloons on ${LEVEL}", + "name": "${LEVEL} Quartermaster!" + }, + "Last Stand Wizard": { + "description": "Loot 500 booty", + "descriptionComplete": "Looted 500 booty", + "descriptionFull": "Loot 500 booty around ${LEVEL} island", + "descriptionFullComplete": "Looted 500 booty over ${LEVEL} island", + "name": "${LEVEL} Privateer" + }, + "Mine Games": { + "description": "Flog 3 landlubbers with land-sharks", + "descriptionComplete": "Flogged 3 landlubbers with land-sharks", + "descriptionFull": "Flog 3 landlubbers with land-sharks around ${LEVEL} island", + "descriptionFullComplete": "Flogged 3 landlubbers with land-sharks over ${LEVEL} island", + "name": "Shark Games" + }, + "Off You Go Then": { + "description": "Maroon 3 landlubbers off the land", + "descriptionComplete": "Marooned 3 landlubbers off the land", + "descriptionFull": "Maroon 3 landlubbers off the ${LEVEL} island", + "descriptionFullComplete": "Marooned 3 landlubbers off the ${LEVEL} island", + "name": "Off Ye Go Then" + }, + "Onslaught God": { + "description": "Loot 5000 booty", + "descriptionComplete": "Looted 5000 booty", + "descriptionFull": "Loot 5000 booty around ${LEVEL} island", + "descriptionFullComplete": "Looted 5000 booty over ${LEVEL} island", + "name": "${LEVEL} Coffer" + }, + "Onslaught Master": { + "description": "Loot 500 booty", + "descriptionComplete": "Looted 500 booty", + "descriptionFull": "Loot 500 booty around ${LEVEL} island", + "descriptionFullComplete": "Looted 500 booty over ${LEVEL} island", + "name": "${LEVEL} Captain" + }, + "Onslaught Training Victory": { + "description": "Make em shark bait", + "descriptionComplete": "Made em shark bait", + "descriptionFull": "Make em shark bait in the ${LEVEL} ship", + "descriptionFullComplete": "Made em shark bait in the ${LEVEL} ship", + "name": "${LEVEL} Victory, Yo Ho Ho!" + }, + "Onslaught Wizard": { + "description": "Loot 1000 booty", + "descriptionComplete": "Looted 1000 booty", + "descriptionFull": "Loot 1000 booty around ${LEVEL} island", + "descriptionFullComplete": "Looted 1000 booty around ${LEVEL} island", + "name": "${LEVEL} Wizarrrrrrd" + }, + "Precision Bombing": { + "description": "Pirate strong, pirate don't need powerrrrups", + "descriptionComplete": "didn need those dumb cheats ehh?", + "descriptionFull": "get over ${LEVEL} island without pesky cheats", + "descriptionFullComplete": "got over ${LEVEL} island without pesky cheats, knew yer could manage it billy", + "name": "Powderrr Master" + }, + "Pro Boxer": { + "description": "a real pirate needs only them fists", + "descriptionComplete": "yer a real pirate ye know that?", + "descriptionFull": "Beat them enemies in ${LEVEL} island usin yer bare hands", + "descriptionFullComplete": "ya killed them enemies in ${LEVEL} island usin yer bare hands", + "name": "Fister" + }, + "Pro Football Shutout": { + "description": "keep them harrs out of our land", + "descriptionComplete": "kept them harrs out of our land (arrrr)", + "descriptionFull": "the best pirate is the one that keeps them harrs out of ${LEVEL} island", + "descriptionFullComplete": "yer the best pirate, raise the black jack! for the one who kept the harrs off of ${LEVEL}", + "name": "${LEVEL} Gatekeep" + }, + "Pro Football Victory": { + "description": "Take them ship down!", + "descriptionComplete": "Took em down", + "descriptionFull": "Destroy the enemy in island ${LEVEL}", + "descriptionFullComplete": "yer claimed ${LEVEL} as yer own. arrrr for the cap'ain!", + "name": "Ocean of ${LEVEL} claimer" + }, + "Pro Onslaught Victory": { + "description": "Take em all on", + "descriptionComplete": "ya claimed them ship like a pro (arrrrr wth is a pro?)", + "descriptionFull": "take over them flibustier's ship in ${LEVEL}", + "descriptionFullComplete": "crashed the enemy ship in the island of ${LEVEL} (yaarrrrrr!)", + "name": "Victor of ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Keep em out of our ship!", + "descriptionComplete": "The ship is safe, chips ahoy everyone (cringe)", + "descriptionFull": "The enemies arrrrre freebooting our ship at ${LEVEL}, stop them!", + "descriptionFullComplete": "Ya kept those freebooters off at ${LEVEL}. Yet a great captain", + "name": "Freeboot Blocker (${LEVEL})" + }, + "Rookie Football Shutout": { + "description": "keep them harrs out of our land", + "descriptionComplete": "kept them harrs out of our land (arrrr)", + "descriptionFull": "Don't let any of themmm freebooters in our land on the ${LEVEL} island", + "descriptionFullComplete": "Didn't let em take the tiniest bit of ourrr prrrrescious ${LEVEL}", + "name": "${LEVEL} Gatekeep" + }, + "Rookie Football Victory": { + "description": "Take the ocean!", + "descriptionComplete": "Im tired of translating these (arrrrrrrr)", + "descriptionFull": "Rekt yer enemies in ${LEVEL}", + "descriptionFullComplete": "Rekted yer enemies in ${LEVEL} (YARRRRRRR)", + "name": "Ocean of ${LEVEL} Claimer" + }, + "Rookie Onslaught Victory": { + "description": "Make them walk yarrr plank", + "descriptionComplete": "Made em walk yarrr plank", + "descriptionFull": "Make them walk yarrr plank in ${LEVEL} island", + "descriptionFullComplete": "Made em walk yarrr plank in ${LEVEL} island", + "name": "Pirate of ${LEVEL} (yarrrr)" + }, + "Runaround God": { + "description": "get 2000 doubloons", + "descriptionComplete": "got them 2000 doubloons", + "descriptionFull": "get 2000 doubloons on ${LEVEL}", + "descriptionFullComplete": "got them 2000 doubloons on ${LEVEL}", + "name": "${LEVEL} Eric" + }, + "Runaround Master": { + "description": "get 500 doubloons", + "descriptionComplete": "got 500 doubloons, now we'rrrre talkin", + "descriptionFull": "get 500 doubloons on ${LEVEL} island", + "descriptionFullComplete": "got them 500 balloons (not doubloons, just balloons) (in ${LEVEL}, ofc)", + "name": "Pirate of The ${LEVEL}s" + }, + "Runaround Wizard": { + "description": "get 1000 doubloons", + "descriptionComplete": "got 1000 doubloons", + "descriptionFull": "get 1000 doubloons in ${LEVEL} island", + "descriptionFullComplete": "got them thousand doubloons on ${LEVEL} ehh", + "name": "${LEVEL} Captain" + }, + "Sharing is Caring": { + "descriptionFull": "share yer lives with a fellow pirrrate", + "descriptionFullComplete": "pirates arrrre happy together", + "name": "Sharrrrrre" + }, + "Stayin' Alive": { + "description": "yarr shall not die", + "descriptionComplete": "yer didn die at all", + "descriptionFull": "beat them lily livered bastards in ${LEVEL} without walkin the plank", + "descriptionFullComplete": "yar didn walk the plank in ${LEVEL} ya bootyful bastard", + "name": "Ya Ain't a Cat" + }, + "Super Mega Punch": { + "description": "have a fist strronger than 3 powderrrs", + "descriptionComplete": "yer fist shall kill a sharrrk", + "descriptionFull": "have yer fists kill a pirrrate with a single blow in ${LEVEL} island", + "descriptionFullComplete": "yer fists arrrre as strrrong as jack morrrgan's! ya prroved it in ${LEVEL}", + "name": "Jack's Strength" + }, + "Super Punch": { + "description": "be half a man jack was", + "descriptionComplete": "yer stepping in the right dirrection pirrate", + "descriptionFull": "be half a ma jack morgan was in ${LEVEL}", + "descriptionFullComplete": "yer stepping in morrgan's footsteps caip'ain, i saw what yarr did in ${LEVEL} island", + "name": "Half a Man" + }, + "TNT Terror": { + "description": "Kill 6 pirates with Sea mines", + "descriptionComplete": "Killed 6 pirates with Sea mines arrr", + "descriptionFull": "Kill 6 pirates with Sea mines on ${LEVEL}", + "descriptionFullComplete": "Killed 6 pirates with Sea mine on ${LEVEL} rawwrrrr", + "name": "Sea mine Mystery" + }, + "Team Player": { + "descriptionFull": "havve a ba'le between two groups with at least 4 pirrrates", + "descriptionFullComplete": "i hope ya did well", + "name": "Ship vs. Ship" + }, + "The Great Wall": { + "description": "Thou shalln't pass", + "descriptionComplete": "Stopped the pirate arrrrr", + "descriptionFull": "Stop all bad pirates on ${LEVEL} arghhhh....", + "descriptionFullComplete": "Stopped all enemies on ${LEVEL} arrrr", + "name": "The Deep Sea" + }, + "The Wall": { + "description": "Stop everrry single enemy ship", + "descriptionComplete": "Stopped every single enemy rawrrrr...", + "descriptionFull": "Stop every single enemy pirate on ${LEVEL} arghhhh", + "descriptionFullComplete": "Stopped every single pirate on ${LEVEL} arrrr", + "name": "The Sea" + }, + "Uber Football Shutout": { + "description": "Win without letting the pirates dock", + "descriptionComplete": "Won without letting the pirates dock", + "descriptionFull": "Win ${LEVEL} without letting the pirates dock", + "descriptionFullComplete": "Won ${LEVEL} without letting the pirates dock", + "name": "${LEVEL} faceoff" + }, + "Uber Football Victory": { + "description": "Win the duel", + "descriptionComplete": "Won the duel arghhhh", + "descriptionFull": "Win the duel in ${LEVEL}", + "descriptionFullComplete": "Won the duel in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Uber Onslaught Victory": { + "description": "Truth shall prevail", + "descriptionComplete": "Sweet victory mate", + "descriptionFull": "Defeat all waves in ${LEVEL}", + "descriptionFullComplete": "Defeated all waves in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Uber Runaround Victory": { + "description": "Complete all waves arrrrr", + "descriptionComplete": "Completed all waves arrrr", + "descriptionFull": "Complete all waves on ${LEVEL} arrrr", + "descriptionFullComplete": "Completed all waves on ${LEVEL} arrrr", + "name": "aye ${LEVEL} Victory" + } + }, + "achievementsRemainingText": "Treasures Remaining:", + "achievementsText": "Treasures", + "achievementsUnavailableForOldSeasonsText": "Sorry, treasure book is not found for old seasons. arrrghhhhh", + "activatedText": "${THING} arrrrctivated.", + "addGameWindow": { + "getMoreGamesText": "Get More Rigs...", + "titleText": "Add Rig" + }, + "addToFavoritesText": "Plunder to Favorites", + "addedToFavoritesText": "Addin' '${NAME}' to yer treasure trove o' Favorites.", + "allText": "All", + "allowText": "Permit", + "alreadySignedInText": "Ye ship is being controlled by a privateer;\nswap ships or track down and flog the privateer on ye ship and try again.\nFlank em out!", + "apiVersionErrorText": "We can't hoist the module ${NAME} aboard; it be aimin' for api-version ${VERSION_USED}; we be needin' api-version ${VERSION_REQUIRED}.", + "applyText": "APPLY!!!!", + "areYouSureText": "Are ya sure cap'ain?", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" enables this only when headphones are plugged in)", + "headRelativeVRAudioText": "Cap'n's ear-beguilin' VR sound", + "musicVolumeText": "How Loud's t'e Shanties", + "soundVolumeText": "How Loud's t'e Bombs", + "soundtrackButtonText": "Chanties", + "soundtrackDescriptionText": "(pick ye own shanty f'r t'e battles)", + "titleText": "Sounds" + }, + "autoText": "Arr-uto", + "backText": "Rear", + "banThisPlayerText": "Banish This Pirate Out!", + "bestOfFinalText": "Finest-of-${COUNT} End", + "bestOfSeriesText": "Finest of ${COUNT} drinks:", + "bestRankText": "Ye worst is #${RANK}, matey", + "bestRatingText": "Ye greatest loot is ${RATING}", + "betaErrorText": "This'n ship don't float anymore; time t'e check f'r a new 'un.", + "betaValidateErrorText": "Don't know if'n t'e ship's float'n. (me'be ye net's broken?)", + "betaValidatedText": "This Ship Floats; Have Fun!", + "bombBoldText": "KABOOM", + "bombText": "Kaboomy", + "boostText": ">Rum", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} is arranged in t'e Wheel itself.", + "buttonText": "stud", + "canWeDebugText": "Would'n ye mind if'n ye Ship automatically sends crew\nreports o' bugs, crashes n' basic usage t' t'e shipwright?\n\nT'e report hasn't any personal stuff in it n' will help t'\nkeep t'e ${APP_NAME} ship sailin' smoothly n' wi'out any bugs.", + "cancelText": "Abandon", + "cantConfigureDeviceText": "${DEVICE} can nay be altered", + "challengeEndedText": "This scramble is finished.", + "chatMuteText": "Close Ears", + "chatMutedText": "Ears Closed", + "chatUnMuteText": "Open Ears", + "chests": { + "prizeOddsText": "Yer chances o' 'avin'", + "reduceWaitText": "Travel Faster", + "slotDescriptionText": "Tis' be space for holdin yer treasure.\n\nEarn treasure by going on battles,\ngetting in tourrrrnaments, and getting \nmedals.", + "slotText": "Room for Beauty ${NUM}", + "slotsFullWarningText": "WARRNIN': All yer room for treasure chests are used.\nIf ye find any booty, it'll be goin' to the ocean.", + "unlocksInText": "rots open in" + }, + "choosingPlayerText": "", + "claimText": "Claim yer bounty", + "codesExplainText": "Codes be provided by the scallywag developer to \nspy out and right pirate troubles.", + "completeThisLevelToProceedText": "Ye be need'n finish this'n\nwaters t' sail further!", + "completionBonusText": "Loot f'r Finish'n it!", + "configControllersWindow": { + "configureControllersText": "Sharpen Cutlasses", + "configureGamepadsText": "Change ye Ship's Wheels", + "configureKeyboard2Text": "Arrange ye Keyboard (P2)", + "configureKeyboardText": "Arrange ye Keyboard", + "configureMobileText": "Set up some Planks as Cutlasses", + "configureTouchText": "Arrange Fingernails", + "ps3Text": "PS3 Cutlasses", + "titleText": "Cutlasses", + "wiimotesText": "Wiilasses", + "xbox360Text": "TangerineBox 360 Cutlasses" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Entry: cutlass support varies by hand and Bone type.", + "pressAnyButtonText": "Touc' any studs on t'e cutlass\n ye want to arrange...", + "titleText": "Arrange Cutlasses" + }, + "configGamepadWindow": { + "advancedText": "Complicate", + "advancedTitleText": "Complicated Cutlass Sharpening", + "analogStickDeadZoneDescriptionText": "(increase this if ye character be move'n when ye let go the stick)", + "analogStickDeadZoneText": "Blade Blind Spot", + "appliesToAllText": "(applies to all cutlasses of t'is class)", + "autoRecalibrateDescriptionText": "(enable this if ye character can nay move at full ahead)", + "autoRecalibrateText": "Auto-Realign Blade", + "axisText": "compass", + "clearText": "flog", + "dpadText": "diarrrrrheapad", + "extraStartButtonText": "Extra Shiny Stud", + "ifNothingHappensTryAnalogText": "If only air blows, try using t'e blade instead.", + "ifNothingHappensTryDpadText": "If only air blows, try using t'e diarrrrrheapad instead.", + "ignoreCompletelyDescriptionText": "(makes t'is cutlass useless, can not affect a thing)", + "ignoreCompletelyText": "Avoid Cutlass At All Costs", + "ignoredButton1Text": "Avoided Stud 1", + "ignoredButton2Text": "Avoided Stud 2", + "ignoredButton3Text": "Avoided Collision", + "ignoredButton4Text": "Arrrvoided Stud Four", + "ignoredButtonDescriptionText": "(use t'is to stop ye 'home' or 'sync' stud from affecting t'e B.O.A.T)", + "pressAnyAnalogTriggerText": "Touc'h any upper blade...", + "pressAnyButtonOrDpadText": "Touc' any stud or diarrrrheapad...", + "pressAnyButtonText": "Touc' a stud...", + "pressLeftRightText": "Touc' right or left...", + "pressUpDownText": "Touc' above or below...", + "runButton1Text": "Run Stud 1", + "runButton2Text": "Run Stud 2", + "runTrigger1Text": "Run Upper Blade 1", + "runTrigger2Text": "Run Upper Blade 2", + "runTriggerDescriptionText": "(analog upper blades let ye run like a briney deep turtle)", + "secondHalfText": "Use t'is to arrange t'e second half\nof a 2-cutlasses-in-1 sword that\ns'ows up as a single cutlass.", + "secondaryEnableText": "Permit", + "secondaryText": "Shared Cutlass", + "startButtonActivatesDefaultDescriptionText": "(t'row t'is off if yer start stud is more of a 'menu' stud)", + "startButtonActivatesDefaultText": "Start Stud Arrctivates Default Spyglass", + "titleText": "Cutlass Arrangement", + "twoInOneSetupText": "2-in-1 Cutlass Arrangement", + "uiOnlyDescriptionText": "(heave to t'is cutlass from truly slashing anyone)", + "uiOnlyText": "Allow Only for B.O.A.T Use", + "unassignedButtonsRunText": "Every No Use Studs Run", + "unsetText": "", + "vrReorientButtonText": "HATR Realign Stud" + }, + "configKeyboardWindow": { + "configuringText": "Arranging ${DEVICE}, Ahoy!", + "keyboard2NoteText": "Entry 63: most boards can only register a few touc'es at\nonce, so 'aving a second board buccaneer may work better\nif t'ere is a separate board attac'ed for t'em to use.\nNote that ye'll still need to assign unique studs to the\ntwo buccaneers even in that case." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Size Of The Wheels", + "actionsText": "Arrrctions", + "buttonsText": "studs", + "dragControlsText": "< drag around the stuff to place where ye want >", + "joystickText": "joyblade", + "movementControlScaleText": "Size Of The Ship", + "movementText": "Maneuver", + "resetText": "Re-Arrange", + "swipeControlsHiddenText": "Dispose of T'e Arrows on Yer Front", + "swipeInfoText": "'Swipe' style tec'niques take a little getting used to but\nmake it easier to play wit'out looking at t'e tec'niques.", + "swipeText": "swipe", + "titleText": "Arrange Fingernails" + }, + "configureDeviceInSystemSettingsText": "${DEVICE} can be rigged in the System Settings app.", + "configureItNowText": "Arrange the stuff now?", + "configureText": "Arrange", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Bladestore", + "appStoreText": "Blade Store", + "bestResultsText": "For best results ye'll need a water-free ship network. Ye can\nreduce ship lag by turning off other wireless boats, by\nplaying close to your ship 'eart, and by connecting the\ngame captain directly to the network via ethernet.", + "explanationText": "To use a plank or a larger plank as a wireless cutlass,\nadquire t'e \"${REMOTE_APP_NAME}\" cog on it. Any number of planks\ncan connect to a ${APP_NAME} battle over Se-As, and it's free of cost!", + "forAndroidText": "For Boatroid:", + "forIOSText": "for iBiteS:", + "getItForText": "Get ${REMOTE_APP_NAME} for iBiteS at t'e Banana App Store\nor for Boatroid at the Hoogle's Rig Store or Aazon's Bladestore", + "googlePlayText": "Hoogle's Rig", + "titleText": "Using Planks as Cutlasses:" + }, + "continuePurchaseText": "Proceed for ${PRICE}, matey?", + "continueText": "Proceed", + "controlsText": "Cuts", + "coopSelectWindow": { + "activenessAllTimeInfoText": "T'is does not apply to t'e all-time finest pirate status", + "activenessInfoText": "T'is multiplier rises on days w'en ye\nfind coffers and drops on days w'en ye break a leg. AAAAARRRRGGGGHHHH!!!", + "activityText": "Nauticals", + "campaignText": "Champagne", + "challengesInfoText": "Earn prizes for completing mini-games.\n\nPrizes and difficulty levels increase\neach time a challenge is completed and\ndecrease when one expires or is forfeited.", + "challengesText": "Trrravel The Lands", + "currentBestText": "Whippsnapper's Goldies", + "customText": "Yarr Choice", + "entryFeeText": "Give Treasure!!", + "forfeitConfirmText": "Give up yarr treasure?!?", + "forfeitNotAllowedYetText": "Not yet arr!! Continue!!", + "forfeitText": "Sail the seas again!", + "multipliersText": "Extrra Help", + "nextChallengeText": "Next Trrreasure", + "nextPlayText": "Only get playyerr at", + "ofTotalTimeText": "yet ${TOTAL}", + "playNowText": "Yarr go!!", + "pointsText": "Doubloons", + "powerRankingFinishedSeasonUnrankedText": "(ship tourrnament end in which ya lad did not get)", + "powerRankingNotInTopText": "(yarr not in goodie ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} dbs", + "powerRankingPointsMultText": "(x ${NUMBER} dbs)", + "powerRankingPointsText": "${NUMBER} dbs", + "powerRankingPointsToRankedText": "(${CURRENT} o' ${REMAINING} dbs)", + "powerRankingText": "Yarr Goods", + "prizesText": "Me treasure!", + "proMultInfoText": "Yarr lad if had ${PRO}\nCould get trreasury ${PERCENT}% good extrras!!", + "seeMoreText": "All best ships..arr..", + "skipWaitText": "Skipperr, Wait", + "timeRemainingText": "Yarr Time", + "toRankedText": "Lad not goodie", + "totalText": "yarr result", + "tournamentInfoText": "Yarr get treasure to see whos\nBetter at Pirate Traveling!\n\nYarr will also receive a bit\nof goodies from the trreasure.", + "welcome1Text": "Arrr! This is group ${LEAGUE}. Yarr can get good\nat group best by gettin good results,receiving at\nthe trreasure book,and win trreasure at trreasure hunt.", + "welcome2Text": "Yarr can gett the goodies frrom the same hunts.\nThe goodies can be used to hirree new pirates,\nislands,adventure,enter treasure hunting, and morree.", + "yourPowerRankingText": "Yarr best evar:" + }, + "copyConfirmText": "Put that rrvicious text to your boat!", + "copyOfText": "${NAME} Take", + "copyText": "Take", + "createAPlayerProfileText": "Make a new pirate?", + "createEditPlayerText": "", + "createText": "Make", + "creditsWindow": { + "additionalAudioArtIdeasText": "Supplymental Audio, Early Artwork, and Ideas by ${NAME}, Ahoy!", + "additionalMusicFromText": "Supplymental chantey from ${NAME}", + "allMyFamilyText": "All of me buckos and hearties w'o 'elped me learn to be a true pirate", + "codingGraphicsAudioText": "Building, Paint, and Mansail by ${NAME}", + "languageTranslationsText": "Over Sea Buccaneers:", + "legalText": "Letters of Marque:", + "publicDomainMusicViaText": "Chanties over ${NAME}", + "softwareBasedOnText": "T'is jacob's ladder is based in part on t'e work of ${NAME}", + "songCreditText": "${TITLE} Song by ${PERFORMER}\nInvented by ${COMPOSER}, Arranged by ${ARRANGER}, S'ared by ${PUBLISHER},\nCourtesy of ${SOURCE}", + "soundAndMusicText": "Screams and Chanteys:", + "soundsText": "Burps (${SOURCE}):", + "specialThanksText": "Special Words:", + "thanksEspeciallyToText": "T'is word is especially special to ${NAME}", + "titleText": "${APP_NAME} Entries", + "whoeverInventedCoffeeText": "Who'ver thought o' rum" + }, + "currentStandingText": "Yer current leg is #${RANK}", + "customizeText": "Plunder...", + "deathsTallyText": "${COUNT} scuttled", + "deathsText": "Shark Baits", + "debugText": "random", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Yarr good if you used the high graphic!", + "runCPUBenchmarkText": "Watch the fight with yarr CPU", + "runGPUBenchmarkText": "Watch fight yarr GPU", + "runMediaReloadBenchmarkText": "Re-use tha boat.", + "runStressTestText": "Pirate rrrandomness fighting", + "stressTestPlayerCountText": "Ammount of lads", + "stressTestPlaylistDescriptionText": "Ship", + "stressTestPlaylistNameText": "Yarr ship", + "stressTestPlaylistTypeText": "Yarr Ship Type", + "stressTestRoundDurationText": "Time to go", + "stressTestTitleText": "Piratey Rrrandoms Fight", + "titleText": "Computer Fights And Piratey Randomness", + "totalReloadTimeText": "Yarr knots at reuse is ${TIME} yarr see label for morree" + }, + "defaultGameListNameText": "The Norrmal Ship Forr ${PLAYMODE}", + "defaultNewGameListNameText": "Me Ship Forr ${PLAYMODE}}", + "deleteText": "Get rrid", + "demoText": "show", + "denyText": "Yar not!", + "deprecatedText": "Oldie", + "descriptionText": "Knowabouts", + "desktopResText": "Yarr ship's size", + "deviceAccountUpgradeText": "Yarr!!\nYou're using a ship that's a device!\nThe device ships (like ${NAME}) will be plungered later on!!\nYarr better use the v2 ships and we'll see so!", + "difficultyEasyText": "Lil' Buccaneer", + "difficultyHardOnlyText": "Privateers Only", + "difficultyHardText": "Privateer", + "difficultyHardUnlockOnlyText": "T'is land can only be looted in privateer mode.\nYe think yer pirate enough? Yo Ho Ho!", + "directBrowserToURLText": "Direct a cobweb to t'e following gibberish:", + "disableRemoteAppConnectionsText": "Disallow Remote-Mateys Connections", + "disableXInputDescriptionText": "Yarr can control more that 4 pirates but might not have it's beauty!!", + "disableXInputText": "Get rid of CrossButtony", + "disabledText": "Narr", + "discardText": "Heave overboard", + "discordFriendsText": "Be ye lookin' to gather a crew for yer adventures? \nCome aboard our Discord and meet some new shipmates!", + "discordJoinText": "Plunder t' Discord", + "doneText": "Yarr got it!!", + "drawText": "Not enough!!", + "duplicateText": "Magically Twwice", + "editGameListWindow": { + "addGameText": "New\nAdventure", + "cantOverwriteDefaultText": "Yarr can't change the main ship's beauty!", + "cantSaveAlreadyExistsText": "That ship alrready exists!", + "cantSaveEmptyListText": "Yarr cant use a ship without adventure!!", + "editGameText": "Change\nAdventure", + "listNameText": "Yarr ship's name", + "nameText": "Naame", + "removeGameText": "Forgor\nGaem", + "saveText": "Take Treasure Map", + "titleText": "Ye Ship" + }, + "editProfileWindow": { + "accountProfileInfoText": "Ye special pirate can have\nsame name as yer boat and\nhat.\n${ICONS}\n\nMake yer own pirates to use\ndifferrrent names and hats!", + "accountProfileText": "(ship pirate)", + "availableText": "Ye pirate name ${NAME} is good.", + "characterText": "yer pirate", + "checkingAvailabilityText": "waitin for pirate name \"${NAME}\" to be used..", + "colorText": "colorrrr", + "getMoreCharactersText": "Get more pirrrates..", + "getMoreIconsText": "Arrrrange Those Hats...", + "globalProfileInfoText": "Shared pirates surrree have good names\nto each other; Yarr also get hats for it.", + "globalProfileText": "(shared pirate)", + "highlightText": "colory second", + "iconText": "yarr hat", + "localProfileInfoText": "Ye alone pirate is not good enough for hats and yerr\nnames are not good. Get em shared forr betterrr name\nand good looki'n hats.", + "localProfileText": "(alone pirate)", + "nameDescriptionText": "Pirate Name", + "nameText": "Pirate Name", + "profileAlreadyExistsText": "There be a scallywag with that name already sailin' these waters!", + "randomText": "ranndom", + "titleEditText": "Change ye Pirate", + "titleNewText": "New Pirate", + "unavailableText": "Ye name ${NAME} is not good for all; ye need other name", + "upgradeProfileInfoText": "Yarr can magically share this pirate's name\nand can give em cool hats.", + "upgradeToGlobalProfileText": "Magically Share Pirate" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Arr! The music is too beauty to get off!", + "cantEditDefaultText": "Ye can't change normal music's beauty! Make two or make a new one.", + "cantOverwriteDefaultText": "Can't get off the music", + "cantSaveAlreadyExistsText": "That music alrready is there!!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Music Show", + "deleteConfirmText": "Get off the show:\n\n${NAME}??", + "deleteText": "Rrride that music \ndown the plank!", + "duplicateText": "Twice\nMusic", + "editSoundtrackText": "Change music", + "editText": "Change\nMusic", + "fetchingITunesText": "loot'n shanties from Music App...", + "musicVolumeZeroWarning": "W'at's t'e point o' stop'n t'e chanties?", + "nameText": "Label", + "newSoundtrackNameText": "Yarrr sound magic ${COUNT}", + "newSoundtrackText": "New chanty:", + "newText": "New\nChanty", + "selectAPlaylistText": "Choose a list of chanties matey", + "selectASourceText": "Stream of yerrr chantyfall", + "testText": "Arg", + "titleText": "Chanties", + "useDefaultGameMusicText": "Curse of Eric's Chanties", + "useITunesPlaylistText": "Chanties Magic Gamerlist", + "useMusicFileText": "Chanty scroll (mpc, og3, etc)", + "useMusicFolderText": "Chest of yerrr chanties" + }, + "editText": "Reassemble", + "enabledText": "Yarr", + "endText": "Kill", + "enjoyText": "Arr!!", + "epicDescriptionFilterText": "${DESCRIPTION} in epic magic mode.", + "epicNameFilterText": "Epok ${NAME}", + "errorAccessDeniedText": "Arrrgh, the lock budgen't", + "errorDeviceTimeIncorrectText": "Yerrr migical @&#$'s clock is off by ${HOURS} nightpieces.\nThis could sunk yerrr ship.\nGo fix yerrrr crap before I make ya walk the plank.", + "errorOutOfDiskSpaceText": "I'm 100% sure you're the only human being that has seen this message...", + "errorSecureConnectionFailText": "Arrrr! The passage ain't safe, I won't take yerrr ship through, some crates may break (nooooooo)", + "errorText": "Argh!", + "errorUnknownText": "Arrrrrghh!!!", + "exitGameText": "Take yerrr ship out of ${APP_NAME}?", + "expiredAgoText": "Ran out ${T} ago", + "expiresInText": "Until ${T}", + "exportSuccessText": "'${NAME}' taken out.", + "externalStorageText": "Deep Chest", + "failText": "Urg...!", + "fatalErrorText": "Arr!! Me ship is not have the thing!!\nGo get new ship or maybe \nSend the parrot a message forrr ${EMAIL}!", + "fileSelectorWindow": { + "titleFileFolderText": "Get me a file orrr folderrr!!", + "titleFileText": "Bring me a thingy will ya?", + "titleFolderText": "Get the otherrrr ship!", + "useThisFolderButtonText": "Use Yerrr Chest?" + }, + "filterText": "Cerrtain", + "finalScoreText": "Last Doubloons", + "finalScoresText": "Results!", + "finalTimeText": "Final Hour", + "finishingInstallText": "No way in hell you're actually seeing this text", + "fireTVRemoteWarningText": "Yarr better off using a\nController Thing orrr\nGett ${REMOTE_APP_NAME} \nForrr ya weapons!!", + "firstToFinalText": "Trreasure of ${COUNT} Captain", + "firstToSeriesText": "Treasure of ${COUNT} Ship", + "fiveKillText": "SUBMARINE CREW!!!", + "flawlessWaveText": "Scratchless Wave!", + "fourKillText": "QUOUT!!!", + "friendScoresUnavailableText": "Couldn't find yerrr matey doubloons.", + "gameCenterText": "GaemSquare", + "gameCircleText": "GaemTriangle", + "gameLeadersText": "Top ${COUNT} Captains", + "gameListWindow": { + "cantDeleteDefaultText": "That cursed scroll can't be destroyed.", + "cantEditDefaultText": "That cursed scroll can't be reassembled, copy it or write a new scroll.", + "cantShareDefaultText": "The cursed scroll is stuck in the palm of your hand.", + "deleteConfirmText": "Burn \"${LIST}\"?", + "deleteText": "Destroy\nScroll", + "duplicateText": "Copy\nScroll", + "editText": "Reassemble\nScroll", + "newText": "New\nScroll", + "pointsToWinText": "Booty to Conquer", + "seriesLengthText": "Voyage Duration", + "showTutorialText": "me noob", + "shuffleGameOrderText": "Scramble The Lines of Yerrr Scroll", + "titleText": "Assemble ${TYPE} Scroll" + }, + "gameSettingsWindow": { + "addGameText": "Put Gaem" + }, + "gamesToText": "${WINCOUNT} sure beats ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Get this: any ship in ya ship can get more \npirrates if they have control thingies.", + "aboutDescriptionText": "Use this pad to assemble a crew.\n\nCrews let ya capture the world\nWith yerrr fellow pirates together!\n\nUse ${PARTY} to speak with yer crew\n(using PirateSpeak!1!1!!!}\n(${BUTTON} works too)", + "aboutText": "Scroll", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} gave ya ${COUNT} doubloons in ${APP_NAME}", + "appInviteSendACodeText": "Give Yerr Matey A Key", + "appInviteTitleText": "${APP_NAME} Magical Invite", + "bluetoothAndroidSupportText": "(sails with any android pad that has a tooth that is blue)", + "bluetoothDescriptionText": "Get yarrr sailors on using a blue tooth!", + "bluetoothHostText": "Hold the tooth", + "bluetoothJoinText": "Be consumed by the tooth", + "bluetoothText": "Blue tooth", + "checkingText": "Looking at yerr map...", + "copyCodeConfirmText": "I put the order on yerr clipboard captain!", + "copyCodeText": "Copy ze code", + "dedicatedServerInfoText": "For the best ship, make yerrr own sea! Head over to bombsquadgame.com/server to learn how.", + "descriptionShortText": "Use the crew tab to assemble yerr.. crew.", + "disconnectClientsText": "This will throw ${COUNT} sailor(s)\noff yer ship. Are you sure captain?", + "earnTicketsForRecommendingAmountText": "Yerr maties will get ${COUNT} gold if they try the game\n(and you will get ${YOU_COUNT} gold from the treasure forrr each)", + "earnTicketsForRecommendingText": "Share PowderBomb\nfor painless treasure!", + "emailItText": "Send A Morse Code", + "favoritesSaveText": "Save As Favorite (arrr)", + "favoritesText": "Favorites", + "freeCloudServerAvailableMinutesText": "Next painless cloud sea available in ${MINUTES} daypieces.", + "freeCloudServerAvailableNowText": "There's a painless cloud sea available now captain!", + "freeCloudServerNotAvailableText": "There aren't any easy to get cloud seas here...", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} goodies from ${NAME}arrrr", + "friendPromoCodeAwardText": "Yerr will snatch ${COUNT} from the treasure every time it's used.", + "friendPromoCodeExpireText": "The code will rot in ${EXPIRE_HOURS} nightpieces and only new sailors can use it.", + "friendPromoCodeInstructionsText": "To snatch the treasure, open ${APP_NAME}, then \"Settings->Advanced->Send Info\".\nSee bombsquadgame.com for available oceans and paths to them.", + "friendPromoCodeRedeemLongText": "${MAX_USES} sailors, ${COUNT} tickets each...", + "friendPromoCodeRedeemShortText": "It can open a ${COUNT} ticket treasure chest.", + "friendPromoCodeWhereToEnterText": "(in yer \"Settin's->Advanced->Send Info\")", + "getFriendInviteCodeText": "Get A Lock Code For Yerr Maties", + "googlePlayDescriptionText": "Long live google play games multiplayer...", + "googlePlayInviteText": "Summon", + "googlePlayReInviteText": "${COUNT}\nno\nno", + "googlePlaySeeInvitesText": "Be Summoned", + "googlePlayText": "Goggles", + "googlePlayVersionOnlyText": "The Lost Option", + "hostPublicPartyDescriptionText": "Make yerr own public sea", + "hostingUnavailableText": "Arrrgh! The ocean is gone!", + "inDevelopmentWarningText": "Note:\nThis\nIs\nA\nLie", + "internetText": "International Waters", + "inviteAFriendText": "Yerr maties don't have PowderTime? Summon them\nAnd they'll get ${COUNT} painless tickets!", + "inviteFriendsText": "Summon Mateys", + "joinPublicPartyDescriptionText": "Go to a Public Ocean", + "localNetworkDescriptionText": "Fight Over a Local Sea (Lantern, Blue Tooth, etc.)", + "localNetworkText": "Local Ocean", + "makePartyPrivateText": "Horde Yerr Treasure!", + "makePartyPublicText": "Share Yerr Treasure (with yerrr friens!!!)", + "manualAddressText": "Path", + "manualConnectText": "Set Sail Captain!", + "manualDescriptionText": "WHERES THE CITY?!", + "manualJoinSectionText": "Join By Path", + "manualJoinableFromInternetText": "Is yerr port available to international sailors?:", + "manualJoinableNoWithAsteriskText": "NEVER*", + "manualJoinableYesText": "YARRR!!", + "manualRouterForwardingText": "*port ${PORT} isn't connected to yerr sea matey", + "manualText": "Binnacle", + "manualYourAddressFromInternetText": "Yerr path from international waters:", + "manualYourLocalAddressText": "Yerr path from the bay:", + "nearbyText": "Local", + "noConnectionText": "", + "noPartiesAddedText": "No Crews Assembled", + "otherVersionsText": "eric remove these unused lstrs", + "partyCodeText": "Sea Fish", + "partyInviteAcceptText": "Be Summoned", + "partyInviteDeclineText": "NOOOOOO", + "partyInviteGooglePlayExtraText": "(embrace the 'Google Play' docks in yer 'Gather' outpost)", + "partyInviteIgnoreText": "Forgor", + "partyInviteText": "${NAME} has summoned\nYou to their ship captain!", + "partyNameText": "Name of Yerrr Sea", + "partyServerRunningText": "Yerr gaming ocean is gamin.", + "partySizeText": "allowed sailors", + "partyStatusCheckingText": "lookin' for yerr sea...", + "partyStatusJoinableText": "yerr sea is now known by all pirates!", + "partyStatusNoConnectionText": "can't navigate to port", + "partyStatusNotJoinableText": "yerr sea isn't known by anyone", + "partyStatusNotPublicText": "yerr ocean is not public", + "pingText": "pong", + "portText": "Seaport", + "privatePartyCloudDescriptionText": "Private seas are on cloud oceans; no need to build a dock.", + "privatePartyHostText": "Host yerr Own Private Shindig!", + "privatePartyJoinText": "Drop yerr Anchor", + "privateText": "Secret", + "publicHostRouterConfigText": "Arrr! Ye might need to be adjustin' the port-forwardin' on yer box, matey! Or if ye want a lazier option, just throw yer own secret party!", + "publicText": "Open Seas", + "requestingAPromoCodeText": "Askin' fer a key...", + "sendDirectInvitesText": "Send Out Bottles to Yer Shipmates", + "shareThisCodeWithFriendsText": "Pass along this Secret Code to yer Crewmates:", + "showMyAddressText": "Read Me Bey's Port and Sails", + "startHostingPaidText": "Host yer Own Now fer ${COST}", + "startHostingText": "Yar", + "startStopHostingMinutesText": "Ye can hoist and lower yer ships for free for the next ${MINUTES} daypieces.", + "stopHostingText": "Hat yer Ship", + "titleText": "Gatherrr", + "wifiDirectDescriptionBottomText": "If all yer magicpad64s have a 'Direct Magic' panel, they shall be able to use it to find\nand pair to each other. Once all stuff do be connected, ye can form docks to fight on\nhere usin' the 'Local Magic' tab, just the same as with regular magic.\n\nFer ye greatest result, the Direct Magic host should also be the ${APP_NAME} dock host.", + "wifiDirectDescriptionTopText": "Arr, Direct Magic can be used to connect Arch linux devices directly without\nneedin' boring magic. This works best on linux kernel 4.2 or newer.\n\nTo use it, open yer magic book and look for the Direct Magic spell matey.", + "wifiDirectOpenWiFiSettingsText": "Open Magic Book", + "wifiDirectText": "Direct Magic", + "worksBetweenAllPlatformsText": "(works between all sorts of magic stuff matey)", + "worksWithGooglePlayDevicesText": "(works with tabs with the internet explorer version of the gaem)", + "youHaveBeenSentAPromoCodeText": "Yar been sent a ${APP_NAME} treasure key:" + }, + "getTicketsWindow": { + "freeText": "FRREEE!", + "freeTicketsText": "Painless Treasure", + "inProgressText": "Arrgh! we're already waiting for another ship to arrive, wait a lightfragment!", + "purchasesRestoredText": "Ships retrieved matey.", + "receivedTicketsText": "Got ${COUNT} treasures!", + "restorePurchasesText": "Retrieve Ships", + "ticketPack1Text": "smol treasure", + "ticketPack2Text": "Treasure", + "ticketPack3Text": "BIIIIIIIIG TREASURE", + "ticketPack4Text": "VERY BIIIIG TREASURE", + "ticketPack5Text": "that's a lot", + "ticketPack6Text": "like, ur mama size a lot", + "ticketsFromASponsorText": "Be enslaved\nfor ${COUNT} treasures", + "ticketsText": "${COUNT} Treasures", + "titleText": "Hoard Treasures", + "unavailableLinkAccountText": "Arrr, shipping be illegal on this bay.\nye can send a boat to a ship on\nanother bay and make purchases therre.", + "unavailableTemporarilyText": "Arrrgh! We can't do that right now cap'ain; we'll do it later matey.", + "unavailableText": "Sorry cap'ain, They don't ship this right now.", + "versionTooOldText": "Arrrgh! yer PowderTime(patent pending) is dying of old age!!! update to a newer version mate.", + "youHaveShortText": "ye got ${COUNT}", + "youHaveText": "ye have ${COUNT} treasures" + }, + "goldPass": { + "desc1InfTokensText": "INFINITE GAMBLING!!!", + "desc2NoAdsText": "None of 'er pesky ads.", + "desc3ForeverText": "Till the end of the seven seas.", + "goldPassText": "Golden Ultimate Delux Limited-Edition Fire Pass" + }, + "googleMultiplayerDiscontinuedText": "no\nno\nno\n-Cap'ain Eric", + "googlePlayPurchasesNotAvailableText": "Arrgh! Google's shipping ain't workin!\nTry to get in contact with them nerds!", + "googlePlayServicesNotAvailableText": "Google HQ is being infiltrated.\nWe may need to retreat.", + "googlePlayText": "Google go brrr", + "graphicsSettingsWindow": { + "alwaysText": "NEVER!!!", + "fullScreenCmdText": "Big view (Cmd-F)", + "fullScreenCtrlText": "Big view (Ctrl-F)", + "fullScreenText": "Whole Horizon", + "gammaText": "Delta", + "highText": "Better", + "higherText": "Best", + "lowText": "Bad", + "maxFPSText": "Max SPF", + "mediumText": "Meh", + "neverText": "ALWAYS!!!", + "resolutionText": "-Air pollution", + "showFPSText": "Show yer SPF", + "texturesText": "Crates", + "titleText": "Quality", + "tvBorderText": "gamer mode", + "verticalSyncText": "Vertical Sink Hole", + "visualsText": "Monocle Settings" + }, + "helpWindow": { + "bombInfoText": "- Bomb -\nPack'n more punch than punches,\nbut c'n be cost'n ye an arm 'n a leg.\nF'r cheaper'n that ye be need'n t'\nthrow it b'fore t' fuse be run'n out.", + "canHelpText": "${APP_NAME} can help matey.", + "controllersInfoText": "Yarr can set sail in ${APP_NAME} with yer mateys over the sea, or ye\ncan all sail from the same dock if ye have enough boats.\n${APP_NAME} accepts any of yer boats; yarr can even use rafts\nas boats with the \"${REMOTE_APP_NAME}\" app.\nRead through Settings->Boats to learn more.", + "controllersInfoTextRemoteOnly": "Yarr can set sail in ${APP_NAME} with yer mateys over the sea, or ye\ncan all sail from the same dock if ye use rafts\nas boats with the \"${REMOTE_APP_NAME}\" app.", + "controllersText": "Boats", + "controlsSubtitleText": "Yer ${APP_NAME} pirate can do some violent stuff cap'ain:", + "controlsText": "Actions", + "devicesInfoText": "The VR version of ${APP_NAME} can battle against other ships over\nthe sea. So get yer mateys on their normy rafts, boats,\nand ships and fight for glory cap'ain. ya can even get\na regular ship hooked up to the VR version just so that yer\nmateys can watch yer glorious battles from land.", + "devicesText": "Docks", + "friendsGoodText": "These be treasures worth havin', me matey! ${APP_NAME} be at its finest with \na crew of scurvy dogs, and it can accommodate up to 8 buccaneers at a time, which brings us to:", + "friendsText": "Mateys", + "jumpInfoText": "- Leap -\nLeap to cross small gaps,\nto heave things higher, and \nto let the wind fill yer sails!", + "orPunchingSomethingText": "Or give it a good wallop, toss it overboard, and blast it to smithereens with a sticky bomb as it falls to Davy Jones' Locker.", + "pickUpInfoText": "- Plunder -\nGrab flags, enemies, or anything \nnot nailed down to the deck. \nPress again to toss it overboard!", + "powerupBombDescriptionText": "Lets ye wield three bombs \nin a row instead of just one, me heartie!", + "powerupBombNameText": "Thrice-Blessed Bombs", + "powerupCurseDescriptionText": "Ye probably want to steer clear o' these.\n...or do ye?", + "powerupCurseNameText": "The Black Spot", + "powerupHealthDescriptionText": "Brings ye back from Davy Jones' Locker, with nary a scratch. \nYe'd never have reckoned it, but 'tis true, me heartie!", + "powerupHealthNameText": "Healer's Chest", + "powerupIceBombsDescriptionText": "Be weaker than yer typical bomb, \nbut leave yer enemies frozen solid \nand as brittle as an old piece o' hardtack.", + "powerupIceBombsNameText": "Frosty Grenades", + "powerupImpactBombsDescriptionText": "Be a tad weaker than yer standard bombs, \nbut they burst on impact with a mighty bang.", + "powerupImpactBombsNameText": "Blastin' Balls", + "powerupLandMinesDescriptionText": "Ye can get 'em in packs o' three; \nhandy fer protectin' yer base or \nstoppin' quick-footed foes in their tracks.", + "powerupLandMinesNameText": "Landlubber Mines", + "powerupPunchDescriptionText": "Gives ye fists more oomph, \nspeed, and power, me hearties!", + "powerupPunchNameText": "Fisticuffs Mittens", + "powerupShieldDescriptionText": "Takes a lickin' for ye, me hearty, \nso ye don't have to!", + "powerupShieldNameText": "Force Field", + "powerupStickyBombsDescriptionText": "Stick to anythin' they hit.\nMirth ensues.", + "powerupStickyBombsNameText": "Adhesive Grenades", + "powerupsSubtitleText": "Aye, no game worth its salt be complete without booty to plunder!", + "powerupsText": "Booty", + "punchInfoText": "- Punch -\nPunches do more damage th'\nfaster yer fists be movin', so\nrun and spin like a madlad.", + "runInfoText": "- Sail -\nGrasp ANY swashbucklin' button to set yer boots in motion. Triggers or shoulder buttons be fine choices if ye possess 'em.\nSailing be a swift course to reach yer destinations, yet be wary o' treacherous cliffs, for turning be a mighty challenge.", + "someDaysText": "Arrr, some days yer just feelin' like punchin' somethin'. Or blowin' somethin' up to smithereens, me hearty.", + "titleText": "${APP_NAME} Help", + "toGetTheMostText": "Ye'll need the right tools to plunder the depths of this game, me hearty:", + "welcomeText": "Ahoy and welcome aboard the good ship ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} be navigatin' menus like a fearsome captain -", + "importPlaylistCodeInstructionsText": "Employ the followin' code to import this playlist elsewhere, ye scallywag:", + "importPlaylistSuccessText": "Imported ${TYPE} playlist '${NAME}', me heartie!", + "importText": "Plunder", + "importingText": "Plunderin'...", + "inGameClippedNameText": "in-game will be\n\"${NAME}\", me matey!", + "inboxText": "Treasure Chest", + "installDiskSpaceErrorText": "Arrr! Unable to complete the install, ye scurvy dog!\nYe may be out of space on yer ship.\nClear some space and give it another go, or ye'll walk the plank!", + "internal": { + "arrowsToExitListText": "Press ${LEFT} or ${RIGHT} to set sail from this list, ye scallywag!", + "buttonText": "button", + "cantKickHostError": "Ye can't commit mutiny, ye landlubber!", + "chatBlockedText": "Avast ye! ${NAME} be chat-blocked for ${TIME} seconds!", + "connectedToGameText": "Ye have joined the crew of '${NAME}', me matey!", + "connectedToPartyText": "Ye have joined the party of ${NAME}, me hearty!", + "connectingToPartyText": "Settin' sail, we be! Connectin'...", + "connectionFailedHostAlreadyInPartyText": "Arr, ye scallywag! Connection be a failure! The host be already part of another party.", + "connectionFailedPartyFullText": "Avast ye! Connection be a failure! The party be filled to the brim, ye scurvy sea dog!", + "connectionFailedText": "Arr, connection be a failure, me heartie.", + "connectionFailedVersionMismatchText": "Avast ye! Connection be a failure, for the host be runnin' a different version of the game. \nMake sure ye both be up-to-date and give it another shot, me matey!", + "connectionRejectedText": "Arr, yer connection be rejected, ye landlubber! Ye may need an invitation or proper permissions to join.", + "controllerConnectedText": "Avast ye! ${CONTROLLER} be connected, ready to set sail on this adventure!", + "controllerDetectedText": "Arr, me heartie! We be spyin' a single controller on the horizon.", + "controllerDisconnectedText": "Avast ye! ${CONTROLLER} be disconnected and be leavin' the crew. Farewell, me matey!", + "controllerDisconnectedTryAgainText": "Avast ye! ${CONTROLLER} be disconnected. Please make another attempt at connectin', me hearty!", + "controllerForMenusOnlyText": "Avast ye! This controller be fit for navigatin' menus, but not for playin' the game.", + "controllerReconnectedText": "Avast ye! ${CONTROLLER} be reconnected and back in action!", + "controllersConnectedText": "Avast ye! We be havin' ${COUNT} controllers connected!", + "controllersDetectedText": "Arr, me matey! We be detectin' ${COUNT} controllers on the horizon.", + "controllersDisconnectedText": "Avast ye! ${COUNT} controllers be disconnected and be partin' ways.", + "corruptFileText": "Avast ye! Corrupt file(s) be detected, me heartie! Give reinstallin' a try, or send an email to ${EMAIL} for further assistance. May the winds of good fortune be with ye!", + "errorPlayingMusicText": "Avast ye! There be an error playin' the shanties \"${MUSIC}\".", + "errorResettingAchievementsText": "Avast ye! Ye be unable to reset yer online achievements at this time.", + "hasMenuControlText": "Avast ye! ${NAME} be takin' hold of the menu controls like a true captain of the ship!", + "incompatibleNewerVersionHostText": "Avast ye! The host be sailin' with a newer version of the game. Ye be needin' to update to the latest version if ye want to join the crew. \nSet yer sails to the latest version and give it another try, me hearty!", + "incompatibleVersionHostText": "Avast ye! The host be runnin' a different version of the game, me matey! Make sure ye and the host be sailin' \nwith the same version by updatin' yer game. Once ye be both up-to-date, set sail again and give it another shot!", + "incompatibleVersionPlayerText": "Avast ye! ${NAME} be runnin' a different version of the game, me heartie! \nMake sure ye and they scurvy dogs be both up-to-date by checkin' for updates.", + "invalidAddressErrorText": "Avast ye! 'Tis an error I be seein'. The address ye be providin' be invalid, ye scurvy sea dog!", + "invalidNameErrorText": "Avast ye! 'Tis an error in the name ye be providin'.", + "invalidPortErrorText": "Avast ye! 'Tis an error in the port number ye be providin'.", + "invitationSentText": "Avast ye! The invitation be sent, me heartie!", + "invitationsSentText": "Avast ye! ${COUNT} invitations be sent, me matey!", + "joinedPartyInstructionsText": "Someone has joined yer parrie!.\nGo t' 'Play' t' starrr a game.", + "keyboardText": "'Kayboarrd", + "kickIdlePlayersKickedText": "Kickin' ${NAME} fer bein' idle.", + "kickIdlePlayersWarning1Text": "${NAME} is kickin' te' bucket in ${COUNT} seconds if still idle.", + "kickIdlePlayersWarning2Text": "(ye could turrrn tis' off in Settings -> Advanced)", + "leftGameText": "Leeeft '${NAME}'.", + "leftPartyText": "Left ${NAME}'s ship.", + "noMusicFilesInFolderText": "Folder conteins no shanties files.", + "playerJoinedPartyText": "${NAME} joined the ship!", + "playerLeftPartyText": "${NAME} left the ship.", + "rejectingInviteAlreadyInPartyText": "Avast ye! Ye be rejectin' the invite, me hearty! 'Tis because ye be already in a party.", + "serverRestartingText": "Avast ye! The server be restartin', me matey! Hold tight and give it a moment..", + "serverShuttingDownText": "Avast ye! The server be shuttin' down, me heartie!", + "signInErrorText": "Avast ye! 'Tis an error signin' in, me matey!", + "signInNoConnectionText": "Avast ye! Ye be unable to sign in, me heartie! It seems ye be lackin' an internet connection.", + "telnetAccessDeniedText": "Avast ye! 'Tis an error I be seein'. The user be not grantin' telnet access!", + "timeOutText": "(the operation be timed out in ${TIME} seconds)", + "touchScreenJoinWarningText": "Avast ye! Ye be joinin' with the touchscreen, me hearty! \nIf ye made a mistake and wish to leave the game, simply tap 'Menu->Leave Game' with the touchscreen.", + "touchScreenText": "TouchScreen", + "unableToCompleteTryAgainText": "Arr, we be unable to do that now.\nYe' be patient for now!", + "unableToResolveHostText": "Arr, seems like we've hit a snag.", + "unavailableNoConnectionText": "Arrr! This is currently unavailable (in the storm?)", + "vrOrientationResetCardboardText": "Use this to reset yarr compass.\nTo ride this ship ye need an external wheel.", + "vrOrientationResetText": "Spin reset.", + "willTimeOutText": "(will throw ya off the ship if idle)" + }, + "inventoryText": "Treasure n' Booties", + "jumpBoldText": "BOING", + "jumpText": "Boing", + "keepText": "Hoard", + "keepTheseSettingsText": "Hoard these ship configs?", + "keyboardChangeInstructionsText": "Smash space twice to change yerr keyboard.", + "keyboardNoOthersAvailableText": "Arrr! Ya don't have any other keyboards!", + "keyboardSwitchText": "Switching yerr keyboard to \"${NAME}\".", + "kickOccurredText": "${NAME} was thrown off the ship.", + "kickQuestionText": "Throw ${NAME} off the ship?", + "kickText": "Throw off the ship", + "kickVoteCantKickAdminsText": "Ya wanna throw the cap'ain off the ship? Yar crazy?", + "kickVoteCantKickSelfText": "Ya can't throw yerself into the sharks!", + "kickVoteFailedNotEnoughVotersText": "ya need more pirates for tryin to throw em off.", + "kickVoteFailedText": "Arrr! we couldn't throw em off.", + "kickVoteStartedText": "Yarr! Someone wants to throw ${NAME} off the ship.", + "kickVoteText": "Try to throw em off?", + "kickVotingDisabledText": "Yarr! this ship is peaceful.", + "kickWithChatText": "Write ${YES} in the scroll for yes and ${NO} for no.", + "killsTallyText": "${COUNT} executions", + "killsText": "Executions", + "kioskWindow": { + "easyText": "OS", + "epicModeText": "That One Mode Where Everyone Goes Sweaty Gamer Mode In", + "fullMenuText": "The Actual Ship", + "hardText": "OSOGOF", + "mediumText": "OSOG", + "singlePlayerExamplesText": "Cap'ain Mode Examples", + "versusExamplesText": "Battle Mode Examples" + }, + "languageSetText": "Ye are now read'n \"${LANGUAGE}", + "lapNumberText": "Lap ${CURRENT}/${TOTAL} (Arrr!)", + "lastGamesText": "(last ${COUNT} battles)", + "leaderboardsText": "Wanted Poster", + "league": { + "allTimeText": "Ever", + "currentSeasonText": "Present Tide (${NUMBER})", + "leagueFullText": "${NAME} Tide", + "leagueRankText": "Crew Standin", + "leagueText": "Tide", + "rankInLeagueText": "#${RANK}, ${NAME} Tide${SUFFIX}", + "seasonEndedDaysAgoText": "The season met its end ${NUMBER} days back, matey.", + "seasonEndsDaysText": "The season be settin' sail in ${NUMBER} days!", + "seasonEndsHoursText": "The season be comin' to a close in ${NUMBER} hours!", + "seasonEndsMinutesText": "The season be endin' in a mere ${NUMBER} minutes!", + "seasonText": "Tide ${NUMBER}", + "tournamentLeagueText": "Ye must climb to the ranks of the ${NAME} crew to enter this tournament.", + "trophyCountsResetText": "Trophy tallies be settin' sail anew come the next season.", + "upToDateBonusDescriptionText": "arrrr, thy game version be too old,\nupdate it for a ${PERCENT}% morr points.", + "upToDateBonusText": "Modern Boat Bonus" + }, + "learnMoreText": "But wait captain, THERE'S MORE!!!", + "levelBestScoresText": "Finest marks on ${LEVEL}", + "levelBestTimesText": "Finest times on ${LEVEL}", + "levelIsLockedText": "${LEVEL}\" be bolted tight, matey.", + "levelMustBeCompletedFirstText": "Ye must first sail ${LEVEL}", + "levelText": "Tide ${NUMBER}", + "levelUnlockedText": "Tide Freed!", + "livesBonusText": "Extra Lives Bounty", + "loadingText": "Anchors Aweigh", + "loadingTryAgainText": "Setting Sail; Try again in a blink of the eye...", + "macControllerSubsystemBothText": "Both (not advis'd)", + "macControllerSubsystemClassicText": "Timeless", + "macControllerSubsystemDescriptionText": "(try adjustin' this if yer controllers be actin' up)", + "macControllerSubsystemMFiNoteText": "Spotted a Made-for-iOS/Mac controller, matey! \nYe might want to hoist 'em up in Settings -> Controllers.", + "macControllerSubsystemMFiText": "Crafted for iOS/Mac", + "macControllerSubsystemTitleText": "Controller Aid", + "mainMenu": { + "creditsText": "Salutes", + "demoMenuText": "Trial Tavern", + "endGameText": "Cease the Gambol", + "endTestText": "Finish the Trial", + "exitGameText": "Abandon the Quest", + "exitToMenuText": "Abandon Ship and Return to the Chart?", + "howToPlayText": "Learn The Ropes", + "justPlayerText": "(Only pirate ${NAME})", + "leaveGameText": "Abandon Ship", + "leavePartyConfirmText": "Arr, ye sure about really abandonin the crew?", + "leavePartyText": "Abandon Crew", + "quitText": "Belay", + "resumeText": "Return", + "settingsText": "Chart Your Course" + }, + "makeItSoText": "Aye, Set Sail!", + "mapSelectGetMoreMapsText": "Find More Charts...", + "mapSelectText": "Choose...", + "mapSelectTitleText": "${GAME} Charts", + "mapText": "Chart", + "maxConnectionsText": "Max Shipmates", + "maxPartySizeText": "Max Crew Size", + "maxPlayersText": "Max Pirates", + "merchText": "Booty for Sale!", + "modeArcadeText": "Tavern Brawl", + "modeClassicText": "Old Salt's Mode", + "modeDemoText": "Teaser Mode", + "moreSoonText": "More be arrivin' soon...", + "mostDestroyedPlayerText": "Most Shipwrecked Pirate", + "mostValuablePlayerText": "Most Wanted Pirate", + "mostViolatedPlayerText": "Most Sunken Pirate", + "mostViolentPlayerText": "Most Dreaded Pirate", + "moveText": "Shove off", + "multiKillText": "${COUNT}-SLAY!!!", + "multiPlayerCountText": "${COUNT} pirateers", + "mustInviteFriendsText": "Note: ye must invite shipmates \nin the \"${GATHER}\" panel \nor put on a controller to sail with ye crew.", + "nameBetrayedText": "${NAME} hornswaggled ${VICTIM}.", + "nameDiedText": "${NAME} met Davy Jones.", + "nameKilledText": "${NAME} sent ${VICTIM} to the briny deep.", + "nameNotEmptyText": "Ye forgot to hoist yer flag!", + "nameScoresText": "${NAME} Plunders!", + "nameSuicideKidFriendlyText": "${NAME} jumped o'r board.", + "nameSuicideText": "${NAME} walked the plank.", + "nameText": "Moniker", + "nativeText": "Landlubber", + "newExclaimText": "Straight out of the deep sea!", + "newPersonalBestText": "New personal record on the logbook!", + "newTestBuildAvailableText": "A fresher trial version be ready! (${VERSION} build ${BUILD}).\nFetch it at ${ADDRESS}", + "newText": "Craft", + "newVersionAvailableText": "A fresher version of ${APP_NAME} be ready to set sail! (${VERSION})", + "nextAchievementsText": "Next Booty to Plunder:", + "nextLevelText": "Next Dock", + "noAchievementsRemainingText": "- none...?", + "noContinuesText": "(no escaping from death)", + "noExternalStorageErrorText": "Yo dont have a exxterrnal storage on yor deviz", + "noGameCircleText": "There's an issue cap'ain: yer not logged into gameball", + "noMessagesText": "Nary a message.", + "noPluginsInstalledText": "No Modifications Are On The Ship Cap'ain", + "noScoresYetText": "No one has sailed near this land sir.", + "noServersFoundText": "Arrrgh! No bays in sight!", + "noThanksText": "Arghhhh...", + "noTournamentsInTestBuildText": "Captain! Yer ship is unstable, they won't let us take 'er to tournaments.", + "noValidMapsErrorText": "Pirates haven' found a dock worthy of this ba'le.", + "notEnoughPlayersRemainingText": "Aarghhh! Not enough pirates are battling here; we should go elsewhere cap'ain.", + "notEnoughPlayersText": "Cap'ain! We need at least ${COUNT} pirates to go on this journey.", + "notEnoughTicketsText": "Yer don't got enough tickets!", + "notNowText": "Not Now Captain...", + "notSignedInErrorText": "Yer must show an ID to enter.", + "notSignedInGooglePlayErrorText": "Ya must be accompanied by Google Play to enter.", + "notSignedInText": "no ID", + "notUsingAccountText": "Note: ignoring ${SERVICE} ID.\nGo to 'Account -> Be accompanied by ${SERVICE}' if yar want to use it.", + "nothingIsSelectedErrorText": "YER HAVEN'T SELECTED ANYTHING YA MORO- I mean cap'ain. (please don't make me walk the plank sir)", + "numberText": "#${NUMBER}", + "offText": "NARRR", + "okText": "Ok", + "onText": "YARRR", + "oneMomentText": "Wait a bit sir...", + "onslaughtRespawnText": "${PLAYER} will get back to the dock in wave ${WAVE} cap'ain!", + "openMeText": "the treasure be yours!", + "openNowText": "tearrr it open", + "openText": "crack", + "orText": "${A} or ${B}", + "otherText": "Other...", + "outOfText": "(#${RANK} out of ${ALL})", + "ownFlagAtYourBaseWarning": "Yer own flag must fly high at \nyer base to tally yer score!", + "partyWindow": { + "chatMessageText": "spit it out", + "emptyText": "Yer ship is empty", + "hostText": "(captain)", + "sendText": "->", + "titleText": "Yer Ship" + }, + "pausedByHostText": "(halted by the captain)", + "perfectWaveText": "Clean Abaft!", + "pickUpText": "Lift", + "playModes": { + "coopText": "Treasure-Rush", + "freeForAllText": "Rafts", + "multiTeamText": "Multi-Ship", + "singlePlayerCoopText": "Captain Mode / Treasure-Rush", + "teamsText": "Ships" + }, + "playText": "Set Sail", + "playWindow": { + "oneToFourPlayersText": "1-4 pirates", + "titleText": "Set Sail", + "twoToEightPlayersText": "2-8 pirates" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} will get on the dock once the next fight begins.", + "playerInfoText": "Pirate Info", + "playerLeftText": "${PLAYER} abandoned the ship, je was verry cowarr'", + "playerLimitReachedText": "Aarggh. We can't bring more than ${COUNT} pirates on this dock; stay on the ship.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "You can't erase who you are, captain; if that even is your real n-", + "deleteButtonText": "Erase\nFake ID", + "deleteConfirmText": "Erase '${PROFILE}'?", + "editButtonText": "Edit\nFake ID", + "explanationText": "(fake IDs you have gathered over the years)", + "newButtonText": "New\nFake ID", + "titleText": "Fake IDs" + }, + "playerText": "Pirate", + "playlistNoValidGamesErrorText": "None of these scurvy dogs can understand this scroll.", + "playlistNotFoundText": "scroll not found", + "playlistText": "Scroll", + "playlistsText": "Scrolls", + "pleaseRateText": "If ye be enjoyin' ${APP_NAME}, kindly consider takin' a moment \nto rate it or scribe a review. \nThis be providin' valuable feedback and helps chart the course for future development.\n\nCheers!\n-eric", + "pleaseWaitText": "We will get there cap'ain, eventually...", + "pluginClassLoadErrorText": "Arrrgh we weren't able to load '${PLUGIN}' onto the ship: ${ERROR}", + "pluginInitErrorText": "These landlubbers couldn't install the '${PLUGIN}' onto yer ship cap'ain: ${ERROR}", + "pluginSettingsText": "Modification Control Room", + "pluginsAutoEnableNewText": "Install All New Modifications Once Brought Onboard", + "pluginsDetectedText": "New modification(s) are bein' installed cap'ain, they'll be ready next time. Ye can check on those scallywags.", + "pluginsDisableAllText": "Remove All Modifications From Me Ship", + "pluginsEnableAllText": "Install All Modifications Onboard", + "pluginsRemovedText": "Captain! ${NUM} modification(s) ain' on this ship no more! Some son of a biscuit eater has stolen yer goods!", + "pluginsText": "Modifications", + "practiceText": "Trainin'", + "pressAnyButtonPlayAgainText": "We are ready to fight for glory once more! Waitin' for yer command cap'ain...", + "pressAnyButtonText": "We are waitin' for yer command cap'ain...", + "pressAnyButtonToJoinText": "We will join the battle with the smallest move of yerr succulent lips cap'ain...", + "pressAnyKeyButtonPlayAgainText": "We are ready to fight for glory once more! Waitin' for yer command cap'ain...", + "pressAnyKeyButtonText": "We are waitin' for yer command cap'ain...", + "pressAnyKeyText": "We are waitin' for yer command cap'ain...", + "pressJumpToFlyText": "** Jump t' catch that Peter Pan! **", + "pressPunchToJoinText": "press HOOK to get aboard the ship...", + "pressToOverrideCharacterText": "hit ${BUTTONS} to send in a differen' landlubber", + "pressToSelectProfileText": "hit ${BUTTONS} to select which ID yerr wanna go in with", + "pressToSelectTeamText": "hit ${BUTTONS} to choose which ship yar wanna help out", + "promoCodeWindow": { + "codeText": "Magic Numbe's", + "enterText": "Smash" + }, + "promoSubmitErrorText": "Aargh! our magic numbers didn' make it through the seas; try again on a calmer night", + "ps3ControllersWindow": { + "macInstructionsText": "Arrr, Switch off the power on the back of yer PS3, \nthen make sure yer Bluetooth be enabled on yer Mac. \nThen, connect yer controller to yer Mac via a USB cable to pair the two. \nFrom then on, ye can use the controller's home button to connect it to yer Mac in either wired (USB) \nor wireless (Bluetooth) mode.\n\n\nOn some Macs, ye may be prompted for a passcode when pairing. \nIf this happens, see the followin' tutorial or google for help.\n\n\n\nPS3 controllers connected wirelessly should show up in the device list in System Preferences->Bluetooth. \nYe may need to remove them from that list when ye want to use them with yer PS3 again.\n\n\nAlso, make sure to disconnect them from Bluetooth when not in use, \nor their batteries will continue to drain.\n\nBluetooth should handle up to 7 connected devices, \nthough yer mileage may vary.", + "ouyaInstructionsText": "to use yer damn ps3 thingamajig with ya dead console, just connect it with a USB cable\nfor once to make em fall in love. Doin' this may disconnect other thingamajigs, so\nyarr should then kill the dead thing and unplug the USB cable.\n\nAfter that the thingamajig's HOME button makes a mythical connection\nto yer ship. When yerr done sailin', SMASH that HOME button for 10 hours\nto kill the thingimajig; otherwise it will need the men to work harder\non the head.", + "pairingTutorialText": "*insert edgy joke with pirate slang here*", + "titleText": "Usin' ps3 thingamajigs with ${APP_NAME}:" + }, + "punchBoldText": "HOOK", + "punchText": "Hook", + "purchaseForText": "Pay up ${PRICE}", + "purchaseGameText": "if you're seeing this message in-game, something really bad must have happened", + "purchaseNeverAvailableText": "Arrrgh! These lily livered bilge suckers will never let us buy stuff on this dock.\nWe should try going to a differen' dock with the same IDs and buy supplies from there.", + "purchaseNotAvailableText": "These landlubbers aren't sellin' this.", + "purchasingText": "Buying... (arrr?)", + "quitGameText": "Walk ${APP_NAME}'s planks?", + "quittingIn5SecondsText": "CBF Detected, Loser! Quitting in 5 seconds...", + "randomPlayerNamesText": "DEFAULT_NAMES, Vaporeon, Jolly Roger, Fenix, Calico Jack, Blackbeard, Anne Bonny, William Kidd, Aegea, Alistair, Echo", + "randomText": "Dice", + "rankText": "Rank", + "ratingText": "Rating", + "reachWave2Text": "Survive at least the first batch of scallywags cap'ain.", + "readyText": "man o' war", + "recentText": "Newborn", + "remoteAppInfoShortText": "${APP_NAME} be most jolly when played with kin & shipmates.\nConnect one or more hardware controllers or install the\n${REMOTE_APP_NAME} app on phones or tablets to use 'em\nas controllers.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Button Position", + "button_size": "Button Size", + "cant_resolve_host": "Can't find the dock cap'ain.", + "capturing": "Capturing...", + "connected": "Reached the dock.", + "description": "Use your phone or tablet as a controller with BombSquad.\nUp to 8 devices can connect at once for epic local multiplayer madness on a single TV or tablet.", + "disconnected": "Arrrgh they made us walk the plank cap'ain.", + "dpad_fixed": "fixed", + "dpad_floating": "floating", + "dpad_position": "D-Pad Position", + "dpad_size": "D-Pad Size", + "dpad_type": "D-Pad Type", + "enter_an_address": "What's the path, cap'ain", + "game_full": "These flibustiers aren't letting us in cap'ain.", + "game_shut_down": "The ship has sunken.", + "hardware_buttons": "Hardware Buttons", + "join_by_address": "Binnacle", + "lag": "Lag: ${SECONDS} seconds", + "reset": "Fix the ship", + "run1": "Rrrun 1", + "run2": "Rrrun 2", + "searching": "Searching for coffers...", + "searching_caption": "Tap on the name of a coffer to fight for it.\nMake sure you are on the same wifi network as the other pirates.", + "start": "Starrrt", + "version_mismatch": "Arrrgh! the shiip don't fit.\nWe have to update both the dock and the ship\nto join the fight!" + }, + "removeInGameAdsText": "We have to pay up for \"${PRO}\" to get rid of these pessky ads cap'ain.", + "removeInGameAdsTokenPurchaseText": "LIMITED TIME OFFERR: Get ANY type of coins to remove in-battle videos!", + "renameText": "Morrph", + "replayEndText": "End History", + "replayNameDefaultText": "Last Battle History", + "replayReadErrorText": "Errorr remembering history.", + "replayRenameWarningText": "Morrph \"${REPLAY}\" after a battle if you want to keep it; otherwise it will be forrgotten.", + "replayVersionErrorText": "Sorry, this memory was made in a different\nocean of the earth and can't be used.", + "replayWatchText": "Recall Memory", + "replayWriteErrorText": "Errorr creating memories aghhh.", + "replaysText": "Memories", + "reportPlayerExplanationText": "Use this email to report unfair ships, foul language, or other unethics.\nPlease descrribe below:", + "reportThisPlayerCheatingText": "Unfair ship", + "reportThisPlayerLanguageText": "Foul language rawrr..", + "reportThisPlayerReasonText": "What would you like to reporrt?", + "reportThisPlayerText": "Report This Sailor", + "requestingText": "Rrequesting...", + "restartText": "Sail again", + "retryText": "Retrry", + "revertText": "Revert", + "runText": "Speeeed", + "saveText": "Save", + "scanScriptsErrorText": "Errorrr scanning scrolls. see log for details.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} and ${NUM} other canon(s) need to be changed for the time ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} needs to be updated for the time ${API}.", + "scoreChallengesText": "Score Challenges", + "scoreListUnavailableText": "Score merits unavailable.", + "scoreText": "Scorre", + "scoreUnits": { + "millisecondsText": "Milliseconds", + "pointsText": "Points", + "secondsText": "Seconds" + }, + "scoreWasText": "(was ${COUNT})", + "selectText": "Select", + "sendInfoDescriptionText": "Delivers account and app state information to the developer.\nKindly include yer name or reason for sending.", + "seriesWinLine1PlayerText": "CONQUERS", + "seriesWinLine1TeamText": "DOMINATES", + "seriesWinLine1Text": "WINS THE", + "seriesWinLine2Text": "WARR!", + "settingsWindow": { + "accountText": "Arrcount", + "advancedText": "Tactics", + "audioText": "Arrdio", + "controllersText": "Equipment", + "graphicsText": "Boat Flag", + "playerProfilesMovedText": "Note: Ship captains have moved to the Account window in the main menu.", + "titleText": "Ship's Configurations" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(A humble contraption fer scribblin' with yer hands o' the helm!)", + "alwaysUseInternalKeyboardText": "Always stir virtually", + "benchmarksText": "Buoyancy & Stress-Tests", + "devToolsText": "Old Salt's Room", + "disableCameraGyroscopeMotionText": "Disable bird's-eye motion", + "disableCameraShakeText": "Stabilize the ship", + "disableThisNotice": "(you can disable this notice in advanced settings)", + "enterPromoCodeText": "Enter Chant", + "forTestingText": "Note: these values are only for testing and will be lost when the app exits.", + "helpTranslateText": "${APP_NAME}'s non-English translations are a community supported\neffort. If you'd like to contribute or correct a translation,\nfollow the link below. Thanks in advance! Arrrghhhhh......", + "insecureConnectionsDescriptionText": "Not the wisest course, but it might let ye set sail from\nblocked ports or tricky waters!", + "insecureConnectionsText": "Hoist the sails on uncharted seas", + "kickIdlePlayersText": "Cut off those keelhaulers", + "kidFriendlyModeText": "Kid-Friendly Mode (reduced violence, etc)", + "languageText": "Lingo", + "moddingGuideText": "Captain's Code o' Customizin'", + "moddingToolsText": "Orlop", + "mustRestartText": "You must restarrt the game for this to take effect.", + "netTestingText": "Network Testing", + "resetText": "Reset", + "sendInfoText": "Throw Yerr Bo'les", + "showBombTrajectoriesText": "Predict Yer Bomb's", + "showDemosWhenIdleText": "Display examples while yer be statue", + "showDeprecatedLoginTypesText": "Show ye olden ID types", + "showDevConsoleButtonText": "Let the old seadog help", + "showInGamePingText": "See how long it takes these scallywags to carry out yer commands", + "showPlayerNamesText": "Show Pirate Names", + "showUserModsText": "Reveal the Treasure Chest o' Mods", + "titleText": "Advanced", + "translationEditorButtonText": "${APP_NAME} Translation Editor", + "translationFetchErrorText": "translation status unavailable", + "translationFetchingStatusText": "checking translation status...", + "translationInformMe": "Inform me when my language needs updates", + "translationNoUpdateNeededText": "The current lingo be shipshape; huzzah!", + "translationUpdateNeededText": "**The current lingo be needin' some fresh winds!!**", + "vrTestingText": "VR Testing" + }, + "shareText": "Share", + "sharingText": "Sharing...", + "showText": "See", + "signInForPromoCodeText": "Ye must have a real ID for those to work cap'ain.", + "singleGamePlaylistNameText": "Just ${GAME}", + "singlePlayerCountText": "1 pirate", + "sizeLargeText": "Beeg", + "sizeMediumText": "Median", + "sizeSmallText": "Tiny", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Pirate Selection", + "Chosen One": "Bounty", + "Epic": "Epic Fights", + "Epic Race": "Epic Rush", + "FlagCatcher": "Steal the Booty", + "Flying": "Jolly Dreams", + "Football": "Flibustiers' Sport", + "ForwardMarch": "Fire in the Hole", + "GrandRomp": "Control the Island", + "Hockey": "Ice Battley", + "Keep Away": "Hold the Coffer", + "Marching": "Ship Defense", + "Menu": "Main Menu", + "Onslaught": "Slaughter", + "Race": "Rush", + "Scary": "Defend the Booty", + "Scores": "Doubloon List", + "Survival": "Scuttle", + "ToTheDeath": "Swashbuckle", + "Victory": "Screen of Glory" + }, + "spaceKeyText": "space", + "statsText": "Stats", + "stopRemindingMeText": "yaarr don't tell me about this here again", + "storagePermissionAccessText": "This here requires storage access", + "store": { + "alreadyOwnText": "Ye already own ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Plunders out in-game ads and bothersome screens\n• Unlocks more ship chartin'\n• Also has:", + "buyText": "Buy", + "charactersText": "Characters", + "comingSoonText": "Comin' soon...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad be free now, but since ye originally purchased it, ye be gettin' \nthe BombSquad Pro upgrade and ${COUNT} tickets as a thank-you. \nEnjoy the new features, and thank ye for yer support!\n-Eric (best captain)", + "holidaySpecialText": "'oliday special", + "howToSwitchCharactersText": "(go to \"${SETTINGS} -> ${PLAYER_PROFILES}\" to assign & customize characters)", + "howToUseIconsText": "(create global player profiles (in the account window) to use these)", + "howToUseMapsText": "(use these maps in yer own teams/free-for-all playlists)", + "iconsText": "Icons", + "loadErrorText": "Unable to load page.\n check yer internet connection.", + "loadingText": "loadin'", + "mapsText": "Maps", + "miniGamesText": "Minigames", + "oneTimeOnlyText": "(one time only)", + "purchaseAlreadyInProgressText": "A purchase o' this here item be already in progress.", + "purchaseConfirmText": "Purchase ${ITEM}?", + "purchaseNotValidError": "Yer purchase be not valid.\nHail ${EMAIL} if this be a mistake.", + "purchaseText": "Buy yer booty", + "saleBundleText": "Treasure Trove Sale!", + "saleExclaimText": "Bargain Ahoy!", + "salePercentText": "(${PERCENT}% off)", + "saleText": "Sale", + "searchText": "Search", + "teamsFreeForAllGamesText": "Teams / free-for-all games", + "totalWorthText": "*** ${TOTAL_WORTH} value! ***", + "upgradeQuestionText": "Upgrade?", + "winterSpecialText": "Winter special", + "youOwnThisText": "- ye own this here -" + }, + "storeDescriptionText": "8 Player Party Game Madness!\n\nBlast yer hearties (or the computer) in a tourney of explosive mini-games like Steal-the-Booty, Bomber-Ice-Battley, and Epic-Slow-Motion-Swashbuckle!\n\nEasy controls and broad controller support make it a breeze for up to 8 folks to get in on the action; ye can even use yer mobile devices as controllers via the free 'BombSquad Remote' app!\n\nGunpowder be at yer ship!\n\nVisit www.froemling.net/bombsquad for more info.", + "storeDescriptions": { + "blowUpYourFriendsText": "Blow to the sky yer mates.", + "competeInMiniGamesText": "Compete in mini-games rangin' from racin' to flyin'.", + "customize2Text": "Customize characters, mini-games, an' even the soundtrack.", + "customizeText": "Customize characters 'n create yer owns mini-game playlists.", + "sportsMoreFunText": "Sports be more fun with explosives.", + "teamUpAgainstComputerText": "Crew up against the computer." + }, + "storeText": "Store", + "submitText": "Submit", + "submittingPromoCodeText": "Submittin' Code...", + "successText": "Success!", + "supportEmailText": "If ye be experiencin' any problems wit' the\napp, please email ${EMAIL}.", + "teamNamesColorText": "Crew Names/Colors...", + "telnetAccessGrantedText": "Telnet access enabled.", + "telnetAccessText": "Telnet access detected; allow?", + "testBuildErrorText": "Dis test build be no longer active; please check fer a new version.", + "testBuildText": "Test Build", + "testBuildValidateErrorText": "Unable t' validate test build. (no net connection?)", + "testBuildValidatedText": "Test Build Validated; Enjoy!", + "thankYouText": "Thank ye fer yer support! Enjoy the game!!", + "threeKillText": "TRIPLE SCUTTLE!!", + "ticketsDescriptionText": "Tickets be a way to unlock pirates,\nlands, battles, and more in the store!\n\nTickets be only found in treasure chests\nfound in fighting, tourrrnaments and achievements.", + "timeBonusText": "Time Bonus", + "timeElapsedText": "Time Elapsed", + "timeExpiredText": "Time Expired", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Get coins", + "notEnoughTokensText": "Nah enough gold!", + "numTokensText": "${COUNT} Coins", + "openNowDescriptionText": "ye 'ave enough gold to open this \nhere now - or ye can give me some so\ni could fix me boat (10 zillion gold)", + "shinyNewCurrencyText": "BombSquad's shiny new currency.", + "tokenPack1Text": "Wee Token Pack", + "tokenPack2Text": "Medium Token Pack", + "tokenPack3Text": "Large Token Pack", + "tokenPack4Text": "Jumbo Token Pack", + "tokensDescriptionText": "Coins are used if you want chests to open faster\nand for other things for your ship/pirateers.\n\nYer can win coins in battles or buy them\nin bunches. Or get the Golden Tooth Pass for\ninfinite coins and never need anymore of 'em!", + "youHaveGoldPassText": "Ye 'ave a Gold Pass.\nAll token purchases be free.\nEnjoy!" + }, + "topFriendsText": "Top Hearties", + "tournamentCheckingStateText": "Checkin' tournament state; please wait...", + "tournamentEndedText": "This here tourney be over. A new one be comin' soon.", + "tournamentEntryText": "Tournament Entry", + "tournamentFinalStandingsText": "Last Standin's", + "tournamentResultsRecentText": "Recent Tournament Results", + "tournamentStandingsText": "Tournament Standings", + "tournamentText": "Tournament", + "tournamentTimeExpiredText": "Tournament Time Expired", + "tournamentsDisabledWorkspaceText": "Tournaments be disabled when workspaces be active.\nTo re-enable tournaments, turn off yer workspace and restart.", + "tournamentsText": "Tournaments", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000, matey!", + "Bernard": "Blackbeard Bernard", + "Bones": "Be bones, me hearty!", + "Butch": "Butch be", + "Easter Bunny": "Easter Pirate", + "Flopsy": "Flopsy", + "Frosty": "Frigid", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jumpy Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lootin' Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Scallywag", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixie", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Captain Christmas", + "Snake Shadow": "Serpent Shade", + "Spaz": "Sparrow", + "Taobao Mascot": "Taobao Jolly Roger", + "Todd McBurton": "Cap'n Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Trainin'", + "Infinite ${GAME}": "${GAME} War", + "Infinite Onslaught": "Slaughter War", + "Infinite Runaround": "Ship Defense War", + "Onslaught Training": "Slaughter Trainin'", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Pro Flibustiers' Sport", + "Pro Onslaught": "Pro Slaughter", + "Pro Runaround": "Pro Ship Defense", + "Rookie ${GAME}": "Scallywag ${GAME}", + "Rookie Football": "Scallywag Flibustiers' Sport", + "Rookie Onslaught": "Scallywag Slaughter", + "The Last Stand": "Th' Final Battl'n", + "Uber ${GAME}": "Old Salt ${GAME}", + "Uber Football": "Old Salt Flibustiers' Sport", + "Uber Onslaught": "Old Salt Slaughter", + "Uber Runaround": "Old Salt Ship Defense" + }, + "displayItemNames": { + "${C} Tickets": "${C} Tickets (or playing cards)", + "${C} Tokens": "${C} Coins (arr)", + "Chest": "Treasure Chest", + "L1 Chest": "L1 Treasure Chest (least shiny)", + "L2 Chest": "L2 Treasure Chest (kind o' shiny)", + "L3 Chest": "L3 Treasure Chest (strangely shiny)", + "L4 Chest": "L4 Treasure Chest (almost shiny)", + "L5 Chest": "L5 Treasure Chest (shiny!)", + "L6 Chest": "L6 Treasure Chest (shinier!)", + "Unknown Chest": "Treasure Chest with Something" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Have the bounty for some time to win.\nClaim the bounty by killing the pirate who has it.", + "Bomb as many targets as you can.": "Bomb as many targets as ye can.", + "Carry the flag for ${ARG1} seconds.": "Carry the Jolly Rowdy Roger fer ${ARG1} seconds.", + "Carry the flag for a set length of time.": "Carry the Jolly Redbeard Roger fer a set length o' time.", + "Crush ${ARG1} of your enemies.": "Crush ${ARG1} o' yer enemies.", + "Defeat all enemies.": "Swab the deck o' all foes.", + "Dodge the falling bombs.": "Dodge the fallin' bombs.", + "Final glorious epic slow motion battle to the death.": "Final glorious epic slow motion battle t' the death.", + "Gather eggs!": "Gather ye eggs, matey!", + "Get the flag to the enemy end zone.": "Get the Jolly Rowdy Roger t' the enemy end zone.", + "How fast can you defeat the ninjas?": "How fast can ye defeat the ninjas?", + "Kill a set number of enemies to win.": "Scuttle a set number o' enemies t' win.", + "Last one standing wins.": "Last one standin' wins.", + "Last remaining alive wins.": "Last matey standin' wins.", + "Last team standing wins.": "Last crew standin' wins.", + "Prevent enemies from reaching the exit.": "Stop yer foes from hittin' the exit, arrr!", + "Reach the enemy flag to score.": "Claim th' enemy banner t' score.", + "Return the enemy flag to score.": "Return the enemy Jolly Redbeard Roger t' score.", + "Run ${ARG1} laps.": "sail ${ARG1} laps.", + "Run ${ARG1} laps. Your entire team has to finish.": "Run ${ARG1} laps. Yer entire crew has t' finish.", + "Run 1 lap.": "sail 1 circuit.", + "Run 1 lap. Your entire team has to finish.": "Hoist the sails fer 1 lap. All hands must finish the race!", + "Run real fast!": "Run like the wind, matey!", + "Score ${ARG1} goals.": "Score ${ARG1} booty!", + "Score ${ARG1} touchdowns.": "Score ${ARG1} touchdowns.", + "Score a goal.": "bag a bounty.", + "Score a touchdown.": "plunder a touchdown.", + "Score some goals.": "Plunder some goals.", + "Secure all ${ARG1} flags.": "Hoist all ${ARG1} flags!", + "Secure all flags on the map to win.": "Hoist all flags on th' map t' claim victory!", + "Secure the flag for ${ARG1} seconds.": "Hoist the flag fer ${ARG1} ticks.", + "Secure the flag for a set length of time.": "Hoist the flag fer a spell o' time.", + "Steal the enemy flag ${ARG1} times.": "Snatch th' enemy's flag ${ARG1} times, matey!", + "Steal the enemy flag.": "Plunder the foe's flag.", + "There can be only one.": "There be only one!", + "Touch the enemy flag ${ARG1} times.": "Give th' enemy flag a good poke ${ARG1} times.", + "Touch the enemy flag.": "Touch th' enemy flag.", + "carry the flag for ${ARG1} seconds": "carry the Jolly Redbeard Roger fer ${ARG1} seconds", + "kill ${ARG1} enemies": "scuttle ${ARG1} enemies", + "last one standing wins": "last one standin' wins", + "last team standing wins": "last crew standin' wins", + "return ${ARG1} flags": "return ${ARG1} Jolly Rogers", + "return 1 flag": "return 1 Jolly Redbeard Roger", + "run ${ARG1} laps": "sail ${ARG1} laps", + "run 1 lap": "sail 1 circuit", + "score ${ARG1} goals": "score ye ${ARG1} goals, matey", + "score ${ARG1} touchdowns": "score ${ARG1} touchdowns, ye scallywag!", + "score a goal": "bag a bounty", + "score a touchdown": "plunder a touchdown", + "secure all ${ARG1} flags": "secure all yer ${ARG1} flags, savvy?", + "secure the flag for ${ARG1} seconds": "plunder the flag fer ${ARG1} ticks", + "touch ${ARG1} flags": "tap yer ${ARG1} flags", + "touch 1 flag": "ye be touchin' 1 flag" + }, + "gameNames": { + "Assault": "Fire in the Hole", + "Capture the Flag": "Steal the Booty", + "Chosen One": "Bounty", + "Conquest": "Control the Island", + "Death Match": "Swashbuckle", + "Easter Egg Hunt": "Egg Hunt o' Easter", + "Elimination": "Scuttle", + "Football": "Flibustiers' Sport", + "Hockey": "Ice Battley", + "Keep Away": "Hold the Coffer", + "King of the Hill": "Defend the Booty", + "Meteor Shower": "Meteor Broadsides", + "Ninja Fight": "Ninja Battle", + "Onslaught": "Slaughter", + "Race": "Rush", + "Runaround": "Ship Defense", + "Target Practice": "Target Practicin'", + "The Last Stand": "Thar Final Stand" + }, + "inputDeviceNames": { + "Keyboard": "Plank o' keys", + "Keyboard P2": "Keybeard P2" + }, + "languages": { + "Arabic": "Arrr, Arabic be it!", + "Belarussian": "Belarusian Scallywag", + "Chinese": "Chinesey Simplified", + "ChineseTraditional": "Chinaman's Olde", + "Croatian": "Croatian lass", + "Czech": "Czech, matey!", + "Danish": "Danish scallywag", + "Dutch": "Dutchy", + "English": "English, matey", + "Esperanto": "Arrr, Esperanto!", + "Filipino": "Filipino matey", + "Finnish": "Finnish, aye", + "French": "Frenchy", + "German": "German, aye!", + "Gibberish": "Blather", + "Greek": "Greek", + "Hindi": "Arrr, Hindi!", + "Hungarian": "Hungarian, arrr!", + "Indonesian": "Indonesian be", + "Italian": "Italin'", + "Japanese": "Japanese", + "Korean": "Korey", + "Malay": "Malaysie", + "Persian": "Persian Sea Dog", + "PirateSpeak": "Pirate Speak", + "Polish": "Polish", + "Portuguese": "Portuguese, matey!", + "Romanian": "Romanian, me hearty!", + "Russian": "Russian", + "Serbian": "Serbiarr", + "Slovak": "Slovak scallywag", + "Spanish": "Spanish matey", + "Swedish": "Swedisher", + "Tamil": "Tamin", + "Thai": "Thai be", + "Turkish": "Turk", + "Ukrainian": "Ukrainian Sea Dog", + "Venetian": "Venetian scallywag", + "Vietnamese": "Vietnamin'!" + }, + "leagueNames": { + "Bronze": "Bronze be", + "Diamond": "Shiny gem", + "Gold": "Dubloons", + "Silver": "Argent" + }, + "mapsNames": { + "Big G": "Cap'n G", + "Bridgit": "Bridgit", + "Courtyard": "Hearties' Haven", + "Crag Castle": "Crag Fortress", + "Doom Shroom": "Doom Shroom, matey", + "Football Stadium": "Flibustiers' Ground", + "Happy Thoughts": "Jolly Dreams", + "Hockey Stadium": "Icy Field", + "Lake Frigid": "Frigid Cove", + "Monkey Face": "Monkey Mug", + "Rampage": "Ruckus", + "Roundabout": "Roundabout, matey", + "Step Right Up": "Step Right Aboard", + "The Pad": "Th' Corsair's Cradle", + "Tip Top": "Tip Top", + "Tower D": "D Tower", + "Zigzag": "Zigzag, matey!" + }, + "playlistNames": { + "Just Epic": "Just Bonkers", + "Just Sports": "Jest Sportin'" + }, + "scoreNames": { + "Flags": "Jolly Rogers", + "Goals": "booty", + "Score": "Plunder", + "Survived": "Be survivin'!", + "Time": "Tide", + "Time Held": "Time Captured" + }, + "serverResponses": { + "A code has already been used on this account.": "A codex be already in use on this account, matey.", + "A reward has already been given for that address.": "A bounty's already been served fer that location, matey.", + "Account linking successful!": "Account linkin' be a success, matey!", + "Account unlinking successful!": "Account be unlinked, savvy!", + "Accounts are already linked.": "Accounts be already linked, matey.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Ad view be not verified, matey.\n Make sure ye be usin' an official and up-to-date version o' the game.", + "An error has occurred; (${ERROR})": "A blunder beha' happened; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Arrr! A blunder be afoot; seek out the support crew. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "A blunder be happened; do contact support@froemling.net.", + "An error has occurred; please try again later.": "A mishap be happenin'; try again later, matey.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Be ye sure ye want to link these accounts? \n\n${ACCOUNT1} \n${ACCOUNT2} \n\nThis deed can't be undone!", + "BombSquad Pro unlocked!": "BombSquad Pro be unlocked, arrr!", + "Can't link 2 accounts of this type.": "Ye can't be linkin' 2 accounts o' this sort.", + "Can't link 2 diamond league accounts.": "Can't be joinin' 2 diamond league accounts, matey.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Can’t link; would be over ${COUNT} mateys linked accounts.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Cheatin' be detected; scores an' booty suspended fer ${COUNT} days.", + "Could not establish a secure connection.": "Couldn’t forge a trusty link, matey.", + "Daily maximum reached.": "Arrr, daily max be hit!", + "Daily sign-in reward": "Reward fer daily boardin' the ship", + "Entering tournament...": "Settin' sail fer the tournament...", + "Invalid code.": "Code be invalid, matey.", + "Invalid payment; purchase canceled.": "Ye payment be invalid; yer buyin' be scuttled.", + "Invalid promo code.": "Ye be using a scallywag promo code!", + "Invalid purchase.": "Ye be makin' a wrong buy.", + "Invalid tournament entry; score will be ignored.": "Blasted tournament entry be invalid; yer score be ignored!", + "Item unlocked!": "Ye be unlockin' an item!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKING DENIED. ${ACCOUNT} be havin' \nimportant treasure that'd ALL BE LOST. \nYe can link it in the opposite order if ye fancy\n(and lose THIS account's booty instead)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Be ye wantin' to link account ${ACCOUNT} to this here account? \nAll treasure on ${ACCOUNT} be settin' sail to \nDavy Jones' locker. This be irreversible. Be ye certain?", + "Longer streaks lead to better rewards.": "better treasures awaits them o' brave 'earts", + "Max number of playlists reached.": "Aye, ye've hit th' max o' playlists!", + "Max number of profiles reached.": "Ye've hit the max o' profiles, matey!", + "Maximum friend code rewards reached.": "Ye be hittin’ the max friend code booty!", + "Message is too long.": "The message be too long, matey.", + "New tournament result!": "New result for yer last battle!", + "No servers are available. Please try again soon.": "No servers be available. Try again soon, matey.", + "No slots available. Free a slot and try again.": "No room for yer booty. Open them for room and trrry again.", + "Profile \"${NAME}\" upgraded successfully.": "Profile o' ${NAME} be upgraded splendidly.", + "Profile could not be upgraded.": "Profile be unable t' be upgraded.", + "Purchase successful!": "Ye be buyin' successful!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Got yer ${COUNT} tickets fer signin' in.\nReturn tomorrow fer ${TOMORROW_COUNT} more!", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Server be out o' service in this version o' the game;\nUpdate to a newer version, matey.", + "Sorry, there are no uses remaining on this code.": "Arrr, no uses be left fer this code, matey.", + "Sorry, this code has already been used.": "Arrr, this code be already used, matey.", + "Sorry, this code has expired.": "Arrr, this code be expired, matey.", + "Sorry, this code only works for new accounts.": "Arrr, this code be workin' only fer fresh accounts!", + "Sorry, this has expired.": "Arr! Tis' be from too long ago!", + "Still searching for nearby servers; please try again soon.": "Still huntin' fer nearby ships; try again shortly, matey.", + "Streak: ${NUM} days": "days with no accidents: ${NUM}", + "Temporarily unavailable; please try again later.": "Be out o' reach fer now; please try again later, matey.", + "The tournament ended before you finished.": "The tourney be over 'fore ye finished.", + "This account cannot be unlinked for ${NUM} days.": "This account be stuck fer ${NUM} days.", + "This code cannot be used on the account that created it.": "This code be not fer use on the account that made it.", + "This is currently unavailable; please try again later.": "This be not available now; try again later, matey.", + "This requires version ${VERSION} or newer.": "This be needin' version ${VERSION} or newer, matey.", + "Tournaments disabled due to rooted device.": "Tournaments be disabled 'cause o' rooted contraption.", + "Tournaments require ${VERSION} or newer": "Tournaments be needin' ${VERSION} or newer, matey!", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Be ye wantin' t' unlink ${ACCOUNT} from this account?\nAll treasure on ${ACCOUNT} be reset.\n(Except fer achievements in some cases, arr!)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ARRR: Beware! Complaints o' hackin' be raised against yer account.\nAccounts caught hackin' shall be banned. Play fair, me hearty!", + "Wait reduced!": "Ye no more need for waitin'!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "WARNING: the version o' this ship is limited to old pirate data; stuff may appear missin' or outdated.\nPlease upgrade to newer ship so ye can see your latest pirate data.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Be ye wantin' to link yer device account to this one?\n\nYe device account be ${ACCOUNT1}\nThis account be ${ACCOUNT2}\n\nThis be lettin' ye keep yer current progress.\nArrr: this can’t be undone!", + "You already own this!": "Ye already be ownin' this!", + "You can join in ${COUNT} seconds.": "Ye can join in ${COUNT} heartbeats.", + "You don't have enough tickets for this!": "Ye ain't got enough tickets fer this!", + "You don't own that.": "Ye don't be ownin' that.", + "You got ${COUNT} tickets!": "Ye got ${COUNT} tickets, matey!", + "You got ${COUNT} tokens!": "Ye be gettin ${COUNT} coins, matey!", + "You got a ${ITEM}!": "Ye got a ${ITEM}!", + "You got a chest!": "Yer got yerself a treasure chest! Ehyyyy!!!", + "You got an achievement reward!": "Yer got a achievement shiny!", + "You have been promoted to a new league; congratulations!": "Ye be promoted to a new league; congrats, matey!", + "You lost a chest! (All your chest slots were full)": "Arr! Ye be lost yer treasure! (All room for booty were taken)", + "You must update the app to view this.": "Ye be needin' t' update th' app t' see this.", + "You must update to a newer version of the app to do this.": "Ye be needin' t' upgrade t' a fresh version o' th' app t' do this.", + "You must update to the newest version of the game to do this.": "Ye be needin' t' update t' the latest version o' th' game t' do this.", + "You must wait a few seconds before entering a new code.": "Ye be needin' to wait a spell 'fore ye enter a new code.", + "You placed #${RANK} in a tournament!": "Ye' be placed #${RANK} in the last battle!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ye be ranked #${RANK} in th' last tournament. Arrr, thanks fer playin'!", + "Your account was rejected. Are you signed in?": "Yer account be rejected, matey. Be ye signed in?", + "Your ad views are not registering. Ad options will be limited for a while.": "Yerr' be not watching the videos (or just not registering). We be limitin them for now.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ye copy o' the game be altered.\nPlease undo any changes and give it another go.", + "Your friend code was used by ${ACCOUNT}": "Ye matey code be usin' by ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Tick o' the Clock", + "1 Second": "1 Heartbeats", + "10 Minutes": "10 Tick o' the Clock", + "2 Minutes": "2 Tick o' the Clock", + "2 Seconds": "2 Heartbeats", + "20 Minutes": "20 Tick o' the Clock", + "4 Seconds": "4 Heartbeats", + "5 Minutes": "5 Tick o' the Clock", + "8 Seconds": "8 Tickin' Seconds", + "Allow Negative Scores": "Let the Scallywags Score Negatively", + "Balance Total Lives": "Balance Total Lives, Arrr!", + "Bomb Spawning": "Powder Keg Spawnin'", + "Chosen One Gets Gloves": "Bounty Has Strong Hooks", + "Chosen One Gets Shield": "Bounty Has Abs", + "Chosen One Time": "Bounty Time", + "Enable Impact Bombs": "Engage Impact Bombs, matey!", + "Enable Triple Bombs": "Unleash Triple Bombs", + "Entire Team Must Finish": "All Hands Must Complete", + "Epic Mode": "Epic Ahoy", + "Flag Idle Return Time": "Jolly Roger Idle Return Time", + "Flag Touch Return Time": "Jolly Roger Touch Back Time", + "Hold Time": "Avast Time", + "Kills to Win Per Player": "Kills t' Win Fer Player", + "Laps": "Laps, matey!", + "Lives Per Player": "Lives Fer Matey", + "Long": "Long John", + "Longer": "Longer", + "Mine Spawning": "Arrr, Spawnin' o' Mines", + "No Mines": "Nay Mines", + "None": "Naught", + "Normal": "Naught", + "Pro Mode": "Cap'n Mode", + "Respawn Times": "Rebirth Intervals", + "Score to Win": "Mark fer Victory", + "Short": "Brief", + "Shorter": "Briefer", + "Solo Mode": "Alone Mode", + "Target Count": "Target Count be", + "Time Limit": "Hourglass Boundary" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} be walkin' the plank 'cause ${PLAYER} abandoned ship", + "Killing ${NAME} for skipping part of the track!": "Slayin' ${NAME} for skippin' part o' the course!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Be warned, ${NAME}: Goin fast or button-breakin may knock ye out cold!" + }, + "teamNames": { + "Bad Guys": "Scoundrel Crew", + "Blue": "Sapphire", + "Good Guys": "Righteous Crew", + "Red": "Scarlet" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "A perfectly timed running-jumping-spin-punch can send a scallywag to \nDavy Jones' locker in a single blow and earn ye lifelong respect from yer mates.", + "Always remember to floss.": "Always be rememberin' to keep yer teeth shipshape, matey! Aye, and don't forget to floss!", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Craft player pirates for ye and yer mates with \nyer preferred names and looks, instead of relyin' on random ones.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Curse boxes turn ye into a ticking time bomb, matey. \nThe only cure be to swiftly snatch a health-pack afore ye blow", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Despite their appearances, all characters be possessin' the same abilities. \nSo choose the one that resembles ye the most!", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Don't be too cocksure with that energy shield, matey. Ye can still find yerself hurled off a cliff if ye ain't careful!", + "Don't run all the time. Really. You will fall off cliffs.": "Don't be sprintin' all the time, matey. Mark me words, ye'll find yerself overboard off cliffs if ye don't ease up!", + "Don't spin for too long; you'll become dizzy and fall.": "Don't be spinning for too long, lest ye become dizzy and keel over like a drunken sailor!", + "Hold any button to run. (Trigger buttons work well if you have them)": "Clutch any button to break into a run. (The trigger buttons be fine choices if ye have 'em aboard)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Clutch any button to break into a run. Ye'll cover ground quicker, but beware, \nye won't be turning on a dime, so keep a weather eye out for cliffs ahead!", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ice gunpowder may not pack much punch, but they freeze \nthe soul of whoever they strike, leaving 'em vulnerable to shattering.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "If a scallywag grabs ye, give 'em a good punch and they'll likely drop ye. \nWorks just as well on land as it does at sea!", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "If ye find yerself short on controllers, hoist the '${REMOTE_APP_NAME}' app onto yer mobile devices, \nand ye can steer yer ship with 'em just like a proper captain!", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "If ye find yerself stuck with a sticky-bomb, jump like a bilge rat and spin like a whirlpool. \nYe might just shake the blasted thing loose, or at least make a grand show of yer final moments!", + "If you kill an enemy in one hit you get double points for it.": "If ye send a foe to Davy Jones' locker in a single blow, ye'll be haulin' in double the booty for yer trouble.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "If ye be cursed by ill fate, yer only chance for survival be to spy out \na health powerup in the next few ticks o' the clock.", + "If you stay in one place, you're toast. Run and dodge to survive..": "If ye be stayin' anchored in one spot, ye'll be meetin' Davy Jones soon enough! Run and weave to keep the sharks at bay and yer ship afloat", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "If ye be havin' a swarm o' sailors joinin' and departin' yer ship, be sure to hoist the 'auto-kick-idle-players' flag \nin yer settings, lest any scallywag forgets to walk the plank", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "If yarr ship is getting too warrrm or you don't want it go down,\nTurn down the graphicky stuff.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Yarr ship is too slow?\nIf so then trry turnin the graphicky stuff down!", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "In Steal-the-Booty, yarr trreasure must be at boat to get their trrreasure!\nIf you steal theirrr coffer before they do, yarr might get a chance!", + "In hockey, you'll maintain more speed if you turn gradually.": "In Ice Battley,yarr can keep yarself runnin' if ya just slowlye turrrn.", + "It's easier to win with a friend or two helping.": "Yarr hire some pirate to help ya! It's betterrr.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Yarr jump as yarr's shootin' to take it more higherrr!", + "Land-mines are a good way to stop speedy enemies.": "Shoot the mine forr stoppin those runnin scallywags!!", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Yarr arrms can pick up any thing and thrrrow,Yarr can also thrrow some scallywags.\nThrrowing them offf the ship is yar best thinkin!", + "No, you can't get up on the ledge. You have to throw bombs.": "Arr, you can't get up there lad. You have to throw bombs.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Yarr pirates can join and abandon me ship at any time!\nThey can also brrring some and leave buttony stuff!", + "Practice using your momentum to throw bombs more accurately.": "Use yarr legs to shoot betterrrr!", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Swings be mightier the faster yer fists be movin', \nso try runnin', jumpin', and spinnin' like a whirlwind.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "rrun baack en forth before blasdtin\nto whip it into yerr enemies", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "if ya wanna get a buncha pirates out\nblast a powder near them powder cubes", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "as a wise captain once said:\n\"BE CAREFUL OF YER STUPID HEAD\"", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "these scallywags aint gonna stop coming, but the more ye kill\nthe more yer legends will spread accross the sea (arrrrr)", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "the powerr of yer throws is based on where yer walkin\nif ya want them in front of yer, then stop movin", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "tired of them shanties? replace it with yer owns!\nidk how tho", + "Try 'Cooking off' bombs for a second or two before throwing them.": "cook yer enemies some delicious powderrr", + "Try tricking enemies into killing eachother or running off cliffs.": "trick them bilge suckers into hittin eachother or runnin of yer ship", + "Use the pick-up button to grab the flag < ${PICKUP} >": "smash them ${PICKUP} button to grrrab them flag", + "Whip back and forth to get more distance on your throws..": "whip yer powder to get them blast further", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "ya can 'aim' yer fists like powder by whippin yer body.\nya can use this for knocking them lily livers off yer ship or claimin doubloons in ice age", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "ya can tell when the powder is gonna blast from them\ncolors hopin on the fuse: yeller..orange..red..BLAST!", + "You can throw bombs higher if you jump just before throwing.": "yer powderr can reach the top of them ship if ya jump before blastin", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "pirrates' skulls arre sensitive\ndont blast yer's into them walls", + "Your punches do much more damage if you are running or spinning.": "yer fists deal more than powderr if yer runnin or whippin" + } + }, + "trophiesRequiredText": "this thingy need them ${NUMBER} of yer treasures", + "trophiesText": "treasures", + "trophiesThisSeasonText": "yer treasures this season", + "tutorial": { + "cpuBenchmarkText": "yer tutorial is gonna fight yer CPU at the speed of 583153348.236 knots", + "phrase01Text": "Ahoy, Captain!", + "phrase02Text": "Welcome to ${APP_NAME}(its actually PowderTime(C) but ok)", + "phrase03Text": "here's a few tips on how to control yer pirate:", + "phrase04Text": "alotta stuff in ${APP_NAME} are SCIENCE based.", + "phrase05Text": "like when ya fist them enemies,...", + "phrase06Text": "..damage is based on the speed of yer fists.", + "phrase07Text": "Aye? We weren't movin, so that barely hurt them ${NAME}.", + "phrase08Text": "lets try jumpin and gettin dizzy to get more speed", + "phrase09Text": "Aye, that did the deed.", + "phrase10Text": "runnin is cool too captain.", + "phrase11Text": "smash ANY of them buttons to run", + "phrase12Text": "ya wanna be like jack? run AND spin.", + "phrase13Text": "(${NAME} was gonna walk yer plank anyways)", + "phrase14Text": "ya can pick up and throw alotta stuff, ${NAME} is just one example", + "phrase15Text": "and finally, powder", + "phrase16Text": "Hurlin' bombs be an art ye need to hone, matey.", + "phrase17Text": "Arrr! Ye call that a toss? That be a sorry excuse for a throw, matey!", + "phrase18Text": "movin helps ya powderr further", + "phrase19Text": "jumpin makes ya get higher", + "phrase20Text": "whiplashin them makes a hole in the ship even before the powder blasts!", + "phrase21Text": "timin them powder is a bit hard", + "phrase22Text": "err", + "phrase23Text": "let them powder \"cook\" for a bit", + "phrase24Text": "delicious!", + "phrase25Text": "Well, that be just about it.", + "phrase26Text": "go and take back the sea, captain", + "phrase27Text": "Remember yer training, and ye WILL come back alive!", + "phrase28Text": "...aye, mayhap..", + "phrase29Text": "Good luck mate!", + "randomName1Text": "Douglass", + "randomName2Text": "Morgan", + "randomName3Text": "Ironfist", + "randomName4Text": "Jones", + "randomName5Text": "Jack", + "skipConfirmText": "Are ye sure mate? Tap or press to confirm.", + "skipVoteCountText": "${COUNT}/${TOTAL} skip votes", + "skippingText": "skipping training... Arrrgh", + "toSkipPressAnythingText": "(tap or prress anything to skip training)" + }, + "twoKillText": "2x KILL!", + "uiScaleText": "UI Spyglass Magnification", + "unavailableText": "unavailable", + "unclaimedPrizesText": "ye 'ave unclaimed booty!", + "unconfiguredControllerDetectedText": "Unconfigured controller detected:", + "unlockThisInTheStoreText": "This must be unlocked in the shore.", + "unlockThisProfilesText": "To create more than ${NUM} pirates, ye need:", + "unlockThisText": "To unlock this, ye need:", + "unsupportedControllerText": "Arrr, that contraption by the name o' \"${NAME}\" be not a sailin' ship we support.", + "unsupportedHardwareText": "Sorrry mate, this harrdware is not supporrted by this build of the game.", + "upFirstText": "Up first:", + "upNextText": "Up next in game ${COUNT}:", + "updatingAccountText": "Updating your arrcount...", + "upgradeText": "Upgrade", + "upgradeToPlayText": "Ye need to get \"${PRO}\" in the gunpowder shore t' sail around here.", + "useDefaultText": "Use Default", + "userSystemScriptsCreateText": "Craft User System Scripts", + "userSystemScriptsDeleteText": "Blast User System Scripts from the plank", + "usesExternalControllerText": "This game uses an external controllerrr for input.", + "usingItunesText": "Using Music App for soungtrack...", + "v2AccountLinkingInfoText": "To share ye beauty pirate, tap that Manage Account.", + "v2AccountRequiredText": "This here needs a bilge sucking V2 ID to work. Go try getting one of those.", + "validatingTestBuildText": "Validating Test Build...", + "viaText": "by", + "victoryText": "Bounty !!!", + "voteDelayText": "Ye can't start anotherr vote for ${NUMBER} seconds", + "voteInProgressText": "A vote is already in prrogrrress...", + "votedAlreadyText": "Ye already voted", + "votesNeededText": "${NUMBER} votes needed arrrhh...", + "vsText": "V/s.", + "waitingForHostText": "(waiting for ${HOST} to set sail)", + "waitingForPlayersText": "waiting for pirates to join...", + "waitingInLineText": "Waiting in line (ship is full)... arrr...", + "watchAVideoText": "Scout a Ship", + "watchAnAdText": "Watch a Show", + "watchWindow": { + "deleteConfirmText": "Forget \"${REPLAY}\"?", + "deleteReplayButtonText": "Forget\nMemory", + "myReplaysText": "My Memories", + "noReplaySelectedErrorText": "No Memory Chosen", + "playbackSpeedText": "Memory Speed: ${SPEED}", + "renameReplayButtonText": "Rename\nMemory", + "renameReplayText": "Rename \"${REPLAY}\" to:", + "renameText": "Rename", + "replayDeleteErrorText": "Errorr forgetting memory. Arrr!!", + "replayNameText": "Memory Name", + "replayRenameErrorAlreadyExistsText": "A memory with that name already exists.", + "replayRenameErrorInvalidName": "Can't rename memory; invalid name. Arrr!", + "replayRenameErrorText": "Errorrr renaming memory.", + "sharedReplaysText": "Shared Memories", + "titleText": "Watch", + "watchReplayButtonText": "Watch yer\nmemory" + }, + "waveText": "Wave", + "wellSureText": "Sure Mate!", + "whatIsThisText": "And what tis supposed to be??", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright ©" + }, + "wiimoteListenWindow": { + "listeningText": "Listening For Weemotes...", + "pressText": "Prress Weemote buttons 1 and 2 togetherr. Arr!!!", + "pressText2": "On newerr Weemotes with Motion Plus built in, prress the red 'sink' button on the back instead." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Ahoy Listen", + "macInstructionsText": "Make sure your Wee is off and Goldtooth is enabled\non yer Mac, then prress 'Listen'. Weemote support can\nbe a bit yanky, so yer may have to trry a few times\nbefore yer get a connection.\n\nGoldtooth should handle up to 7 pirates,\nthough yer mileage may varry.\n\nBombSquad supports the original Weemotes, Nunchuks,\nand the Classic Controllerr.\nThe newer Wee Remote Plus now works too\nbut not with luggage.", + "thanksText": "Thanks to the DarwiinRemote gang\nFor making this possible. Arrr!!!\n", + "titleText": "Weemote setup arrr !" + }, + "winsPlayerText": "${NAME} Wins! Arrr !!!", + "winsTeamText": "${NAME} Wins! Arrrr !!!", + "winsText": "${NAME} Wins! Arrrr !!!", + "workspaceSyncErrorText": "Errrorrr sinking ${WORKSPACE}. See log for morrre.", + "workspaceSyncReuseText": "Can't sink ${WORKSPACE}. Reusing prrevious sinked verrrsion.", + "worldScoresUnavailableText": "Sea points arr gone.", + "worldsBestScoresText": "Best scorrr o all sailorrs", + "worldsBestTimesText": "Best times o all sailorrs", + "xbox360ControllersWindow": { + "getDriverText": "Get yer Drivers", + "macInstructions2Text": "to contrrol yer pirates, yaar also need them magic receivers thaart\ncome wit the 'CrrossBox magic contrroler for holes in yer ship'.\nget 1 magic receiver, powder with 4 pirrrrates!\n\n\nAvast ye! magic stuuf frrom the 3rrd class ships wont do magic!\nsmallcushion(Trademark pending) ain't selling em separately! yer need em\nfrom them bundle or yer can get em on the bay.\n\nif this makes ya go yarrrr then give the vrrroom vrroooom dev\nsome pieces of eight at his place", + "macInstructionsText": "ya need sum\nmac\ndrivers", + "ouyaInstructionsText": "to use them crros box 360(C) controllers with PowderTime(Trademark pending, simply\nplug em into yer plastic thing's USP port. yer can use a psp bob\nto have multiplee pirrrates\n\nte use them magical ones yer have to get a magic thingy,\ndunno where ya can get em\nbut\nit lets yarrr powder around with 4 pirrates!", + "titleText": "usin the crrross box contrrolers with ${APP_NAME}:" + }, + "yesAllowText": "Aye, Captain!", + "yourBestScoresText": "yer best doubloons", + "yourBestTimesText": "yer best times", + "yourPrizeText": "Yar treasure:" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/polish.json b/dist/ba_data/data/languages/polish.json index e5bee292..bc0dda39 100644 --- a/dist/ba_data/data/languages/polish.json +++ b/dist/ba_data/data/languages/polish.json @@ -1,18 +1,20 @@ { "accountSettingsWindow": { - "accountNameRules": "Nazwy kont nie mogą zawierać emotikonków ani innych znaków specjalnych", + "accountNameRules": "Nazwy kont nie mogą zawierać emotikonów, ani innych znaków specjalnych", "accountProfileText": "(profil konta)", "accountsText": "Konta", "achievementProgressText": "Osiągnięcia: ${COUNT} z ${TOTAL}", "campaignProgressText": "Postęp Kampanii [Trudny]: ${PROGRESS}", "changeOncePerSeason": "Możesz to zmienić tylko raz na sezon.", - "changeOncePerSeasonError": "Musisz poczekać do następnego sezonu by znowu to zmienić (${NUM} dni)", - "customName": "Losowa Nazwa", + "changeOncePerSeasonError": "Musisz poczekać do następnego sezonu, by znowu to zmienić (${NUM} dni)", + "createAnAccountText": "Stwórz Konto", + "customName": "Własna Nazwa", + "deleteAccountText": "Usuń konto", "googlePlayGamesAccountSwitchText": "Jeśli chcesz użyć innego konta Google,\nużyj aplikacji Gry Google Play, aby przełączyć się na to konto.", "linkAccountsEnterCodeText": "Wpisz Kod", "linkAccountsGenerateCodeText": "Wygeneruj Kod", "linkAccountsInfoText": "(przenoś postęp między różnymi platformami)", - "linkAccountsInstructionsNewText": "Aby połączyć dwa konta, wygeneruj kod na pierwszym,\ni wpisz ten kod na drugim. Postęp z drugiego\nbędzie podzielony między oba konta.\n(Postęp z pierwszego zostanie utracony)\n\nMożesz połączyć do ${COUNT} kont.\n\nWAŻNE: łącz tylko swoje własne konta;\nJeśli łączysz konto ze znajomym, nie będziecie\nmogli grać przez internet w tym samym czasie.", + "linkAccountsInstructionsNewText": "Aby połączyć dwa konta, wygeneruj kod na pierwszym\ni wpisz ten kod na drugim. Postęp z drugiego\nbędzie podzielony między oba konta.\n(Postęp z pierwszego konta zostanie utracony)\n\nMożesz połączyć do ${COUNT} kont.\n\nWAŻNE: łącz tylko swoje własne konta;\nJeśli łączysz konto ze znajomym, nie będziecie\nmogli grać przez internet w tym samym czasie.", "linkAccountsInstructionsText": "By połączyć dwa konta, wygeneruj kod\nna jednym z nich i wpisz na drugim.\nPostęp i ekwipunek zostaną połączone.\nMożesz połączyć do ${COUNT} kont.\n\nUWAGA: Łącz tylko konta, które należą do Ciebie!\nJeśli połączysz konto z przyjacielem,\nnie będziecie mogli grać w tym samym czasie!\n\nAktualnie nie można tego cofnąć, więc uważaj!", "linkAccountsText": "Połącz Konta", "linkedAccountsText": "Połączone Konta:", @@ -24,19 +26,21 @@ "resetProgressText": "Wyczyść postęp", "setAccountName": "Wybierz nazwę konta", "setAccountNameDesc": "Wybierz nazwę do wyświetlenia dla swojego konta.\nMożesz użyć nazwy z jednego z połączonych kont\n lub utworzyć unikalną niestandardową nazwę.", - "signInInfoText": "Zapisz się, by zbierać kupony, rywalizować online\ni przenosić postęp gry między urządzeniami", - "signInText": "Zapisz się", + "signInInfoText": "Zaloguj się, by zbierać kupony, rywalizować online\ni przenosić postęp gry między urządzeniami", + "signInText": "Zaloguj się", + "signInWithAnEmailAddressText": "Zaloguj się adresem email", "signInWithDeviceInfoText": "(automatyczne konto dostępne tylko z tego urządzenia)", - "signInWithDeviceText": "Zapisz się kontem z urządzenia.", - "signInWithGameCircleText": "Zapisz się z Game Circle", - "signInWithGooglePlayText": "Zapisz się kontem Google Play", - "signInWithTestAccountInfoText": "Konto.", - "signInWithTestAccountText": "Zapisz się testowym kontem.", + "signInWithDeviceText": "Zaloguj się kontem urządzenia", + "signInWithGameCircleText": "Zaloguj się z Game Circle", + "signInWithGooglePlayText": "Zaloguj się kontem Google Play", + "signInWithTestAccountInfoText": "(przestarzały typ konta; w przyszłości używaj konta urządzenia)", + "signInWithTestAccountText": "Zaloguj się kontem testowym", + "signInWithText": "Zaloguj się kontem ${SERVICE}", "signInWithV2InfoText": "(konto działa na wszystkich platformach)", - "signInWithV2Text": "Zaloguj się używając konta BombSquad", + "signInWithV2Text": "Zaloguj się kontem ${APP_NAME}", "signOutText": "Wypisz się", - "signingInText": "Zapisywanie się...", - "signingOutText": "Wypisywanie...", + "signingInText": "Trwa logowanie...", + "signingOutText": "Trwa wylogowywanie...", "testAccountWarningCardboardText": "Ostrzeżenie: Zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem Google w momencie\nwspierania gry przez Google Cardboard.\n\nOd tego momentu musisz zdobywać wszystkie kupony w grze.\n(zaktualizuj grę do wersji BombSquad Pro za darmo)", "testAccountWarningOculusText": "Ostrzeżenie: zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem oculusowym jeszcze w tym roku,\nktóre będzie oferowało zakup kuponów i inne funkcje.\n\nTeraz musisz zarobić wszystkie kupony grając.\n(jednakże możesz uzyskać aktualizację do wersji Pro za darmo)", "testAccountWarningText": "Ostrzeżenie: możesz się zapisać używając konta \"test\".\nTo konto jest powiązane z konkretnym urządzeniem i \nmoże okresowo się zresetować. (wobec tego proszę nie\nzbierać/odblokowywać rzeczy lub osiągnięć dla tego konta)", @@ -45,7 +49,7 @@ "unlinkAccountsInstructionsText": "Wybierz konto do rozłączenia", "unlinkAccountsText": "Rozłącz konta", "unlinkLegacyV1AccountsText": "Rozłącz stare konta (V1)", - "v2LinkInstructionsText": "Użyj tego linku aby stworzyć konto lub zaloguj się.", + "v2LinkInstructionsText": "Użyj tego linku, aby stworzyć konto lub zalogować się.", "viaAccount": "(przez konto ${NAME})", "youAreLoggedInAsText": "Jesteś zalogowany jako:", "youAreSignedInAsText": "Jesteś zalogowany jako:" @@ -54,11 +58,11 @@ "achievementText": "Osiągnięcia", "achievements": { "Boom Goes the Dynamite": { - "description": "Zabij 3 złych gości używając TNT", - "descriptionComplete": "Zabiłeś 3 złych gości używając TNT", + "description": "Zabij 3 złych gości, używając TNT", + "descriptionComplete": "Zabiłeś 3 złych gości, używając TNT", "descriptionFull": "Zabij 3 złych gości za pomocą TNT w trybie ${LEVEL}", "descriptionFullComplete": "Zabiłeś 3 złych gości za pomocą TNT w trybie ${LEVEL}", - "name": "Uwaga Leci Dynamit" + "name": "Uwaga, Leci Dynamit" }, "Boxer": { "description": "Wygraj bez używania bomb", @@ -73,15 +77,15 @@ "name": "Podwójne dzierżenie" }, "Flawless Victory": { - "description": "Wygraj nie dając się uderzyć", - "descriptionComplete": "Wygrałeś nie dając się uderzyć", - "descriptionFull": "Wygraj w trybie ${LEVEL} nie dając się uderzyć", - "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie dając się uderzyć", + "description": "Wygraj, nie dając się uderzyć", + "descriptionComplete": "Wygrałeś, nie dając się uderzyć", + "descriptionFull": "Wygraj w trybie ${LEVEL}, nie dając się uderzyć", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL}, nie dając się uderzyć", "name": "Zwycięstwo bez skazy" }, "Free Loader": { "descriptionFull": "Zacznij grę Free-For-All z dwoma graczami lub więcej", - "descriptionFullComplete": "Zaczęto grę Free-For-All z dwoma, lub większą ilością graczy", + "descriptionFullComplete": "Zaczęto grę Free-For-All z dwoma lub większą ilością graczy", "name": "Łącznik graczy" }, "Gold Miner": { @@ -181,10 +185,10 @@ "name": "Zawodowy Bokser" }, "Pro Football Shutout": { - "description": "Wygraj nie pozwalając zapunktować złym gościom", - "descriptionComplete": "Wygrałeś nie pozwalając zapunktować złym gościom", - "descriptionFull": "Wygraj w trybie ${LEVEL} nie pozwalając zapunktować złym gościom", - "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie pozwalając zapunktować złym gościom", + "description": "Wygraj, nie pozwalając zapunktować złym gościom", + "descriptionComplete": "Wygrałeś, nie pozwalając zapunktować złym gościom", + "descriptionFull": "Wygraj w trybie ${LEVEL}, nie pozwalając zapunktować złym gościom", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL}, nie pozwalając zapunktować złym gościom", "name": "Zamurowanie bramki w trybie ${LEVEL}" }, "Pro Football Victory": { @@ -303,10 +307,10 @@ "name": "Ściana" }, "Uber Football Shutout": { - "description": "Wygraj nie pozwalając zapunktować wrogom", - "descriptionComplete": "Wygrałeś nie pozwalając zapunktować wrogom", - "descriptionFull": "Wygraj w trybie ${LEVEL} nie pozwalając zapunktować wrogom", - "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie pozwalając zapunktować wrogom", + "description": "Wygraj, nie pozwalając zapunktować wrogom", + "descriptionComplete": "Wygrałeś, nie pozwalając zapunktować wrogom", + "descriptionFull": "Wygraj w trybie ${LEVEL}, nie pozwalając zapunktować wrogom", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL}, nie pozwalając zapunktować wrogom", "name": "Zamurowanie bramki w trybie ${LEVEL}" }, "Uber Football Victory": { @@ -339,9 +343,14 @@ "getMoreGamesText": "Więcej rozgrywek...", "titleText": "Dodaj grę" }, + "addToFavoritesText": "Dodaj do ulubionych", + "addedToFavoritesText": "Dodano '${NAME}' do ulubionych", + "allText": "Wszystko", "allowText": "Zezwól", "alreadySignedInText": "Twoje konto jest zalogowane z innego urządzenia;\nproszę zmienić konta lub zamknąć grę na innych\nurządzeniach i spróbować ponownie.", "apiVersionErrorText": "Nie mogę załadować modułu ${NAME}; wersja używana - ${VERSION_USED}; wymagana - ${VERSION_REQUIRED}.", + "applyText": "Zatwierdź", + "areYouSureText": "Jesteś pewny?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" aktywuj tylko wtedy, gdy są podłączone słuchawki)", "headRelativeVRAudioText": "Head-Relative VR Audio", @@ -366,15 +375,25 @@ "bombText": "Bomba", "boostText": "Dopalacz", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} jest konfigurowany w samej aplikacji.", - "buttonText": "Przycisk", - "canWeDebugText": "Chcesz aby BombSquad automatycznie raportował błędy,\nawarie i podstawowe informacje o użytkowaniu deweloperowi?\n\nPrzesyłane dane nie będą zawierać Twoich osobistych danych,\na pomogą jedynie poprawić działanie gry i usunąć jej błędy.", + "buttonText": "przycisk", + "canWeDebugText": "Chcesz, aby ${APP_NAME} automatycznie raportował błędy,\nawarie i podstawowe informacje o użytkowaniu deweloperowi?\n\nPrzesyłane dane nie będą zawierać Twoich osobistych danych,\na pomogą jedynie poprawić działanie gry i usunąć jej błędy.", "cancelText": "Anuluj", "cantConfigureDeviceText": "Wybacz ale ${DEVICE} nie jest konfigurowalne.", "challengeEndedText": "To wyzwanie zostało zakończone.", "chatMuteText": "Wycisz Czat", "chatMutedText": "Czat Wyciszony", "chatUnMuteText": "Podgłośnij Czat", + "chests": { + "prizeOddsText": "Szanse na Nagrody", + "reduceWaitText": "Skróć Czekanie", + "slotDescriptionText": "Ta komórka może trzymać skrzynkę.\n\nSkrzynki można otrzymać przechodząc poziomy w kampanii, \njako nagrody w turniejach i zdobywając \nosiągnięcia.", + "slotText": "Komórka ${NUM}", + "slotsFullWarningText": "UWAGA: Wszystkie komórki na skrzynki są pełne.\nNowo zdobyte skrzynki zostaną utracone.", + "unlocksInText": "Odblokuje się za" + }, "choosingPlayerText": "", + "claimText": "Odbierz", + "codesExplainText": "Kody są dostarczane przez dewelopera w celu\ndiagnozowania i poprawiania problemów z kontem.", "completeThisLevelToProceedText": "Musisz ukończyć ten\netap aby kontynuować!", "completionBonusText": "Bonusowe zakończenie", "configControllersWindow": { @@ -391,7 +410,7 @@ }, "configGamepadSelectWindow": { "androidNoteText": "Uwaga: wsparcie kontrolera uzależnione jest od urządzenia i wersji Androida.", - "pressAnyButtonText": "Naciśnij dowolny na kontrolerze,\nktórego chcesz skonfigurować...", + "pressAnyButtonText": "Naciśnij dowolny przycisk na kontrolerze,\nktórego chcesz skonfigurować...", "titleText": "Skonfiguruj Kontrolery" }, "configGamepadWindow": { @@ -399,8 +418,8 @@ "advancedTitleText": "Zaawansowane ustawienia Kontrolera", "analogStickDeadZoneDescriptionText": "(włącz jeśli Twoja postać dryfuje po zwolnieniu drążka)", "analogStickDeadZoneText": "Martwa strefa analogowego drążka", - "appliesToAllText": "(zastosuj dla wszystkich kontrolerów tego typu)", - "autoRecalibrateDescriptionText": "(aktywuj jeśli Twoja postać nie porusza się z pełną szybkością)", + "appliesToAllText": "(dotyczy wszystkich kontrolerów tego typu)", + "autoRecalibrateDescriptionText": "(aktywuj, jeśli Twoja postać nie porusza się z pełną szybkością)", "autoRecalibrateText": "Auto kalibracja drążka analogowego", "axisText": "oś", "clearText": "wyczyść", @@ -425,7 +444,7 @@ "runButton2Text": "Uruchom przycisk 2", "runTrigger1Text": "Uruchom spust 1", "runTrigger2Text": "Uruchom spust 2", - "runTriggerDescriptionText": "(analogowe triggery pozwalają na uruchomione przy różnych prędkościach)", + "runTriggerDescriptionText": "(analogowe triggery pozwalają ci biec przy różnych prędkościach)", "secondHalfText": "Użyj aby skonfigurować drugiego kontrolera,\nktóry widoczny jest jako pierwszy będąc\npodłączonym do tego samego urządzenia.", "secondaryEnableText": "Aktywuj", "secondaryText": "Drugi Kontroler", @@ -458,16 +477,17 @@ "titleText": "Skonfiguruj ekran dotykowy", "touchControlsScaleText": "Skala przycisków dotykowych" }, + "configureDeviceInSystemSettingsText": "${DEVICE} może zostać skonfigurowany w ustawieniach systemu.", "configureItNowText": "Skonfigurować teraz?", "configureText": "Skonfiguruj", "connectMobileDevicesWindow": { "amazonText": "Sklep Amazon", "appStoreText": "App Store", - "bestResultsText": "Dla lepszych efektów stwórz szybką sieć bezprzewodową.\nMożesz zredukować opóźnienia w grze poprzez: wyłączenie innych\nurządzeń korzystających w czasie gry z sieci wifi, będąc\nodpowiednio blisko routera wifi lub podpięcie się do hosta\nbezpośrednio przewodem sieciowym.", + "bestResultsText": "Dla lepszych efektów użyj szybkiej sieci bezprzewodowej. Możesz\nzredukować opóźnienia w grze poprzez wyłączenie innych urządzeń\nkorzystających w czasie gry z sieci wifi, bycie odpowiednio blisko\nroutera wifi lub podpięcie się do hosta bezpośrednio przewodem sieciowym.", "explanationText": "Aby użyć smartfona lub tableta jako kontrolera w grze,\nzainstaluj na nim aplikację ${REMOTE_APP_NAME}. Do gry ${APP_NAME} można\nprzyłączyć dowolną ilość urządzeń poprzez sieć WiFi i to całkowicie za darmo!", "forAndroidText": "dla Androida:", "forIOSText": "dla iOS:", - "getItForText": "Pobierz ${REMOTE_APP_NAME} dla systemu iOS ze sklepu Apple, a \ndla systemu Android ze sklepu Google Play lub Amazon Appstore.", + "getItForText": "Pobierz ${REMOTE_APP_NAME} dla systemu iOS ze sklepu Apple, a \ndla systemu Android ze sklepu Google Play lub Amazon Appstore", "googlePlayText": "Google Play", "titleText": "Używanie urządzeń mobilnych jako kontrolerów:" }, @@ -501,7 +521,7 @@ "powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} pkt)", "powerRankingText": "Osiągnięcia", "prizesText": "Nagrody", - "proMultInfoText": "Gracze z aktualizacją ${PRO} otrzymują\n${PERCENT}% punktów więcej.", + "proMultInfoText": "Gracze z ulepszeniem ${PRO} otrzymują\n${PERCENT}% punktów więcej.", "seeMoreText": "Więcej...", "skipWaitText": "Pomiń oczekiwanie", "timeRemainingText": "Pozostały czas", @@ -528,7 +548,7 @@ "legalText": "Prawa autorskie:", "publicDomainMusicViaText": "Podkład muzyczny - ${NAME}", "softwareBasedOnText": "To oprogramowanie jest częściowo oparte na pracy ${NAME}", - "songCreditText": "${TITLE} wykonywana przez ${PERFORMER}.\nSkomponowana przez ${COMPOSER}. Zorganizowana przez ${ARRANGER}.\nOpublikowana przez ${PUBLISHER}.\nDzięki uprzejmości ${SOURCE}", + "songCreditText": "${TITLE} wykonywana przez ${PERFORMER}.\nSkomponowana przez ${COMPOSER}. Zorganizował ją ${ARRANGER}.\nOpublikowana przez ${PUBLISHER}, dzięki uprzejmości ${SOURCE}.", "soundAndMusicText": "Dźwięk i muzyka:", "soundsText": "Dźwięki (${SOURCE}):", "specialThanksText": "Specjalne podziękowania dla:", @@ -567,16 +587,21 @@ "demoText": "Demo", "denyText": "Odmów", "deprecatedText": "Przestarzałe", + "descriptionText": "Opis", "desktopResText": "Rozdzielczość ekranu", "deviceAccountUpgradeText": "Uwaga:\nLogujesz się kontem urządzenia (${NAME}).\nKonta urządzenia zostaną usunięte w przyszłej aktualizacji.\nUlepsz do konta V2, jeżeli chcesz zachować swój postęp.", "difficultyEasyText": "Łatwy", "difficultyHardOnlyText": "Tylko w trudnym trybie", "difficultyHardText": "Trudny", - "difficultyHardUnlockOnlyText": "Ten poziom może zostać odblokowany tylko w trudnym trybie.\nCzy uważasz, że posiadasz to czego wymaga?!", + "difficultyHardUnlockOnlyText": "Ten poziom może zostać odblokowany tylko w trudnym trybie.\nCzy uważasz, że posiadasz to, czego wymaga?!?!", "directBrowserToURLText": "Proszę, otwórz przeglądarkę na podanym adresie:", "disableRemoteAppConnectionsText": "Wyłącz łączenia aplikacji BS-Remote", "disableXInputDescriptionText": "Pozwala na podłączenie 4 kontrolerów, ale może nie działać.", "disableXInputText": "Wyłącz XInput", + "disabledText": "Wyłączone", + "discardText": "Odrzuć", + "discordFriendsText": "Chcesz poszukać nowych ludzi do gry?\nDołącz do naszego Discorda i znajdź nowych znajomych!", + "discordJoinText": "Dołącz do Discorda", "doneText": "Gotowe", "drawText": "Remis", "duplicateText": "Duplikuj", @@ -611,10 +636,11 @@ "localProfileText": "(lokalny profil)", "nameDescriptionText": "Nazwa gracza", "nameText": "Nazwa", + "profileAlreadyExistsText": "Profil z taką nazwą już istnieje.", "randomText": "losuj", "titleEditText": "Edytuj profil", "titleNewText": "Nowy profil", - "unavailableText": "\"${NAME}\" jest zajęta, spróbuj innej.", + "unavailableText": "Nazwa \"${NAME}\" jest zajęta; spróbuj innej.", "upgradeProfileInfoText": "To zarezerwuje nazwę gracza tylko dla\nciebie i pozwoli ci dodać do niego ikonkę.", "upgradeToGlobalProfileText": "Ulepsz do Profilu Globalnego" }, @@ -649,6 +675,7 @@ "useMusicFolderText": "Katalog plików muzycznych" }, "editText": "Edytuj", + "enabledText": "Włączone", "endText": "Koniec", "enjoyText": "Miłej zabawy!", "epicDescriptionFilterText": "${DESCRIPTION} Epickie zwolnione tempo.", @@ -660,10 +687,12 @@ "errorText": "Błąd", "errorUnknownText": "nieznany błąd", "exitGameText": "Wyjść z ${APP_NAME}?", + "expiredAgoText": "Wygasło ${T} temu", + "expiresInText": "Wygaśnie za ${T}", "exportSuccessText": "'${NAME}' eksportowane.", "externalStorageText": "Pamięć zewnętrzna", "failText": "Niepowodzenie", - "fatalErrorText": "O nie, czegoś brakuje lub jest uszkodzone.\nSpróbuj przeinstalować grę lub skontaktuj się \npoprzez ${EMAIL} dla uzyskania pomocy.", + "fatalErrorText": "O nie, czegoś brakuje lub coś jest uszkodzone.\nSpróbuj przeinstalować grę lub skontaktuj się \npoprzez ${EMAIL} dla uzyskania pomocy.", "fileSelectorWindow": { "titleFileFolderText": "Wybierz plik lub katalog", "titleFileText": "Wybierz plik", @@ -696,6 +725,8 @@ "editText": "Edytuj\nlistę", "gameListText": "Lista rozgrywek", "newText": "Nowa\nlista", + "pointsToWinText": "Punkty do zwycięstwa", + "seriesLengthText": "Długość serii", "showTutorialText": "Pokaż samouczek po grze", "shuffleGameOrderText": "Losowa kolejność rozgrywek", "titleText": "Własne listy rozgrywek trybu ${TYPE}" @@ -708,7 +739,7 @@ "gamesToText": "${WINCOUNT} do ${LOSECOUNT}", "gatherWindow": { "aboutDescriptionLocalMultiplayerExtraText": "Pamiętaj: każde urządzenie podczas imprezy może posiadać\nwięcej niż jednego gracza jeśli masz więcej kontrolerów.", - "aboutDescriptionText": "Używaj tych zakładek aby zorganizować imprezę.\n\nImprezy pozwalają na organizowanie rozgrywek i\nturniejów ze znajomymi wykorzystując różne urządzenia.\n\nUżyj przycisku ${PARTY} w prawym górnym rogu aby\nrozmawiać i współdziałać podczas imprezy.\n(na kontrolerze wciśnij ${BUTTON} gdy jesteś w menu)", + "aboutDescriptionText": "Używaj tych zakładek, aby zorganizować imprezę.\n\nImprezy pozwalają na organizowanie rozgrywek i\nturniejów ze znajomymi, wykorzystując różne urządzenia.\n\nUżyj przycisku ${PARTY} w prawym górnym rogu, aby\nrozmawiać i współdziałać podczas imprezy.\n(na kontrolerze wciśnij ${BUTTON}, gdy jesteś w menu)", "aboutText": "Info", "addressFetchErrorText": "", "appInviteInfoText": "Zaproś przyjaciół by wypróbowali BombSquada, a dostaną \n${COUNT} darmowych kuponów. Dostaniesz ${YOU_COUNT}\nza każdego ktory wypróbuje.", @@ -724,6 +755,7 @@ "copyCodeConfirmText": "Kod skopiowany do schowka.", "copyCodeText": "Skopiuj kod", "dedicatedServerInfoText": "Dla najlepszych wyników ustaw serwer dedykowany. Zobacz jak na bombsquadgame.com/server.", + "descriptionShortText": "Użyj okna zbiórki by stworzyć imprezę.", "disconnectClientsText": "Spowoduje to rozłączenie ${COUNT} graczy\nbędących na imprezie. Jesteś pewny?", "earnTicketsForRecommendingAmountText": "Znajomi dostaną ${COUNT} kuponów jeżeli wypróbują grę\n(a Ty dostaniesz ${YOU_COUNT} za każdego kto zagra.)", "earnTicketsForRecommendingText": "Poleć grę dla darmowych\n kuponów...", @@ -737,14 +769,14 @@ "friendPromoCodeAwardText": "Dostaniesz ${COUNT} kuponów zawsze gdy tego użyjesz.", "friendPromoCodeExpireText": "Ten kod wygaśnie po ${EXPIRE_HOURS} godzinach i działa tylko dla nowych graczy.", "friendPromoCodeInfoText": "Może zostać wykupione do ${COUNT} kuponów.\n\nIdź do \"Ustawienia->Zaawansowane->Wpisz Kod Promocyjny\" w grze aby go użyć. Idź do bombsquadgame.com by pobrać\nlinki do wszystkich wspieranych platform. Ten kod\nwygaśnie w ${EXPIRE_HOURS} godzin i jest prawidłowy tylko dla nowych graczy.", - "friendPromoCodeInstructionsText": "Aby użyć, otwórz ${APP_NAME} i idź do \"Ustawienia->Zaawansowane-> Wpisz kod\".\nWejdź na bombsquadgame.com by zobaczyć linki dla wszystkich dostępnych platform (Android itp.)", - "friendPromoCodeRedeemLongText": "Może być żądane do ${COUNT} darmowych kuponów dla najwięcej ${MAX_USES} ludzi.", + "friendPromoCodeInstructionsText": "Aby go użyć, otwórz ${APP_NAME} i przejdź do \"Ustawienia->Zaawansowane->Wyślij informacje\".\nLinki do pobrania gry dla wszystkich obsługiwanych platform znajdziesz na stronie bombsquadgame.com.", + "friendPromoCodeRedeemLongText": "Wykorzystanie go daje ${COUNT} darmowych kuponów dla najwięcej ${MAX_USES} ludzi.", "friendPromoCodeRedeemShortText": "Może być żądane do ${COUNT} kuponów w grze.", - "friendPromoCodeWhereToEnterText": "(W \"Ustawienia->Zaawansowane->Wpisz kod\")", + "friendPromoCodeWhereToEnterText": "(w \"Ustawienia->Zaawansowane->Wyślij informacje\")", "getFriendInviteCodeText": "Zdobądź kod promocyjny kumpla", - "googlePlayDescriptionText": "Zaproś użytkowników Google Play na imprezę:", + "googlePlayDescriptionText": "Zaproś użytkowników Google Play do imprezy:", "googlePlayInviteText": "Zaproś", - "googlePlayReInviteText": "Obecnie jest ${COUNT} graczy Google Play'a na imprezie,\nktórzy zostaną rozłączeni jeśli uruchomisz nowe zaproszenie.\nUwzględnij ich w nowym zaproszeniu, aby mogli powrócić.", + "googlePlayReInviteText": "Obecnie jest ${COUNT} graczy z Google Play'a na imprezie\nktórzy zostaną rozłączeni jeśli uruchomisz nowe zaproszenie.\nUwzględnij ich w nowym zaproszeniu, aby mogli powrócić.", "googlePlaySeeInvitesText": "Zobacz zaproszenia", "googlePlayText": "Google Play", "googlePlayVersionOnlyText": "(Tylko Android / Google Play)", @@ -772,11 +804,12 @@ "manualYourLocalAddressText": "Twój adres lokalny:", "nearbyText": "W pobliżu", "noConnectionText": "", + "noPartiesAddedText": "Nie dodano imprez", "otherVersionsText": "(Inne wersje)", "partyCodeText": "Kod imprezy", "partyInviteAcceptText": "Akceptuj", "partyInviteDeclineText": "Ignoruj", - "partyInviteGooglePlayExtraText": "(zobacz zakładkę 'Google Play' w oknie 'Punkt Zborny')", + "partyInviteGooglePlayExtraText": "(zobacz zakładkę 'Google Play' w oknie 'Zbiórka')", "partyInviteIgnoreText": "Ignoruj", "partyInviteText": "${NAME} zaprosił Cię abyś\ndołączył do ich imprezy.", "partyNameText": "Nazwa Imprezy", @@ -804,7 +837,7 @@ "startHostingText": "Hostuj", "startStopHostingMinutesText": "Możesz rozpocząć i zakończyć hostowanie za darmo przez następne ${MINUTES} minut.", "stopHostingText": "Zakończ hostowanie", - "titleText": "Punkt Zborny", + "titleText": "Zbiórka", "wifiDirectDescriptionBottomText": "Jeśli wszystkie urządzenia posiadają panel 'Wi-Fi Direct', to powinny użyć go aby\nodnaleźć i połączyć się między sobą. Kiedy wszystkie są już połączone, możesz utworzyć\nimprezę używając zakładki 'Lokalna sieć', tak samo jak w standardowej sieci Wi-Fi.\n\nDla optymalnego działania, host Wi-Fi Direct powinien być hostem imprezy w ${APP_NAME}.", "wifiDirectDescriptionTopText": "Wi-Fi Direct może być używany do bezpośredniego łączenia urządzeń na\nAndroidzie bez konieczności stosowania sieci Wi-Fi. Najlepiej działa na\nurządzeniach z systemem Android 4.2 lub nowszym.\nAby go użyć, otwórz ustawienia Wi-Fi urządzenia i odszukaj 'Wi-Fi Direct'.", "wifiDirectOpenWiFiSettingsText": "Otwórz ustawienia Wi-Fi", @@ -821,7 +854,7 @@ "titleText": "Zdobądź monety" }, "getTicketsWindow": { - "freeText": "DARMOWE!", + "freeText": "ZA DARMO!", "freeTicketsText": "Darmowe kupony", "inProgressText": "Transakcja w toku; proszę spróbować za chwilkę.", "purchasesRestoredText": "Zakupy przywrócone.", @@ -831,7 +864,7 @@ "ticketPack1Text": "Mała paczka kuponów", "ticketPack2Text": "Średnia paczka kuponów", "ticketPack3Text": "Duża paczka kuponów", - "ticketPack4Text": "Paczka Kolos kuponów", + "ticketPack4Text": "Kolosalna paczka kuponów", "ticketPack5Text": "Mamucia paczka kuponów", "ticketPack6Text": "Paczka Ultimate kuponów", "ticketsFromASponsorText": "Obejrzyj reklamę\ndla ${COUNT} kuponów", @@ -844,6 +877,12 @@ "youHaveShortText": "masz ${COUNT} kuponów", "youHaveText": "masz ${COUNT} kuponów" }, + "goldPass": { + "desc1InfTokensText": "Nieskończone żetony.", + "desc2NoAdsText": "Brak reklam.", + "desc3ForeverText": "Na zawsze.", + "goldPassText": "Złota Przepustka" + }, "googleMultiplayerDiscontinuedText": "Przepraszam, usługa gry wieloosobowej Google nie jest już dostępna.\nPracuję nad zamiennikiem tak szybko jak potrafię.\nTymczasem proszę o wypróbowanie innej metody połączenia.\n-Eric", "googlePlayPurchasesNotAvailableText": "Zakupy Google Play niedostępne.\nSpróbuj zaktualizować aplikację Google Play.", "googlePlayServicesNotAvailableText": "Usługi Google Play są niedostępne.\nNiektóre funkcje aplikacji mogą być wyłączone.", @@ -852,10 +891,12 @@ "alwaysText": "Zawsze", "fullScreenCmdText": "Pełny ekran (Cmd-F)", "fullScreenCtrlText": "Pełny ekran (Ctrl+F)", + "fullScreenText": "Pełny ekran", "gammaText": "Gamma", "highText": "Wysokie", "higherText": "Max", "lowText": "Niskie", + "maxFPSText": "Maks FPS", "mediumText": "Średnie", "neverText": "Nigdy", "resolutionText": "Rozdzielczość", @@ -869,7 +910,7 @@ "helpWindow": { "bombInfoText": "- Bomba -\nSilniejsza niż ciosy, lecz\nz powodu obrażeń może Cię\nwpędzić do grobu. Dla\nlepszego efektu wyrzuć ją przed\nwypaleniem się lontu.", "canHelpText": "${APP_NAME} może Ci w tym pomóc", - "controllersInfoText": "Możesz zagrać w ${APP_NAME} ze znajomymi poprzez sieć lub na tym\nsamym urządzeniu jeśli masz wystarczająco dużo kontrolerów.\n${APP_NAME} obsługuje wiele z nich; możesz nawet użyć smartfonów\njako kontrolery wykorzystując aplikację '${REMOTE_APP_NAME}'.\nZobacz Ustawienia->Kontrolery, aby uzyskać szczegółowe informacje", + "controllersInfoText": "Możesz zagrać w ${APP_NAME} ze znajomymi poprzez sieć lub na tym\nsamym urządzeniu, jeśli masz wystarczająco dużo kontrolerów.\n${APP_NAME} obsługuje wiele z nich; możesz nawet użyć smartfonów\njako kontrolery, wykorzystując aplikację \"${REMOTE_APP_NAME}\".\nZobacz Ustawienia->Kontrolery, aby uzyskać szczegółowe informacje.", "controllersInfoTextFantasia": "Gracz może używać zdalnego kontrolera, jednak zalecane są\ngamepady. Możesz także użyć urządzeń mobilnych jako kontrolerów\ngry za pomocą darmowej aplikacji 'BombSquad Remote'.\nSprawdź informacje dostępne w ustawieniach kontrolerów.", "controllersInfoTextMac": "Jeden lub dwóch graczy może używać klawiatury, jednak najlepiej korzystać z\ngamepadów. Gra obsługuje pady USB, kontrolery PS3, Xbox360, Wiimote i urządzenia\nz systemem iOS/Android. Na pewno coś z tego posiadasz aby sterować postaciami?\nWięcej informacji dostępnych jest w ustawieniach kontrolerów.", "controllersInfoTextOuya": "Do gry w BombSquad możesz wykorzystać kontrolery OUYA, PS3, Xbox360\ni wiele innych gamepadów podłączanych za pomocą USB lub Bluetootha.\nMożesz również używać jako kontrolery urządzenia z systemami iOS/Android\nz pomocą darmowej aplikacji 'BombSquad Remote'. Więcej informacji w\nustawieniach kontrolerów.", @@ -877,7 +918,7 @@ "controllersText": "Kontrolery", "controlsSubtitleText": "Twoja postać w ${APP_NAME} posiada kilka podstawowych umiejętności:", "controlsText": "Przyciski", - "devicesInfoText": "Wersja VR ${APP_NAME} może być używana w rozgrywce sieciowej wraz z\nwersją regularną, więc wbijaj do gry ze swoimi telefonami, tabletami\ni komputerami do rozgrywki. Wersja regularna gry może być również\nwykorzystana do przyłączenia się zainteresowanych do wersji VR aby\npokazać jak wygląda rozgrywka.", + "devicesInfoText": "Wersja VR ${APP_NAME} może być używana w rozgrywce sieciowej wraz z\nwersją regularną, więc wyciągaj swoje dodatkowe telefony, tablety\noraz komputery i wbijaj do gry. Regularną wersję gry można nawet\nużyć do połączenia się z wersją VR tylko po to, aby umożliwić\nludziom z zewnątrz oglądanie tej akcji.", "devicesText": "Urządzenia", "friendsGoodText": "Dobrze ich mieć. ${APP_NAME} sprawia największą frajdę\nz kilkoma graczami. Gra może obsłużyć do 8 graczy jednocześnie.", "friendsText": "Znajomych", @@ -913,12 +954,13 @@ }, "holdAnyButtonText": "", "holdAnyKeyText": "", - "hostIsNavigatingMenusText": "- ${HOST} nawiguje w menu jako szef -", + "hostIsNavigatingMenusText": "- ${HOST} nawiguje w menu jak szef -", "importPlaylistCodeInstructionsText": "Użyj tego kodu, by zimportować tą listę w innym miejscu:", "importPlaylistSuccessText": "Zimportowano playlistę '${NAME}' rozgrywek ${TYPE}", "importText": "Importuj", "importingText": "Importowanie...", "inGameClippedNameText": "w grze widoczne jako\n\"${NAME}\"", + "inboxText": "Skrzynka odbiorcza", "installDiskSpaceErrorText": "BŁĄD: Niemożliwe dokończenie instalacji.\nByć może mało miejsca w pamięci urządzenia.\nZrób więcej miejsca i spróbuj jeszcze raz.", "internal": { "arrowsToExitListText": "wciśnij ${LEFT} lub ${RIGHT} aby opuścić listę", @@ -975,12 +1017,14 @@ "touchScreenJoinWarningText": "Dołączyłeś się wykorzystując ekran dotykowy.\nJeśli to pomyłka, stuknij 'Menu->Opuść grę'.", "touchScreenText": "Ekran dotykowy", "trialText": "trial", + "unableToCompleteTryAgainText": "Nie można teraz tego zrobić.\nSpróbuj ponownie później.", "unableToResolveHostText": "Błąd: nie można odnaleźć hosta.", "unavailableNoConnectionText": "Obecnie niedostępne (sprawdź połączenie internetowe).", "vrOrientationResetCardboardText": "Użyj tego aby zresetować orientację VR.\nAby zagrać w grę będziesz potrzebować zewnętrznego kontrolera.", "vrOrientationResetText": "Reset orientacji VR.", "willTimeOutText": "(czas upłynie przy bezczynności)" }, + "inventoryText": "Ekwipunek", "jumpBoldText": "SKOK", "jumpText": "Skok", "keepText": "Zachowaj", @@ -1027,8 +1071,11 @@ "seasonEndsMinutesText": "Sezon zakończy się za ${NUMBER} minut.", "seasonText": "Sezon ${NUMBER}", "tournamentLeagueText": "Musisz uzyskać ligę ${NAME} aby wejść do tego turnieju.", - "trophyCountsResetText": "Liczba Zdobyczy zresetuje się w przyszłym sezonie." + "trophyCountsResetText": "Liczba Zdobyczy zresetuje się w przyszłym sezonie.", + "upToDateBonusDescriptionText": "Gracze na najnowszej wersji gry\notrzymają tutaj ${PERCENT}% bonusu.", + "upToDateBonusText": "Bonus Wersji" }, + "learnMoreText": "Dowiedz się więcej", "levelBestScoresText": "Najlepsze wyniki w ${LEVEL}", "levelBestTimesText": "Najlepsze czasy w ${LEVEL}", "levelFastestTimesText": "Najszybsze czasy w ${LEVEL}", @@ -1075,6 +1122,8 @@ "modeArcadeText": "Tryb Salonu Gier", "modeClassicText": "Tryb Klasyczny", "modeDemoText": "Tryb Demo", + "moreSoonText": "Przybędzie w przyszłości...", + "mostDestroyedPlayerText": "Najbardziej Zgładzony Gracz", "mostValuablePlayerText": "Najwartościowszy gracz", "mostViolatedPlayerText": "Gracz najbardziej sprofanowany", "mostViolentPlayerText": "Gracz najbardziej brutalny", @@ -1091,6 +1140,7 @@ "nameSuicideText": "${NAME} popełnił samobójstwo.", "nameText": "Nazwa", "nativeText": "Natywna", + "newExclaimText": "Nowy!", "newPersonalBestText": "Nowy rekord życiowy!", "newTestBuildAvailableText": "Dostępna jest nowa wersja! (${VERSION} build ${BUILD}).\nPobierz ją z ${ADDRESS}", "newText": "Nowy", @@ -1102,13 +1152,17 @@ "noExternalStorageErrorText": "Brak pamięci zewnętrznej w tym urządzeniu", "noGameCircleText": "Błąd: niezalogowany w GameCircle", "noJoinCoopMidwayText": "Rozgrywki trybu Kooperacji nie mogą być łączone w czasie ich trwania.", + "noMessagesText": "Brak wiadomości.", + "noPluginsInstalledText": "Brak zainstalowanych pluginów", "noProfilesErrorText": "Nie masz własnego profilu gracza, dlatego nazwano Cię: '${NAME}'.\nPrzejdź do Ustawień->Profile Gracza aby stworzyć własny.", "noScoresYetText": "Brak wyników do tej pory.", + "noServersFoundText": "Nie znaleziono serwerów.", "noThanksText": "Nie, dziękuję", "noTournamentsInTestBuildText": "OSTRZEŻENIE: Wyniki turniejów z tej wersji testowej będą ignorowane.", "noValidMapsErrorText": "Nie znaleziono żadnych map dla tego typu rozgrywki.", "notEnoughPlayersRemainingText": "Niewystarczająca ilość graczy. Spróbuj zacząć nową grę.", "notEnoughPlayersText": "Aby rozpocząć grę potrzeba ${COUNT} graczy!", + "notEnoughTicketsText": "Za mało biletów!", "notNowText": "Nie teraz", "notSignedInErrorText": "Musisz zalogować się, aby to zrobić.", "notSignedInGooglePlayErrorText": "Zaloguj się z Google Play, by to zrobić.", @@ -1116,11 +1170,14 @@ "notUsingAccountText": "Uwaga: ignorowanie konta ${SERVICE}.\nIdź do \"Konto -> Zaloguj się kontem ${SERVICE}\", jeżeli chcesz go używać.", "nothingIsSelectedErrorText": "Nic nie zaznaczyłeś!", "numberText": "#${NUMBER}", - "offText": "Off", + "offText": "Wył.", "okText": "Ok", - "onText": "On", + "onText": "Wł.", "oneMomentText": "Chwileczkę...", "onslaughtRespawnText": "${PLAYER} odrodzi się w fali ${WAVE}", + "openMeText": "Otwórz Mnie!", + "openNowText": "Otwórz Teraz", + "openText": "Otwórz", "orText": "${A} lub ${B}", "otherText": "Inny...", "outOfText": "(#${RANK} na ${ALL})", @@ -1185,17 +1242,17 @@ "pluginsRemovedText": "Usunięto ${NUM} pluginy(ów)", "pluginsText": "Pluginy", "practiceText": "Praktyka", - "pressAnyButtonPlayAgainText": "Naciśnij dowolny przycisk aby zagrać ponownie...", - "pressAnyButtonText": "Naciśnij dowolny przycisk aby kontynuować...", - "pressAnyButtonToJoinText": "naciśnij dowolny przycisk aby dołączyć...", - "pressAnyKeyButtonPlayAgainText": "Naciśnij dowolny klawisz/przycisk aby zagrać ponownie...", - "pressAnyKeyButtonText": "Naciśnij dowolny klawisz/przycisk aby kontynuować...", + "pressAnyButtonPlayAgainText": "Naciśnij dowolny przycisk, aby zagrać ponownie...", + "pressAnyButtonText": "Naciśnij dowolny przycisk, aby kontynuować...", + "pressAnyButtonToJoinText": "naciśnij dowolny przycisk, aby dołączyć...", + "pressAnyKeyButtonPlayAgainText": "Naciśnij dowolny klawisz/przycisk, aby zagrać ponownie...", + "pressAnyKeyButtonText": "Naciśnij dowolny klawisz/przycisk, aby kontynuować...", "pressAnyKeyText": "Naciśnij dowolny klawisz...", - "pressJumpToFlyText": "** Naciśnij wielokrotnie skok aby polecieć **", - "pressPunchToJoinText": "naciśnij CIOS aby dołączyć...", - "pressToOverrideCharacterText": "naciśnij ${BUTTONS} aby zastąpić swoją postać", - "pressToSelectProfileText": "naciśnij ${BUTTONS} aby wybrać gracza.", - "pressToSelectTeamText": "naciśnij ${BUTTONS} aby wybrać drużynę.", + "pressJumpToFlyText": "** Naciskaj wielokrotnie skok, aby polecieć **", + "pressPunchToJoinText": "naciśnij CIOS, aby dołączyć...", + "pressToOverrideCharacterText": "naciśnij ${BUTTONS}, aby zastąpić swoją postać", + "pressToSelectProfileText": "naciśnij ${BUTTONS}, aby wybrać gracza", + "pressToSelectTeamText": "naciśnij ${BUTTONS}, aby wybrać drużynę", "profileInfoText": "Stwórz profile dla siebie i swoich znajomych\ndostosowując ich nazwy i kolory postaci.", "promoCodeWindow": { "codeText": "Kod", @@ -1206,7 +1263,7 @@ "ps3ControllersWindow": { "macInstructionsText": "Wyłącz zasilanie konsoli PS3, upewnij się, że masz uruchomiony\nBluetooth w swoim Mac'u, następnie podłącz kontroler do portu\nUSB Mac'a aby sparować urządzenia. Od teraz można używać na\nkontrolerze przycisku 'home' aby podłączyć go do Mac'a w obu\ntrybach - przewodowym (USB) i bezprzewodowym (Bluetooth).\n\nNa niektórych Mac'ach trzeba podać kod aby urządzenia sparować.\nJeśli się tak stanie poszukaj poradnika na google.\n\n\n\n\nKontrolery PS3 podłączone bezprzewodowo powinny być widoczne na\nliście urządzeń w Preferencjach Systemu->Bluetooth. Być może\ntrzeba będzie je usunąć z tej listy, kiedy zechcesz korzystać\nz nich ponownie w PS3.\n\nPamiętaj aby rozłączyć je z Bluetootha kiedy nie będą używane\nponieważ wyładują się ich baterie.\n\nBluetooth powinien obsłużyć do 7 podłączonych urządzeń, chociaż\nliczba ta może się wahać.", "macInstructionsTextScale": 0.74, - "ouyaInstructionsText": "Aby używać kontrolerów PS3 z konsolą OUYA, po prostu podłącz je kablem USB\naby sparować urządzenia. Może to spowodować rozłączenie innych kontrolerów,\nwięc powinieneś później uruchomić ponownie konsolę OUYA i odłączyć kabel USB.\n\nOd teraz powinien być aktywny przycisk HOME aby połączyć się bezprzewodowo. Kiedy zakończysz grę, przytrzymaj HOME przez 10 sekund aby wyłączyć kontroler;\nw przeciwnym razie może on wyczerpać jego baterie.", + "ouyaInstructionsText": "Aby używać kontrolera PS3 z konsolą OUYA, po prostu podłącz go kablem USB,\naby go sparować. Może to spowodować rozłączenie innych kontrolerów,\nwięc powinieneś później uruchomić ponownie konsolę OUYA i odłączyć kabel USB.\n\nOd teraz powinien być aktywny przycisk HOME, aby połączyć się bezprzewodowo.\nKiedy zakończysz grę, przytrzymaj HOME przez 10 sekund, aby wyłączyć kontroler;\nw przeciwnym razie może on wyczerpać jego baterie.", "ouyaInstructionsTextScale": 0.74, "pairingTutorialText": "poradnik video parowania kontrolerów", "titleText": "Korzystanie z kontrolerów PS3 w ${APP_NAME}:" @@ -1215,11 +1272,13 @@ "punchBoldText": "CIOS", "punchText": "Cios", "purchaseForText": "Kup za ${PRICE}", - "purchaseGameText": "Zakup Grę", + "purchaseGameText": "Kup Grę", + "purchaseNeverAvailableText": "Przepraszamy, w tej kompilacji nie można dokonać zakupów.\nSpróbuj zalogować się na swoje konto na innej platformie i dokonać tam zakupów.", + "purchaseNotAvailableText": "Ten zakup jest niedostępny.", "purchasingText": "Kupowanie...", "quitGameText": "Wyjść z ${APP_NAME}?", "quittingIn5SecondsText": "Wyjście za 5 sekund...", - "randomPlayerNamesText": "DOMYŚLNE_NAZWY", + "randomPlayerNamesText": "Albin, Aleksandra, Agata, Agnieszka, Aleksy, Alina, Antoni, Aldona, Alicja, Amelia, Aniela, Bazyli, Dobrogost, Filip, Jan, Julia, Maria, Szymon, Zofia, Adok, Anastazja, Andrzej, Armand, Aron, Polish", "randomText": "Losowo", "rankText": "Ranking", "ratingText": "Ocena", @@ -1257,7 +1316,8 @@ "start": "Start", "version_mismatch": "Wersje nie pasują.\nSprawdź czy BombSquad i BombSquad Remote\nmają najnowszą wersję i spróbuj ponownie." }, - "removeInGameAdsText": "Odblokowywując wersję \"${PRO}\" pozbędziesz się reklam w grze.", + "removeInGameAdsText": "Odblokowując wersję \"${PRO}\", pozbędziesz się reklam w grze.", + "removeInGameAdsTokenPurchaseText": "OFERTA: Zakup DOWOLNĄ paczkę żetonów aby usunąć reklamy.", "renameText": "Zmień nazwę", "replayEndText": "Zakończ powtórkę", "replayNameDefaultText": "Ostatnia powtórka", @@ -1279,7 +1339,9 @@ "runBoldText": "URUCHOM", "runText": "Uruchom", "saveText": "Zapisz", - "scanScriptsErrorText": "Błąd w skanowaniu skryptów; sprawdź konsolę dla szczegółów", + "scanScriptsErrorText": "Błąd w skanowaniu skryptów. Sprawdź konsolę dla szczegółów.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} oraz ${NUM} innych modułów potrzebują aktualizacji do api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} potrzebuje aktualizacji do api ${API}.", "scoreChallengesText": "Wyzwania Punktowe", "scoreListUnavailableText": "Lista wyników niedostępna.", "scoreText": "Wynik", @@ -1290,6 +1352,7 @@ }, "scoreWasText": "(było ${COUNT})", "selectText": "Wybierz", + "sendInfoDescriptionText": "Przesyła stan konta i aplikacji do dewelopera.\nProszę o podanie imienia lub powodu wysłania.", "seriesWinLine1PlayerText": "WYGRAŁ", "seriesWinLine1TeamText": "WYGRALI", "seriesWinLine1Text": "WYGRAŁ", @@ -1308,22 +1371,30 @@ "alwaysUseInternalKeyboardDescriptionText": "(prosta klawiatura na ekranie do edycji tekstu - przyjazna kontrolerom)", "alwaysUseInternalKeyboardText": "Zawsze używaj wewn. klawiatury", "benchmarksText": "Benchmarki & Testy Wydajności", - "disableCameraGyroscopeMotionText": "Wyłącz Kontrolę Kamery Żyroskopem", - "disableCameraShakeText": "Wyłącz Trzęsącą Kamerę", + "devToolsText": "Narzędzia deweloperskie", + "disableCameraGyroscopeMotionText": "Wyłącz kontrolę kamery żyroskopem", + "disableCameraShakeText": "Wyłącz trzęsienie kamery", "disableThisNotice": "(możesz wyłączyć to powiadomienie w ustawieniach zaawansowanych)", "enablePackageModsDescriptionText": "(aktywuje dodatkowe możliwości modowania ale wyłącza grę sieciową)", "enablePackageModsText": "Włącz lokalne pakiety modów", "enterPromoCodeText": "Wpisz kod", "forTestingText": "Uwaga: wartości stosowane do testów będą utracone po wyjściu z gry.", "helpTranslateText": "Tłumaczenia ${APP_NAME} na inne języki są wysiłkiem społeczności\nfanów tej gry. Jeśli chcesz przyczynić się lub poprawić istniejące\nbłędy w tłumaczeniu, kliknij w poniższy link. Z góry dziękuję!", - "kickIdlePlayersText": "Wyrzuć nieaktywnych graczy", + "insecureConnectionsDescriptionText": "niezalecane, ale może umożliwić grę online\nz krajów lub sieci objętych ograniczeniami", + "insecureConnectionsText": "Używaj niezabezpieczonych połączeń", + "kickIdlePlayersText": "Wyrzucaj nieaktywnych graczy", "kidFriendlyModeText": "Tryb dla dzieciaków (zredukowana przemoc itd.)", "languageText": "Język", "moddingGuideText": "Przewodnik modowania gry", - "mustRestartText": "Musisz uruchomić ponownie grę aby zastosować zmiany.", + "moddingToolsText": "Narzędzia do modyfikacji", + "mustRestartText": "Musisz uruchomić ponownie grę, aby zastosować zmiany.", "netTestingText": "Testowanie sieci", "resetText": "Reset", + "sendInfoText": "Wyślij Info", "showBombTrajectoriesText": "Pokaż trajektorię bomb", + "showDemosWhenIdleText": "Pokazuj wersje demonstracyjne w stanie bezczynności", + "showDeprecatedLoginTypesText": "Pokaż przestarzałe typy logowania", + "showDevConsoleButtonText": "Pokaż przycisk konsoli deweloperskiej", "showInGamePingText": "Pokaż ping w grze", "showPlayerNamesText": "Pokazuj nazwy graczy", "showUserModsText": "Pokaż katalog modów", @@ -1331,18 +1402,21 @@ "translationEditorButtonText": "Edytor tłumaczeń ${APP_NAME}", "translationFetchErrorText": "status tłumaczenia niedostępny", "translationFetchingStatusText": "sprawdzanie statusu tłumaczenia...", - "translationInformMe": "Powiadom mnie gdy mój język będzie potrzebował uaktualnienia", + "translationInformMe": "Powiadom mnie, gdy mój język będzie potrzebował uaktualnienia", "translationNoUpdateNeededText": "Obecnie używany język jest aktualny; ekstra!", - "translationUpdateNeededText": "** obecnie używany język wymaga jego zaktualizowania! **", + "translationUpdateNeededText": "** Obecnie używany język wymaga jego zaktualizowania! **", "vrTestingText": "Testowanie VR" }, "shareText": "Udostępnij", "sharingText": "Udostępnianie...", "showText": "Wyświetl", - "signInForPromoCodeText": "Musisz się zalogować do konta aby kody zadziałały.", + "signInForPromoCodeText": "Musisz się zalogować do konta, aby kody zadziałały.", "signInWithGameCenterText": "By użyć konta Game Center\nzapisz się aplikacją Game Center.", "singleGamePlaylistNameText": "Tylko ${GAME}", "singlePlayerCountText": "1 gracz", + "sizeLargeText": "Duży", + "sizeMediumText": "Średni", + "sizeSmallText": "Mały", "soloNameFilterText": "Solówka ${NAME}", "soundtrackTypeNames": { "CharSelect": "Wybór postaci", @@ -1368,6 +1442,7 @@ }, "spaceKeyText": "spacja", "statsText": "Statystyki", + "stopRemindingMeText": "Przestań mi przypominać", "storagePermissionAccessText": "To wymaga dostępu do pamięci masowej", "store": { "alreadyOwnText": "Masz już ${NAME}!", @@ -1407,7 +1482,7 @@ "winterSpecialText": "Specjały Zimowe", "youOwnThisText": "- zdobyłeś już to -" }, - "storeDescriptionText": "8 Osobowe Szaleństwo!\n\nWysadź w powietrze swoich znajomych (lub komputerowych przeciwników) w turnieju z wybuchowymi mini gierkami jak np. Przechwyć Flagę, Bombowy Hokej i Epicki Mecz Śmierci w zwolnionym tempie!\n\nProste sterowanie i rozszerzone wsparcie dla kontrolerów może wprowadzić do gry aż 8 przeciwników; możesz nawet wykorzystać swoje mobilne urządzenie jako kontroler do gry dostępne jako darmowa aplikacja 'BombSquad Remote'!\n\nBomby w Górę!\n\nSprawdź na www.froemling.net/bombsquad i dowiedz się więcej.", + "storeDescriptionText": "8-Osobowe Szaleństwo!\n\nWysadź w powietrze swoich znajomych (lub komputerowych przeciwników) w turnieju z wybuchowymi mini gierkami jak np. Przechwyć Flagę, Bombowy Hokej i Epicki Mecz Śmierci w zwolnionym tempie!\n\nProste sterowanie i rozszerzone wsparcie dla kontrolerów może wprowadzić do gry aż 8 przeciwników; możesz nawet wykorzystać swoje mobilne urządzenie jako kontroler do gry dostępne jako darmowa aplikacja \"BombSquad Remote\"!\n\nBomby w Górę!\n\nSprawdź www.froemling.net/bombsquad i dowiedz się więcej.", "storeDescriptions": { "blowUpYourFriendsText": "Wysadź w powietrze swoich znajomych.", "competeInMiniGamesText": "Ukończ mini gierki aby awansować z wyścigów do lotów.", @@ -1419,6 +1494,8 @@ "storeText": "Sklep", "submitText": "Prześlij", "submittingPromoCodeText": "Przesyłanie Kodu...", + "successText": "Sukces!", + "supportEmailText": "Jeśli doświadczasz jakichś problemów z\naplikacją, wyślij e-maila na ${EMAIL}.", "teamNamesColorText": "Nazwy Drużyn/Kolory...", "teamsText": "Gra Zespołowa", "telnetAccessGrantedText": "Dostęp telnet włączony.", @@ -1429,8 +1506,9 @@ "testBuildValidatedText": "Wersja Testowa Zatwierdzona! Miłej zabawy!", "thankYouText": "Dziękuję za Twoje wsparcie! Miłej gry!", "threeKillText": "POTRÓJNE ZABÓJSTWO!!", + "ticketsDescriptionText": "Bilety pozwalają odblokować postacie,\nmapy, minigry, i więcej w sklepe.\n\nBilety można znaleźć w skrzynkach\nz kampanii, turniejów, czy osiągnięć.", "timeBonusText": "Bonus czasowy", - "timeElapsedText": "Czas upłynął", + "timeElapsedText": "Czas, jaki upłynął", "timeExpiredText": "Czas minął", "timeSuffixDaysText": "${COUNT}d", "timeSuffixHoursText": "${COUNT}h", @@ -1439,10 +1517,24 @@ "tipText": "Wskazówka", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Zdobądź żetony", + "notEnoughTokensText": "Za mało żetonów!", + "numTokensText": "${COUNT} żetonów", + "openNowDescriptionText": "Masz wystarczająco dużo biletów\naby otworzyć to teraz \n- nie musisz czekać.", + "shinyNewCurrencyText": "Nowa, błyszcząca waluta BombSquad.", + "tokenPack1Text": "Mały pakiet żetonów", + "tokenPack2Text": "Średni pakiet żetonów", + "tokenPack3Text": "Duży pakiet żetonów", + "tokenPack4Text": "Gigantyczny pakiet żetonów", + "tokensDescriptionText": "Żetony przyspieszają prędkość odblokowania\nskrzynek i za inne operacje związane z grą czy kontem.\n\nMożesz wygrać żetony w grze lub kupić je\nw paczkach. Albo kupić Złoty Karnet dla nieskończonych\nżetonów i nie będziesz o nich więcej słyszeć.", + "youHaveGoldPassText": "Masz Złotą Przepustkę.\nWszystkie zakupy żetonów są bezpłatne.\nSuper!" + }, "topFriendsText": "Najlepsi znajomi", "tournamentCheckingStateText": "Sprawdzanie statusu turnieju; proszę czekać...", "tournamentEndedText": "Ten turniej został zakończony. Nowy wkrótce się rozpocznie.", "tournamentEntryText": "Wejście do Turnieju", + "tournamentFinalStandingsText": "Pozycje w Turnieju", "tournamentResultsRecentText": "Najnowsze wyniki Turnieju", "tournamentStandingsText": "Klasyfikacja Turnieju", "tournamentText": "Turniej", @@ -1458,7 +1550,7 @@ "Butch": "Butch", "Easter Bunny": "Zajączek Wielkanocny", "Flopsy": "Flopsy", - "Frosty": "Frosty", + "Frosty": "Mrozek", "Gretel": "Małgosia", "Grumbledorf": "Grumbledorf", "Jack Morgan": "Jack Morgan", @@ -1501,11 +1593,11 @@ "Infinite Onslaught": "Nieskończony Atak", "Infinite Runaround": "Nieskończone Otaczanie", "Onslaught": "Nieskończony Atak", - "Onslaught Training": "Atakujący Trening", - "Pro ${GAME}": "Zawodowy tryb ${GAME}", - "Pro Football": "Zawodowy Futbol", - "Pro Onslaught": "Atak Zawodowca", - "Pro Runaround": "Zawodowe Otaczanie", + "Onslaught Training": "Treningowy Atak", + "Pro ${GAME}": "Cięższy tryb ${GAME}", + "Pro Football": "Cięższy Futbol", + "Pro Onslaught": "Cięższy Atak", + "Pro Runaround": "Cięższe Otaczanie", "Rookie ${GAME}": "Rekrucki tryb ${GAME}", "Rookie Football": "Futbol Rekruta", "Rookie Onslaught": "Atak Rekruta", @@ -1516,8 +1608,20 @@ "Uber Onslaught": "Super Atak", "Uber Runaround": "Super Otaczanie" }, + "displayItemNames": { + "${C} Tickets": "${C} Biletów", + "${C} Tokens": "${C} Żetonów", + "Chest": "Skrzynka", + "L1 Chest": "Skrzynka P1", + "L2 Chest": "Skrzynka P2", + "L3 Chest": "Skrzynka P3", + "L4 Chest": "Skrzynka P4", + "L5 Chest": "Skrzynka P5", + "L6 Chest": "Skrzynka P6", + "Unknown Chest": "Nieznana Skrzynka" + }, "gameDescriptions": { - "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bądź wybrańcem przez określony czas aby wygrać.\nZabij wybrańca aby się nim stać.", + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bądź wybrańcem przez określony czas, aby wygrać.\nZabij wybrańca, aby się nim stać.", "Bomb as many targets as you can.": "Zbombarduj tyle celów, ile tylko możesz.", "Carry the flag for ${ARG1} seconds.": "Utrzymaj flagę przez ${ARG1} sekund.", "Carry the flag for a set length of time.": "Utrzymaj flagę przez określony czas.", @@ -1620,6 +1724,7 @@ "Korean": "Koreański", "Malay": "Malajski", "Persian": "Perski", + "PirateSpeak": "Piracki język", "Polish": "Polski", "Portuguese": "Portugalski", "Romanian": "Rumuński", @@ -1686,7 +1791,7 @@ "An error has occurred; please contact support. (${ERROR})": "Wystąpił błąd; skontaktuj się z pomocą techniczną. (${ERROR})", "An error has occurred; please contact support@froemling.net.": "Wystąpił błąd; skontaktuj się z support@froemling.net.", "An error has occurred; please try again later.": "Wystąpił błąd; spróbuj ponownie później.", - "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Na pewno chcesz połączyć te konta?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nUwaga: To nie może być cofnięte!", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Na pewno chcesz połączyć te konta?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nNie da się tego cofnąć!", "BombSquad Pro unlocked!": "BombSquad Pro odblokowane!", "Can't link 2 accounts of this type.": "Nie można połączyć dwóch kont tego typu.", "Can't link 2 diamond league accounts.": "Nie można połączyć dwóch kont w diamentowej lidze.", @@ -1694,6 +1799,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Oszukiwanie wykryte; punkty i nagrody zawieszone na ${COUNT} dni.", "Could not establish a secure connection.": "Nie udało się nawiązać bezpiecznego połączenia.", "Daily maximum reached.": "Dzienne maksimum wykorzystane.", + "Daily sign-in reward": "Nagroda za codzienne logowanie", "Entering tournament...": "Wchodzenie do turnieju...", "Invalid code.": "Nieprawidłowy kod.", "Invalid payment; purchase canceled.": "Nieprawidłowa zapłata; zamówienie anulowane.", @@ -1703,11 +1809,14 @@ "Item unlocked!": "Przedmiot odblokowany!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ŁĄCZENIE ODRZUCONE. ${ACCOUNT} zawiera\nznaczący postęp który zostałby USUNIĘTY.\nMożesz połączyć konta na odwrót jeśli chcesz\n(i stracić postęp Z TEGO konta).", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Połączyć konto ${ACCOUNT} z tym kontem?\nCały postęp z konta ${ACCOUNT} będzie stracony.\nNie można tego odwrócić. Pewna decyzja?", - "Max number of playlists reached.": "Osiągnięto maksymalną ilość playlist.", + "Longer streaks lead to better rewards.": "Dłuższe serie dają lepsze nagrody", + "Max number of playlists reached.": "Osiągnięto maksymalną liczbę playlist.", "Max number of profiles reached.": "Osiągnięto maksymalną liczbę profili.", "Maximum friend code rewards reached.": "Osiągnięto limit kodów promocyjnych.", "Message is too long.": "Wiadomość jest za długa.", + "New tournament result!": "Nowy wynik w turnieju!", "No servers are available. Please try again soon.": "Brak dostępnych serwerów. Spróbuj ponownie wkrótce.", + "No slots available. Free a slot and try again.": "Brak wolnych komórek. Zwolnij komórkę i spróbuj ponownie.", "Profile \"${NAME}\" upgraded successfully.": "Nazwa \"${NAME}\" ulepszona pomyślnie.", "Profile could not be upgraded.": "Profil nie może być ulepszony.", "Purchase successful!": "Udany zakup!", @@ -1717,7 +1826,9 @@ "Sorry, this code has already been used.": "Przepraszamy, ten kod został już użyty.", "Sorry, this code has expired.": "Przepraszamy, ten kod wygasł.", "Sorry, this code only works for new accounts.": "Przepraszamy, ten kod działa tylko na nowych kontach.", + "Sorry, this has expired.": "Niestety, czas minął.", "Still searching for nearby servers; please try again soon.": "Wciąż szukam pobliskich serwerów; proszę spróbuj ponownie wkrótce.", + "Streak: ${NUM} days": "Seria: ${NUM} dni", "Temporarily unavailable; please try again later.": "Tymczasowo niedostępne; spróbuj ponownie później.", "The tournament ended before you finished.": "Wyniki po zakończonym turnieju.", "This account cannot be unlinked for ${NUM} days.": "To konto nie może zostać rozłączone przez ${NUM} dni.", @@ -1728,19 +1839,28 @@ "Tournaments require ${VERSION} or newer": "Turnieje potrzebują ${VERSION} albo nowszej", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Rozłączyć konto ${ACCOUNT} z tego konta?\nCały postęp z konta ${ACCOUNT} zostanie zresetowany.\n(oprócz osiągnięć w niektórych przypadkach)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "OSTRZEŻENIE: przeciwko Tobie zostały złożone skargi o oszukiwanie.\nKonta ludzi oszukujących zostaną zablokowane. Proszę grać uczciwie.", - "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Chcesz połączyć swoje konto z urządzenia z tym?\n\nTwoje konto urządzenia to ${ACCOUNT1}\nTo konto to ${ACCOUNT2}\n\nTo pozwoli Ci zapisać istniejący postęp.\nUwaga: To nie może zostać cofnięte!!!", + "Wait reduced!": "Skrócono czas czekania!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "OSTRZEŻENIE: Ta wersja gry jest ograniczona do starych danych konta; rzeczy mogą być nieaktualne lub brakujace.\nProszę zaktualizować gre do najnowszej wersji aby zobaczyć najnowsze dane.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Chcesz połączyć swoje konto z urządzenia z tym?\n\nTwoje konto urządzenia to ${ACCOUNT1}\nTo konto to ${ACCOUNT2}\n\nTo pozwoli Ci zapisać istniejący postęp.\nUwaga: Nie da się tego cofnąć!", "You already own this!": "Już to posiadasz!", "You can join in ${COUNT} seconds.": "Możesz dołączyć w ciągu ${COUNT} sekund.", "You don't have enough tickets for this!": "Nie masz wystarczająco dużo kuponów!", "You don't own that.": "Nie posiadasz tego.", "You got ${COUNT} tickets!": "Masz ${COUNT} kuponów!", + "You got ${COUNT} tokens!": "Zdobyłeś ${COUNT} żetonów!", "You got a ${ITEM}!": "Otrzymałeś ${ITEM}!", + "You got a chest!": "Zdobyłeś skrzynkę!", + "You got an achievement reward!": "Zdobyłeś nagrodę za osiągnięcie!", "You have been promoted to a new league; congratulations!": "Zostałeś awansowany do nowej ligi; gratulacje!", - "You must update to a newer version of the app to do this.": "Musisz zaktualizować do nowszej wersji gry aby to zrobić.", - "You must update to the newest version of the game to do this.": "Musisz zaktualizować grę do nowej wersji aby to zrobić.", + "You lost a chest! (All your chest slots were full)": "Straciłeś skrzynkę! (Wszystkie komórki na skrzynki są pełne)", + "You must update the app to view this.": "Musisz zaktualizować aplikację, aby to wyświetlić.", + "You must update to a newer version of the app to do this.": "Musisz zaktualizować do nowszej wersji gry, aby to zrobić.", + "You must update to the newest version of the game to do this.": "Musisz zaktualizować grę do nowej wersji, aby to zrobić.", "You must wait a few seconds before entering a new code.": "Musisz odczekać kilka sekund zanim wpiszesz nowy kod.", + "You placed #${RANK} in a tournament!": "Zdobyłeś #${RANK} miejsce w turnieju!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Zostałeś sklasyfikowany na ${RANK} pozycji w ostatnim turnieju. Dzięki za udział!", - "Your account was rejected. Are you signed in?": "Twoje Konto Zostało Odrzucone. Jesteś Zalogowany?", + "Your account was rejected. Are you signed in?": "Twoje konto zostało odrzucone. Czy jesteś zalogowany?", + "Your ad views are not registering. Ad options will be limited for a while.": "Obejrzenie reklamy nie zostało zarejestrowane. Opcje reklamowe zostaną chwilowo ograniczone.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Twoja kopia gry została zmodyfikowana.\nCofnij zmiany i spróbuj ponownie.", "Your friend code was used by ${ACCOUNT}": "Kod kumpla został użyty przez ${ACCOUNT}" }, @@ -1798,37 +1918,37 @@ }, "tips": { "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfekcyjne w czasie wykonanie biegu, skoku, obrotu i uderzenia\nmoże zabić jednym ruchem wzbudzając respekt wśród znajomych.", - "Always remember to floss.": "Pamiętaj żeby nitkować zęby.", + "Always remember to floss.": "Pamiętaj, żeby nitkować zęby.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Stwórz takie profile gracza (nazwa i wygląd) dla siebie i znajomych, które\nbędą Wam najbardziej odpowiadać zamiast tych losowo dobieranych.", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Pudła z Klątwą zamienią Cię w tykającą bombę.\nJedynym ratunkiem jest wtedy szybkie zdobycie apteczki.", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Pomimo różnego wyglądu, postacie posiadają te same umiejętności, więc ma\non tylko znaczenie wizualne. Wobec tego dobierz taki, który Ci odpowiada.", "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nie bądź zbyt pewny siebie mając tarczę energetyczną; wciąż ktoś może Cię zrzucić z klifu.", "Don't run all the time. Really. You will fall off cliffs.": "Nie biegaj cały czas, bo spadniesz z klifu.", "Don't spin for too long; you'll become dizzy and fall.": "Nie obracaj się za długo; zakręci ci się w głowie i się wywrócisz.", - "Hold any button to run. (Trigger buttons work well if you have them)": "Przytrzymaj dowolny przycisk aby biec. (Triggery działają równie\ndobrze (jeśli je masz)).", + "Hold any button to run. (Trigger buttons work well if you have them)": "Przytrzymaj dowolny przycisk, aby biec. (Triggery działają równie dobrze, jeśli je masz).", "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Przytrzymaj dowolny przycisk aby biec. Wówczas osiągniesz szybciej\nswój cel lecz biegnąc ciężko się skręca, więc uważaj aby nie spaść.", "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Lodowe bomby nie są potężne, ale potrafią zamrozić każdego kto\nbędzie w ich polu rażenia, wówczas będzie on podatny na skruszenie.", - "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jeśli ktoś Cię podniesie, uderz go wówczas Cię puści.\nSkutkuje to również w prawdziwym życiu ;)", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jeśli ktoś Cię podniesie, uderz go wówczas Cię puści.\nDziała to również w prawdziwym życiu ;)", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów, zainstaluj aplikację '${REMOTE_APP_NAME}'\nna swoich urządzeniach, aby użyć ich jako kontrolerów.", "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów do gry, zainstaluj 'BombSquad Remote'\ndostępny w odpowiednich sklepach dla urządzeń iOS/Android.\nUżyj telefonów i tabletów jako kontrolerów do gry.", "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Jeśli przyklei się do Ciebie bomba przylepna, skacz i kręć się szalenie, to może ją\nzrzucisz. Jeżeli Ci się nie uda, wówczas twoje ostatnie chwile będą przezabawne ;).", "If you kill an enemy in one hit you get double points for it.": "Jeśli zabijesz wroga jednym uderzeniem, otrzymasz podwójne punkty.", - "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jeśli zbierzesz 'Klątwę', to jedyną nadzieją aby\nprzetrwać jest szybkie zebranie apteczki.", - "If you stay in one place, you're toast. Run and dodge to survive..": "Jeśli będziesz się czaił w jednym miejscu to jesteś usmażony.\nBiegaj i unikaj ataków aby przetrwać.", - "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jeśli doświadczasz dużej rotacji wśród graczy, najlepiej włącz 'auto wyrzucanie\nbezczynnych graczy' w ustawieniach. Wyrzuci to tych, którzy nie grają a jedynie\nwiszą w grze blokując nowych chcących zagrać.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jeśli zbierzesz 'Klątwę', to jedyną nadzieją, aby\nprzetrwać, jest szybkie zebranie apteczki.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Jeśli będziesz stał w jednym miejscu, to staniesz się tostem. Biegaj i unikaj ataków, aby przetrwać..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jeśli doświadczasz dużej rotacji wśród graczy, włącz 'Wyrzucaj nieaktywnych graczy'\nw ustawieniach, a wszyscy, co zapomnieli wyjść z gry, magicznie znikną.", "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jeśli Twoje urządzenie mocno się przegrzewa lub po prostu chcesz oszczędzić baterię,\nwyłącz 'Wizualizacje' lub zmniejsz 'Rozdzielczość' w Ustawienia->Grafika", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jeśli ilość klatek na sekundę jest zbyt niska, spróbuj\nzmniejszyć rozdzielczość lub jakość ustawień graficznych.", - "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "W trybie 'Przechwycenia Flagi', Twoja flaga musi znajdować się w bazie aby zapunktować.\nJeśli drugi zespół zamierza zdobyć punkt, przechwycenie ich flagi będzie dobrym\nrozwiązaniem aby ich powstrzymać.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "W 'Przechwyceniu Flagi' wasza flaga musi znajdować się w waszej bazie, aby zapunktować. Jeśli drugi\nzespół zamierza zdobyć punkt, przechwycenie ich flagi może być dobrym rozwiązaniem, aby ich powstrzymać.", "In hockey, you'll maintain more speed if you turn gradually.": "Grając w hokeja, większą prędkość utrzymywać będziesz przy\nstopniowym i delikatnym skręcaniu postacią.", - "It's easier to win with a friend or two helping.": "Łatwiej zwyciężyć grając w zespole z jednym lub kilkoma\ntowarzyszami broni.", + "It's easier to win with a friend or two helping.": "Łatwiej zwyciężyć, grając w zespole z jednym lub kilkoma towarzyszami broni.", "Jump just as you're throwing to get bombs up to the highest levels.": "Dzięki podskokowi przy wyrzucaniu bomby można je wrzucić\nna wyższe, ciężko dostępne poziomy mapy.", - "Land-mines are a good way to stop speedy enemies.": "Miny lądowe są dobrym rozwiązaniem aby powstrzymywać\nszybkich i wściekłych wrogów.", + "Land-mines are a good way to stop speedy enemies.": "Miny lądowe idealnie zatrzymują szybkich i wściekłych wrogów.", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Można podnosić i rzucać wieloma rzeczami, włącznie z graczami. Zrzucanie\nwrogów z klifów może być skuteczne, a taka strategia satysfakcjonująca.", "No, you can't get up on the ledge. You have to throw bombs.": "Nie, nie dostaniesz się na wyższe półki. Może rzuć na nie bomby? :)", "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Gracze mogą dołączyć/opuścić grę w trakcie jej trwania,\na Ty możesz dołączać/odłączać kontrolery w locie.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Gracze mogą się dołączać/opuszczać grę w trakcie większości\nrozgrywek, tak samo można w locie podłączać/rozłączać gamepady.", "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Bonusy mają czasowe limity jedynie w rozgrywkach trybu Kooperacji.\nW rozgrywkach drużynowych i Free-for-All są Twoje aż do śmierci.", - "Practice using your momentum to throw bombs more accurately.": "Poćwicz wyczucie tempa aby rzucać bombami dokładniej.", + "Practice using your momentum to throw bombs more accurately.": "Poćwicz wyczucie tempa, aby rzucać bombami dokładniej.", "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ciosy powodują większe obrażenia jeśli się energicznie porusza\npięściami, więc staraj się biegać, skakać i kręcić jak szalony.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Podbiegnij do tyłu i przed rzuceniem bomby znów\ndo przodu. Pozwoli to na jej dalsze wyrzucenie.", "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Pozbądź się grupy wrogów poprzez\nrzucenie bomby blisko skrzyni TNT.", @@ -1837,14 +1957,14 @@ "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Siła rzutu zależy od kierunku, który trzymasz. Aby delikatnie tylko\ncoś podrzucić przed sobą, nie trzymaj żadnego klawisza kierunku.", "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Zmęczony domyślną ścieżką dźwiękową? Zamień ją na swoją!\nZobacz Ustawienia->Audio->Ścieżka dźwiękowa", "Try 'Cooking off' bombs for a second or two before throwing them.": "Przytrzymaj 'odpaloną bombę' przez 1 lub 2 sekundy zanim ją rzucisz.", - "Try tricking enemies into killing eachother or running off cliffs.": "Spróbuj oszukać wrogów aby się wzajemnie pozabijali lub zrzucili z klifów.", + "Try tricking enemies into killing eachother or running off cliffs.": "Spróbuj oszukać wrogów, aby się wzajemnie pozabijali lub zrzucili z klifów.", "Use the pick-up button to grab the flag < ${PICKUP} >": "Użyj przycisku 'Podnieś' aby chwycić flagę < ${PICKUP} >", "Whip back and forth to get more distance on your throws..": "Cofnij się... i do przodu, aby uzyskać dalsze rzuty...", "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Możesz wycelować swoje uderzenia obracając się w lewo lub prawo.\nJest to przydatne do spychania wrogów poza krawędzie lub w hokeju.", "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Możesz sam kontrolować i określić czas kiedy bomba eksploduje\npo kolorze iskier na jej loncie: żółty.. pomarańczowy.. czerwony.. BUM!", "You can throw bombs higher if you jump just before throwing.": "Możesz rzucać bombami wyżej jeśli podskoczysz przed wyrzuceniem.", "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Nie musisz edytować swojego profilu aby zmienić postacie. Naciśnij górny\nprzycisk (podnoszenie) kiedy dołączasz do gry aby zamienić domyślną postać.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Przyjmujesz obrażenia jeśli uderzasz głową w różne\nrzeczy, więc staraj się tego nie robić.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Przyjmujesz obrażenia, jeśli uderzasz głową w różne\nrzeczy, więc staraj się tego nie robić.", "Your punches do much more damage if you are running or spinning.": "Twoje ciosy zadadzą więcej obrażeń, jeśli będziesz biegać lub się kręcić." } }, @@ -1853,7 +1973,7 @@ "trophiesText": "Zdobycze", "trophiesThisSeasonText": "Zdobycze w tym Sezonie", "tutorial": { - "cpuBenchmarkText": "Wykonywanie testu szybkości (głównie testuje szybkość procesora)", + "cpuBenchmarkText": "Odtwarzanie samouczka na niedorzecznej prędkości (głównie testuje szybkość procesora)", "phrase01Text": "Hejka!", "phrase02Text": "Witaj w ${APP_NAME}!", "phrase03Text": "Oto kilka porad jak kontrolować swoją postać:", @@ -1864,9 +1984,9 @@ "phrase08Text": "Teraz skoczymy i wykonamy obrót aby zwiększyć szybkość.", "phrase09Text": "Ooo, tak lepiej.", "phrase10Text": "Bieganie również pomaga.", - "phrase11Text": "Przytrzymaj dowolny przycisk aby biec.", + "phrase11Text": "Przytrzymaj dowolny przycisk, aby biec.", "phrase12Text": "Dla uzyskania mocnych uderzeń, staraj się biegać i obracać.", - "phrase13Text": "Ojjj... sorki ${NAME}.", + "phrase13Text": "Ojjj... sorki, ${NAME}.", "phrase14Text": "Możesz podnosić i rzucać np. flagami, bombami, a nawet przeciwnikiem - ${NAME}.", "phrase15Text": "Ale BombSquad to głównie BOMBY.", "phrase16Text": "Skuteczne rzucanie bombami wymaga odrobinę praktyki.", @@ -1879,7 +1999,7 @@ "phrase23Text": "Spróbuj \"przysmażyć\" lont przez sekundę lub dwie.", "phrase24Text": "I proszę! Nieźle upieczony.", "phrase25Text": "Cóż, to by było na tyle.", - "phrase26Text": "A teraz bierz ich tygrysie!", + "phrase26Text": "A teraz bierz ich, tygrysie!", "phrase27Text": "Zapamiętaj to szkolenie rekrucie, a RACZEJ wrócisz żywy!", "phrase28Text": "...może...", "phrase29Text": "Powodzenia!", @@ -1888,30 +2008,37 @@ "randomName3Text": "Benio", "randomName4Text": "Czesio", "randomName5Text": "Ignaś", - "skipConfirmText": "Naprawdę chcesz pominąć samouczek? Stuknij lub naciśnij aby zatwierdzić.", + "skipConfirmText": "Naprawdę chcesz pominąć samouczek? Stuknij lub naciśnij, aby zatwierdzić.", "skipVoteCountText": "${COUNT}/${TOTAL} pominiętych głosów", "skippingText": "pomijam samouczek...", - "toSkipPressAnythingText": "(stuknij lub naciśnij cokolwiek aby pominąć samouczek)" + "toSkipPressAnythingText": "(stuknij lub naciśnij cokolwiek, aby pominąć samouczek)" }, "twoKillText": "PODWÓJNE ZABÓJSTWO!", + "uiScaleText": "Skala interfejsu", "unavailableText": "niedostępne", + "unclaimedPrizesText": "Masz nieodebrane nagrody!", "unconfiguredControllerDetectedText": "Wykryto nieskonfigurowany kontroler:", "unlockThisInTheStoreText": "To musi zostać odblokowane w sklepie.", "unlockThisProfilesText": "By stworzyć więcej niż ${NUM} kont, potrzebujesz:", "unlockThisText": "Żeby to odblokować, potrzebujesz:", - "unsupportedHardwareText": "Przepraszam ale ten sprzęt nie jest obsługiwany przez tą wersję gry.", + "unsupportedControllerText": "Wybacz, ale kontroler \"${NAME}\" nie jest wspierany.", + "unsupportedHardwareText": "Przepraszam, ale ten sprzęt nie jest obsługiwany przez tę wersję gry.", "upFirstText": "Pierwsza gra:", "upNextText": "Kolejna, ${COUNT} gra w rozgrywce:", "updatingAccountText": "Aktualizowanie twojego konta...", "upgradeText": "Ulepsz", - "upgradeToPlayText": "Aby zagrać odblokuj grę w wersji \"${PRO}\".", + "upgradeToPlayText": "Aby zagrać, odblokuj grę w wersji \"${PRO}\".", "useDefaultText": "Użyj domyślnych", + "userSystemScriptsCreateText": "Utwórz skrypty systemowe użytkownika", + "userSystemScriptsDeleteText": "Usuń skrypty systemowe użytkownika", "usesExternalControllerText": "Ta gra wykorzystuje zewnętrzny kontroler jako wejście.", "usingItunesText": "Korzystanie z aplikacji muzycznej jako ścieżki dźwiękowej...", "usingItunesTurnRepeatAndShuffleOnText": "Upewnij się, że w ustawieniach iTunes tasowanie utworów i powtarzanie całości jest włączone.", "v2AccountLinkingInfoText": "Aby połączyć konta V2, użyj przycisku \"Zarządzaj Kontem\".", + "v2AccountRequiredText": "Wymaga to konta V2. Uaktualnij swoje konto i spróbuj ponownie.", "validatingBetaText": "Legalizowanie wersji Beta...", "validatingTestBuildText": "Sprawdzanie wersji testowej...", + "viaText": "poprzez", "victoryText": "Zwycięstwo!", "voteDelayText": "Nie możesz zagłosować przez następne ${NUMBER} sekund", "voteInProgressText": "Głosowanie jest już w toku.", @@ -1922,7 +2049,7 @@ "waitingForLocalPlayersText": "Oczekiwanie na lokalnych graczy...", "waitingForPlayersText": "oczekiwanie na dołączenie graczy...", "waitingInLineText": "Czekanie w kolejce (impreza pełna)...", - "watchAVideoText": "Zobacz Filmik", + "watchAVideoText": "Obejrzyj filmik", "watchAnAdText": "Obejrzyj reklamę", "watchWindow": { "deleteConfirmText": "Usunąć \"${REPLAY}\"?", @@ -1956,7 +2083,7 @@ "wiimoteSetupWindow": { "copyrightText": "Prawa autorskie DarwiinRemote", "listenText": "Nasłuchiwanie", - "macInstructionsText": "Upewnij się, że twój kontroler Wii jest wyłączony a\nBluetooth uruchomiony na twoim Mac'u, następnie\nnaciśnij 'Słuchaj'. Wsparcie dla Wiimote może być\ntroszkę ciężko kojarzone, więc musisz spróbować\nkilkakrotnie aby uzyskać połączenie.\n\nBluetooth poradzi sobie z połączeniem do 7 urządzeń,\nchociaż ta liczba może się wahać.\n\nBombSquad wspiera oryginalne Wiimotes, Nunchuks,\ni klasyczne kontrolery. Nowy Wii Remote Plus również\npowinien współpracować lecz bez dodatków.", + "macInstructionsText": "Upewnij się, że twój kontroler Wii jest wyłączony a\nBluetooth włączony na twoim Mac'u, a następnie\nnaciśnij 'Słuchaj'. Wsparcie dla Wiimote może być\ntroszkę kulawe, więc być może będziesz musiał\npopróbować kilka razy, zanim uzyskasz połączenie.\n\nBluetooth poradzi sobie z połączeniem do 7 urządzeń,\nchociaż ta liczba może się wahać.\n\nBombSquad wspiera oryginalne Wiimoty, Nunchuki\ni klasyczne kontrolery. Nowy Wii Remote Plus również\npowinien współpracować, ale nie z dodatkami.", "thanksText": "Podziękowania dla zespołu DarwiinRemote\nza wykonanie tej możliwości.", "titleText": "Ustawienia Wiimote" }, @@ -1971,11 +2098,12 @@ "xbox360ControllersWindow": { "getDriverText": "Pobierz sterownik", "macInstructions2Text": "Aby używać kontrolery bezprzewodowo, musisz posiadać odbiornik\ndostępny w zestawie 'Bezprzewodowy kontroler Xbox360 dla Windows'.\nJeden odbiornik pozwala na podłączenie do 4 kontrolerów.\n\nWażne: inne odbiorniki mogą nie współpracować ze sterownikiem;\nupewnij się, czy odbiornik posiada napis 'Microsoft', nie 'XBOX360'.\nMicrosoft nie sprzedaje odbiorników osobno, więc musisz nabyć go\nw zestawie z kontrolerem lub zakupić na aukcjach.\n\nJeśli powyższe informacje okazały się przydatne, rozważ przekazanie\ndotacji dla producenta sterownika na jego stronie.", - "macInstructionsText": "Aby użyć kontrolerów z konsoli Xbox360, musisz\nzainstalować sterownik Mac'a dostępny w poniższym linku.\nSterownik współpracuje zarówno z przewodowymi jak i\nbezprzewodowymi kontrolerami.", - "ouyaInstructionsText": "Aby skorzystać z bezprzewodowych kontrolerów konsoli Xbox360,\npodłącz je do portów USB urządzeń. Możesz skorzystać z hubu USB\naby podłączyć klika kontrolerów.\n\nAby użyć bezprzewodowe kontrolery musisz posiadać bezprzewodowy\nodbiornik, dostępny w zestawie \"Bezprzewodowy kontroler Xbox360\ndla Windows\" lub sprzedawany oddzielnie. Każdy odbiornik podłączony\ndo portu USB urządzenia pozwoli na podłączenie do 4 bezprzewodowych\nkontrolerów.", - "titleText": "Wykorzystywanie kontrolerów Xbox360 w ${APP_NAME}" + "macInstructionsText": "Aby użyć kontrolerów z Xboxa 360, musisz zainstalować\nsterownik do Maca dostępny w poniższym linku. Działa on zarówno\nz przewodowymi jak i bezprzewodowymi kontrolerami.", + "ouyaInstructionsText": "Aby skorzystać z bezprzewodowych kontrolerów konsoli Xbox 360,\npodłącz je do portów USB w twoim urządzeniu. Możesz skorzystać\nz huba USB, aby podłączyć wiele kontrolerów.\n\nAby używać bezprzewodowych kontrolerów, musisz posiadać bezprzewodowy\nodbiornik, dostępny w zestawie \"Bezprzewodowy kontroler Xbox 360 dla \nWindows\" lub sprzedawany oddzielnie. Każdy odbiornik podłączony do portu\nUSB urządzenia pozwoli na podłączenie do 4 bezprzewodowych kontrolerów.", + "titleText": "Wykorzystywanie kontrolerów Xbox 360 w ${APP_NAME}:" }, "yesAllowText": "Dajesz!", "yourBestScoresText": "Twoje najlepsze wyniki", - "yourBestTimesText": "Twoje najlepsze czasy" + "yourBestTimesText": "Twoje najlepsze czasy", + "yourPrizeText": "Twoja nagroda:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/portuguese.json b/dist/ba_data/data/languages/portuguese.json index 20bdf20c..56eaf26a 100644 --- a/dist/ba_data/data/languages/portuguese.json +++ b/dist/ba_data/data/languages/portuguese.json @@ -26,12 +26,14 @@ "setAccountNameDesc": "Escolha o nome que será exibido na sua conta.\nVocê pode usar o nome de uma de suas contas\nou criar um nome personalizado exclusivo.", "signInInfoText": "Inicie sessão para ganhar bilhetes, compita online e compartilhe\no seu progresso entre vários dispositivos.", "signInText": "Iniciar sessão", + "signInWithAnEmailAddressText": "Faça login com um endereço de e-mail", "signInWithDeviceInfoText": "(uma conta automática disponível apenas neste aparelho)", "signInWithDeviceText": "Iniciar sessão com conta do dispositivo", "signInWithGameCircleText": "Iniciar sessão com Game Circle", "signInWithGooglePlayText": "Iniciar sessão com Google Play", "signInWithTestAccountInfoText": "(tipo de conta legado; use as contas do dispositivo daqui em diante)", "signInWithTestAccountText": "Iniciar sessão com conta teste", + "signInWithText": "Entrar com ${SERVICE}", "signInWithV2InfoText": "(uma conta que funciona em todas as plataformas)", "signInWithV2Text": "Iniciar sessão com conta do BombSquad", "signOutText": "Finalizar sessão", @@ -339,6 +341,9 @@ "getMoreGamesText": "Mais jogos...", "titleText": "Adicionar jogo" }, + "addToFavoritesText": "Adicionar aos Favoritos", + "addedToFavoritesText": "Adicionou '${NAME}' aos Favoritos.", + "allText": "Tudo", "allowText": "Permitir", "alreadySignedInText": "A conta tem sessão iniciada em outro dispositivo;\nMude de conta ou feche o jogo no seu\noutro dispositivo e tente novamente.", "apiVersionErrorText": "Não é possível carregar o módulo ${NAME}; ele é destinado à versão ${VERSION_USED}; exigimos a ${VERSION_REQUIRED}.", @@ -374,6 +379,7 @@ "chatMutedText": "Chat silenciado", "chatUnMuteText": "Reativar som do chat", "choosingPlayerText": "", + "codesExplainText": "Os códigos são fornecidos pelo desenvolvedor para \ndiagnosticar e corrigir problemas de conta.", "completeThisLevelToProceedText": "Você deve completar \neste nível para continuar!", "completionBonusText": "Bônus de conclusão", "configControllersWindow": { @@ -423,11 +429,11 @@ "pressAnyButtonText": "Aperte qualquer botão...", "pressLeftRightText": "Aperte esquerda ou direita...", "pressUpDownText": "Aperte cima ou baixo...", - "runButton1Text": "Executar botão 1", - "runButton2Text": "Executar botão 2", - "runTrigger1Text": "Executar gatilho 1", - "runTrigger2Text": "Executar gatilho 2", - "runTriggerDescriptionText": "(os gatilhos o permitem correr em diferentes velocidades)", + "runButton1Text": "Correr Botão 1", + "runButton2Text": "Correr Botão 2", + "runTrigger1Text": "Correr Gatilho 1", + "runTrigger2Text": "Correr Gatilho 2", + "runTriggerDescriptionText": "(os gatilhos analogicos o permitem correr em diferentes velocidades)", "secondHalfText": "Use isto para configurar a segunda metade\nde um controle que funciona\ncomo 2-em-1.", "secondaryEnableText": "Ativar", "secondaryText": "Controle secundário", @@ -463,6 +469,7 @@ "titleText": "Configurar touchscreen", "touchControlsScaleText": "Escala de Toque do Controle" }, + "configureDeviceInSystemSettingsText": "${DEVICE} pode ser configurado no aplicativo \"Configurações do sistema\".", "configureItNowText": "Configurar agora?", "configureText": "Configurar", "connectMobileDevicesWindow": { @@ -576,6 +583,7 @@ "demoText": "Teste", "denyText": "Recusar", "deprecatedText": "Descontinuado", + "descriptionText": "Descrição", "desktopResText": "Resolução da área de trabalho", "deviceAccountUpgradeText": "Aviso:\nVocê está logado com a conta do seu dispositivo\n(${NAME}).\nContas de dispositivo serão removidas em uma atualização futura.", "difficultyEasyText": "Fácil", @@ -586,6 +594,9 @@ "disableRemoteAppConnectionsText": "Desativar conexões do aplicativo BombSquad Remote", "disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.", "disableXInputText": "Desativar XInput", + "disabledText": "Desabilitado", + "discordFriendsText": "Quer procurar por pessoas para jogar com elas?\nEntre no nosso Discord e encontre novos amigos!", + "discordJoinText": "Junte-se ao Discord", "doneText": "Concluído", "drawText": "Empate", "duplicateText": "Duplicar", @@ -620,6 +631,7 @@ "localProfileText": "(perfil local)", "nameDescriptionText": "Nome do jogador", "nameText": "Nome", + "profileAlreadyExistsText": "Um perfil com este nome já existe.", "randomText": "aleatório", "titleEditText": "Editar perfil", "titleNewText": "Novo perfil", @@ -659,6 +671,7 @@ "useMusicFolderText": "Pasta de arquivos de música" }, "editText": "Editar", + "enabledText": "Abilitado", "endText": "Fim", "enjoyText": "Aproveite!", "epicDescriptionFilterText": "${DESCRIPTION} em câmera lenta épica.", @@ -706,6 +719,8 @@ "editText": "Editar\nPlaylist", "gameListText": "Lista de Games", "newText": "Nova\nPlaylist", + "pointsToWinText": "Pontos para ganhar", + "seriesLengthText": "Tamanho da série", "showTutorialText": "Mostrar Tutorial", "shuffleGameOrderText": "Ordem de partida aleatória", "titleText": "Personalizar playlists de ${TYPE}" @@ -745,10 +760,10 @@ "friendHasSentPromoCodeText": "${COUNT} bilhetes do ${APP_NAME} mandados por ${NAME}", "friendPromoCodeAwardText": "Você ganhará ${COUNT} bilhetes toda vez que for usado.", "friendPromoCodeExpireText": "O código expira em ${EXPIRE_HOURS} horas e só funcionará para novos jogadores.", - "friendPromoCodeInstructionsText": "Para usar, abra ${APP_NAME} e vá até \"Configurações-> Avançado-> Inserir código\".\nVeja bombsquadgame.com para os links de download para todas as plataformas disponíveis.", + "friendPromoCodeInstructionsText": "Para usar, abra ${APP_NAME} e vá até \"Configurações-> Avançaodo-> Inserir código\". \nVeja bombsquadgame.com para os download de links para todas as plataformas disponíveis.", "friendPromoCodeRedeemLongText": "Pode ser resgatado por ${COUNT} bilhetes gratuitos por até ${MAX_USES} pessoas.", "friendPromoCodeRedeemShortText": "Pode ser resgatado por ${COUNT} bilhetes no jogo.", - "friendPromoCodeWhereToEnterText": "(em \"Configurações-> Avançado-> Inserir código\")", + "friendPromoCodeWhereToEnterText": "(em \"Configuração -> Avançado -> Inserir código\")", "getFriendInviteCodeText": "Obter código de convite", "googlePlayDescriptionText": "Convidar jogadores do Google Play para a sua sala:", "googlePlayInviteText": "Convidar", @@ -780,6 +795,7 @@ "manualYourLocalAddressText": "Seu endereço local:", "nearbyText": "Próximo", "noConnectionText": "", + "noPartiesAddedText": "Nenhum grupo adicionado", "otherVersionsText": "(outras versões)", "partyCodeText": "Código da Sala", "partyInviteAcceptText": "Aceitar", @@ -860,10 +876,12 @@ "autoText": "Auto", "fullScreenCmdText": "Tela cheia (Cmd-F)", "fullScreenCtrlText": "Tela cheia (Ctrl-F)", + "fullScreenText": "Tela cheia", "gammaText": "Gama", "highText": "Alto", "higherText": "Mais alto", "lowText": "Baixo", + "maxFPSText": "FPS máximo", "mediumText": "Médio", "neverText": "Nunca", "resolutionText": "Resolução", @@ -1124,8 +1142,10 @@ "noExternalStorageErrorText": "Armazenamento externo não encontrado", "noGameCircleText": "Erro: não conectado no GameCircle", "noJoinCoopMidwayText": "Jogos cooperativos não podem ser afiliados no meio do caminho.", + "noPluginsInstalledText": "Nenhum Plugin instalado", "noProfilesErrorText": "Você não tem perfis de jogadores, então você está preso com '${NAME}'.\nVá para Configurações->Perfis de Jogador para criar um perfil.", "noScoresYetText": "Ainda sem pontuação.", + "noServersFoundText": "Servidores não encontrados.", "noThanksText": "Não, obrigado", "noTournamentsInTestBuildText": "Atenção: As pontuações dos torneios desta compilação de teste serão ignoradas.", "noValidMapsErrorText": "Nenhum mapa válido encontrado para este tipo de jogo.", @@ -1300,7 +1320,9 @@ "revertText": "Reverter", "runText": "Correr", "saveText": "Salvar", - "scanScriptsErrorText": "Erro ao ler scripts; verifica o Log para mais informações", + "scanScriptsErrorText": "Erro(s) de verificação de scripts; consulte o registro para obter mais detalhes.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} e outro(s) módulo(s) precisam de atualizações paro o api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} precisa ser atualizado para api${API}.", "scoreChallengesText": "Desafios de Pontuação", "scoreListUnavailableText": "Lista de pontuação indisponível.", "scoreText": "Pontuação", @@ -1311,6 +1333,7 @@ }, "scoreWasText": "(foi ${COUNT})", "selectText": "Selecionar", + "sendInfoDescriptionText": "Envia a informação sua conta e estado de aplicativo para o desenvolvedor.\nPor favor incluir seu nome ou razão para mandar.", "seriesWinLine1PlayerText": "VENCEU A", "seriesWinLine1Scale": 0.65, "seriesWinLine1TeamText": "VENCEU A", @@ -1332,25 +1355,31 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(um teclado simples para edição de texto)", - "alwaysUseInternalKeyboardText": "Sempre usar o teclado interno", + "alwaysUseInternalKeyboardText": "Sempre Usar O Teclado Interno", "benchmarksText": "Testes de desempenho", - "disableCameraGyroscopeMotionText": "Desativar o movimento do giroscópio da câmera", - "disableCameraShakeText": "Desabilitar o shake da câmera", + "devToolsText": "Ferramentas de Desenvolvimento", + "disableCameraGyroscopeMotionText": "Desativar Movimento Giroscópio da Câmera", + "disableCameraShakeText": "Desativar Tremida da câmera", "disableThisNotice": "(você pode desativar este aviso em configurações avançadas)", "enablePackageModsDescriptionText": "(ativa habilidades de modificação do jogo mas desabilita jogos em LAN)", "enablePackageModsText": "Ativar modificações locais do jogo", "enterPromoCodeText": "Inserir código", "forTestingText": "Nota: esses valores são somente para teste e serão perdidos assim que o aplicativo for fechado.", "helpTranslateText": "As traduções do ${APP_NAME} são sustentadas pelo\nesforço público. Se você gostaria de ajudar ou corrigir\numa tradução, siga o link a seguir. Agradeço desde já!", - "kickIdlePlayersText": "Expulsar jogadores ausentes", + "kickIdlePlayersText": "Expulsar Jogadores Ausentes", "kidFriendlyModeText": "Modo para crianças (violência reduzida, etc)", "languageText": "Idioma", "moddingGuideText": "Guia de modificação", + "moddingToolsText": "Ferramentas Para Mods", "mustRestartText": "Você deve reiniciar o jogo para a modificação ter efeito.", "netTestingText": "Teste de conexão", "resetText": "Redefinir", + "sendInfoText": "Enviar Informação", "showBombTrajectoriesText": "Mostrar trajetórias da bomba", - "showInGamePingText": "Mostrar latência no jogo", + "showDemosWhenIdleText": "Mostrar Demonstrações Quando ocioso", + "showDeprecatedLoginTypesText": "Mostrar tipos de logins ultrapassados", + "showDevConsoleButtonText": "Mostrar console de desenvolvedor", + "showInGamePingText": "Mostrar Latência no jogo", "showPlayerNamesText": "Mostrar nomes dos jogadores", "showUserModsText": "Mostrar Pasta de Modificações", "titleText": "Avançado", @@ -1359,7 +1388,7 @@ "translationFetchingStatusText": "verificando estado da tradução...", "translationInformMe": "Informe quando meu idioma precisar de atualizações", "translationNoUpdateNeededText": "o idioma atual está atualizado; woohoo!", - "translationUpdateNeededText": "** o idioma atual precisa de atualizações!! **", + "translationUpdateNeededText": "** o idioma atual necessita de atualizações!! **", "vrTestingText": "Teste de RV" }, "shareText": "Compartilhar", @@ -1369,6 +1398,9 @@ "signInWithGameCenterText": "Para usar uma conta Game Center,\ninicie a sessão com o aplicativo Game Center.", "singleGamePlaylistNameText": "Somente ${GAME}", "singlePlayerCountText": "1 jogador", + "sizeLargeText": "Grande", + "sizeMediumText": "Médio", + "sizeSmallText": "Pequeno", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Seleção do personagem", @@ -1445,6 +1477,8 @@ "storeText": "Loja", "submitText": "Valor", "submittingPromoCodeText": "Enviando código promocional...", + "successText": "Sucesso!", + "supportEmailText": "Se estiver passando por problemas com o aplicativo, \nenvie um e-mail para ${EMAIL}.", "teamNamesColorText": "Nome/cores das equipes...", "teamsText": "Times", "telnetAccessGrantedText": "Acesso ao Telnet ativado.", @@ -1480,16 +1514,16 @@ "Agent Johnson": "Agente Johnson", "B-9000": "B-9000", "Bernard": "Bernardo", - "Bones": "Bones", + "Bones": "Ossos", "Butch": "Butch", - "Easter Bunny": "Coelho de Páscoa", + "Easter Bunny": "Coelho da Páscoa", "Flopsy": "Flopsy", "Frosty": "Frosty", "Gretel": "Gretel", - "Grumbledorf": "Grumblodor", + "Grumbledorf": "Grumboldor", "Jack Morgan": "Jack Morgan", "Kronk": "Kronk", - "Lee": "Sotavento", + "Lee": "Lee", "Lucky": "Lucky", "Mel": "Mel", "Middle-Man": "Homenzinho", @@ -1498,9 +1532,9 @@ "Pixel": "Pixel", "Sammy Slam": "Sammy Slam", "Santa Claus": "Papai Noel", - "Snake Shadow": "Serpente sombria", + "Snake Shadow": "Serpente Sombria", "Spaz": "Spaz", - "Taobao Mascot": "Mascote da Taobao", + "Taobao Mascot": "Mascote Taobao", "Todd": "Teddy", "Todd McBurton": "Todd McBurton", "Xara": "Zara", @@ -1921,11 +1955,13 @@ "toSkipPressAnythingText": "(pressione qualquer coisa para pular o tutorial)" }, "twoKillText": "MATOU DOIS!", + "uiScaleText": "Tamanho da Interface", "unavailableText": "indisponível", "unconfiguredControllerDetectedText": "Controle não configurado detectado:", "unlockThisInTheStoreText": "Isto deve ser desbloqueado na loja.", "unlockThisProfilesText": "Para criar mais que ${NUM} perfis, você precisa:", "unlockThisText": "Para desbloquear isso:", + "unsupportedControllerText": "Desculpe, o controlador \"${NAME}\" não é compatível.", "unsupportedHardwareText": "Desculpe, este hardware não é suportado por esta versão do jogo.", "upFirstText": "Em primeiro lugar:", "upNextText": "O próximo jogo em ${COUNT}:", @@ -1933,12 +1969,15 @@ "upgradeText": "Melhorar", "upgradeToPlayText": "Atualize para \"${PRO}\" na loja para jogar.", "useDefaultText": "Usar padrão", + "userSystemScriptsCreateText": "Criar Scripts do Sistema do Usuário", + "userSystemScriptsDeleteText": "Deletar Scripts do Sistema do Usuário", "usesExternalControllerText": "Este jogo usa um controle externo para entrada.", "usingItunesText": "Usando o app de música para a trilha sonora", "usingItunesTurnRepeatAndShuffleOnText": "Por favor, certifique-se de que o aleatório esteja ligado e que a repetição seja TODAS AS MÚSICAS no iTunes.", "v2AccountLinkingInfoText": "Para vincular contas V2, use o botão 'Gerenciar conta'.", "validatingBetaText": "Validando Beta...", "validatingTestBuildText": "Validando versão de teste...", + "viaText": "via", "victoryText": "Vitória!", "voteDelayText": "Você não pode começar outra votação por ${NUMBER} segundo(s)", "voteInProgressText": "Uma votação já está em progresso.", diff --git a/dist/ba_data/data/languages/portuguesebrazil.json b/dist/ba_data/data/languages/portuguesebrazil.json new file mode 100644 index 00000000..fccf034c --- /dev/null +++ b/dist/ba_data/data/languages/portuguesebrazil.json @@ -0,0 +1,1980 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "O seu nome não pode conter emojis ou outros caracteres especiais", + "accountsText": "Contas", + "achievementProgressText": "Conquistas: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progresso da Campanha Difícil: ${PROGRESS}", + "changeOncePerSeason": "Você só pode mudar isso uma vez por temporada.", + "changeOncePerSeasonError": "Você deve esperar até a próxima temporada para mudar isso novamente (${NUM} dias)", + "createAnAccountText": "Crie uma conta", + "customName": "Nome personalizado", + "deleteAccountText": "Deletar conta", + "googlePlayGamesAccountSwitchText": "Se você quer usar uma conta Google diferente,\nUse o Google Play Games para trocar de conta.", + "linkAccountsEnterCodeText": "Colocar Código", + "linkAccountsGenerateCodeText": "Gerar Código", + "linkAccountsInfoText": "(compartilhar progresso entre varios dispositivos)", + "linkAccountsInstructionsNewText": "Para vincular duas contas, crie um código na primeira\ne coloque o código na segunda. O progresso de\nambas as contas serão sincronizadas. Tornando se uma unica conta\n(O progresso da primeira conta será perdido)\n\nVocê pode vincular até ${COUNT} contas.\n\nIMPORTANTE: vincule apenas contas que tem acesso; \nSe você vincular a conta de um amigo, vocês não\nirão conseguir jogar online ao mesmo tempo.", + "linkAccountsText": "Vincular contas", + "linkedAccountsText": "Contas vinculadas:", + "manageAccountText": "Gerenciar Conta", + "nameChangeConfirm": "Mudar o nome da sua conta para ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Isto reiniciará o seu progresso no cooperativo e\nas suas pontuações (mas não os seus bilhetes).\nIsto não pode ser desfeito. Tem certeza?", + "resetProgressConfirmText": "Isto reiniciará o seu progresso no cooperativo,\nas suas conquistas e as suas pontuações\n(mas não os seus bilhetes). Isto não pode\nser desfeito. Tem certeza?", + "resetProgressText": "Restaurar progresso", + "setAccountName": "Escolha o Nome da Conta", + "setAccountNameDesc": "Escolha o nome que será exibido na sua conta.\nVocê pode usar o nome de uma de suas contas\nou criar um nome personalizado exclusivo.", + "signInInfoText": "Conecte uma conta para ganhar bilhetes, compita online e compartilhe\no seu progresso entre vários dispositivos.", + "signInText": "Conectar-se a sua conta", + "signInWithAnEmailAddressText": "Faça login com um endereço de e-mail", + "signInWithDeviceInfoText": "(uma conta automática disponível apenas neste aparelho)", + "signInWithDeviceText": "Conectar-se com a conta de seu proprio dispositivo", + "signInWithText": "Entrar com ${SERVICE}", + "signInWithV2InfoText": "(uma conta que funciona em todas as plataformas)", + "signInWithV2Text": "Usar uma conta do(a) ${APP_NAME}", + "signOutText": "Sair da conta", + "signingInText": "Iniciando sessão...", + "signingOutText": "Finalizando sessão...", + "ticketsText": "Bilhetes: ${COUNT}", + "titleText": "Conta", + "unlinkAccountsInstructionsText": "Selecione uma conta a qual você quer sair", + "unlinkAccountsText": "Desvincular contas", + "unlinkLegacyV1AccountsText": "Retirar contas V1", + "v2LinkInstructionsText": "Utilize o link para criar uma conta ou entrar nela.", + "viaAccount": "(via ${NAME})", + "youAreSignedInAsText": "Conectou-se como:" + }, + "achievementChallengesText": "Desafios feitos", + "achievementText": "Conquistas", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mate 3 inimigos com TNT", + "descriptionComplete": "Você matou 3 inimigos com TNT", + "descriptionFull": "Mate 3 inimigos com TNT no ${LEVEL}", + "descriptionFullComplete": "Você matou 3 inimigos com TNT no ${LEVEL}", + "name": "Quem brinca com fogo, sai queimado" + }, + "Boxer": { + "description": "Ganhe sem usar bombas", + "descriptionComplete": "Ganhou sem usar bombas", + "descriptionFull": "Complete o ${LEVEL} sem usar bombas", + "descriptionFullComplete": "Completou o ${LEVEL} sem usar bombas", + "name": "Boxeador" + }, + "Dual Wielding": { + "descriptionFull": "Conecte 2 controles sendo fisicos ou sendo virtuais (pelo aplicativo)", + "descriptionFullComplete": "Conectou 2 controles sendo fisicos ou sendo virtuais (pelo aplicativo)", + "name": "Dominação dupla" + }, + "Flawless Victory": { + "description": "Ganhe sem ser atingido", + "descriptionComplete": "Ganhou sem ser atingido", + "descriptionFull": "Ganhe o ${LEVEL} sem ser atingido", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem ser atingido", + "name": "Vitória perfeita" + }, + "Free Loader": { + "descriptionFull": "Comece um Todos contra todos com mais de 2 jogadores", + "descriptionFullComplete": "Começou um Todos contra todos com mais de 2 jogadores", + "name": "Carregador livre" + }, + "Gold Miner": { + "description": "Mate 6 inimigos com minas", + "descriptionComplete": "Matou 6 inimigos com minas", + "descriptionFull": "Mate 6 inimigos com minas no ${LEVEL}", + "descriptionFullComplete": "Matou 6 inimigos com minas no ${LEVEL}", + "name": "Garimpeiro" + }, + "Got the Moves": { + "description": "Ganhe sem usar socos ou bombas", + "descriptionComplete": "Ganhou sem usar socos ou bombas", + "descriptionFull": "Ganhe o ${LEVEL} sem socos ou bombas", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem socos ou bombas", + "name": "Esse Tem Gingado" + }, + "In Control": { + "descriptionFull": "Conecte um controle (hardware ou aplicativo)", + "descriptionFullComplete": "Conectou um controle. (hardware ou aplicativo)", + "name": "No controle" + }, + "Last Stand God": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "${LEVEL} Deus" + }, + "Last Stand Master": { + "description": "Marque 250 pontos", + "descriptionComplete": "Marcou 250 pontos", + "descriptionFull": "Marque 250 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 250 pontos no ${LEVEL}", + "name": "${LEVEL} Mestre" + }, + "Last Stand Wizard": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "${LEVEL} Mago" + }, + "Mine Games": { + "description": "Mate 3 inimigos com minas", + "descriptionComplete": "Matou 3 inimigos com minas", + "descriptionFull": "Mate 3 inimigos com minas no ${LEVEL}", + "descriptionFullComplete": "Matou 3 inimigos com minas no ${LEVEL}", + "name": "Brincando com Minas" + }, + "Off You Go Then": { + "description": "Mande 3 inimigos para fora do mapa", + "descriptionComplete": "Mandou 3 inimigos para fora do mapa", + "descriptionFull": "Mande 3 inimigos para fora do mapa no ${LEVEL}", + "descriptionFullComplete": "Mandou 3 inimigos para fora do mapa no ${LEVEL}", + "name": "Pode Ir Agora" + }, + "Onslaught God": { + "description": "Marque 5000 pontos", + "descriptionComplete": "Marcou 5000 pontos", + "descriptionFull": "Marque 5000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 5000 pontos no ${LEVEL}", + "name": "${LEVEL} Deus" + }, + "Onslaught Master": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "${LEVEL} Mestre" + }, + "Onslaught Training Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Derrotou todas as ondas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Derrotou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "Mago do ${LEVEL}" + }, + "Precision Bombing": { + "description": "Ganhe sem poderes", + "descriptionComplete": "Ganhou sem poderes", + "descriptionFull": "Ganhe ${LEVEL} sem poderes", + "descriptionFullComplete": "Ganhou ${LEVEL} sem poderes", + "name": "Chuva de Bomba" + }, + "Pro Boxer": { + "description": "Ganhe sem usar bombas", + "descriptionComplete": "Ganhou sem usar bombas", + "descriptionFull": "Complete o ${LEVEL} sem usar bombas", + "descriptionFullComplete": "Completou o ${LEVEL} sem usar bombas", + "name": "Pugilista" + }, + "Pro Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe o ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} De Lavada" + }, + "Pro Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Todas as ondas derrotadas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas do ${LEVEL} derrotadas", + "name": "Vitória no ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Complete todas as ondas", + "descriptionComplete": "Todas as ondas completadas", + "descriptionFull": "Complete todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas completadas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe no ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou no ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} de levada" + }, + "Rookie Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Todas as ondas derrotadas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas no ${LEVEL} derrotadas", + "name": "Vitória no ${LEVEL}" + }, + "Runaround God": { + "description": "Marque 2000 pontos", + "descriptionComplete": "Marcou 2000 pontos", + "descriptionFull": "Marque 2000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 2000 pontos no ${LEVEL}", + "name": "Deus da ${LEVEL}" + }, + "Runaround Master": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "Mestre do ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "Mago do ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Compartilhe o jogo com um amigo", + "descriptionFullComplete": "Jogo compartilhado com um amigo", + "name": "Compartilhar é amar" + }, + "Stayin' Alive": { + "description": "Ganhe sem morrer", + "descriptionComplete": "Ganhou sem morrer", + "descriptionFull": "Ganhe o ${LEVEL} sem morrer", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem morrer", + "name": "Sobrevivendo" + }, + "Super Mega Punch": { + "description": "Cause 100% de dano com um soco", + "descriptionComplete": "Causou 100% de dano com um soco", + "descriptionFull": "Cause 100% de dano com um soco no ${LEVEL}", + "descriptionFullComplete": "Causou 100% de dano com um soco no ${LEVEL}", + "name": "Super mega soco" + }, + "Super Punch": { + "description": "Cause 50% de dano com um soco", + "descriptionComplete": "Causou 50% de dano com um soco", + "descriptionFull": "Cause 50% de dano com um soco no ${LEVEL}", + "descriptionFullComplete": "Causou 50% de dano com um soco no ${LEVEL}", + "name": "Supersoco" + }, + "TNT Terror": { + "description": "Mate 6 inimigos com TNT", + "descriptionComplete": "Matou 6 inimigos com TNT", + "descriptionFull": "Mate 6 inimigos com TNT no ${LEVEL}", + "descriptionFullComplete": "Matou 6 inimigos com TNT no ${LEVEL}", + "name": "Terror do TNT" + }, + "Team Player": { + "descriptionFull": "Comece um jogo de equipes com mais de 4 jogadores", + "descriptionFullComplete": "Começou um jogo de equipes com mais de 4 jogadores", + "name": "Jogador de equipe" + }, + "The Great Wall": { + "description": "Pare todos os inimigos", + "descriptionComplete": "Parou todos os inimigos", + "descriptionFull": "Pare todos os inimigos no ${LEVEL}", + "descriptionFullComplete": "Parou todos os inimigos no ${LEVEL}", + "name": "A Grande Muralha" + }, + "The Wall": { + "description": "Pare todos os inimigos", + "descriptionComplete": "Parou todos os inimigos", + "descriptionFull": "Pare todos os inimigos no ${LEVEL}", + "descriptionFullComplete": "Parou todos os inimigos no ${LEVEL}", + "name": "A Muralha" + }, + "Uber Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe o ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} De Lavada" + }, + "Uber Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Derrotou todas as ondas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Derrotou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Complete todas as ondas", + "descriptionComplete": "Completou todas as ondas", + "descriptionFull": "Complete todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Completou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + } + }, + "achievementsRemainingText": "Conquistas restantes:", + "achievementsText": "Conquistas", + "achievementsUnavailableForOldSeasonsText": "Desculpe, algumas conquistas não estão disponíveis em temporadas antigas.", + "activatedText": "${THING} foi ativado.", + "addGameWindow": { + "getMoreGamesText": "Mais jogos...", + "titleText": "Adicionar jogo" + }, + "addToFavoritesText": "Adicionar aos Favoritos", + "addedToFavoritesText": "Adicionou '${NAME}' aos Favoritos.", + "allText": "Tudo", + "allowText": "Permitir", + "alreadySignedInText": "A conta tem sessão iniciada em outro dispositivo;\nMude de conta ou feche o jogo no seu\noutro dispositivo e tente novamente.", + "apiVersionErrorText": "Não é possível carregar o módulo ${NAME}; ele é destinado à versão ${VERSION_USED}; exigimos a ${VERSION_REQUIRED}.", + "applyText": "Aplicar", + "areYouSureText": "Voce tem certeza?", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" ativa isso apenas quando fones estão conectados)", + "headRelativeVRAudioText": "Áudio para fones de RV", + "musicVolumeText": "Volume da música", + "soundVolumeText": "Volume do som", + "soundtrackButtonText": "Trilha sonora", + "soundtrackDescriptionText": "(tocar a sua própria música durante o jogo)", + "titleText": "Áudio" + }, + "autoText": "Automático", + "backText": "Voltar", + "banThisPlayerText": "Banir este jogador", + "bestOfFinalText": "Final de Melhor-de-${COUNT}", + "bestOfSeriesText": "Melhor série de ${COUNT}:", + "bestRankText": "Sua melhor pontuação é #${RANK}", + "bestRatingText": "Sua melhor classificação é ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Impulso", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} é configurado no próprio aplicativo.", + "buttonText": "botão", + "canWeDebugText": "Você gostaria que o ${APP_NAME} automaticamente comunique\nerros, falhas e informações de uso básico para o desenvolvedor?\n\nEsses dados não contem informações pessoais e ajudam\nà manter o jogo rodando suavemente e livre de bugs.", + "cancelText": "Cancelar", + "cantConfigureDeviceText": "Desculpe, ${DEVICE} não é configurável.", + "challengeEndedText": "Este desafio acabou.", + "chatMuteText": "Silenciar Chat", + "chatMutedText": "Chat Silenciado", + "chatUnMuteText": "Reativar Chat", + "chests": { + "prizeOddsText": "Chances de Ganhar", + "reduceWaitText": "Reduzir a espera", + "slotDescriptionText": "Este slot pode conter um baú.\n\nGanhe baús jogando níveis de campanha,\ncolocando-se em torneios e completando\nconquistas.", + "slotText": "Slot de baú ${NUM}", + "slotsFullWarningText": "AVISO: Todos os seus slots de baú estão cheios.\nQuaisquer baús que você ganhar neste jogo serão perdidos.", + "unlocksInText": "Desbloqueia Em" + }, + "choosingPlayerText": "", + "claimText": "Resgatar", + "codesExplainText": "Os códigos são fornecidos pelo desenvolvedor para \ndiagnosticar e corrigir problemas de conta.", + "completeThisLevelToProceedText": "Você deve completar \neste nível para continuar!", + "completionBonusText": "Bônus de conclusão", + "configControllersWindow": { + "configureControllersText": "Configurar controles", + "configureKeyboard2Text": "Configurar teclado P2", + "configureKeyboardText": "Configurar teclado", + "configureMobileText": "Usar dispositivos como controles", + "configureTouchText": "Configurar touchscreen", + "ps3Text": "Controles PS3", + "titleText": "Controles", + "wiimotesText": "Wiimotes", + "xbox360Text": "Controles Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: o suporte ao controle varia conforme o dispositivo e a versão do Android.", + "pressAnyButtonText": "Aperte qualquer botão no controle\nque você deseja configurar...", + "titleText": "Configurar controles" + }, + "configGamepadWindow": { + "advancedText": "Avançado", + "advancedTitleText": "Configuração avançada dos controles", + "analogStickDeadZoneDescriptionText": "(ative isto se o personagem 'escorrega' quando você solta o direcional)", + "analogStickDeadZoneText": "Área morta do analógico", + "appliesToAllText": "(serve para todos os controles deste tipo)", + "autoRecalibrateDescriptionText": "(ative isto se o personagem não se move na velocidade máxima)", + "autoRecalibrateText": "Calibrar automaticamente o analógico", + "axisText": "eixo", + "clearText": "limpar", + "dpadText": "direcional", + "extraStartButtonText": "Botão Start Extra", + "ifNothingHappensTryAnalogText": "Se nada acontecer, tente mudar para o analógico.", + "ifNothingHappensTryDpadText": "Se nada acontecer, tente mudar para o botão direcional.", + "ignoreCompletelyDescriptionText": "(impedir este controle de afetar tanto o jogo quanto o menu)", + "ignoreCompletelyText": "Ignorar totalmente", + "ignoredButton1Text": "Botão 1 ignorado", + "ignoredButton2Text": "Botão 2 ignorado", + "ignoredButton3Text": "Botão 3 ignorado", + "ignoredButton4Text": "Botão 4 ignorado", + "ignoredButtonDescriptionText": "(use isto para evitar que os botões 'home' ou 'sync' afetem a UI)", + "pressAnyAnalogTriggerText": "Aperte qualquer gatilho...", + "pressAnyButtonOrDpadText": "Aperte qualquer botão ou direcional...", + "pressAnyButtonText": "Aperte qualquer botão...", + "pressLeftRightText": "Aperte esquerda ou direita...", + "pressUpDownText": "Aperte cima ou baixo...", + "runButton1Text": "Correr Botão 1", + "runButton2Text": "Correr Botão 2", + "runTrigger1Text": "Correr Gatilho 1", + "runTrigger2Text": "Correr Gatilho 2", + "runTriggerDescriptionText": "(os gatilhos analogicos o permitem correr em diferentes velocidades)", + "secondHalfText": "Use isto para configurar a segunda metade\nde um controle que funciona\ncomo 2-em-1.", + "secondaryEnableText": "Ativar", + "secondaryText": "Controle secundário", + "startButtonActivatesDefaultDescriptionText": "(desative se o seu botão start está mais para um botão de menu)", + "startButtonActivatesDefaultText": "O botão Start ativa o widget padrão", + "titleText": "Configuração do controle", + "twoInOneSetupText": "Configuração do Controle 2-em-1", + "uiOnlyDescriptionText": "(impede que este controle entre em um jogo)", + "uiOnlyText": "Limitar o Uso ao Menu", + "unassignedButtonsRunText": "Todo o botão não definido executa", + "unsetText": "", + "vrReorientButtonText": "Botão Reorientar VR" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteText": "Nota: a maioria dos teclados só podem registrar\nalgumas teclas pressionadas de uma só vez, portanto\npode funcionar melhor se houver um segundo teclado\nconectado. Perceba que, mesmo nesse caso, você ainda\nprecisará definir teclas exclusivas para os dois jogadores." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Escala de ação do controle", + "actionsText": "Ações", + "buttonsText": "botões", + "dragControlsText": "< arraste controles para reposicioná-los >", + "joystickText": "joystick", + "movementControlScaleText": "Escala de movimento do controle", + "movementText": "Movimento", + "resetText": "Reiniciar", + "swipeControlsHiddenText": "Ocultar ícones de deslize", + "swipeInfoText": "O estilo 'Deslize' do controle leva um tempo para se acostumar, mas\nfaz com que seja mais fácil de jogar sem olhar para os controles.", + "swipeText": "deslize", + "titleText": "Configurar touchscreen" + }, + "configureDeviceInSystemSettingsText": "${DEVICE} pode ser configurado no aplicativo \"Configurações do sistema\".", + "configureItNowText": "Configurar agora?", + "configureText": "Configurar", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Para melhores resultados, é necessário uma rede Wi-Fi\nsem lag. Você pode melhorar o desempenho desligando outros\ndispositivos, jogando perto do seu roteador e conectando\no anfitrião do jogo à rede através do Ethernet.", + "explanationText": "Para usar um telefone ou tablet como controle,\nbaixe gratuitamente o aplicativo \"${REMOTE_APP_NAME}\".\nDá para conectar quantos dispositivos quiser a ${APP_NAME} pelo Wi-Fi!", + "forAndroidText": "para Android:", + "forIOSText": "para iOS:", + "getItForText": "Baixe ${REMOTE_APP_NAME} para iOS na Apple App Store\nou para Android na Google Play Store ou na Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Usando dispositivos como controles:" + }, + "continuePurchaseText": "Continuar por ${PRICE}?", + "continueText": "Continuar", + "controlsText": "Controles", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Isso não se aplica às classificações de todos os tempos.", + "activenessInfoText": "Este multiplicador aumenta nos dias que você joga\ne diminui nos dias que você não joga.", + "activityText": "Atividade", + "campaignText": "Campanha", + "challengesInfoText": "Ganhe prêmios por completar minijogos.\n\nPrêmios e dificuldade aumentam toda\nvez que um desafio é concluído e\ndiminui quando expira ou é abandonado.", + "challengesText": "Desafios", + "currentBestText": "O Melhor do Momento", + "customText": "Personalizado", + "entryFeeText": "Entrada", + "forfeitConfirmText": "Abandonar este desafio?", + "forfeitNotAllowedYetText": "Este desafio ainda não pode ser abandonado.", + "forfeitText": "Abandonar", + "multipliersText": "Multiplicadores", + "nextChallengeText": "Próximo desafio", + "nextPlayText": "Próximo jogo", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Jogar agora", + "pointsText": "Pontos", + "powerRankingFinishedSeasonUnrankedText": "(acabou a temporada casual)", + "powerRankingNotInTopText": "(não está no top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Classificação geral", + "prizesText": "Prêmios", + "proMultInfoText": "Jogadores com a versão ${PRO}\nrecebem um aumento de ${PERCENT}% nos pontos.", + "seeMoreText": "Mais...", + "skipWaitText": "Pular espera", + "timeRemainingText": "Tempo restante", + "toRankedText": "Para classificar", + "totalText": "total", + "tournamentInfoText": "Jogue para ser o melhor contra\noutros jogadores na sua liga.\n\nOs prêmios são dados aos melhores\njogadores quando o torneio acaba.", + "welcome1Text": "Bem-vindo à ${LEAGUE}. Você pode melhorar a sua\nclassificação de liga ao receber estrelas, ao obter\nconquistas e ao ganhar troféus em torneios.", + "welcome2Text": "Você também pode ganhar bilhetes ao fazer várias dessas atividades.\nOs bilhetes podem ser usados para desbloquear novos personagens,\nmapas e minijogos, entrar em torneios e muito mais.", + "yourPowerRankingText": "Sua classificação geral:" + }, + "copyConfirmText": "Copiado para a área de transferência", + "copyOfText": "Cópia de ${NAME}", + "copyText": "Copiar", + "createEditPlayerText": "", + "createText": "Criar", + "creditsWindow": { + "additionalAudioArtIdeasText": "Áudio adicional, Arte inicial e ideias por ${NAME}", + "additionalMusicFromText": "Música adicional de ${NAME}", + "allMyFamilyText": "Toda a família e amigos que ajudaram nos testes", + "codingGraphicsAudioText": "Programação, gráficos e áudio por ${NAME}", + "languageTranslationsText": "Traduções:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Musica de domínio público via ${NAME}", + "softwareBasedOnText": "Este software é baseado em parte do trabalho de ${NAME}", + "songCreditText": "${TITLE} Executada por ${PERFORMER}\nComposta por ${COMPOSER}, Arranjo por ${ARRANGER}, Publicada por ${PUBLISHER},\nCortesia de ${SOURCE}", + "soundAndMusicText": "Som e música:", + "soundsText": "Sons (${SOURCE}):", + "specialThanksText": "Agradecimentos especiais:", + "thanksEspeciallyToText": "Obrigado especialmente a ${NAME}", + "titleText": "Créditos do ${APP_NAME}", + "whoeverInventedCoffeeText": "Seja lá quem for o inventor do café" + }, + "currentStandingText": "Sua posição atual é #${RANK}", + "customizeText": "Personalizar...", + "deathsTallyText": "${COUNT} mortes", + "deathsText": "Mortes", + "debugText": "depurar", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: recomenda-se que defina Configurações->Gráficos->Texturas para \"Alto\" ao testar isto.", + "runCPUBenchmarkText": "Rodar Benchmark de CPU", + "runGPUBenchmarkText": "Rodar Benchmark de GPU", + "runMediaReloadBenchmarkText": "Rodar Benchmark de Recarregar Mídia", + "runStressTestText": "Rodar teste de estresse", + "stressTestPlayerCountText": "Contagem de Jogadores", + "stressTestPlaylistDescriptionText": "Playlist Teste de Estresse", + "stressTestPlaylistNameText": "Nome da Playlist", + "stressTestPlaylistTypeText": "Tipo de Playlist", + "stressTestRoundDurationText": "Duração da Rodada", + "stressTestTitleText": "Teste de estabilidade", + "titleText": "Benchmarks e Testes de Estresse", + "totalReloadTimeText": "Tempo total de carregamento: ${TIME} (veja relatório para detalhes)" + }, + "defaultGameListNameText": "Playlist ${PLAYMODE} Padrão", + "defaultNewGameListNameText": "Minha playlist ${PLAYMODE}", + "deleteText": "Excluir", + "demoText": "Teste", + "denyText": "Recusar", + "deprecatedText": "Descontinuado", + "descriptionText": "Descrição", + "desktopResText": "Resolução da área de trabalho", + "deviceAccountUpgradeText": "Aviso:\nVocê está logado com a conta do seu dispositivo\n(${NAME}).\nContas de dispositivo serão removidas em uma atualização futura.", + "difficultyEasyText": "Fácil", + "difficultyHardOnlyText": "Modo difícil apenas", + "difficultyHardText": "Difícil", + "difficultyHardUnlockOnlyText": "Esta fase só pode ser desbloqueada no modo difícil.\nVocê acha que aguenta o desafio!?!?!", + "directBrowserToURLText": "Por favor, direcione a seguinte URL para um navegador:", + "disableRemoteAppConnectionsText": "Desativar conexões do aplicativo BombSquad Remote", + "disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.", + "disableXInputText": "Desativar XInput", + "disabledText": "Desativado", + "discardText": "Descarte", + "discordFriendsText": "Quer procurar por mais pessoas para jogar junto?\nEntre no nosso Discord e encontre novos amigos!", + "discordJoinText": "Junte-se ao Discord", + "doneText": "Concluído", + "drawText": "Empate", + "duplicateText": "Duplicar", + "editGameListWindow": { + "addGameText": "Adicionar\nJogo", + "cantOverwriteDefaultText": "Não é possível sobrescrever a playlist padrão!", + "cantSaveAlreadyExistsText": "Já existe uma playlist com este nome!", + "cantSaveEmptyListText": "Não é possível salvar uma playlist vazia!", + "editGameText": "Editar\nJogo", + "listNameText": "Nome da Playlist", + "nameText": "Nome", + "removeGameText": "Remover\nJogo", + "saveText": "Salvar lista", + "titleText": "Editor de Playlist" + }, + "editProfileWindow": { + "accountProfileInfoText": "Este perfil especial tem nome e\nícone baseado na sua conta.\n\n${ICONS}\n\nCrie perfis personalizados para usar\nnomes diferentes ou ícones personalizados.", + "accountProfileText": "(perfil da conta)", + "availableText": "O nome \"${NAME}\" está disponível.", + "characterText": "personagem", + "checkingAvailabilityText": "Verificando disponibilidade para \"${NAME}\"...", + "colorText": "cor", + "getMoreCharactersText": "Obter mais personagens...", + "getMoreIconsText": "Obter mais ícones...", + "globalProfileInfoText": "Garante-se que perfis globais tenham nomes\núnicos. Possuem também ícones personalizados.", + "globalProfileText": "(perfil global)", + "highlightText": "detalhe", + "iconText": "ícone", + "localProfileInfoText": "Os perfis de jogadores locais não possuem ícones e não garantem que seus\nnomes sejam únicos.\n\nAprimore para um perfil global para\nreservar um nome único e adicionar um ícone personalizado.", + "localProfileText": "(perfil local)", + "nameDescriptionText": "Nome do Jogador", + "nameText": "Nome", + "profileAlreadyExistsText": "Um perfil com este nome já existe.", + "randomText": "aleatório", + "titleEditText": "Editar perfil", + "titleNewText": "Novo Perfil", + "unavailableText": "\"${NAME}\" está indisponível; tente outro nome.", + "upgradeProfileInfoText": "Isso irá reservar o seu nome de jogador mundialmente\ne permitirá definir um ícone personalizado a ele.", + "upgradeToGlobalProfileText": "Aprimorar para Perfil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Você não pode excluir a trilha sonora padrão.", + "cantEditDefaultText": "Não é possível editar a trilha sonora padrão. Duplique ou crie uma nova.", + "cantOverwriteDefaultText": "Não é possível sobrescrever a trilha sonora padrão", + "cantSaveAlreadyExistsText": "Já existe uma trilha sonora com esse nome!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Trilha sonora padrão", + "deleteConfirmText": "Excluir trilha sonora:\n\n'${NAME}'?", + "deleteText": "Excluir\nTrilha sonora", + "duplicateText": "Duplicar\nTrilha sonora", + "editSoundtrackText": "Editor de Trilha Sonora", + "editText": "Editar\nTrilha sonora", + "fetchingITunesText": "Buscando playlists do app de música", + "musicVolumeZeroWarning": "Aviso: o volume da música está zerado", + "nameText": "Nome", + "newSoundtrackNameText": "Minha trilha sonora ${COUNT}", + "newSoundtrackText": "Nova trilha sonora:", + "newText": "Nova\nTrilha sonora", + "selectAPlaylistText": "Selecione uma playlist", + "selectASourceText": "Fonte de música", + "testText": "teste", + "titleText": "Trilhas sonoras", + "useDefaultGameMusicText": "Música padrão", + "useITunesPlaylistText": "Playlist do app de música", + "useMusicFileText": "Arquivo de música (mp3, etc)", + "useMusicFolderText": "Pasta de arquivos de música" + }, + "editText": "Editar", + "enabledText": "Ativado", + "endText": "Fim", + "enjoyText": "Aproveite!", + "epicDescriptionFilterText": "${DESCRIPTION} em câmera lenta épica.", + "epicNameFilterText": "${NAME} épico(a)", + "errorAccessDeniedText": "acesso negado", + "errorDeviceTimeIncorrectText": "A hora do seu dispositivo está incorreta por ${HOURS} horas.\nIsso causará problemas. \nPor-Favor cheque suas configurações de hora e fuso horário.", + "errorOutOfDiskSpaceText": "pouco espaço em disco", + "errorSecureConnectionFailText": "Não foi possível estabelecer uma conexão segura à nuvem; a funcionalidade da rede pode falhar.", + "errorText": "Erro", + "errorUnknownText": "erro desconhecido", + "exitGameText": "Sair do ${APP_NAME}?", + "expiredAgoText": "Expirado há ${T}", + "expiresInText": "Expira em ${T}", + "exportSuccessText": "'${NAME}' foi exportado.", + "externalStorageText": "Armazenamento externo", + "failText": "Falhou", + "fatalErrorText": "Ops; algo está faltando ou está corrompido.\nPor favor, tente reinstalar BombSquad ou\nentre em contato ${EMAIL} para ajuda.", + "fileSelectorWindow": { + "titleFileFolderText": "Selecione um arquivo ou pasta", + "titleFileText": "Selecione um arquivo", + "titleFolderText": "Selecione uma pasta", + "useThisFolderButtonText": "Use esta pasta" + }, + "filterText": "Filtro", + "finalScoreText": "Pontuação final", + "finalScoresText": "Pontuações finais", + "finalTimeText": "Tempo final", + "finishingInstallText": "Terminando de instalar; aguarde...", + "fireTVRemoteWarningText": "* Para uma melhor experiência, use\njoysticks ou baixe o aplicativo\n'${REMOTE_APP_NAME}' no seu\ntelefone ou tablet.", + "firstToFinalText": "Primeiro-a-${COUNT} Final", + "firstToSeriesText": "Primeiro-a-${COUNT} Séries", + "fiveKillText": "MATOU CINCO!!!", + "flawlessWaveText": "Onda Perfeita!", + "fourKillText": "MORTE QUÁDRUPLA!!!", + "friendScoresUnavailableText": "Pontuação dos amigos indisponível.", + "gameLeadersText": "Game ${COUNT} Líderes", + "gameListWindow": { + "cantDeleteDefaultText": "Você não pode excluir a playlist padrão!", + "cantEditDefaultText": "Você não pode editar a playlist padrão! Duplique ou crie uma nova.", + "cantShareDefaultText": "Você não pode compartilhar a playlist padrão.", + "deleteConfirmText": "Excluir ${LIST}?", + "deleteText": "Excluir\nPlaylist", + "duplicateText": "Duplicar\nPlaylist", + "editText": "Editar\nPlaylist", + "newText": "Nova\nPlaylist", + "pointsToWinText": "Pontos para Ganhar", + "seriesLengthText": "Tamanho da Série", + "showTutorialText": "Mostrar Tutorial", + "shuffleGameOrderText": "Ordem de Partida Aleatória", + "titleText": "Personalizar Playlists de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Adicionar jogo" + }, + "gamesToText": "${WINCOUNT} jogos para ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Lembre-se: qualquer dispositivo em grupo pode ter\nmais de um jogador se você tiver controles o suficiente.", + "aboutDescriptionText": "Use essas guias para criar um grupo.\n\nGrupos o permitem jogar com seus amigos\natravés de dispositivos diferentes.\n\nUse o botão ${PARTY} no canto superior direito\npara conversar e interagir com seu grupo.\n(em um controle, aperte ${BUTTON} enquanto estiver em um menu)", + "aboutText": "Sobre", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} mandou ${COUNT} cupons ${APP_NAME}", + "appInviteSendACodeText": "Envie um código", + "appInviteTitleText": "Convite para testar ${APP_NAME}", + "bluetoothAndroidSupportText": "(funciona com qualquer dispositivo Android com Bluetooth)", + "bluetoothDescriptionText": "Hospedar/entrar em um grupo pelo Bluetooth:", + "bluetoothHostText": "Hospedar pelo Bluetooth", + "bluetoothJoinText": "Entrar pelo Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "verificando...", + "copyCodeConfirmText": "Código copiado para área de transferência.", + "copyCodeText": "Copiar código", + "dedicatedServerInfoText": "Para melhores resultados, inicie um servidor dedicado. Visite bombsquadgame.com/server para saber como.", + "descriptionShortText": "Use a janela de \"Juntar-se\" para formar um grupo.", + "disconnectClientsText": "Isso irá desconectar ${COUNT}jogador(es)\nde seu grupo. Você tem certeza?", + "earnTicketsForRecommendingAmountText": "Os amigos ganharão ${COUNT} bilhetes ao experimentar o jogo\n(e você ganhará ${YOU_COUNT} por cada um que o fizer)", + "earnTicketsForRecommendingText": "Compartilhe o jogo\npara bilhetes grátis...", + "emailItText": "Enviar e-mail", + "favoritesSaveText": "Salvar como Favorito", + "favoritesText": "Favoritos", + "freeCloudServerAvailableMinutesText": "Próximo servidor na nuvem grátis disponível em ${MINUTES} minutos.", + "freeCloudServerAvailableNowText": "Servidor na nuvem grátis disponível!", + "freeCloudServerNotAvailableText": "Nenhum servidor na nuvem grátis disponível.", + "friendHasSentPromoCodeText": "${COUNT} bilhetes do ${APP_NAME} mandados por ${NAME}", + "friendPromoCodeAwardText": "Você ganhará ${COUNT} bilhetes toda vez que for usado.", + "friendPromoCodeExpireText": "O código expira em ${EXPIRE_HOURS} horas e só funcionará para novos jogadores.", + "friendPromoCodeInstructionsText": "Para usar, abra ${APP_NAME} e vá até \"Configurações-> Avançado-> Inserir Código\". \nVeja bombsquadgame.com para os links de download para todas as plataformas suportadas.", + "friendPromoCodeRedeemLongText": "Pode ser resgatado por ${COUNT} bilhetes gratuitos por até ${MAX_USES} pessoas.", + "friendPromoCodeRedeemShortText": "Pode ser resgatado por ${COUNT} bilhetes no jogo.", + "friendPromoCodeWhereToEnterText": "(em \"Configuração -> Avançado -> Inserir Código\")", + "getFriendInviteCodeText": "Obter código de convite", + "googlePlayDescriptionText": "Convidar jogadores do Google Play para a seu grupo:", + "googlePlayInviteText": "Convidar", + "googlePlayReInviteText": "Há ${COUNT} jogador(es) do Google Play na seu grupo\nque serão desconectados se você iniciar um novo convite.\nInclua-os neste novo convite para adicioná-los de volta.", + "googlePlaySeeInvitesText": "Ver convites", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android/versão Google Play)", + "hostPublicPartyDescriptionText": "Hospedar um Grupo Público", + "hostingUnavailableText": "Host indisponível", + "inDevelopmentWarningText": "Nota:\n\nJogo em rede ainda é um novo recurso em desenvolvimento.\nPor enquanto, é altamente recomendável que todos\nos jogadores estejam na mesma rede Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Seus amigos ainda não têm o jogo? Convide-os para\nexperimentar e eles ganharão ${COUNT} bilhetes grátis.", + "inviteFriendsText": "Convidar amigos", + "joinPublicPartyDescriptionText": "Entrar em um Grupo Público", + "localNetworkDescriptionText": "Entrar em um Grupo Próximo (LAN, Bluetooth, etc.)", + "localNetworkText": "Rede Local", + "makePartyPrivateText": "Tornar Meu Grupo Privado", + "makePartyPublicText": "Tornar Meu Grupo Público", + "manualAddressText": "Endereço", + "manualConnectText": "Conectar", + "manualDescriptionText": "Entrar em um grupo por endereço:", + "manualJoinSectionText": "Entrar pelo Endereço", + "manualJoinableFromInternetText": "Conseguem se juntar à você pela internet?:", + "manualJoinableNoWithAsteriskText": "NÃO*", + "manualJoinableYesText": "SIM", + "manualRouterForwardingText": "*para resolver, tente configurar seu roteador para encaminhar a porta UDP ${PORT} para o seu endereço local", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Seu endereço na internet:", + "manualYourLocalAddressText": "Seu endereço local:", + "nearbyText": "Próximo", + "noConnectionText": "", + "noPartiesAddedText": "Nenhum Grupo Adicionado", + "otherVersionsText": "(outras versões)", + "partyCodeText": "Código do Grupo", + "partyInviteAcceptText": "Aceitar", + "partyInviteDeclineText": "Recusar", + "partyInviteIgnoreText": "Ignorar", + "partyInviteText": "${NAME} convidou você\npara entrar no grupo dele(a)!", + "partyNameText": "Nome do Grupo", + "partyServerRunningText": "Seu servidor de grupo está rodando.", + "partySizeText": "tamanho do grupo", + "partyStatusCheckingText": "verificando estado...", + "partyStatusJoinableText": "agora podem entrar no seu grupo pela internet", + "partyStatusNoConnectionText": "não foi possível conectar ao servidor", + "partyStatusNotJoinableText": "não podem entrar no seu grupo pela internet", + "partyStatusNotPublicText": "seu grupo não é público", + "pingText": "latência", + "portText": "Porta", + "privatePartyCloudDescriptionText": "Grupo privados funcionam em servidores da nuvem dedicados; nenhuma configuração no roteador é requirida.", + "privatePartyHostText": "Hospedar um Grupo Privado", + "privatePartyJoinText": "Entrar em um Grupo Privado", + "privateText": "Privado", + "publicHostRouterConfigText": "Isso pode requerer uma configuração de porta no seu roteador. Para uma opção mais simples, crie um grupo privado.", + "publicText": "Público", + "requestingAPromoCodeText": "Solicitando um código...", + "sendDirectInvitesText": "Enviar Convites Diretos", + "shareThisCodeWithFriendsText": "Compartilhe esse código com seus amigos:", + "showMyAddressText": "Mostrar Meu Endereço", + "startHostingPaidText": "Crie Agora por ${COST}", + "startHostingText": "Criar", + "startStopHostingMinutesText": "Você pode iniciar ou interromper a hospedagem de graça nos próximos ${MINUTES} minutos.", + "stopHostingText": "Interromper hospedagem", + "titleText": "Juntar-se", + "wifiDirectDescriptionBottomText": "Se todos os dispositivos tiverem 'Wi-Fi Direct', poderão usar para encontrar\ne conectar um com o outro. Conectados todos os dispositivos, você pode formar grupos\naqui usando a guia 'Rede Local', como em uma rede Wi-Fi comum.\n\nPara melhores resultados, o anfitrião do Wi-Fi Direct deverá ser também o anfitrião do grupo do ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct pode conectar dispositivos Android sem a necessidade\nde uma rede Wi-Fi. Funciona melhor a partir da versão Android 4.2.\n\nPara usar, abra as configurações de Wi-Fi e procure por 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Abrir as configurações de Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funciona entre todas as plataformas)", + "youHaveBeenSentAPromoCodeText": "Mandaram um código promocional do ${APP_NAME} para você:" + }, + "getTicketsWindow": { + "freeText": "GRÁTIS!", + "freeTicketsText": "Cupons Grátis", + "inProgressText": "Uma transação está em andamento; tente de novo em um momento.", + "purchasesRestoredText": "Compras restauradas.", + "receivedTicketsText": "Você recebeu ${COUNT} cupons!", + "restorePurchasesText": "Restaurar Compras", + "ticketPack1Text": "Pacote Pequeno de Bilhetes", + "ticketPack2Text": "Pacote Médio de Bilhetes", + "ticketPack3Text": "Pacote Grande de Bilhetes", + "ticketPack4Text": "Pacote Jumbo de Bilhetes", + "ticketPack5Text": "Pacote Mamute de Bilhetes", + "ticketPack6Text": "Pacote Supremo de Bilhetes", + "ticketsFromASponsorText": "Assista a um anúncio \ne ganhe ${COUNT} bilhetes", + "ticketsText": "${COUNT} bilhetes", + "titleText": "Obter bilhetes", + "unavailableLinkAccountText": "Desculpe, as compras não estão disponíveis nesta plataforma.\nComo solução alternativa, você pode vincular esta conta para\noutra conta de outra plataforma e fazer compras lá.", + "unavailableTemporarilyText": "Indisponível no momento; tente novamente mais tarde.", + "unavailableText": "Desculpe, não está disponível.", + "versionTooOldText": "Desculpe, esta versão do jogo é muito antiga; por favor, atualize.", + "youHaveShortText": "você tem ${COUNT}", + "youHaveText": "você possui ${COUNT} bilhetes" + }, + "goldPass": { + "desc1InfTokensText": "Tokens infinitos.", + "desc2NoAdsText": "Sem anúncios.", + "desc3ForeverText": "Para sempre.", + "goldPassText": "Passe de Ouro" + }, + "googlePlayPurchasesNotAvailableText": "Compras pela Google Play não estão disponíveis.\nTalvez seja necessário atualizar sua loja para isso.", + "googlePlayServicesNotAvailableText": "Os serviços do Google Play não estão disponíveis. \nAlgumas funções do aplicativo talvez serão desabilitadas.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Sempre", + "fullScreenCmdText": "Tela cheia (Cmd-F)", + "fullScreenCtrlText": "Tela cheia (Ctrl-F)", + "fullScreenText": "Tela cheia", + "gammaText": "Gama", + "highText": "Alto", + "higherText": "Mais alto", + "lowText": "Baixo", + "maxFPSText": "FPS máximo", + "mediumText": "Médio", + "neverText": "Nunca", + "resolutionText": "Resolução", + "showFPSText": "Mostrar FPS", + "texturesText": "Texturas", + "titleText": "Gráficos", + "tvBorderText": "Borda da TV", + "verticalSyncText": "Sincronização vertical", + "visualsText": "Visuais" + }, + "helpWindow": { + "bombInfoText": "- Bomba - \nMais forte que socos, mas pode \ncausar graves ferimentos em você mesmo.\nPara melhores resultados, atire no\ninimigo antes do pavio acabar.", + "canHelpText": "${APP_NAME} pode ajudar.", + "controllersInfoText": "Você pode jogar ${APP_NAME} com amigos em uma rede, ou todos \npodem jogar no mesmo dispositivo se tiverem controles suficientes.\n${APP_NAME} suporta muitos deles; você pode até mesmo usar\ncelulares como controle com o aplicativo '${REMOTE_APP_NAME}'.\nVeja as Configurações->Controles para mais informações.", + "controllersInfoTextRemoteOnly": "Você pode jogar ${APP_NAME} com amigos na rede ou \ntodos podem jogar no mesmo dispositivo usando telefones como\ncontroladores através do aplicativo gratuito '${REMOTE_APP_NAME}'.", + "controllersText": "Controles", + "controlsSubtitleText": "O seu personagem bonitinho do ${APP_NAME} tem algumas ações básicas:", + "controlsText": "Controles", + "devicesInfoText": "A versão VR de ${APP_NAME} pode ser jogada em rede com\na versão comum, portanto saquem seus celulares extras, tablets,\ne computadores e mandem ver. Pode ser útil conectar uma\nversão comum do jogo à versão VR para permitir que\npessoas de fora assistam a ação.", + "devicesText": "Dispositivos", + "friendsGoodText": "São sempre boas companhias. ${APP_NAME} é mais divertido com muitos\njogadores e pode suportar até 8 ao mesmo tempo, o que nos leva a:", + "friendsText": "Amigos", + "jumpInfoText": "- Saltar -\nSalte por cima de buracos,\npara jogar coisas mais alto e\npara expressar sua alegria.", + "orPunchingSomethingText": "Ou dar um soco em algo, jogar de um penhasco e explodir em pedacinhos com uma bomba grudenta.", + "pickUpInfoText": "- Pegar -\nAgarre bandeiras, inimigos ou\nqualquer coisa não aparafusada no\nchão. Aperte novamente para jogar.", + "powerupBombDescriptionText": "Permite você lançar três bombas\nseguidas ao invés de uma só.", + "powerupBombNameText": "Tribombas", + "powerupCurseDescriptionText": "É melhor você ficar longe de um desses.\n...ou será que não?", + "powerupCurseNameText": "Maldição", + "powerupHealthDescriptionText": "Restaura toda a sua energia.\nVocê jamais teria adivinhado.", + "powerupHealthNameText": "Kit médico", + "powerupIceBombsDescriptionText": "Mais fraca que a normal, mas\ndeixa seus inimigos congelados\ne bem fragilizados.", + "powerupIceBombsNameText": "Criobombas", + "powerupImpactBombsDescriptionText": "Um pouco mais fraca que a normal\nregular, mas explode ao impacto.", + "powerupImpactBombsNameText": "Impactobombas", + "powerupLandMinesDescriptionText": "Estes vêm em pacotes de 3;\nÉ útil para proteger a base ou\ndeter inimigos correndo em sua direção.", + "powerupLandMinesNameText": "Minas", + "powerupPunchDescriptionText": "Deixa seus socos poderosos, \nrápidos, melhores, fortes.", + "powerupPunchNameText": "Luvas de Boxe", + "powerupShieldDescriptionText": "Absorve um pouco de dano para\nvocê não ter passar por isso.", + "powerupShieldNameText": "Escudo de Energia", + "powerupStickyBombsDescriptionText": "Gruda em tudo que toca.\nHilaridade segue.", + "powerupStickyBombsNameText": "Bombas Grudentas", + "powerupsSubtitleText": "É claro, nenhum jogo está completo sem poderes:", + "powerupsText": "Poderes", + "punchInfoText": "- Soco -\nQuanto mais rápidos seus punhos,\nmais danos seus socos dão, então\nsaia correndo feito um louco.", + "runInfoText": "- Correr -\nSegure QUALQUER botão para correr. Gatilhos ou botões de ombro funcionam bem se você tiver. \nCorrer o leva a lugares mais rápido, mas dificulta na hora de virar, então fique de olho nos penhascos.", + "someDaysText": "Tem dias que você só quer bater em algo. Ou então explodir coisas.", + "titleText": "Ajuda do ${APP_NAME}", + "toGetTheMostText": "Para aproveitar ao máximo este jogo, você precisará de:", + "welcomeText": "Bem-vindo ao ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} está navegando pelos menus como se não houvesse amanhã -", + "importPlaylistCodeInstructionsText": "Use o seguinte código para importar essa playlist:", + "importPlaylistSuccessText": "Playlist '${NAME}' importada ${TYPE}", + "importText": "Importar", + "importingText": "Importando...", + "inGameClippedNameText": "No jogo será\n\"${NAME}\"", + "inboxText": "Caixa de entrada", + "installDiskSpaceErrorText": "ERRO: Não pôde concluir a instalação.\nVocê deve estar com pouco espaço no seu dispositivo.\nApague algumas coisas e tente novamente.", + "internal": { + "arrowsToExitListText": "aperte ${LEFT} ou ${RIGHT} para sair da lista", + "buttonText": "botão", + "cantKickHostError": "Você não pode expulsar o anfitrião.", + "chatBlockedText": "O chat de ${NAME} está bloqueado por ${TIME} segundo(s).", + "connectedToGameText": "Conectou-se a '${NAME}'", + "connectedToPartyText": "Entrou no grupo de ${NAME}!", + "connectingToPartyText": "Conectando...", + "connectionFailedHostAlreadyInPartyText": "A conexão falhou; anfitrião está em outro grupo.", + "connectionFailedPartyFullText": "Conexão falhou; o grupo está cheio.", + "connectionFailedText": "A conexão falhou.", + "connectionFailedVersionMismatchText": "A conexão falhou; anfitrião está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente novamente.", + "connectionRejectedText": "Conexão negada.", + "controllerConnectedText": "${CONTROLLER} conectado.", + "controllerDetectedText": "1 controle detectado.", + "controllerDisconnectedText": "${CONTROLLER} desconectado.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Por favor, tente novamente.", + "controllerForMenusOnlyText": "Este controle não pode ser usado para jogar; apenas para navegar pelo menu.", + "controllerReconnectedText": "${CONTROLLER} reconectado.", + "controllersConnectedText": "${COUNT} controles conectados.", + "controllersDetectedText": "${COUNT} controles detectados.", + "controllersDisconnectedText": "${COUNT} controles desconectados.", + "corruptFileText": "Arquivos corrompidos detectados. Tente reinstalar o jogo ou mande um e-mail para ${EMAIL}", + "errorPlayingMusicText": "Erro ao tocar música: ${MUSIC}", + "errorResettingAchievementsText": "Não foi possível reiniciar as conquistas online; por favor, tente novamente mais tarde.", + "hasMenuControlText": "${NAME} possui o controle do menu.", + "incompatibleNewerVersionHostText": "Anfitrião do grupo está usando uma versão mais nova do jogo.\nAtualize seu jogo e tente novamente.", + "incompatibleVersionHostText": "Anfitrião está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente de novo.", + "incompatibleVersionPlayerText": "${NAME} está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente novamente.", + "invalidAddressErrorText": "Erro: endereço invalido.", + "invalidNameErrorText": "Erro: nome inválido.", + "invalidPortErrorText": "Erro: porta inválida.", + "invitationSentText": "Convite enviado.", + "invitationsSentText": "${COUNT} convites enviados.", + "joinedPartyInstructionsText": "Alguém entrou no seu grupo.\nAperte 'Jogar' para começar.", + "keyboardText": "Teclado", + "kickIdlePlayersKickedText": "Expulsando ${NAME} por não mostrar movimento.", + "kickIdlePlayersWarning1Text": "${NAME} será expulso em ${COUNT} segundos se continuar imóvel.", + "kickIdlePlayersWarning2Text": "(você pode desativar isto em Configurações-> Avançado)", + "leftGameText": "Saiu de '${NAME}'", + "leftPartyText": "Você saiu do grupo de ${NAME}.", + "noMusicFilesInFolderText": "A pasta não contém arquivos de música.", + "playerJoinedPartyText": "${NAME} entrou no grupo!", + "playerLeftPartyText": "${NAME} saiu do grupo.", + "rejectingInviteAlreadyInPartyText": "Recusando convite (já está em um grupo).", + "serverRestartingText": "Servidor reiniciando. Por favor, reconecte-se em um momento...", + "serverShuttingDownText": "Servidor está desligando...", + "signInErrorText": "Erro ao entrar.", + "signInNoConnectionText": "Não pôde entrar. (sem conexão à internet?)", + "telnetAccessDeniedText": "ERRO: o usuário não liberou acesso telnet.", + "timeOutText": "(tempo acaba em ${TIME} segundos)", + "touchScreenJoinWarningText": "Você entrou com o modo touchscreen.\nSe isso foi um erro, toque em 'Menu->Sair do Jogo'.", + "touchScreenText": "Touchscreen", + "unableToCompleteTryAgainText": "Não é possível concluir isso agora.\nPor favor, tente novamente.", + "unableToResolveHostText": "Erro: não é possível resolver a fonte do anfitrião", + "unavailableNoConnectionText": "Isso não está disponível agora (sem conexão à internet?)", + "vrOrientationResetCardboardText": "Use para reiniciar a orientação do VR.\nPara jogar, você precisa de um controle externo.", + "vrOrientationResetText": "Orientação do VR reiniciada.", + "willTimeOutText": "(o tempo acabará se ficar imóvel)" + }, + "inventoryText": "Inventário", + "jumpBoldText": "SALTAR", + "jumpText": "Saltar", + "keepText": "Manter", + "keepTheseSettingsText": "Manter essas configurações?", + "keyboardChangeInstructionsText": "Pressione duas vezes o espaço para alterar os teclados.", + "keyboardNoOthersAvailableText": "Nenhum outro teclado disponível.", + "keyboardSwitchText": "Alterando teclado para \"${NAME}\".", + "kickOccurredText": "${NAME} foi expulso.", + "kickQuestionText": "Expulsar ${NAME}?", + "kickText": "Expulsar", + "kickVoteCantKickAdminsText": "O Administrador não pode ser expulso.", + "kickVoteCantKickSelfText": "Você não pode se expulsar.", + "kickVoteFailedNotEnoughVotersText": "Não há jogadores suficientes para uma votação.", + "kickVoteFailedText": "A votação para expulsão falhou.", + "kickVoteStartedText": "Uma votação para expulsar ${NAME} foi iniciada.", + "kickVoteText": "Votação para expulsar", + "kickVotingDisabledText": "A votação para expulsar está desativada.", + "kickWithChatText": "Escreva ${YES} no chat para sim e ${NO} para não.", + "killsTallyText": "${COUNT} abates", + "killsText": "Abates", + "kioskWindow": { + "easyText": "Fácil", + "epicModeText": "Modo Épico", + "fullMenuText": "Menu Completo", + "hardText": "Difícil", + "mediumText": "Médio", + "singlePlayerExamplesText": "Exemplos de Um jogador / Cooperativo", + "versusExamplesText": "Exemplos de Versus" + }, + "languageSetText": "O idioma agora é \"${LANGUAGE}\".", + "lapNumberText": "Volta ${CURRENT}/${TOTAL}", + "lastGamesText": "(últimas ${COUNT} partidas)", + "leaderboardsText": "Classificação", + "league": { + "allTimeText": "Todos os Tempos", + "currentSeasonText": "Temporada atual (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Classificação da liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "A temporada acabou ${NUMBER} dia(s) atrás.", + "seasonEndsDaysText": "A temporada acaba em ${NUMBER} dia(s).", + "seasonEndsHoursText": "A temporada acaba em ${NUMBER} hora(s).", + "seasonEndsMinutesText": "Temporada acaba em ${NUMBER} minuto(s).", + "seasonText": "Temporada ${NUMBER}", + "tournamentLeagueText": "Você deve alcançar a liga ${NAME} para entrar neste torneio.", + "trophyCountsResetText": "A contagem de troféus reiniciará na próxima temporada.", + "upToDateBonusDescriptionText": "Os jogadores que estiverem jogando uma versão recente do\njogo recebem um bônus de ${PERCENT}% aqui.", + "upToDateBonusText": "Bônus por Estar Atualizado" + }, + "learnMoreText": "Saiba Mais", + "levelBestScoresText": "Melhores pontuações no ${LEVEL}", + "levelBestTimesText": "Melhores tempos no ${LEVEL}", + "levelIsLockedText": "${LEVEL} está bloqueado.", + "levelMustBeCompletedFirstText": "${LEVEL} deve ser concluído primeiro.", + "levelText": "Nível ${NUMBER}", + "levelUnlockedText": "Nível desbloqueado!", + "livesBonusText": "Bônus de Vida", + "loadingText": "carregando", + "loadingTryAgainText": "Carregando; tente novamente daqui a pouco...", + "macControllerSubsystemBothText": "Ambos (não recomendado)", + "macControllerSubsystemClassicText": "Clássico", + "macControllerSubsystemDescriptionText": "Tente ativar isso se os controles não estiverem funcionando", + "macControllerSubsystemMFiNoteText": "Feito para iOS/Mac controle detectado ;\nvocê pode querer ativar isso em Configurações -> Controles", + "macControllerSubsystemMFiText": "Feito para iOS/Mac", + "macControllerSubsystemTitleText": "Suporte para controle", + "mainMenu": { + "creditsText": "Créditos", + "demoMenuText": "Menu de demonstração", + "endGameText": "Terminar Jogo", + "endTestText": "Terminar Teste", + "exitGameText": "Sair do Jogo", + "exitToMenuText": "Sair para o menu?", + "howToPlayText": "Como Jogar", + "justPlayerText": "(Somente ${NAME})", + "leaveGameText": "Sair do Jogo", + "leavePartyConfirmText": "Deseja realmente sair do grupo?", + "leavePartyText": "Sair do Grupo", + "quitText": "Sair", + "resumeText": "Retomar", + "settingsText": "Configurações" + }, + "makeItSoText": "Aplicar", + "mapSelectGetMoreMapsText": "Obter Mais Mapas...", + "mapSelectText": "Selecionar...", + "mapSelectTitleText": "${GAME} mapas", + "mapText": "Mapa", + "maxConnectionsText": "Limite de Conexões", + "maxPartySizeText": "Tamanho Máximo do Grupo", + "maxPlayersText": "Limite de Jogadores", + "merchText": "Produtos BombSquad!", + "modeArcadeText": "Modo Arcade", + "modeClassicText": "Modo Clássico", + "modeDemoText": "Modo Demonstração", + "moreSoonText": "Mais novidades em breve...", + "mostDestroyedPlayerText": "Player Mais Destruído", + "mostValuablePlayerText": "Jogador Mais Valioso", + "mostViolatedPlayerText": "Jogador Mais Violado", + "mostViolentPlayerText": "Jogador Mais Violento", + "moveText": "Mover", + "multiKillText": "MATOU ${COUNT}!!!", + "multiPlayerCountText": "${COUNT} jogadores", + "mustInviteFriendsText": "Nota: você deve convidar amigos no\npainel \"${GATHER}\" ou adicionar\ncontroles para jogar no multijogador.", + "nameBetrayedText": "${NAME} traiu ${VICTIM}.", + "nameDiedText": "${NAME} morreu.", + "nameKilledText": "${NAME} espancou ${VICTIM}.", + "nameNotEmptyText": "Nome não pode estar vazio!", + "nameScoresText": "${NAME} fez um ponto!", + "nameSuicideKidFriendlyText": "${NAME} acidentalmente morreu.", + "nameSuicideText": "${NAME} cometeu suicídio.", + "nameText": "Nome", + "nativeText": "Nativo", + "newExclaimText": "Novo!", + "newPersonalBestText": "Novo recorde pessoal!", + "newTestBuildAvailableText": "Uma nova versão de teste está disponível! (${VERSION} teste ${BUILD}).\nAdquira em ${ADDRESS}", + "newText": "Novo", + "newVersionAvailableText": "Uma nova versão de ${APP_NAME} está disponível! (${VERSION})", + "nextAchievementsText": "Próximas conquistas:", + "nextLevelText": "Próximo nível", + "noAchievementsRemainingText": "- nenhum", + "noContinuesText": "(sem continuar)", + "noExternalStorageErrorText": "Armazenamento externo não encontrado", + "noGameCircleText": "Erro: não conectado no GameCircle", + "noMessagesText": "Sem mensagens.", + "noPluginsInstalledText": "Nenhum Plugin instalado", + "noScoresYetText": "Ainda sem pontuação.", + "noServersFoundText": "Servidores não encontrados.", + "noThanksText": "Não, obrigado", + "noTournamentsInTestBuildText": "Atenção: As pontuações dos torneios desta compilação de teste serão ignoradas.", + "noValidMapsErrorText": "Nenhum mapa válido encontrado para este tipo de jogo.", + "notEnoughPlayersRemainingText": "Não há jogadores suficientes sobrando; saia e comece um novo jogo.", + "notEnoughPlayersText": "Você precisa de pelo menos ${COUNT} jogadores para começar o jogo!", + "notEnoughTicketsText": "Sem bilhetes suficientes!", + "notNowText": "Agora não", + "notSignedInErrorText": "Você deve iniciar sessão primeiro.", + "notSignedInGooglePlayErrorText": "Você deve iniciar sessão no Google Play primeiro.", + "notSignedInText": "sem sessão iniciada", + "notUsingAccountText": "Aviso: Ignorando a conta ${SERVICE}.\nVá em 'Conta -> Entrar com ${SERVICE}' se quiser usá-la.", + "nothingIsSelectedErrorText": "Nada foi selecionado!", + "numberText": "#${NUMBER}", + "offText": "Desativado", + "okText": "Certo", + "onText": "Ativado", + "oneMomentText": "Um Momento...", + "onslaughtRespawnText": "${PLAYER} vai renascer na onda ${WAVE}", + "openMeText": "Abra-Me!", + "openNowText": "Abrir Agora", + "openText": "Abrir", + "orText": "${A} ou ${B}", + "otherText": "Outro...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "Sua própria bandeira deve estar\nem sua base para fazer um ponto!", + "partyWindow": { + "chatMessageText": "Mensagem do Chat", + "emptyText": "Seu grupo está vazio", + "hostText": "(anfitrião)", + "sendText": "Enviar", + "titleText": "Seu Grupo" + }, + "pausedByHostText": "(pausado pelo anfitrião)", + "perfectWaveText": "Onda Perfeita!", + "pickUpText": "Pegar", + "playModes": { + "coopText": "Cooperativo", + "freeForAllText": "Todos contra todos", + "multiTeamText": "Equipes múltiplas", + "singlePlayerCoopText": "Um jogador / Cooperativo", + "teamsText": "Equipes" + }, + "playText": "Jogar", + "playWindow": { + "oneToFourPlayersText": "1-4 jogadores", + "titleText": "Jogar", + "twoToEightPlayersText": "2-8 jogadores" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} entrará no começo da próxima rodada.", + "playerInfoText": "Info. do jogador", + "playerLeftText": "${PLAYER} saiu da partida.", + "playerLimitReachedText": "Limite de ${COUNT} jogadores atingido; entrada não permitida.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Você não pode excluir o seu perfil.", + "deleteButtonText": "Excluir\nPerfil", + "deleteConfirmText": "Excluir '${PROFILE}'?", + "editButtonText": "Editar\nPerfil", + "explanationText": "(personalize nomes e aparências do jogador para esta conta)", + "newButtonText": "Novo\nPerfil", + "titleText": "Perfis de Jogadores" + }, + "playerText": "Jogador", + "playlistNoValidGamesErrorText": "Esta playlist não contém nenhum jogo desbloqueado válido.", + "playlistNotFoundText": "playlist não encontrada", + "playlistText": "Playlist", + "playlistsText": "Playlists", + "pleaseRateText": "Se você está curtindo ${APP_NAME}, por favor, dê um tempinho\npara avaliar e comentar. Isso nos dá uma opinião útil\ne ajuda no desenvolvimento do jogo.\n\nobrigado!\n-eric", + "pleaseWaitText": "Por favor, aguarde...", + "pluginClassLoadErrorText": "Erro ao carregar a classe de um plugin '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Erro ao inicializar plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Configurações de Plugins", + "pluginsAutoEnableNewText": "Ativar Automaticamente Novos Plugins", + "pluginsDetectedText": "Novo(s) plugin(s) detetados. Reinicie o jogo para ativá-los ou configure-os nas configurações.", + "pluginsDisableAllText": "Desativar todos os Plugins!", + "pluginsEnableAllText": "Ativar todos os Plugins!", + "pluginsRemovedText": "${NUM} plugin(s) não foram encontrados.", + "pluginsText": "Plugins", + "practiceText": "Praticar", + "pressAnyButtonPlayAgainText": "Aperte qualquer botão para jogar novamente...", + "pressAnyButtonText": "Aperte qualquer botão para continuar...", + "pressAnyButtonToJoinText": "aperte qualquer botão para entrar...", + "pressAnyKeyButtonPlayAgainText": "Aperte qualquer tecla/botão para jogar novamente...", + "pressAnyKeyButtonText": "Aperte qualquer tecla/botão para continuar...", + "pressAnyKeyText": "Aperte qualquer tecla...", + "pressJumpToFlyText": "** Aperte saltar repetidamente para voar **", + "pressPunchToJoinText": "aperte SOCO para entrar...", + "pressToOverrideCharacterText": "aperte ${BUTTONS} para substituir o seu personagem", + "pressToSelectProfileText": "aperte ${BUTTONS} para selecionar um jogador", + "pressToSelectTeamText": "aperte ${BUTTONS} para selecionar uma equipe", + "promoCodeWindow": { + "codeText": "Código", + "enterText": "Entrar" + }, + "promoSubmitErrorText": "Erro ao enviar código; Verifique a sua conexão com a internet!", + "ps3ControllersWindow": { + "macInstructionsText": "Desligue a energia na parte traseira do seu PS3, verifique se\no Bluetooth do seu Mac está ativado, em seguida conecte o seu controle\nno seu Mac através de um cabo USB para emparelhar os dois. A partir daí, você\npode usar o botão home do controle para conectá-lo ao seu Mac\nseja por fio (USB) ou sem fio (Bluetooth).\n\nEm alguns Macs, uma senha pode ser solicitada ao emparelhar.\nSe isso acontecer, consulte o seguinte tutorial ou o Google para obter ajuda.\n\n\n\n\nOs controles de PS3 conectados sem fio devem aparecer na lista de\ndispositivos em Preferências do Sistema > Bluetooth. Você pode precisar remover\nda lista quando você quiser usar com o seu PS3 novamente.\n\nTambém certifique-se de desconectá-los do Bluetooth quando não estiver\nusando ou a bateria ficará acabando.\n\nBluetooth deve suportar até sete dispositivos conectados,\nembora a sua capacidade possa variar.", + "ouyaInstructionsText": "Para usar um controle de PS3 com seu OUYA, basta conectá-lo com um cabo USB\numa vez para emparelhá-lo. Fazer isso pode desconectar seus outros controles, por\nisso você deve, em seguida, reiniciar seu OUYA e desconectar o cabo USB.\n\nA partir de então você deve ser capaz de usar o botão HOME do controle para\nconectá-lo sem fio. Quando você terminar de jogar, pressione o botão HOME\npor 10 segundos para desligar o controle; caso contrário, pode permanecer ligado\ne desperdiçar bateria.", + "pairingTutorialText": "vídeo tutorial do emparelhamento", + "titleText": "Usando Controles de PS3 com ${APP_NAME}:" + }, + "punchBoldText": "SOCAR", + "punchText": "Socar", + "purchaseForText": "Compre por ${PRICE}", + "purchaseGameText": "Comprar jogo", + "purchaseNeverAvailableText": "Desculpe, as compras não estão disponíveis nesta versão.\nTente entrar em sua conta em outra plataforma e fazer compras nela", + "purchaseNotAvailableText": "Esta compra não está disponível.", + "purchasingText": "Comprando...", + "quitGameText": "Sair do ${APP_NAME}?", + "quittingIn5SecondsText": "Saindo em 5 segundos...", + "randomPlayerNamesText": "João,Maria,Anderson,Lucas,Roberto,César,Felipe,Pedro,Zézinho,Jaílson,Hélvio,Plínio,Clara,Lorena,Beatriz,Wandernilson,Marcos,Michele,Taís,Florentina,Tadeu,Teodoro,Gabriel,Joelma,Chimbinha,Lula,Dilma,Leonardo,Irene,Samanta,Gioconda,Guilhermina,Guilherme,Frederico,Bartolomeu,Dionísio,Diógenes,Haroldo,Ronaldinho,Ricardo,Selma,Bruna,Vanderlei,Danilo,Celso,Vitória,Denise,Samuel,Daniel,Gigi,Manuel,Wiz,Gretchen,Creusa,Chico,Leôncio,Leônidas,Washington,Cleusa,José,Joane,Severino,Casé,Carlos,Davi,Bianca,Clautila,Dafne,Jorge,Sandra,Armando,Basílio,Rochele,Camila,Débora,Rafael,Jonatan,Clodomiro,Clodovil,Vera,Simão,Raíssa,Toni,Tânia,Regina,Bela,Max,Maximiliano,Claudinei,Cláudio,Luciana,Anália,Aparecida,Marcelo,Flávio,Emílio,Tiago,Hebe,Ana,Beth,Gugu,Vítor,Nílton,Maurício,Marciano,Belquior,Clemente,Rosa,Rose,Rosemar,Gabriela,Sérgio,Antônio,Ben,Ivan,jamim,Abreu,Luís,Elton,Fabiana,Waldir,Wilson,Tainá,Tainara,Xuxa,Sacha,Teotônio,Téo,Valdirene,Laurindo,Priscila,Joaquim,Estevão,Gilmar,Erick,Gilson,Romário,Dunga,Ludmila,Luciano,Gilvan,Tamara,Carla,Zezé,Fernando,Fernanda,Adegesto,Acheropita,Anatalino,Lino,Araci,Marluci,Eusébio,Darcília,Dignatario,Ernesto,Cássio,Conrado,Fábio,Heitor,Ivan,Murilo,Andressa,Mateus,Otávio,Helena,Laís,Lavínia,Leila,Letícia,Nair,Henrique,Lara,Diogo,Diego,Geniclécio,Serafim,Lisa,Inri,Eusébio,Gerônimo,Bernardo,Bernadete,Henriete,Eliete,Fudêncio,Peruíbe,Tomás,Tomashedisso,Giovana,Prieto,Gabriely,Suélen,Jamily,Jamil,Geraldo,Nazareth,Forníco,Ícaro,Breno,Bruno,Cilmara,Nilza,Caio,Borges,Cleimara,Janeclécio,Iram,Tico,Teco,Genilson,Marlos,William,Nando,Nanda,Isabel,Jamal,Elias,Félix,Caroline,Carolina,Vilma,Rafaely,Tonho,Túnica,Miguel,Jones,Juan,Anastácio,Francisco,Xavier", + "randomText": "Aleatório", + "rankText": "Classificação", + "ratingText": "Avaliação", + "reachWave2Text": "Chegue a onda 2 para pontuar.", + "readyText": "pronto", + "recentText": "Recente", + "remoteAppInfoShortText": "${APP_NAME} é mais divertido quando é jogado com família e amigos.\nConecte um ou mais controles de hardware ou instale o aplicativo \n${REMOTE_APP_NAME} em telefones ou tablets para usá-los \ncomo controles.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Posição do botão", + "button_size": "Tamanho do botão", + "cant_resolve_host": "Não foi possível localizar o anfitrião.", + "capturing": "Aguardando...", + "connected": "Conectado.", + "description": "Use seu telefone ou tablet como controle com BombSquad.\nAté 8 dispositivos podem se conectar de uma vez para uma loucura épica de multijogador local em uma TV ou tablet.", + "disconnected": "Desconectado pelo servidor.", + "dpad_fixed": "fixo", + "dpad_floating": "Móvel", + "dpad_position": "Posição do direcional", + "dpad_size": "Tamanho do direcional", + "dpad_type": "Tipo de direcional", + "enter_an_address": "Insira um endereço", + "game_full": "A partida está cheia ou não aceita conexões.", + "game_shut_down": "A partida foi fechada.", + "hardware_buttons": "Botões físicos", + "join_by_address": "Entrar por endereço...", + "lag": "Lag: ${SECONDS} segundos", + "reset": "Restaurar padrão", + "run1": "Correr 1", + "run2": "Correr 2", + "searching": "Procurando partidas...", + "searching_caption": "Clique em uma partida para entrar.\nVeja se está na mesma rede Wi-Fi do jogo.", + "start": "Iniciar", + "version_mismatch": "Versão incompatível.\nCertifique-se que o BombSquad e o BombSquad Remote\nestão atualizados e tente novamente." + }, + "removeInGameAdsText": "Desbloqueie \"${PRO}\" na loja para remover anúncios dentro do jogo.", + "removeInGameAdsTokenPurchaseText": "OFERTA POR TEMPO LIMITADO: Compre QUALQUER pacote de tokens para remover anúncios no jogo.", + "renameText": "Renomear", + "replayEndText": "Terminar replay", + "replayNameDefaultText": "Replay do último jogo", + "replayReadErrorText": "Erro ao ler arquivo de replay.", + "replayRenameWarningText": "Renomeie \"${REPLAY}\" após uma partida caso queira salvá-lo; caso contrário será sobrescrito.", + "replayVersionErrorText": "Desculpe, este replay foi feito em uma versão\ndiferente do jogo e não pode ser usado.", + "replayWatchText": "Ver replay", + "replayWriteErrorText": "Erro ao gravar arquivo de replay.", + "replaysText": "Replays", + "reportPlayerExplanationText": "Use este e-mail para denunciar trapaças, linguagem inapropriada, ou outro comportamento ruim.\nPor favor, descreva abaixo:", + "reportThisPlayerCheatingText": "Trapaça", + "reportThisPlayerLanguageText": "Linguagem inapropriada", + "reportThisPlayerReasonText": "O que gostaria de denunciar?", + "reportThisPlayerText": "Denunciar este jogador", + "requestingText": "Solicitando...", + "restartText": "Reiniciar", + "retryText": "Tentar novamente", + "revertText": "Reverter", + "runText": "Correr", + "saveText": "Salvar", + "scanScriptsErrorText": "Erro(s) de verificação de scripts; consulte o registro para obter mais detalhes.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} e outro(s) módulo(s) precisam de atualizações paro o api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} precisa ser atualizado para api${API}.", + "scoreChallengesText": "Desafios de Pontuação", + "scoreListUnavailableText": "Lista de pontuação indisponível.", + "scoreText": "Pontuação", + "scoreUnits": { + "millisecondsText": "Milisegundos", + "pointsText": "Pontos", + "secondsText": "Segundos" + }, + "scoreWasText": "(foi ${COUNT})", + "selectText": "Selecionar", + "sendInfoDescriptionText": "Isto envia informações de sua conta e de estado de aplicativo para o desenvolvedor.\nPor favor inclua seu nome ou razão por ter feito isso.", + "seriesWinLine1PlayerText": "VENCEU A", + "seriesWinLine1TeamText": "VENCEU A", + "seriesWinLine1Text": "VENCEU A", + "seriesWinLine2Text": "SÉRIE!", + "settingsWindow": { + "accountText": "Conta", + "advancedText": "Avançado", + "audioText": "Áudio", + "controllersText": "Controles", + "graphicsText": "Gráficos", + "playerProfilesMovedText": "Nota: os perfis de jogador foram movidos à janela de Conta no menu principal.", + "titleText": "Configurações" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(um simples teclado virtual compatível com controles para edição de texto)", + "alwaysUseInternalKeyboardText": "Sempre usar o teclado interno", + "benchmarksText": "Benchmarks e Testes de Estresse", + "devToolsText": "Ferramentas de Desenvolvedor", + "disableCameraGyroscopeMotionText": "Desativar movimento giroscópio da câmera", + "disableCameraShakeText": "Desativar tremida de câmera", + "disableThisNotice": "(você pode desativar este aviso em configurações avançadas)", + "enterPromoCodeText": "Inserir Código", + "forTestingText": "Nota: esses valores são somente para teste e serão perdidos assim que o aplicativo for fechado.", + "helpTranslateText": "As traduções do ${APP_NAME} são sustentadas pelo esforço\npúblico da comunidade. Se você gostaria de ajudar ou corrigir\numa tradução, siga o link a abaixo. Agradeço desde já!", + "insecureConnectionsDescriptionText": "não recomendado, mas talvez permita você poder jogar online\nde países ou redes restritas", + "insecureConnectionsText": "Usar conexões inseguras", + "kickIdlePlayersText": "Expulsar jogadores inativos", + "kidFriendlyModeText": "Modo para crianças (violência reduzida, etc)", + "languageText": "Idioma", + "moddingGuideText": "Guia para Modificar o Jogo", + "moddingToolsText": "Ferramentas de Modificação", + "mustRestartText": "Você deve reiniciar o jogo para isso ter efeito.", + "netTestingText": "Teste de Conexão", + "resetText": "Redefinir", + "sendInfoText": "Enviar Informação", + "showBombTrajectoriesText": "Mostrar trajetórias da bomba", + "showDemosWhenIdleText": "Mostrar demonstrações quando ocioso", + "showDeprecatedLoginTypesText": "Mostrar tipos de logins ultrapassados", + "showDevConsoleButtonText": "Mostrar opção de desenvolvedor", + "showInGamePingText": "Mostrar latência no jogo", + "showPlayerNamesText": "Mostrar nomes dos jogadores", + "showUserModsText": "Mostrar Caminho da Pasta de Modificações", + "titleText": "Avançado", + "translationEditorButtonText": "Abrir site de Traduções do ${APP_NAME}", + "translationFetchErrorText": "estado da tradução indisponível", + "translationFetchingStatusText": "verificando estado da tradução...", + "translationInformMe": "Avise me quando meu idioma precisar de atualizações", + "translationNoUpdateNeededText": "o seu idioma está atualizado; woohoo!", + "translationUpdateNeededText": "** o seu idioma precisa de atualizações!! **", + "vrTestingText": "Teste de RV" + }, + "shareText": "Compartilhar", + "sharingText": "Compartilhando...", + "showText": "Mostrar", + "signInForPromoCodeText": "Você deve iniciar sia sessão em uma conta para que os códigos promocionais funcionem.", + "singleGamePlaylistNameText": "Somente ${GAME}", + "singlePlayerCountText": "1 jogador", + "sizeLargeText": "Grande", + "sizeMediumText": "Médio", + "sizeSmallText": "Pequeno", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Seleção de personagens", + "Chosen One": "O Escolhido", + "Epic": "Partidas no modo épico", + "Epic Race": "Corrida épica", + "FlagCatcher": "Capture a bandeira", + "Flying": "Pensamentos felizes", + "Football": "Futebol americano", + "ForwardMarch": "Assalto", + "GrandRomp": "Conquista", + "Hockey": "Hóquei", + "Keep Away": "Fique longe", + "Marching": "Casa dos degrais", + "Menu": "Menu principal", + "Onslaught": "Embate", + "Race": "Corrida", + "Scary": "Rei da Colina", + "Scores": "Tela de pontuação", + "Survival": "Eliminatória", + "ToTheDeath": "Mata-mata", + "Victory": "Tela de Pontuação Final" + }, + "spaceKeyText": "espaço", + "statsText": "Estatísticas", + "stopRemindingMeText": "Pare de me lembrar", + "storagePermissionAccessText": "É necessário acesso ao armazenamento", + "store": { + "alreadyOwnText": "Você já possui ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Remove anúncios no jogo\n• Desbloqueia mais opções do jogo\n• E também inclui:", + "buyText": "Comprar", + "charactersText": "Personagens", + "comingSoonText": "Em breve...", + "extrasText": "Extras", + "holidaySpecialText": "Especial de feriado", + "howToSwitchCharactersText": "(vá para \"${SETTINGS} -> ${PLAYER_PROFILES}\" para atribuir e personalizar personagens)", + "howToUseIconsText": "(crie perfis globais - na janela de conta - para usá-los)", + "howToUseMapsText": "(use estes mapas em suas próprias playlist de equipes/todos contra todos)", + "iconsText": "Ícones", + "loadErrorText": "Não foi possível carregar a página.\nVerifique a sua conexão com a internet.", + "loadingText": "carregando", + "mapsText": "Mapas", + "miniGamesText": "Minijogos", + "oneTimeOnlyText": "(somente uma vez)", + "purchaseAlreadyInProgressText": "A compra deste item já está em progresso.", + "purchaseConfirmText": "Comprar ${ITEM}?", + "purchaseNotValidError": "A compra não é valida.\nEntre em contato com ${EMAIL} se isso foi um erro.", + "purchaseText": "Comprar", + "saleBundleText": "Venda de pacotes!", + "saleExclaimText": "Promoção!", + "salePercentText": "(${PERCENT}% de desconto)", + "saleText": "PROMOÇÃO", + "searchText": "Buscar", + "teamsFreeForAllGamesText": "Jogos em equipes / Todos contra todos", + "totalWorthText": "*** Apenas ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Atualizar?", + "winterSpecialText": "Especial de Inverno", + "youOwnThisText": "- você tem isso -" + }, + "storeDescriptionText": "Loucura total com até 8 jogadores!\n\nExploda seus amigos (ou o computador) em um torneio de minijogos desafiadores como Capture a bandeira, Hóquei bombástico e Mata-mata em câmera lenta épica!\n\nControles normais e controles externos possibilitam jogar com até 8 pessoas no mesmo aparelho; você também pode usar outros aparelhos como controles externos usando o aplicativo grátis ‘BombSquad Remote’!\n\nCuidado com as bombas!\n\nDê uma olhada em www.froemling.net/bombsquad para ficar ligado nas novidades.", + "storeDescriptions": { + "blowUpYourFriendsText": "Exploda seus amigos.", + "competeInMiniGamesText": "Compita em minijogos que vão de corridas a voos.", + "customize2Text": "Personalize personagens, minijogos e até mesmo a trilha sonora.", + "customizeText": "Personalize personagens e crie sua própria playlist de minijogos.", + "sportsMoreFunText": "Esportes são mais divertidos com explosivos.", + "teamUpAgainstComputerText": "Una-se a outros contra o computador." + }, + "storeText": "Loja", + "submitText": "Enviar", + "submittingPromoCodeText": "Enviando código promocional...", + "successText": "Sucesso!", + "supportEmailText": "Se estiver passando por problemas com o aplicativo, \nenvie um e-mail para ${EMAIL}.", + "teamNamesColorText": "Nome/Cores das Equipes...", + "telnetAccessGrantedText": "Acesso ao Telnet ativado.", + "telnetAccessText": "Acesso ao Telnet detectado; permitir?", + "testBuildErrorText": "Esta versão de teste não é mais compatível; por favor, confira uma nova versão.", + "testBuildText": "Versão de Teste", + "testBuildValidateErrorText": "Não foi possível validar esta versão. (sem conexão com a internet?)", + "testBuildValidatedText": "Versão de Teste Validada; Divirta-se!", + "thankYouText": "Obrigado pelo seu apoio! Aproveite o jogo!!", + "threeKillText": "MATOU TRÊS!!", + "ticketsDescriptionText": "Os bilhetes podem ser usados para desbloquear personagens,\nmapas, minijogos e muito mais na loja.\n\nOs bilhetes podem ser encontrados em baús obtidos através\nde campanhas, torneios e conquistas.", + "timeBonusText": "Bônus de tempo", + "timeElapsedText": "Tempo Decorrido", + "timeExpiredText": "Tempo Expirado", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Dica", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Obter tokens", + "notEnoughTokensText": "Não há Tokens suficientes!", + "numTokensText": "${COUNT} Tokens", + "openNowDescriptionText": "Você possui tokens suficientes\npara abri-lo agora - você não\nprecisa esperar.", + "shinyNewCurrencyText": "A nova moeda brilhante do BombSquad.", + "tokenPack1Text": "Pacote de tokens pequenos", + "tokenPack2Text": "Pacote de tokens médio", + "tokenPack3Text": "Pacote Grande de Tokens", + "tokenPack4Text": "Pacote de Tokens Jumbo", + "tokensDescriptionText": "Os tokens são usados para acelerar a abertura de baús\ne para outros recursos do jogo e da conta.\n\nVocê pode ganhar tokens no jogo ou comprá-los\nem pacotes. Ou adquira um Gold Pass para tokens infinitos\ne nunca mais se preocupe com eles.", + "youHaveGoldPassText": "Você tem um Passe Dourado.\nTodas as compras de tokens são gratuitas.\nAproveite!" + }, + "topFriendsText": "Melhores amigos", + "tournamentCheckingStateText": "Verificando o estado do torneio; espere um momento...", + "tournamentEndedText": "Este torneio foi finalizado. Um novo começará em breve.", + "tournamentEntryText": "Entrada para o torneio", + "tournamentFinalStandingsText": "Classificação final", + "tournamentResultsRecentText": "Resultados recentes do torneio.", + "tournamentStandingsText": "Classificação do torneio", + "tournamentText": "Torneio", + "tournamentTimeExpiredText": "O tempo do torneio expirou.", + "tournamentsDisabledWorkspaceText": "Os torneios são desabilitados quando os espaços de trabalho estão ativos.\nPara reativar os torneios, desative seu espaço de trabalho e reinicie.", + "tournamentsText": "Torneios", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernardo", + "Bones": "Ossos", + "Butch": "Butch", + "Easter Bunny": "Coelho da Páscoa", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumboldor", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Homenzinho", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Papai Noel", + "Snake Shadow": "Serpente Sombria", + "Spaz": "Spaz", + "Taobao Mascot": "Mascote Taobao", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "Treinamento de ${GAME}", + "Infinite ${GAME}": "${GAME} Infinito", + "Infinite Onslaught": "Embate Infinito", + "Infinite Runaround": "Evasiva Infinita", + "Onslaught Training": "Embate Treinamento", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Futebol americano Pro", + "Pro Onslaught": "Embate Pro", + "Pro Runaround": "Evasiva Pro", + "Rookie ${GAME}": "${GAME} Amador", + "Rookie Football": "Futebol Americano Amador", + "Rookie Onslaught": "Embate Amador", + "The Last Stand": "O Sobrevivente", + "Uber ${GAME}": "${GAME} Elite", + "Uber Football": "Futebol Americano Elite", + "Uber Onslaught": "Embate Elite", + "Uber Runaround": "Evasiva Elite" + }, + "displayItemNames": { + "${C} Tickets": "${C} Bilhetes", + "${C} Tokens": "${C} Tokens", + "Chest": "Baú", + "L1 Chest": "Baú L1", + "L2 Chest": "Baú L2", + "L3 Chest": "Baú L3", + "L4 Chest": "Baú L4", + "L5 Chest": "Baú L5", + "L6 Chest": "Baú L6", + "Unknown Chest": "Baú Desconhecido" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Seja o escolhido por um período de tempo para vencer.\nElimine o escolhido para se tornar ele.", + "Bomb as many targets as you can.": "Bombardeie o máximo de alvos que você puder.", + "Carry the flag for ${ARG1} seconds.": "Carregue a bandeira por ${ARG1} segundos.", + "Carry the flag for a set length of time.": "Carregue a bandeira por um tempo determinado.", + "Crush ${ARG1} of your enemies.": "Esmague ${ARG1} de seus inimigos.", + "Defeat all enemies.": "Derrote todos inimigos.", + "Dodge the falling bombs.": "Esquive das bombas caindo.", + "Final glorious epic slow motion battle to the death.": "Épica gloriosa batalha final até a morte em câmera lenta.", + "Gather eggs!": "Recolha os ovos!", + "Get the flag to the enemy end zone.": "Pegue a bandeira no final da zona inimiga.", + "How fast can you defeat the ninjas?": "Quão rápido você pode derrotar os ninjas?", + "Kill a set number of enemies to win.": "Mate um determinado número de inimigos para vencer.", + "Last one standing wins.": "Último em pé vence.", + "Last remaining alive wins.": "Último sobrevivente vence.", + "Last team standing wins.": "Última equipe de pé vence.", + "Prevent enemies from reaching the exit.": "Impeça que os inimigos alcancem a saída.", + "Reach the enemy flag to score.": "Alcance a bandeira inimiga para marcar.", + "Return the enemy flag to score.": "Retorne a bandeira inimiga para marcar.", + "Run ${ARG1} laps.": "Corra ${ARG1} voltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corra ${ARG1} voltas. Toda a sua equipe precisa terminar.", + "Run 1 lap.": "Corra 1 volta.", + "Run 1 lap. Your entire team has to finish.": "Corra 1 volta. Toda a sua equipe precisa terminar.", + "Run real fast!": "Corra muito rápido!", + "Score ${ARG1} goals.": "Marque ${ARG1} gols.", + "Score ${ARG1} touchdowns.": "Marque ${ARG1} touchdowns.", + "Score a goal.": "Marque um gol.", + "Score a touchdown.": "Marque um touchdown.", + "Score some goals.": "Marque alguns gols.", + "Secure all ${ARG1} flags.": "Proteja todas as ${ARG1} bandeiras.", + "Secure all flags on the map to win.": "Proteja todas as bandeiras no mapa para vencer.", + "Secure the flag for ${ARG1} seconds.": "Proteja a bandeira por ${ARG1} segundos.", + "Secure the flag for a set length of time.": "Proteja a bandeira por um determinado período de tempo.", + "Steal the enemy flag ${ARG1} times.": "Roube a bandeira do inimigo ${ARG1} vezes.", + "Steal the enemy flag.": "Roube a bandeira do inimigo.", + "There can be only one.": "Só pode existir um.", + "Touch the enemy flag ${ARG1} times.": "Toque a bandeira inimiga ${ARG1} vezes.", + "Touch the enemy flag.": "Toque a bandeira inimiga.", + "carry the flag for ${ARG1} seconds": "carregue a bandeira por ${ARG1} segundos", + "kill ${ARG1} enemies": "mate ${ARG1} inimigos", + "last one standing wins": "último em pé vence", + "last team standing wins": "última equipe de pé vence", + "return ${ARG1} flags": "retorne ${ARG1} bandeiras.", + "return 1 flag": "retorne 1 bandeira", + "run ${ARG1} laps": "corra ${ARG1} voltas", + "run 1 lap": "corra 1 volta", + "score ${ARG1} goals": "marque ${ARG1} gols", + "score ${ARG1} touchdowns": "marque ${ARG1} touchdowns", + "score a goal": "marque um gol", + "score a touchdown": "marque um touchdown", + "secure all ${ARG1} flags": "Proteja todas ${ARG1} bandeiras", + "secure the flag for ${ARG1} seconds": "Proteja a bandeira por ${ARG1} segundos", + "touch ${ARG1} flags": "toque ${ARG1} bandeiras", + "touch 1 flag": "toque uma bandeira" + }, + "gameNames": { + "Assault": "Assalto", + "Capture the Flag": "Capture a Bandeira", + "Chosen One": "O Escolhido", + "Conquest": "Conquista", + "Death Match": "Mata-mata", + "Easter Egg Hunt": "Caça aos ovos de Páscoa", + "Elimination": "Eliminatória", + "Football": "Futebol americano", + "Hockey": "Hóquei", + "Keep Away": "Fique longe", + "King of the Hill": "Rei da colina", + "Meteor Shower": "Chuva de meteoros", + "Ninja Fight": "Luta ninja", + "Onslaught": "Embate", + "Race": "Corrida", + "Runaround": "Evasiva", + "Target Practice": "Treino de Alvo", + "The Last Stand": "O Sobrevivente" + }, + "inputDeviceNames": { + "Keyboard": "Teclado", + "Keyboard P2": "Teclado P2" + }, + "languages": { + "Arabic": "Árabe", + "Belarussian": "Bielorrusso", + "Chinese": "Chinês - Simplificado ", + "ChineseSimplified": "Chinês - Simplificado", + "ChineseTraditional": "Chinês - Tradicional", + "Croatian": "Croata", + "Czech": "Tcheco", + "Danish": "Dinamarquês", + "Dutch": "Holandês", + "English": "Inglês", + "Esperanto": "Esperanto", + "Filipino": "Filipino", + "Finnish": "Finlandês", + "French": "Francês", + "German": "Alemão", + "Gibberish": "Embromation", + "Greek": "Grego", + "Hindi": "Hindu", + "Hungarian": "Húngaro", + "Indonesian": "Indonésio", + "Italian": "Italiano", + "Japanese": "Japonês", + "Korean": "Coreano", + "Malay": "Malaio", + "Persian": "Persa", + "PirateSpeak": "Piratês", + "Polish": "Polonês", + "Portuguese": "Português", + "PortugueseBrazil": "Português - Brasil", + "PortuguesePortugal": "Português - Portugal", + "Romanian": "Romeno", + "Russian": "Russo", + "Serbian": "Sérvio", + "Slovak": "Eslovaco", + "Spanish": "Espanhol", + "SpanishLatinAmerica": "Espanhol - América Latina", + "SpanishSpain": "Espanhol - Espanha", + "Swedish": "Sueco", + "Tamil": "tâmil", + "Thai": "Tailandês", + "Turkish": "Turco", + "Ukrainian": "Ucraniano", + "Venetian": "Veneziano", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronze", + "Diamond": "Diamante", + "Gold": "Ouro", + "Silver": "Prata" + }, + "mapsNames": { + "Big G": "Grande G", + "Bridgit": "Bridgit", + "Courtyard": "Pátio", + "Crag Castle": "Castelo Crag", + "Doom Shroom": "Cogumelo da Morte", + "Football Stadium": "Estádio de Futebol", + "Happy Thoughts": "Pensamentos felizes", + "Hockey Stadium": "Estádio de hóquei", + "Lake Frigid": "Lago Frígido", + "Monkey Face": "Cara de macaco", + "Rampage": "Tumulto", + "Roundabout": "Evasiva", + "Step Right Up": "Degrau acima", + "The Pad": "The Pad", + "Tip Top": "Tip Top", + "Tower D": "Torre D", + "Zigzag": "Ziguezague" + }, + "playlistNames": { + "Just Epic": "Somente épico", + "Just Sports": "Somente esportes" + }, + "scoreNames": { + "Flags": "Bandeiras", + "Goals": "Gols", + "Score": "Placar", + "Survived": "Sobreviveu", + "Time": "Tempo", + "Time Held": "Tempo realizado" + }, + "serverResponses": { + "A code has already been used on this account.": "Um código já está sendo usado nesta conta.", + "A reward has already been given for that address.": "Uma recompensa já foi dada para este endereço.", + "Account linking successful!": "A conta foi vinculada com êxito!", + "Account unlinking successful!": "Conta desvinculada com êxito!", + "Accounts are already linked.": "As contas já estão vinculadas.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Não foi possível verificar a visualização do anúncio.\nCertifique-se de que está executando uma versão oficial e atualizada do jogo.", + "An error has occurred; (${ERROR})": "Ocorreu um erro; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ocorreu um erro; entre em contato com a assistência. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ocorreu um erro; por favor, entre em contato com support@froemling.net.", + "An error has occurred; please try again later.": "Aconteceu um erro; tente novamente mais tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Tem certeza de que deseja vincular estas contas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nIsso não poderá ser desfeito!", + "BombSquad Pro unlocked!": "BombSquado Pro desbloqueado!", + "Can't link 2 accounts of this type.": "Não é possível vincular duas contas deste tipo.", + "Can't link 2 diamond league accounts.": "Não é possível vincular duas contas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Impossível vincular; ultrapassaria o máximo de ${COUNT} contas vinculadas.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trapaça detectada; pontuação e prêmios suspensos por ${COUNT} dias.", + "Could not establish a secure connection.": "Não foi possível estabelecer uma conexão segura.", + "Daily maximum reached.": "Máximo diário atingido.", + "Daily sign-in reward": "Recompensa de inscrição diária", + "Entering tournament...": "Entrando no torneio...", + "Invalid code.": "Código invalido.", + "Invalid payment; purchase canceled.": "Pagamento inválido; compra cancelada.", + "Invalid promo code.": "Código promocional invalido.", + "Invalid purchase.": "Compra inválida.", + "Invalid tournament entry; score will be ignored.": "Entrada errada de treinamento; pontuação será ignorada.", + "Item unlocked!": "Item unlocked", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULAÇÃO NEGADA. ${ACCOUNT} contém\ndados significativos que TODOS SERÃO PERDIDOS.\nVocê pode vincular na ordem oposta se desejar\n(e em vez disso perca os dados desta conta)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vincular conta ${ACCOUNT} com essa conta?\nTodo o progresso em ${ACCOUNT} será perdido.\nIsso não pode ser desfeito. Tem certeza?", + "Longer streaks lead to better rewards.": "Sequências mais longas levam a recompensas melhores.", + "Max number of playlists reached.": "Número máximo de playlists alcançado.", + "Max number of profiles reached.": "Número máximo de perfis alcançado.", + "Maximum friend code rewards reached.": "Máximo de recompensas de códigos de amigos atingido.", + "Message is too long.": "A mensagem é muito longa.", + "New tournament result!": "Novo resultado do torneio!", + "No servers are available. Please try again soon.": "Nenhum servidor está disponível. Por favor, tente novamente mais tarde.", + "No slots available. Free a slot and try again.": "Nenhum slot disponível. Libere um slot e tente novamente.", + "Profile \"${NAME}\" upgraded successfully.": "Perfil \"${NAME}\" atualizado com sucesso.", + "Profile could not be upgraded.": "Perfil não pôde ser criado.", + "Purchase successful!": "Compra feita com êxito!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Recebeu ${COUNT} tickets por entrar.\nVolte amanhã para receber ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "A funcionalidade do servidor não é mais compatível nesta versão do jogo;\nPor favor, atualize-o para uma versão mais recente.", + "Sorry, there are no uses remaining on this code.": "Desculpe, não há mais usos remanescentes neste código.", + "Sorry, this code has already been used.": "Desculpe, este código já foi usado.", + "Sorry, this code has expired.": "Desculpe, este código já expirou.", + "Sorry, this code only works for new accounts.": "Desculpe, este código só funciona para novas contas.", + "Sorry, this has expired.": "Desculpe, isso expirou.", + "Still searching for nearby servers; please try again soon.": "Ainda à procura por servidores próximos; tente novamente mais tarde.", + "Streak: ${NUM} days": "Sequência: ${NUM} dias", + "Temporarily unavailable; please try again later.": "Não disponível; por favor, tente novamente mais tarde.", + "The tournament ended before you finished.": "O torneio acabou antes de você terminar.", + "This account cannot be unlinked for ${NUM} days.": "Esta conta não pode ser desvinculada por ${NUM} dias.", + "This code cannot be used on the account that created it.": "Este código não pode ser usado pela conta que o criou.", + "This is currently unavailable; please try again later.": "Isso está atualmente indisponível; por favor tente mais tarde.", + "This requires version ${VERSION} or newer.": "Isso requer a versão ${VERSION} ou novo.", + "Tournaments disabled due to rooted device.": "Torneios desativados devido ao dispositivo estar rooteado.", + "Tournaments require ${VERSION} or newer": "Torneios requerem ${VERSION} ou mais recente", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Desvincular ${ACCOUNT} dessa conta?\nTodo o progresso em ${ACCOUNT} será reiniciado.\n(exceto por conquistas em alguns casos)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATENÇÃO: denúncias sobre você estar usando hack foram feitas.\nContas que usam hack serão banidas. Por favor, jogue limpo.", + "Wait reduced!": "Tempo de espera reduzido!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Aviso: Esta versão do jogo é limitada a dados da conta antigos; algumas coisas podem aparecer ausentes ou desatualizadas.\nPor favor atualize para uma versão mais nova do jogo para ver os dados mais recentes da sua conta.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Gostaria de vincular a sua conta de dispositivo com esta?\n\nA sua conta de dispositivo é ${ACCOUNT1}\nEsta conta é ${ACCOUNT2}\n\nIsso permitirá que você mantenha seu progresso atual.\nAviso: isso não pode ser desfeito!", + "You already own this!": "Você já possui isso.", + "You can join in ${COUNT} seconds.": "Você poderá entrar em ${COUNT} segundos", + "You don't have enough tickets for this!": "Você não tem bilhetes suficientes para isso!", + "You don't own that.": "Você não comprou isso.", + "You got ${COUNT} tickets!": "Você obteve ${COUNT} tickets!", + "You got ${COUNT} tokens!": "Você ganhou ${COUNT} tokens!", + "You got a ${ITEM}!": "Você ganhou ${ITEM}!", + "You got a chest!": "Você ganhou um baú!", + "You got an achievement reward!": "Você ganhou uma recompensa por conquista!", + "You have been promoted to a new league; congratulations!": "Você foi promovido a uma nova liga; parabéns!", + "You lost a chest! (All your chest slots were full)": "Você perdeu um baú! (Todos os seus espaços de baú estavam cheios)", + "You must update the app to view this.": "Você deve atualizar o aplicativo para visualizar isso.", + "You must update to a newer version of the app to do this.": "Você deve atualizar para uma nova versão do aplicativo para fazer isso.", + "You must update to the newest version of the game to do this.": "Você deve atualizar para a nova versão do jogo para fazer isso.", + "You must wait a few seconds before entering a new code.": "Você deve esperar alguns segundos antes de inserir um novo código.", + "You placed #${RANK} in a tournament!": "Você ficou com #${RANK} em um torneio!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Você teve a classificação #${RANK} no último torneio. Obrigado por jogar!", + "Your account was rejected. Are you signed in?": "Sua conta foi rejeitada. Você iniciou a sessão?", + "Your ad views are not registering. Ad options will be limited for a while.": "Suas visualizações de anúncio não estão registrando. As opções de anúncio serão limitadas por um tempo.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Sua copia do jogo foi modificada.\nReverta as modificações e tente novamente.", + "Your friend code was used by ${ACCOUNT}": "Seu código de amigo foi usado por ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 minuto", + "1 Second": "1 segundo", + "10 Minutes": "10 minutos", + "2 Minutes": "2 minutos", + "2 Seconds": "2 segundos", + "20 Minutes": "20 minutos", + "4 Seconds": "4 segundos", + "5 Minutes": "5 minutos", + "8 Seconds": "8 segundos", + "Allow Negative Scores": "Permitir Pontuação Negativa", + "Balance Total Lives": "Saldo Total de Vidas", + "Bomb Spawning": "Bombas Surgindo", + "Chosen One Gets Gloves": "O escolhido obtém luvas", + "Chosen One Gets Shield": "O escolhido obtém escudo", + "Chosen One Time": "Hora do Escolhido", + "Enable Impact Bombs": "Ativar bombas de impacto", + "Enable Triple Bombs": "Ativar tribombas", + "Entire Team Must Finish": "A equipe inteira precisa terminar", + "Epic Mode": "Modo Épico", + "Flag Idle Return Time": "Tempo para Retornar a Bandeira Inativa", + "Flag Touch Return Time": "Tempo para Retornar a Bandeira", + "Hold Time": "Tempo de retenção", + "Kills to Win Per Player": "Mortes para Ganhar Por Jogador", + "Laps": "Voltas", + "Lives Per Player": "Vidas por jogador", + "Long": "Longo", + "Longer": "Mais longo", + "Mine Spawning": "Minas surgindo", + "No Mines": "Sem minas", + "None": "Nenhum", + "Normal": "Normal", + "Pro Mode": "Modo Pro", + "Respawn Times": "Contagem de Renascimentos", + "Score to Win": "Pontuação para Ganhar", + "Short": "Curto", + "Shorter": "Mais curto", + "Solo Mode": "Modo Solo", + "Target Count": "Número de Alvos", + "Time Limit": "Limite de Tempo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} está em desvantagem porque ${PLAYER} saiu", + "Killing ${NAME} for skipping part of the track!": "Matando ${NAME} por cortar o caminho!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Aviso para ${NAME}: o turbo / spam de botão faz você sair." + }, + "teamNames": { + "Bad Guys": "Inimigos", + "Blue": "Azul", + "Good Guys": "Aliados", + "Red": "Vermelho" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Se você bater, correr, pular e girar em perfeita sincronia poderá matar\nem um único golpe e garantir o respeito eterno de seus amigos.", + "Always remember to floss.": "Lembre-se de sempre usar fio dental.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crie perfis de jogadores para você e seus amigos com\nseus nomes preferidos e aparências ao invés de usar os aleatórios.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Caixas amaldiçoadas o transformam em uma bomba-relógio.\nA única cura é agarrar rapidamente um pacote de saúde.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Apesar de suas aparências, as habilidades de todos os personagens são idênticas,\nentão basta escolher qualquer um que você mais se assemelha.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Não fique muito convencido com o escudo de energia; você ainda pode ser arremessado de um penhasco.", + "Don't run all the time. Really. You will fall off cliffs.": "Não corra o tempo todo. Sério. Você vai cair de penhascos.", + "Don't spin for too long; you'll become dizzy and fall.": "Não gire por muito tempo; você vai ficar tonto e cair!", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pressione qualquer botão para correr. (Botões de gatilho funcionam bem, se os tiver)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantenha pressionado qualquer botão para correr. Você vai alcançar lugares mais\nrapidamente, mas não vai fazer curvas muito bem, por isso esteja atento para penhascos.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "As bombas de gelo não são muito poderosas, mas elas congelam\nquem for atingido, deixando-os vulneráveis ​​a estilhaçamentos.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Se alguém te levantar, soque-o e ele irá te largar.\nIsso também funciona na vida real.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Se você está sem controles, instale o aplicativo '${REMOTE_APP_NAME}'\nem seus dispositivos móveis para usá-los como controles.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Se você tiver uma bomba grudenta presa em você, salte e gire em círculos. Você pode\nsacudir a bomba para fora ou, pelo menos, seus últimos momentos serão divertidos.", + "If you kill an enemy in one hit you get double points for it.": "Se você matar um inimigo com um golpe, você obtêm o dobro de pontos por isso.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Se você pegar uma maldição, sua única esperança de sobrevivência é\nencontrar um poder de saúde nos próximos segundos.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Se você ficar em um lugar, você está frito. Corra e se esquive para sobreviver.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se você tem muitos jogadores entrando e saindo, ligue 'Expulsar Jogadores Ociosos Automaticamente'\nnas configurações no caso de alguém esquecer de deixar o jogo.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se seu dispositivo ficar muito quente ou você quiser conservar bateria,\nabaixe os \"Visuais\" ou \"Resolução\" nas Configurações-> Graficos", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se sua taxa de quadros estiver baixa, tente diminuir a resolução\nou visuais nas configurações gráficas do jogo.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Em Capture a bandeira, a sua própria bandeira deve estar em sua base para marcar. Se a outra\nequipe está prestes a marcar, roubar a sua bandeira pode ser uma boa maneira de detê-los.", + "In hockey, you'll maintain more speed if you turn gradually.": "No hóquei, você manterá mais velocidade se girar gradualmente.", + "It's easier to win with a friend or two helping.": "É mais fácil ganhar com um ou dois amigos ajudando.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Apenas salte enquanto você está arremessando para conseguir bombas até os níveis mais altos.", + "Land-mines are a good way to stop speedy enemies.": "Minas terrestres são uma boa maneira de parar inimigos rápidos.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muitas coisas podem ser apanhadas e lançadas, incluindo outros jogadores. Jogar\nos seus inimigos de penhascos pode ser uma estratégia eficaz e emocionalmente gratificante.", + "No, you can't get up on the ledge. You have to throw bombs.": "Não, você não pode levantar-se na borda. Você tem que jogar bombas.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jogadores podem entrar e sair no meio da maioria dos jogos,\ne você também pode ligar ou desligar controles quando quiser.", + "Practice using your momentum to throw bombs more accurately.": "Pratique usando a inércia para arremessar bombas com maior precisão.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Socos fazem mais danos quanto mais rápido os punhos estão se movendo,\nentão tente correr, pular e girar como um louco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corra para frente e para trás antes de arremessar uma bomba\npara 'chicoteá-la' e jogá-la longe.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimine um grupo de inimigos ao\ndesencadear uma bomba perto de uma caixa de TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "A cabeça é a área mais vulnerável, portanto uma bomba grudenta\nna cuca geralmente significa fim de jogo.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nível nunca termina, mas uma alta pontuação aqui\nfaz você ganhar respeito eterno por todo o mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Força de arremesso baseia-se na direção em que você está pressionando.\nPara arremessar algo suavemente na sua frente, não pressione qualquer direção.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Cansado das músicas? Troque-as pelas suas próprias!\nVeja em Configurações-> Áudio-> Músicas", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Experimente 'cozinhar' bombas por um segundo ou dois antes de jogá-las.", + "Try tricking enemies into killing eachother or running off cliffs.": "Tente enganar inimigos para se matarem ou se jogarem do precipício.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Use o botão pegar para pegar a bandeira < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Balance para trás e para frente para fazer arremessos distantes..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Você pode 'mirar' seus socos girando para esquerda ou direita.\nIsso é útil para derrubar inimigos das beiradas ou marcar no hóquei.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Você pode avaliar quando uma bomba vai explodir baseado na\ncor das faíscas do pavio: amarelo..laranja..vermelho..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Você pode jogar as bombas mais alto ao saltar logo antes de arremessar.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Você se fere quando você bate sua cabeça em coisas,\nassim tente não bater sua cabeça em coisas.", + "Your punches do much more damage if you are running or spinning.": "Seus socos causam muito mais dano se você estiver correndo ou girando." + } + }, + "trophiesRequiredText": "Isso necessita de pelo menos ${NUMBER} troféus.", + "trophiesText": "Troféus", + "trophiesThisSeasonText": "Troféus nesta temporada", + "tutorial": { + "cpuBenchmarkText": "Rodando o tutorial numa velocidade MUITO baixa (para testar o processador)", + "phrase01Text": "Olá!", + "phrase02Text": "Bem-vindo ao ${APP_NAME}!", + "phrase03Text": "Aqui estão algumas dicas para controlar seu personagem:", + "phrase04Text": "Muitas coisas no ${APP_NAME} são baseadas na física.", + "phrase05Text": "Por exemplo, quando você soca,..", + "phrase06Text": "..o dano é baseado na velocidade de seus punhos.", + "phrase07Text": "Viu? Nós não estávamos nos movendo então mal fez cócegas no ${NAME}.", + "phrase08Text": "Agora vamos pular e girar para ganhar mais velocidade.", + "phrase09Text": "Ah, assim é melhor.", + "phrase10Text": "Correr ajuda também.", + "phrase11Text": "Mantenha QUALQUER botão pressionado para correr.", + "phrase12Text": "Para socos adicionais incríveis, tente correr e girar.", + "phrase13Text": "Ops! foi mal aí, ${NAME}.", + "phrase14Text": "Você pode pegar e jogar coisas como bandeiras.. ou ${NAME}.", + "phrase15Text": "Por último, há bombas.", + "phrase16Text": "Arremessar bombas requer prática.", + "phrase17Text": "Ai! Não foi um arremesso muito bom.", + "phrase18Text": "Movimentar-se te ajuda a arremessar mais longe.", + "phrase19Text": "Saltar ajuda você a arremessar mais alto.", + "phrase20Text": "Gire e corra e suas bombas irão ainda mais longe.", + "phrase21Text": "Calcular o tempo da explosão pode ser complicado.", + "phrase22Text": "Droga!", + "phrase23Text": "Tente deixar o pavio queimar por um ou dois segundos.", + "phrase24Text": "Eba! No tempo ideal.", + "phrase25Text": "Bem, acho que é só isso.", + "phrase26Text": "Agora vai lá e arrebenta!", + "phrase27Text": "Lembre-se do seu treinamento e você voltará vivo!", + "phrase28Text": "...bem, talvez...", + "phrase29Text": "Boa sorte!", + "randomName1Text": "Fernando", + "randomName2Text": "Henrique", + "randomName3Text": "Guilherme", + "randomName4Text": "Carlos", + "randomName5Text": "Felipe", + "skipConfirmText": "Você deseja realmente pular o tutorial? Toque ou aperte confirmar.", + "skipVoteCountText": "${COUNT}/${TOTAL} votos para pular", + "skippingText": "pulando o tutorial...", + "toSkipPressAnythingText": "(pressione qualquer coisa para pular o tutorial)" + }, + "twoKillText": "MATOU DOIS!", + "uiScaleText": "Tamanho da Interface", + "unavailableText": "indisponível", + "unclaimedPrizesText": "Você possui prêmios não resgatados!", + "unconfiguredControllerDetectedText": "Controle não configurado detectado:", + "unlockThisInTheStoreText": "Isto deve ser desbloqueado na loja.", + "unlockThisProfilesText": "Para criar mais que ${NUM} perfis, você precisa:", + "unlockThisText": "Para desbloquear isso:", + "unsupportedControllerText": "Desculpe, o controlador \"${NAME}\" não é compatível.", + "unsupportedHardwareText": "Desculpe, este hardware não é suportado por esta versão do jogo.", + "upFirstText": "Em primeiro lugar:", + "upNextText": "O próximo jogo em ${COUNT}:", + "updatingAccountText": "Atualizando sua conta...", + "upgradeText": "Aprimorar", + "upgradeToPlayText": "Atualize para \"${PRO}\" na loja para jogar.", + "useDefaultText": "Usar Padrão", + "userSystemScriptsCreateText": "Criar Scripts do Sistema do Usuário", + "userSystemScriptsDeleteText": "Deletar Scripts do Sistema do Usuário", + "usesExternalControllerText": "Este jogo usa um controle externo para entrada.", + "usingItunesText": "Usando o app de música para a trilha sonora", + "v2AccountLinkingInfoText": "Para vincular contas V2, use o botão 'Gerenciar conta'.", + "v2AccountRequiredText": "Isso requer uma conta V2. Atualize sua conta e tente novamente.", + "validatingTestBuildText": "Validando Versão de Teste...", + "viaText": "via", + "victoryText": "Vitória!", + "voteDelayText": "Você não pode começar outra votação por ${NUMBER} segundo(s)", + "voteInProgressText": "Uma votação já está em progresso.", + "votedAlreadyText": "Você já votou", + "votesNeededText": "${NUMBER} votos necessários", + "vsText": "vs.", + "waitingForHostText": "(esperando ${HOST} continuar)", + "waitingForPlayersText": "esperando os jogadores entrarem...", + "waitingInLineText": "Esperando na fila (o grupo está cheio)...", + "watchAVideoText": "Ver um vídeo", + "watchAnAdText": "Assistir uma propaganda.", + "watchWindow": { + "deleteConfirmText": "Excluir \"${REPLAY}\"?", + "deleteReplayButtonText": "Excluir\nReplay", + "myReplaysText": "Meus replays", + "noReplaySelectedErrorText": "Nenhum replay selecionado.", + "playbackSpeedText": "Velocidade de reprodução: ${SPEED}", + "renameReplayButtonText": "Renomear\nReplay", + "renameReplayText": "Renomear \"${REPLAY}\" para:", + "renameText": "Renomear", + "replayDeleteErrorText": "Erro ao excluir o replay.", + "replayNameText": "Nome do replay", + "replayRenameErrorAlreadyExistsText": "Um replay com este nome já existe.", + "replayRenameErrorInvalidName": "Não foi possível renomear; nome invalido.", + "replayRenameErrorText": "Erro ao renomear replay.", + "sharedReplaysText": "Replays compartilhados", + "titleText": "Assistir", + "watchReplayButtonText": "Assistir\nReplay" + }, + "waveText": "Onda", + "wellSureText": "Claro!", + "whatIsThisText": "Oque é isto?", + "winsPlayerText": "${NAME} venceu!", + "winsTeamText": "${NAME} venceu!", + "winsText": "${NAME} ganhou!", + "workspaceSyncErrorText": "Erro ao sincronizar ${WORKSPACE}. Veja o log para mais detalhes.", + "workspaceSyncReuseText": "Não pôde sincronizar ${WORKSPACE}. Reusando uma versão anterior sincronizada.", + "worldScoresUnavailableText": "Pontuações mundiais indisponíveis.", + "worldsBestScoresText": "Melhores Pontuações do Mundo", + "worldsBestTimesText": "Melhores Tempos do Mundo", + "yesAllowText": "Sim, Permitir!", + "yourBestScoresText": "Suas Melhores Pontuações", + "yourBestTimesText": "Seus Melhores Tempos", + "yourPrizeText": "Seu prêmio:" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/portugueseportugal.json b/dist/ba_data/data/languages/portugueseportugal.json new file mode 100644 index 00000000..fccf034c --- /dev/null +++ b/dist/ba_data/data/languages/portugueseportugal.json @@ -0,0 +1,1980 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "O seu nome não pode conter emojis ou outros caracteres especiais", + "accountsText": "Contas", + "achievementProgressText": "Conquistas: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progresso da Campanha Difícil: ${PROGRESS}", + "changeOncePerSeason": "Você só pode mudar isso uma vez por temporada.", + "changeOncePerSeasonError": "Você deve esperar até a próxima temporada para mudar isso novamente (${NUM} dias)", + "createAnAccountText": "Crie uma conta", + "customName": "Nome personalizado", + "deleteAccountText": "Deletar conta", + "googlePlayGamesAccountSwitchText": "Se você quer usar uma conta Google diferente,\nUse o Google Play Games para trocar de conta.", + "linkAccountsEnterCodeText": "Colocar Código", + "linkAccountsGenerateCodeText": "Gerar Código", + "linkAccountsInfoText": "(compartilhar progresso entre varios dispositivos)", + "linkAccountsInstructionsNewText": "Para vincular duas contas, crie um código na primeira\ne coloque o código na segunda. O progresso de\nambas as contas serão sincronizadas. Tornando se uma unica conta\n(O progresso da primeira conta será perdido)\n\nVocê pode vincular até ${COUNT} contas.\n\nIMPORTANTE: vincule apenas contas que tem acesso; \nSe você vincular a conta de um amigo, vocês não\nirão conseguir jogar online ao mesmo tempo.", + "linkAccountsText": "Vincular contas", + "linkedAccountsText": "Contas vinculadas:", + "manageAccountText": "Gerenciar Conta", + "nameChangeConfirm": "Mudar o nome da sua conta para ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Isto reiniciará o seu progresso no cooperativo e\nas suas pontuações (mas não os seus bilhetes).\nIsto não pode ser desfeito. Tem certeza?", + "resetProgressConfirmText": "Isto reiniciará o seu progresso no cooperativo,\nas suas conquistas e as suas pontuações\n(mas não os seus bilhetes). Isto não pode\nser desfeito. Tem certeza?", + "resetProgressText": "Restaurar progresso", + "setAccountName": "Escolha o Nome da Conta", + "setAccountNameDesc": "Escolha o nome que será exibido na sua conta.\nVocê pode usar o nome de uma de suas contas\nou criar um nome personalizado exclusivo.", + "signInInfoText": "Conecte uma conta para ganhar bilhetes, compita online e compartilhe\no seu progresso entre vários dispositivos.", + "signInText": "Conectar-se a sua conta", + "signInWithAnEmailAddressText": "Faça login com um endereço de e-mail", + "signInWithDeviceInfoText": "(uma conta automática disponível apenas neste aparelho)", + "signInWithDeviceText": "Conectar-se com a conta de seu proprio dispositivo", + "signInWithText": "Entrar com ${SERVICE}", + "signInWithV2InfoText": "(uma conta que funciona em todas as plataformas)", + "signInWithV2Text": "Usar uma conta do(a) ${APP_NAME}", + "signOutText": "Sair da conta", + "signingInText": "Iniciando sessão...", + "signingOutText": "Finalizando sessão...", + "ticketsText": "Bilhetes: ${COUNT}", + "titleText": "Conta", + "unlinkAccountsInstructionsText": "Selecione uma conta a qual você quer sair", + "unlinkAccountsText": "Desvincular contas", + "unlinkLegacyV1AccountsText": "Retirar contas V1", + "v2LinkInstructionsText": "Utilize o link para criar uma conta ou entrar nela.", + "viaAccount": "(via ${NAME})", + "youAreSignedInAsText": "Conectou-se como:" + }, + "achievementChallengesText": "Desafios feitos", + "achievementText": "Conquistas", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mate 3 inimigos com TNT", + "descriptionComplete": "Você matou 3 inimigos com TNT", + "descriptionFull": "Mate 3 inimigos com TNT no ${LEVEL}", + "descriptionFullComplete": "Você matou 3 inimigos com TNT no ${LEVEL}", + "name": "Quem brinca com fogo, sai queimado" + }, + "Boxer": { + "description": "Ganhe sem usar bombas", + "descriptionComplete": "Ganhou sem usar bombas", + "descriptionFull": "Complete o ${LEVEL} sem usar bombas", + "descriptionFullComplete": "Completou o ${LEVEL} sem usar bombas", + "name": "Boxeador" + }, + "Dual Wielding": { + "descriptionFull": "Conecte 2 controles sendo fisicos ou sendo virtuais (pelo aplicativo)", + "descriptionFullComplete": "Conectou 2 controles sendo fisicos ou sendo virtuais (pelo aplicativo)", + "name": "Dominação dupla" + }, + "Flawless Victory": { + "description": "Ganhe sem ser atingido", + "descriptionComplete": "Ganhou sem ser atingido", + "descriptionFull": "Ganhe o ${LEVEL} sem ser atingido", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem ser atingido", + "name": "Vitória perfeita" + }, + "Free Loader": { + "descriptionFull": "Comece um Todos contra todos com mais de 2 jogadores", + "descriptionFullComplete": "Começou um Todos contra todos com mais de 2 jogadores", + "name": "Carregador livre" + }, + "Gold Miner": { + "description": "Mate 6 inimigos com minas", + "descriptionComplete": "Matou 6 inimigos com minas", + "descriptionFull": "Mate 6 inimigos com minas no ${LEVEL}", + "descriptionFullComplete": "Matou 6 inimigos com minas no ${LEVEL}", + "name": "Garimpeiro" + }, + "Got the Moves": { + "description": "Ganhe sem usar socos ou bombas", + "descriptionComplete": "Ganhou sem usar socos ou bombas", + "descriptionFull": "Ganhe o ${LEVEL} sem socos ou bombas", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem socos ou bombas", + "name": "Esse Tem Gingado" + }, + "In Control": { + "descriptionFull": "Conecte um controle (hardware ou aplicativo)", + "descriptionFullComplete": "Conectou um controle. (hardware ou aplicativo)", + "name": "No controle" + }, + "Last Stand God": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "${LEVEL} Deus" + }, + "Last Stand Master": { + "description": "Marque 250 pontos", + "descriptionComplete": "Marcou 250 pontos", + "descriptionFull": "Marque 250 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 250 pontos no ${LEVEL}", + "name": "${LEVEL} Mestre" + }, + "Last Stand Wizard": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "${LEVEL} Mago" + }, + "Mine Games": { + "description": "Mate 3 inimigos com minas", + "descriptionComplete": "Matou 3 inimigos com minas", + "descriptionFull": "Mate 3 inimigos com minas no ${LEVEL}", + "descriptionFullComplete": "Matou 3 inimigos com minas no ${LEVEL}", + "name": "Brincando com Minas" + }, + "Off You Go Then": { + "description": "Mande 3 inimigos para fora do mapa", + "descriptionComplete": "Mandou 3 inimigos para fora do mapa", + "descriptionFull": "Mande 3 inimigos para fora do mapa no ${LEVEL}", + "descriptionFullComplete": "Mandou 3 inimigos para fora do mapa no ${LEVEL}", + "name": "Pode Ir Agora" + }, + "Onslaught God": { + "description": "Marque 5000 pontos", + "descriptionComplete": "Marcou 5000 pontos", + "descriptionFull": "Marque 5000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 5000 pontos no ${LEVEL}", + "name": "${LEVEL} Deus" + }, + "Onslaught Master": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "${LEVEL} Mestre" + }, + "Onslaught Training Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Derrotou todas as ondas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Derrotou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "Mago do ${LEVEL}" + }, + "Precision Bombing": { + "description": "Ganhe sem poderes", + "descriptionComplete": "Ganhou sem poderes", + "descriptionFull": "Ganhe ${LEVEL} sem poderes", + "descriptionFullComplete": "Ganhou ${LEVEL} sem poderes", + "name": "Chuva de Bomba" + }, + "Pro Boxer": { + "description": "Ganhe sem usar bombas", + "descriptionComplete": "Ganhou sem usar bombas", + "descriptionFull": "Complete o ${LEVEL} sem usar bombas", + "descriptionFullComplete": "Completou o ${LEVEL} sem usar bombas", + "name": "Pugilista" + }, + "Pro Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe o ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} De Lavada" + }, + "Pro Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Todas as ondas derrotadas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas do ${LEVEL} derrotadas", + "name": "Vitória no ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Complete todas as ondas", + "descriptionComplete": "Todas as ondas completadas", + "descriptionFull": "Complete todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas completadas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe no ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou no ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} de levada" + }, + "Rookie Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Todas as ondas derrotadas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas no ${LEVEL} derrotadas", + "name": "Vitória no ${LEVEL}" + }, + "Runaround God": { + "description": "Marque 2000 pontos", + "descriptionComplete": "Marcou 2000 pontos", + "descriptionFull": "Marque 2000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 2000 pontos no ${LEVEL}", + "name": "Deus da ${LEVEL}" + }, + "Runaround Master": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "Mestre do ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "Mago do ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Compartilhe o jogo com um amigo", + "descriptionFullComplete": "Jogo compartilhado com um amigo", + "name": "Compartilhar é amar" + }, + "Stayin' Alive": { + "description": "Ganhe sem morrer", + "descriptionComplete": "Ganhou sem morrer", + "descriptionFull": "Ganhe o ${LEVEL} sem morrer", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem morrer", + "name": "Sobrevivendo" + }, + "Super Mega Punch": { + "description": "Cause 100% de dano com um soco", + "descriptionComplete": "Causou 100% de dano com um soco", + "descriptionFull": "Cause 100% de dano com um soco no ${LEVEL}", + "descriptionFullComplete": "Causou 100% de dano com um soco no ${LEVEL}", + "name": "Super mega soco" + }, + "Super Punch": { + "description": "Cause 50% de dano com um soco", + "descriptionComplete": "Causou 50% de dano com um soco", + "descriptionFull": "Cause 50% de dano com um soco no ${LEVEL}", + "descriptionFullComplete": "Causou 50% de dano com um soco no ${LEVEL}", + "name": "Supersoco" + }, + "TNT Terror": { + "description": "Mate 6 inimigos com TNT", + "descriptionComplete": "Matou 6 inimigos com TNT", + "descriptionFull": "Mate 6 inimigos com TNT no ${LEVEL}", + "descriptionFullComplete": "Matou 6 inimigos com TNT no ${LEVEL}", + "name": "Terror do TNT" + }, + "Team Player": { + "descriptionFull": "Comece um jogo de equipes com mais de 4 jogadores", + "descriptionFullComplete": "Começou um jogo de equipes com mais de 4 jogadores", + "name": "Jogador de equipe" + }, + "The Great Wall": { + "description": "Pare todos os inimigos", + "descriptionComplete": "Parou todos os inimigos", + "descriptionFull": "Pare todos os inimigos no ${LEVEL}", + "descriptionFullComplete": "Parou todos os inimigos no ${LEVEL}", + "name": "A Grande Muralha" + }, + "The Wall": { + "description": "Pare todos os inimigos", + "descriptionComplete": "Parou todos os inimigos", + "descriptionFull": "Pare todos os inimigos no ${LEVEL}", + "descriptionFullComplete": "Parou todos os inimigos no ${LEVEL}", + "name": "A Muralha" + }, + "Uber Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe o ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} De Lavada" + }, + "Uber Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Derrotou todas as ondas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Derrotou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Complete todas as ondas", + "descriptionComplete": "Completou todas as ondas", + "descriptionFull": "Complete todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Completou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + } + }, + "achievementsRemainingText": "Conquistas restantes:", + "achievementsText": "Conquistas", + "achievementsUnavailableForOldSeasonsText": "Desculpe, algumas conquistas não estão disponíveis em temporadas antigas.", + "activatedText": "${THING} foi ativado.", + "addGameWindow": { + "getMoreGamesText": "Mais jogos...", + "titleText": "Adicionar jogo" + }, + "addToFavoritesText": "Adicionar aos Favoritos", + "addedToFavoritesText": "Adicionou '${NAME}' aos Favoritos.", + "allText": "Tudo", + "allowText": "Permitir", + "alreadySignedInText": "A conta tem sessão iniciada em outro dispositivo;\nMude de conta ou feche o jogo no seu\noutro dispositivo e tente novamente.", + "apiVersionErrorText": "Não é possível carregar o módulo ${NAME}; ele é destinado à versão ${VERSION_USED}; exigimos a ${VERSION_REQUIRED}.", + "applyText": "Aplicar", + "areYouSureText": "Voce tem certeza?", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" ativa isso apenas quando fones estão conectados)", + "headRelativeVRAudioText": "Áudio para fones de RV", + "musicVolumeText": "Volume da música", + "soundVolumeText": "Volume do som", + "soundtrackButtonText": "Trilha sonora", + "soundtrackDescriptionText": "(tocar a sua própria música durante o jogo)", + "titleText": "Áudio" + }, + "autoText": "Automático", + "backText": "Voltar", + "banThisPlayerText": "Banir este jogador", + "bestOfFinalText": "Final de Melhor-de-${COUNT}", + "bestOfSeriesText": "Melhor série de ${COUNT}:", + "bestRankText": "Sua melhor pontuação é #${RANK}", + "bestRatingText": "Sua melhor classificação é ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Impulso", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} é configurado no próprio aplicativo.", + "buttonText": "botão", + "canWeDebugText": "Você gostaria que o ${APP_NAME} automaticamente comunique\nerros, falhas e informações de uso básico para o desenvolvedor?\n\nEsses dados não contem informações pessoais e ajudam\nà manter o jogo rodando suavemente e livre de bugs.", + "cancelText": "Cancelar", + "cantConfigureDeviceText": "Desculpe, ${DEVICE} não é configurável.", + "challengeEndedText": "Este desafio acabou.", + "chatMuteText": "Silenciar Chat", + "chatMutedText": "Chat Silenciado", + "chatUnMuteText": "Reativar Chat", + "chests": { + "prizeOddsText": "Chances de Ganhar", + "reduceWaitText": "Reduzir a espera", + "slotDescriptionText": "Este slot pode conter um baú.\n\nGanhe baús jogando níveis de campanha,\ncolocando-se em torneios e completando\nconquistas.", + "slotText": "Slot de baú ${NUM}", + "slotsFullWarningText": "AVISO: Todos os seus slots de baú estão cheios.\nQuaisquer baús que você ganhar neste jogo serão perdidos.", + "unlocksInText": "Desbloqueia Em" + }, + "choosingPlayerText": "", + "claimText": "Resgatar", + "codesExplainText": "Os códigos são fornecidos pelo desenvolvedor para \ndiagnosticar e corrigir problemas de conta.", + "completeThisLevelToProceedText": "Você deve completar \neste nível para continuar!", + "completionBonusText": "Bônus de conclusão", + "configControllersWindow": { + "configureControllersText": "Configurar controles", + "configureKeyboard2Text": "Configurar teclado P2", + "configureKeyboardText": "Configurar teclado", + "configureMobileText": "Usar dispositivos como controles", + "configureTouchText": "Configurar touchscreen", + "ps3Text": "Controles PS3", + "titleText": "Controles", + "wiimotesText": "Wiimotes", + "xbox360Text": "Controles Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: o suporte ao controle varia conforme o dispositivo e a versão do Android.", + "pressAnyButtonText": "Aperte qualquer botão no controle\nque você deseja configurar...", + "titleText": "Configurar controles" + }, + "configGamepadWindow": { + "advancedText": "Avançado", + "advancedTitleText": "Configuração avançada dos controles", + "analogStickDeadZoneDescriptionText": "(ative isto se o personagem 'escorrega' quando você solta o direcional)", + "analogStickDeadZoneText": "Área morta do analógico", + "appliesToAllText": "(serve para todos os controles deste tipo)", + "autoRecalibrateDescriptionText": "(ative isto se o personagem não se move na velocidade máxima)", + "autoRecalibrateText": "Calibrar automaticamente o analógico", + "axisText": "eixo", + "clearText": "limpar", + "dpadText": "direcional", + "extraStartButtonText": "Botão Start Extra", + "ifNothingHappensTryAnalogText": "Se nada acontecer, tente mudar para o analógico.", + "ifNothingHappensTryDpadText": "Se nada acontecer, tente mudar para o botão direcional.", + "ignoreCompletelyDescriptionText": "(impedir este controle de afetar tanto o jogo quanto o menu)", + "ignoreCompletelyText": "Ignorar totalmente", + "ignoredButton1Text": "Botão 1 ignorado", + "ignoredButton2Text": "Botão 2 ignorado", + "ignoredButton3Text": "Botão 3 ignorado", + "ignoredButton4Text": "Botão 4 ignorado", + "ignoredButtonDescriptionText": "(use isto para evitar que os botões 'home' ou 'sync' afetem a UI)", + "pressAnyAnalogTriggerText": "Aperte qualquer gatilho...", + "pressAnyButtonOrDpadText": "Aperte qualquer botão ou direcional...", + "pressAnyButtonText": "Aperte qualquer botão...", + "pressLeftRightText": "Aperte esquerda ou direita...", + "pressUpDownText": "Aperte cima ou baixo...", + "runButton1Text": "Correr Botão 1", + "runButton2Text": "Correr Botão 2", + "runTrigger1Text": "Correr Gatilho 1", + "runTrigger2Text": "Correr Gatilho 2", + "runTriggerDescriptionText": "(os gatilhos analogicos o permitem correr em diferentes velocidades)", + "secondHalfText": "Use isto para configurar a segunda metade\nde um controle que funciona\ncomo 2-em-1.", + "secondaryEnableText": "Ativar", + "secondaryText": "Controle secundário", + "startButtonActivatesDefaultDescriptionText": "(desative se o seu botão start está mais para um botão de menu)", + "startButtonActivatesDefaultText": "O botão Start ativa o widget padrão", + "titleText": "Configuração do controle", + "twoInOneSetupText": "Configuração do Controle 2-em-1", + "uiOnlyDescriptionText": "(impede que este controle entre em um jogo)", + "uiOnlyText": "Limitar o Uso ao Menu", + "unassignedButtonsRunText": "Todo o botão não definido executa", + "unsetText": "", + "vrReorientButtonText": "Botão Reorientar VR" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteText": "Nota: a maioria dos teclados só podem registrar\nalgumas teclas pressionadas de uma só vez, portanto\npode funcionar melhor se houver um segundo teclado\nconectado. Perceba que, mesmo nesse caso, você ainda\nprecisará definir teclas exclusivas para os dois jogadores." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Escala de ação do controle", + "actionsText": "Ações", + "buttonsText": "botões", + "dragControlsText": "< arraste controles para reposicioná-los >", + "joystickText": "joystick", + "movementControlScaleText": "Escala de movimento do controle", + "movementText": "Movimento", + "resetText": "Reiniciar", + "swipeControlsHiddenText": "Ocultar ícones de deslize", + "swipeInfoText": "O estilo 'Deslize' do controle leva um tempo para se acostumar, mas\nfaz com que seja mais fácil de jogar sem olhar para os controles.", + "swipeText": "deslize", + "titleText": "Configurar touchscreen" + }, + "configureDeviceInSystemSettingsText": "${DEVICE} pode ser configurado no aplicativo \"Configurações do sistema\".", + "configureItNowText": "Configurar agora?", + "configureText": "Configurar", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Para melhores resultados, é necessário uma rede Wi-Fi\nsem lag. Você pode melhorar o desempenho desligando outros\ndispositivos, jogando perto do seu roteador e conectando\no anfitrião do jogo à rede através do Ethernet.", + "explanationText": "Para usar um telefone ou tablet como controle,\nbaixe gratuitamente o aplicativo \"${REMOTE_APP_NAME}\".\nDá para conectar quantos dispositivos quiser a ${APP_NAME} pelo Wi-Fi!", + "forAndroidText": "para Android:", + "forIOSText": "para iOS:", + "getItForText": "Baixe ${REMOTE_APP_NAME} para iOS na Apple App Store\nou para Android na Google Play Store ou na Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Usando dispositivos como controles:" + }, + "continuePurchaseText": "Continuar por ${PRICE}?", + "continueText": "Continuar", + "controlsText": "Controles", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Isso não se aplica às classificações de todos os tempos.", + "activenessInfoText": "Este multiplicador aumenta nos dias que você joga\ne diminui nos dias que você não joga.", + "activityText": "Atividade", + "campaignText": "Campanha", + "challengesInfoText": "Ganhe prêmios por completar minijogos.\n\nPrêmios e dificuldade aumentam toda\nvez que um desafio é concluído e\ndiminui quando expira ou é abandonado.", + "challengesText": "Desafios", + "currentBestText": "O Melhor do Momento", + "customText": "Personalizado", + "entryFeeText": "Entrada", + "forfeitConfirmText": "Abandonar este desafio?", + "forfeitNotAllowedYetText": "Este desafio ainda não pode ser abandonado.", + "forfeitText": "Abandonar", + "multipliersText": "Multiplicadores", + "nextChallengeText": "Próximo desafio", + "nextPlayText": "Próximo jogo", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Jogar agora", + "pointsText": "Pontos", + "powerRankingFinishedSeasonUnrankedText": "(acabou a temporada casual)", + "powerRankingNotInTopText": "(não está no top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Classificação geral", + "prizesText": "Prêmios", + "proMultInfoText": "Jogadores com a versão ${PRO}\nrecebem um aumento de ${PERCENT}% nos pontos.", + "seeMoreText": "Mais...", + "skipWaitText": "Pular espera", + "timeRemainingText": "Tempo restante", + "toRankedText": "Para classificar", + "totalText": "total", + "tournamentInfoText": "Jogue para ser o melhor contra\noutros jogadores na sua liga.\n\nOs prêmios são dados aos melhores\njogadores quando o torneio acaba.", + "welcome1Text": "Bem-vindo à ${LEAGUE}. Você pode melhorar a sua\nclassificação de liga ao receber estrelas, ao obter\nconquistas e ao ganhar troféus em torneios.", + "welcome2Text": "Você também pode ganhar bilhetes ao fazer várias dessas atividades.\nOs bilhetes podem ser usados para desbloquear novos personagens,\nmapas e minijogos, entrar em torneios e muito mais.", + "yourPowerRankingText": "Sua classificação geral:" + }, + "copyConfirmText": "Copiado para a área de transferência", + "copyOfText": "Cópia de ${NAME}", + "copyText": "Copiar", + "createEditPlayerText": "", + "createText": "Criar", + "creditsWindow": { + "additionalAudioArtIdeasText": "Áudio adicional, Arte inicial e ideias por ${NAME}", + "additionalMusicFromText": "Música adicional de ${NAME}", + "allMyFamilyText": "Toda a família e amigos que ajudaram nos testes", + "codingGraphicsAudioText": "Programação, gráficos e áudio por ${NAME}", + "languageTranslationsText": "Traduções:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Musica de domínio público via ${NAME}", + "softwareBasedOnText": "Este software é baseado em parte do trabalho de ${NAME}", + "songCreditText": "${TITLE} Executada por ${PERFORMER}\nComposta por ${COMPOSER}, Arranjo por ${ARRANGER}, Publicada por ${PUBLISHER},\nCortesia de ${SOURCE}", + "soundAndMusicText": "Som e música:", + "soundsText": "Sons (${SOURCE}):", + "specialThanksText": "Agradecimentos especiais:", + "thanksEspeciallyToText": "Obrigado especialmente a ${NAME}", + "titleText": "Créditos do ${APP_NAME}", + "whoeverInventedCoffeeText": "Seja lá quem for o inventor do café" + }, + "currentStandingText": "Sua posição atual é #${RANK}", + "customizeText": "Personalizar...", + "deathsTallyText": "${COUNT} mortes", + "deathsText": "Mortes", + "debugText": "depurar", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: recomenda-se que defina Configurações->Gráficos->Texturas para \"Alto\" ao testar isto.", + "runCPUBenchmarkText": "Rodar Benchmark de CPU", + "runGPUBenchmarkText": "Rodar Benchmark de GPU", + "runMediaReloadBenchmarkText": "Rodar Benchmark de Recarregar Mídia", + "runStressTestText": "Rodar teste de estresse", + "stressTestPlayerCountText": "Contagem de Jogadores", + "stressTestPlaylistDescriptionText": "Playlist Teste de Estresse", + "stressTestPlaylistNameText": "Nome da Playlist", + "stressTestPlaylistTypeText": "Tipo de Playlist", + "stressTestRoundDurationText": "Duração da Rodada", + "stressTestTitleText": "Teste de estabilidade", + "titleText": "Benchmarks e Testes de Estresse", + "totalReloadTimeText": "Tempo total de carregamento: ${TIME} (veja relatório para detalhes)" + }, + "defaultGameListNameText": "Playlist ${PLAYMODE} Padrão", + "defaultNewGameListNameText": "Minha playlist ${PLAYMODE}", + "deleteText": "Excluir", + "demoText": "Teste", + "denyText": "Recusar", + "deprecatedText": "Descontinuado", + "descriptionText": "Descrição", + "desktopResText": "Resolução da área de trabalho", + "deviceAccountUpgradeText": "Aviso:\nVocê está logado com a conta do seu dispositivo\n(${NAME}).\nContas de dispositivo serão removidas em uma atualização futura.", + "difficultyEasyText": "Fácil", + "difficultyHardOnlyText": "Modo difícil apenas", + "difficultyHardText": "Difícil", + "difficultyHardUnlockOnlyText": "Esta fase só pode ser desbloqueada no modo difícil.\nVocê acha que aguenta o desafio!?!?!", + "directBrowserToURLText": "Por favor, direcione a seguinte URL para um navegador:", + "disableRemoteAppConnectionsText": "Desativar conexões do aplicativo BombSquad Remote", + "disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.", + "disableXInputText": "Desativar XInput", + "disabledText": "Desativado", + "discardText": "Descarte", + "discordFriendsText": "Quer procurar por mais pessoas para jogar junto?\nEntre no nosso Discord e encontre novos amigos!", + "discordJoinText": "Junte-se ao Discord", + "doneText": "Concluído", + "drawText": "Empate", + "duplicateText": "Duplicar", + "editGameListWindow": { + "addGameText": "Adicionar\nJogo", + "cantOverwriteDefaultText": "Não é possível sobrescrever a playlist padrão!", + "cantSaveAlreadyExistsText": "Já existe uma playlist com este nome!", + "cantSaveEmptyListText": "Não é possível salvar uma playlist vazia!", + "editGameText": "Editar\nJogo", + "listNameText": "Nome da Playlist", + "nameText": "Nome", + "removeGameText": "Remover\nJogo", + "saveText": "Salvar lista", + "titleText": "Editor de Playlist" + }, + "editProfileWindow": { + "accountProfileInfoText": "Este perfil especial tem nome e\nícone baseado na sua conta.\n\n${ICONS}\n\nCrie perfis personalizados para usar\nnomes diferentes ou ícones personalizados.", + "accountProfileText": "(perfil da conta)", + "availableText": "O nome \"${NAME}\" está disponível.", + "characterText": "personagem", + "checkingAvailabilityText": "Verificando disponibilidade para \"${NAME}\"...", + "colorText": "cor", + "getMoreCharactersText": "Obter mais personagens...", + "getMoreIconsText": "Obter mais ícones...", + "globalProfileInfoText": "Garante-se que perfis globais tenham nomes\núnicos. Possuem também ícones personalizados.", + "globalProfileText": "(perfil global)", + "highlightText": "detalhe", + "iconText": "ícone", + "localProfileInfoText": "Os perfis de jogadores locais não possuem ícones e não garantem que seus\nnomes sejam únicos.\n\nAprimore para um perfil global para\nreservar um nome único e adicionar um ícone personalizado.", + "localProfileText": "(perfil local)", + "nameDescriptionText": "Nome do Jogador", + "nameText": "Nome", + "profileAlreadyExistsText": "Um perfil com este nome já existe.", + "randomText": "aleatório", + "titleEditText": "Editar perfil", + "titleNewText": "Novo Perfil", + "unavailableText": "\"${NAME}\" está indisponível; tente outro nome.", + "upgradeProfileInfoText": "Isso irá reservar o seu nome de jogador mundialmente\ne permitirá definir um ícone personalizado a ele.", + "upgradeToGlobalProfileText": "Aprimorar para Perfil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Você não pode excluir a trilha sonora padrão.", + "cantEditDefaultText": "Não é possível editar a trilha sonora padrão. Duplique ou crie uma nova.", + "cantOverwriteDefaultText": "Não é possível sobrescrever a trilha sonora padrão", + "cantSaveAlreadyExistsText": "Já existe uma trilha sonora com esse nome!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Trilha sonora padrão", + "deleteConfirmText": "Excluir trilha sonora:\n\n'${NAME}'?", + "deleteText": "Excluir\nTrilha sonora", + "duplicateText": "Duplicar\nTrilha sonora", + "editSoundtrackText": "Editor de Trilha Sonora", + "editText": "Editar\nTrilha sonora", + "fetchingITunesText": "Buscando playlists do app de música", + "musicVolumeZeroWarning": "Aviso: o volume da música está zerado", + "nameText": "Nome", + "newSoundtrackNameText": "Minha trilha sonora ${COUNT}", + "newSoundtrackText": "Nova trilha sonora:", + "newText": "Nova\nTrilha sonora", + "selectAPlaylistText": "Selecione uma playlist", + "selectASourceText": "Fonte de música", + "testText": "teste", + "titleText": "Trilhas sonoras", + "useDefaultGameMusicText": "Música padrão", + "useITunesPlaylistText": "Playlist do app de música", + "useMusicFileText": "Arquivo de música (mp3, etc)", + "useMusicFolderText": "Pasta de arquivos de música" + }, + "editText": "Editar", + "enabledText": "Ativado", + "endText": "Fim", + "enjoyText": "Aproveite!", + "epicDescriptionFilterText": "${DESCRIPTION} em câmera lenta épica.", + "epicNameFilterText": "${NAME} épico(a)", + "errorAccessDeniedText": "acesso negado", + "errorDeviceTimeIncorrectText": "A hora do seu dispositivo está incorreta por ${HOURS} horas.\nIsso causará problemas. \nPor-Favor cheque suas configurações de hora e fuso horário.", + "errorOutOfDiskSpaceText": "pouco espaço em disco", + "errorSecureConnectionFailText": "Não foi possível estabelecer uma conexão segura à nuvem; a funcionalidade da rede pode falhar.", + "errorText": "Erro", + "errorUnknownText": "erro desconhecido", + "exitGameText": "Sair do ${APP_NAME}?", + "expiredAgoText": "Expirado há ${T}", + "expiresInText": "Expira em ${T}", + "exportSuccessText": "'${NAME}' foi exportado.", + "externalStorageText": "Armazenamento externo", + "failText": "Falhou", + "fatalErrorText": "Ops; algo está faltando ou está corrompido.\nPor favor, tente reinstalar BombSquad ou\nentre em contato ${EMAIL} para ajuda.", + "fileSelectorWindow": { + "titleFileFolderText": "Selecione um arquivo ou pasta", + "titleFileText": "Selecione um arquivo", + "titleFolderText": "Selecione uma pasta", + "useThisFolderButtonText": "Use esta pasta" + }, + "filterText": "Filtro", + "finalScoreText": "Pontuação final", + "finalScoresText": "Pontuações finais", + "finalTimeText": "Tempo final", + "finishingInstallText": "Terminando de instalar; aguarde...", + "fireTVRemoteWarningText": "* Para uma melhor experiência, use\njoysticks ou baixe o aplicativo\n'${REMOTE_APP_NAME}' no seu\ntelefone ou tablet.", + "firstToFinalText": "Primeiro-a-${COUNT} Final", + "firstToSeriesText": "Primeiro-a-${COUNT} Séries", + "fiveKillText": "MATOU CINCO!!!", + "flawlessWaveText": "Onda Perfeita!", + "fourKillText": "MORTE QUÁDRUPLA!!!", + "friendScoresUnavailableText": "Pontuação dos amigos indisponível.", + "gameLeadersText": "Game ${COUNT} Líderes", + "gameListWindow": { + "cantDeleteDefaultText": "Você não pode excluir a playlist padrão!", + "cantEditDefaultText": "Você não pode editar a playlist padrão! Duplique ou crie uma nova.", + "cantShareDefaultText": "Você não pode compartilhar a playlist padrão.", + "deleteConfirmText": "Excluir ${LIST}?", + "deleteText": "Excluir\nPlaylist", + "duplicateText": "Duplicar\nPlaylist", + "editText": "Editar\nPlaylist", + "newText": "Nova\nPlaylist", + "pointsToWinText": "Pontos para Ganhar", + "seriesLengthText": "Tamanho da Série", + "showTutorialText": "Mostrar Tutorial", + "shuffleGameOrderText": "Ordem de Partida Aleatória", + "titleText": "Personalizar Playlists de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Adicionar jogo" + }, + "gamesToText": "${WINCOUNT} jogos para ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Lembre-se: qualquer dispositivo em grupo pode ter\nmais de um jogador se você tiver controles o suficiente.", + "aboutDescriptionText": "Use essas guias para criar um grupo.\n\nGrupos o permitem jogar com seus amigos\natravés de dispositivos diferentes.\n\nUse o botão ${PARTY} no canto superior direito\npara conversar e interagir com seu grupo.\n(em um controle, aperte ${BUTTON} enquanto estiver em um menu)", + "aboutText": "Sobre", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} mandou ${COUNT} cupons ${APP_NAME}", + "appInviteSendACodeText": "Envie um código", + "appInviteTitleText": "Convite para testar ${APP_NAME}", + "bluetoothAndroidSupportText": "(funciona com qualquer dispositivo Android com Bluetooth)", + "bluetoothDescriptionText": "Hospedar/entrar em um grupo pelo Bluetooth:", + "bluetoothHostText": "Hospedar pelo Bluetooth", + "bluetoothJoinText": "Entrar pelo Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "verificando...", + "copyCodeConfirmText": "Código copiado para área de transferência.", + "copyCodeText": "Copiar código", + "dedicatedServerInfoText": "Para melhores resultados, inicie um servidor dedicado. Visite bombsquadgame.com/server para saber como.", + "descriptionShortText": "Use a janela de \"Juntar-se\" para formar um grupo.", + "disconnectClientsText": "Isso irá desconectar ${COUNT}jogador(es)\nde seu grupo. Você tem certeza?", + "earnTicketsForRecommendingAmountText": "Os amigos ganharão ${COUNT} bilhetes ao experimentar o jogo\n(e você ganhará ${YOU_COUNT} por cada um que o fizer)", + "earnTicketsForRecommendingText": "Compartilhe o jogo\npara bilhetes grátis...", + "emailItText": "Enviar e-mail", + "favoritesSaveText": "Salvar como Favorito", + "favoritesText": "Favoritos", + "freeCloudServerAvailableMinutesText": "Próximo servidor na nuvem grátis disponível em ${MINUTES} minutos.", + "freeCloudServerAvailableNowText": "Servidor na nuvem grátis disponível!", + "freeCloudServerNotAvailableText": "Nenhum servidor na nuvem grátis disponível.", + "friendHasSentPromoCodeText": "${COUNT} bilhetes do ${APP_NAME} mandados por ${NAME}", + "friendPromoCodeAwardText": "Você ganhará ${COUNT} bilhetes toda vez que for usado.", + "friendPromoCodeExpireText": "O código expira em ${EXPIRE_HOURS} horas e só funcionará para novos jogadores.", + "friendPromoCodeInstructionsText": "Para usar, abra ${APP_NAME} e vá até \"Configurações-> Avançado-> Inserir Código\". \nVeja bombsquadgame.com para os links de download para todas as plataformas suportadas.", + "friendPromoCodeRedeemLongText": "Pode ser resgatado por ${COUNT} bilhetes gratuitos por até ${MAX_USES} pessoas.", + "friendPromoCodeRedeemShortText": "Pode ser resgatado por ${COUNT} bilhetes no jogo.", + "friendPromoCodeWhereToEnterText": "(em \"Configuração -> Avançado -> Inserir Código\")", + "getFriendInviteCodeText": "Obter código de convite", + "googlePlayDescriptionText": "Convidar jogadores do Google Play para a seu grupo:", + "googlePlayInviteText": "Convidar", + "googlePlayReInviteText": "Há ${COUNT} jogador(es) do Google Play na seu grupo\nque serão desconectados se você iniciar um novo convite.\nInclua-os neste novo convite para adicioná-los de volta.", + "googlePlaySeeInvitesText": "Ver convites", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android/versão Google Play)", + "hostPublicPartyDescriptionText": "Hospedar um Grupo Público", + "hostingUnavailableText": "Host indisponível", + "inDevelopmentWarningText": "Nota:\n\nJogo em rede ainda é um novo recurso em desenvolvimento.\nPor enquanto, é altamente recomendável que todos\nos jogadores estejam na mesma rede Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Seus amigos ainda não têm o jogo? Convide-os para\nexperimentar e eles ganharão ${COUNT} bilhetes grátis.", + "inviteFriendsText": "Convidar amigos", + "joinPublicPartyDescriptionText": "Entrar em um Grupo Público", + "localNetworkDescriptionText": "Entrar em um Grupo Próximo (LAN, Bluetooth, etc.)", + "localNetworkText": "Rede Local", + "makePartyPrivateText": "Tornar Meu Grupo Privado", + "makePartyPublicText": "Tornar Meu Grupo Público", + "manualAddressText": "Endereço", + "manualConnectText": "Conectar", + "manualDescriptionText": "Entrar em um grupo por endereço:", + "manualJoinSectionText": "Entrar pelo Endereço", + "manualJoinableFromInternetText": "Conseguem se juntar à você pela internet?:", + "manualJoinableNoWithAsteriskText": "NÃO*", + "manualJoinableYesText": "SIM", + "manualRouterForwardingText": "*para resolver, tente configurar seu roteador para encaminhar a porta UDP ${PORT} para o seu endereço local", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Seu endereço na internet:", + "manualYourLocalAddressText": "Seu endereço local:", + "nearbyText": "Próximo", + "noConnectionText": "", + "noPartiesAddedText": "Nenhum Grupo Adicionado", + "otherVersionsText": "(outras versões)", + "partyCodeText": "Código do Grupo", + "partyInviteAcceptText": "Aceitar", + "partyInviteDeclineText": "Recusar", + "partyInviteIgnoreText": "Ignorar", + "partyInviteText": "${NAME} convidou você\npara entrar no grupo dele(a)!", + "partyNameText": "Nome do Grupo", + "partyServerRunningText": "Seu servidor de grupo está rodando.", + "partySizeText": "tamanho do grupo", + "partyStatusCheckingText": "verificando estado...", + "partyStatusJoinableText": "agora podem entrar no seu grupo pela internet", + "partyStatusNoConnectionText": "não foi possível conectar ao servidor", + "partyStatusNotJoinableText": "não podem entrar no seu grupo pela internet", + "partyStatusNotPublicText": "seu grupo não é público", + "pingText": "latência", + "portText": "Porta", + "privatePartyCloudDescriptionText": "Grupo privados funcionam em servidores da nuvem dedicados; nenhuma configuração no roteador é requirida.", + "privatePartyHostText": "Hospedar um Grupo Privado", + "privatePartyJoinText": "Entrar em um Grupo Privado", + "privateText": "Privado", + "publicHostRouterConfigText": "Isso pode requerer uma configuração de porta no seu roteador. Para uma opção mais simples, crie um grupo privado.", + "publicText": "Público", + "requestingAPromoCodeText": "Solicitando um código...", + "sendDirectInvitesText": "Enviar Convites Diretos", + "shareThisCodeWithFriendsText": "Compartilhe esse código com seus amigos:", + "showMyAddressText": "Mostrar Meu Endereço", + "startHostingPaidText": "Crie Agora por ${COST}", + "startHostingText": "Criar", + "startStopHostingMinutesText": "Você pode iniciar ou interromper a hospedagem de graça nos próximos ${MINUTES} minutos.", + "stopHostingText": "Interromper hospedagem", + "titleText": "Juntar-se", + "wifiDirectDescriptionBottomText": "Se todos os dispositivos tiverem 'Wi-Fi Direct', poderão usar para encontrar\ne conectar um com o outro. Conectados todos os dispositivos, você pode formar grupos\naqui usando a guia 'Rede Local', como em uma rede Wi-Fi comum.\n\nPara melhores resultados, o anfitrião do Wi-Fi Direct deverá ser também o anfitrião do grupo do ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct pode conectar dispositivos Android sem a necessidade\nde uma rede Wi-Fi. Funciona melhor a partir da versão Android 4.2.\n\nPara usar, abra as configurações de Wi-Fi e procure por 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Abrir as configurações de Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funciona entre todas as plataformas)", + "youHaveBeenSentAPromoCodeText": "Mandaram um código promocional do ${APP_NAME} para você:" + }, + "getTicketsWindow": { + "freeText": "GRÁTIS!", + "freeTicketsText": "Cupons Grátis", + "inProgressText": "Uma transação está em andamento; tente de novo em um momento.", + "purchasesRestoredText": "Compras restauradas.", + "receivedTicketsText": "Você recebeu ${COUNT} cupons!", + "restorePurchasesText": "Restaurar Compras", + "ticketPack1Text": "Pacote Pequeno de Bilhetes", + "ticketPack2Text": "Pacote Médio de Bilhetes", + "ticketPack3Text": "Pacote Grande de Bilhetes", + "ticketPack4Text": "Pacote Jumbo de Bilhetes", + "ticketPack5Text": "Pacote Mamute de Bilhetes", + "ticketPack6Text": "Pacote Supremo de Bilhetes", + "ticketsFromASponsorText": "Assista a um anúncio \ne ganhe ${COUNT} bilhetes", + "ticketsText": "${COUNT} bilhetes", + "titleText": "Obter bilhetes", + "unavailableLinkAccountText": "Desculpe, as compras não estão disponíveis nesta plataforma.\nComo solução alternativa, você pode vincular esta conta para\noutra conta de outra plataforma e fazer compras lá.", + "unavailableTemporarilyText": "Indisponível no momento; tente novamente mais tarde.", + "unavailableText": "Desculpe, não está disponível.", + "versionTooOldText": "Desculpe, esta versão do jogo é muito antiga; por favor, atualize.", + "youHaveShortText": "você tem ${COUNT}", + "youHaveText": "você possui ${COUNT} bilhetes" + }, + "goldPass": { + "desc1InfTokensText": "Tokens infinitos.", + "desc2NoAdsText": "Sem anúncios.", + "desc3ForeverText": "Para sempre.", + "goldPassText": "Passe de Ouro" + }, + "googlePlayPurchasesNotAvailableText": "Compras pela Google Play não estão disponíveis.\nTalvez seja necessário atualizar sua loja para isso.", + "googlePlayServicesNotAvailableText": "Os serviços do Google Play não estão disponíveis. \nAlgumas funções do aplicativo talvez serão desabilitadas.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Sempre", + "fullScreenCmdText": "Tela cheia (Cmd-F)", + "fullScreenCtrlText": "Tela cheia (Ctrl-F)", + "fullScreenText": "Tela cheia", + "gammaText": "Gama", + "highText": "Alto", + "higherText": "Mais alto", + "lowText": "Baixo", + "maxFPSText": "FPS máximo", + "mediumText": "Médio", + "neverText": "Nunca", + "resolutionText": "Resolução", + "showFPSText": "Mostrar FPS", + "texturesText": "Texturas", + "titleText": "Gráficos", + "tvBorderText": "Borda da TV", + "verticalSyncText": "Sincronização vertical", + "visualsText": "Visuais" + }, + "helpWindow": { + "bombInfoText": "- Bomba - \nMais forte que socos, mas pode \ncausar graves ferimentos em você mesmo.\nPara melhores resultados, atire no\ninimigo antes do pavio acabar.", + "canHelpText": "${APP_NAME} pode ajudar.", + "controllersInfoText": "Você pode jogar ${APP_NAME} com amigos em uma rede, ou todos \npodem jogar no mesmo dispositivo se tiverem controles suficientes.\n${APP_NAME} suporta muitos deles; você pode até mesmo usar\ncelulares como controle com o aplicativo '${REMOTE_APP_NAME}'.\nVeja as Configurações->Controles para mais informações.", + "controllersInfoTextRemoteOnly": "Você pode jogar ${APP_NAME} com amigos na rede ou \ntodos podem jogar no mesmo dispositivo usando telefones como\ncontroladores através do aplicativo gratuito '${REMOTE_APP_NAME}'.", + "controllersText": "Controles", + "controlsSubtitleText": "O seu personagem bonitinho do ${APP_NAME} tem algumas ações básicas:", + "controlsText": "Controles", + "devicesInfoText": "A versão VR de ${APP_NAME} pode ser jogada em rede com\na versão comum, portanto saquem seus celulares extras, tablets,\ne computadores e mandem ver. Pode ser útil conectar uma\nversão comum do jogo à versão VR para permitir que\npessoas de fora assistam a ação.", + "devicesText": "Dispositivos", + "friendsGoodText": "São sempre boas companhias. ${APP_NAME} é mais divertido com muitos\njogadores e pode suportar até 8 ao mesmo tempo, o que nos leva a:", + "friendsText": "Amigos", + "jumpInfoText": "- Saltar -\nSalte por cima de buracos,\npara jogar coisas mais alto e\npara expressar sua alegria.", + "orPunchingSomethingText": "Ou dar um soco em algo, jogar de um penhasco e explodir em pedacinhos com uma bomba grudenta.", + "pickUpInfoText": "- Pegar -\nAgarre bandeiras, inimigos ou\nqualquer coisa não aparafusada no\nchão. Aperte novamente para jogar.", + "powerupBombDescriptionText": "Permite você lançar três bombas\nseguidas ao invés de uma só.", + "powerupBombNameText": "Tribombas", + "powerupCurseDescriptionText": "É melhor você ficar longe de um desses.\n...ou será que não?", + "powerupCurseNameText": "Maldição", + "powerupHealthDescriptionText": "Restaura toda a sua energia.\nVocê jamais teria adivinhado.", + "powerupHealthNameText": "Kit médico", + "powerupIceBombsDescriptionText": "Mais fraca que a normal, mas\ndeixa seus inimigos congelados\ne bem fragilizados.", + "powerupIceBombsNameText": "Criobombas", + "powerupImpactBombsDescriptionText": "Um pouco mais fraca que a normal\nregular, mas explode ao impacto.", + "powerupImpactBombsNameText": "Impactobombas", + "powerupLandMinesDescriptionText": "Estes vêm em pacotes de 3;\nÉ útil para proteger a base ou\ndeter inimigos correndo em sua direção.", + "powerupLandMinesNameText": "Minas", + "powerupPunchDescriptionText": "Deixa seus socos poderosos, \nrápidos, melhores, fortes.", + "powerupPunchNameText": "Luvas de Boxe", + "powerupShieldDescriptionText": "Absorve um pouco de dano para\nvocê não ter passar por isso.", + "powerupShieldNameText": "Escudo de Energia", + "powerupStickyBombsDescriptionText": "Gruda em tudo que toca.\nHilaridade segue.", + "powerupStickyBombsNameText": "Bombas Grudentas", + "powerupsSubtitleText": "É claro, nenhum jogo está completo sem poderes:", + "powerupsText": "Poderes", + "punchInfoText": "- Soco -\nQuanto mais rápidos seus punhos,\nmais danos seus socos dão, então\nsaia correndo feito um louco.", + "runInfoText": "- Correr -\nSegure QUALQUER botão para correr. Gatilhos ou botões de ombro funcionam bem se você tiver. \nCorrer o leva a lugares mais rápido, mas dificulta na hora de virar, então fique de olho nos penhascos.", + "someDaysText": "Tem dias que você só quer bater em algo. Ou então explodir coisas.", + "titleText": "Ajuda do ${APP_NAME}", + "toGetTheMostText": "Para aproveitar ao máximo este jogo, você precisará de:", + "welcomeText": "Bem-vindo ao ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} está navegando pelos menus como se não houvesse amanhã -", + "importPlaylistCodeInstructionsText": "Use o seguinte código para importar essa playlist:", + "importPlaylistSuccessText": "Playlist '${NAME}' importada ${TYPE}", + "importText": "Importar", + "importingText": "Importando...", + "inGameClippedNameText": "No jogo será\n\"${NAME}\"", + "inboxText": "Caixa de entrada", + "installDiskSpaceErrorText": "ERRO: Não pôde concluir a instalação.\nVocê deve estar com pouco espaço no seu dispositivo.\nApague algumas coisas e tente novamente.", + "internal": { + "arrowsToExitListText": "aperte ${LEFT} ou ${RIGHT} para sair da lista", + "buttonText": "botão", + "cantKickHostError": "Você não pode expulsar o anfitrião.", + "chatBlockedText": "O chat de ${NAME} está bloqueado por ${TIME} segundo(s).", + "connectedToGameText": "Conectou-se a '${NAME}'", + "connectedToPartyText": "Entrou no grupo de ${NAME}!", + "connectingToPartyText": "Conectando...", + "connectionFailedHostAlreadyInPartyText": "A conexão falhou; anfitrião está em outro grupo.", + "connectionFailedPartyFullText": "Conexão falhou; o grupo está cheio.", + "connectionFailedText": "A conexão falhou.", + "connectionFailedVersionMismatchText": "A conexão falhou; anfitrião está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente novamente.", + "connectionRejectedText": "Conexão negada.", + "controllerConnectedText": "${CONTROLLER} conectado.", + "controllerDetectedText": "1 controle detectado.", + "controllerDisconnectedText": "${CONTROLLER} desconectado.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Por favor, tente novamente.", + "controllerForMenusOnlyText": "Este controle não pode ser usado para jogar; apenas para navegar pelo menu.", + "controllerReconnectedText": "${CONTROLLER} reconectado.", + "controllersConnectedText": "${COUNT} controles conectados.", + "controllersDetectedText": "${COUNT} controles detectados.", + "controllersDisconnectedText": "${COUNT} controles desconectados.", + "corruptFileText": "Arquivos corrompidos detectados. Tente reinstalar o jogo ou mande um e-mail para ${EMAIL}", + "errorPlayingMusicText": "Erro ao tocar música: ${MUSIC}", + "errorResettingAchievementsText": "Não foi possível reiniciar as conquistas online; por favor, tente novamente mais tarde.", + "hasMenuControlText": "${NAME} possui o controle do menu.", + "incompatibleNewerVersionHostText": "Anfitrião do grupo está usando uma versão mais nova do jogo.\nAtualize seu jogo e tente novamente.", + "incompatibleVersionHostText": "Anfitrião está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente de novo.", + "incompatibleVersionPlayerText": "${NAME} está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente novamente.", + "invalidAddressErrorText": "Erro: endereço invalido.", + "invalidNameErrorText": "Erro: nome inválido.", + "invalidPortErrorText": "Erro: porta inválida.", + "invitationSentText": "Convite enviado.", + "invitationsSentText": "${COUNT} convites enviados.", + "joinedPartyInstructionsText": "Alguém entrou no seu grupo.\nAperte 'Jogar' para começar.", + "keyboardText": "Teclado", + "kickIdlePlayersKickedText": "Expulsando ${NAME} por não mostrar movimento.", + "kickIdlePlayersWarning1Text": "${NAME} será expulso em ${COUNT} segundos se continuar imóvel.", + "kickIdlePlayersWarning2Text": "(você pode desativar isto em Configurações-> Avançado)", + "leftGameText": "Saiu de '${NAME}'", + "leftPartyText": "Você saiu do grupo de ${NAME}.", + "noMusicFilesInFolderText": "A pasta não contém arquivos de música.", + "playerJoinedPartyText": "${NAME} entrou no grupo!", + "playerLeftPartyText": "${NAME} saiu do grupo.", + "rejectingInviteAlreadyInPartyText": "Recusando convite (já está em um grupo).", + "serverRestartingText": "Servidor reiniciando. Por favor, reconecte-se em um momento...", + "serverShuttingDownText": "Servidor está desligando...", + "signInErrorText": "Erro ao entrar.", + "signInNoConnectionText": "Não pôde entrar. (sem conexão à internet?)", + "telnetAccessDeniedText": "ERRO: o usuário não liberou acesso telnet.", + "timeOutText": "(tempo acaba em ${TIME} segundos)", + "touchScreenJoinWarningText": "Você entrou com o modo touchscreen.\nSe isso foi um erro, toque em 'Menu->Sair do Jogo'.", + "touchScreenText": "Touchscreen", + "unableToCompleteTryAgainText": "Não é possível concluir isso agora.\nPor favor, tente novamente.", + "unableToResolveHostText": "Erro: não é possível resolver a fonte do anfitrião", + "unavailableNoConnectionText": "Isso não está disponível agora (sem conexão à internet?)", + "vrOrientationResetCardboardText": "Use para reiniciar a orientação do VR.\nPara jogar, você precisa de um controle externo.", + "vrOrientationResetText": "Orientação do VR reiniciada.", + "willTimeOutText": "(o tempo acabará se ficar imóvel)" + }, + "inventoryText": "Inventário", + "jumpBoldText": "SALTAR", + "jumpText": "Saltar", + "keepText": "Manter", + "keepTheseSettingsText": "Manter essas configurações?", + "keyboardChangeInstructionsText": "Pressione duas vezes o espaço para alterar os teclados.", + "keyboardNoOthersAvailableText": "Nenhum outro teclado disponível.", + "keyboardSwitchText": "Alterando teclado para \"${NAME}\".", + "kickOccurredText": "${NAME} foi expulso.", + "kickQuestionText": "Expulsar ${NAME}?", + "kickText": "Expulsar", + "kickVoteCantKickAdminsText": "O Administrador não pode ser expulso.", + "kickVoteCantKickSelfText": "Você não pode se expulsar.", + "kickVoteFailedNotEnoughVotersText": "Não há jogadores suficientes para uma votação.", + "kickVoteFailedText": "A votação para expulsão falhou.", + "kickVoteStartedText": "Uma votação para expulsar ${NAME} foi iniciada.", + "kickVoteText": "Votação para expulsar", + "kickVotingDisabledText": "A votação para expulsar está desativada.", + "kickWithChatText": "Escreva ${YES} no chat para sim e ${NO} para não.", + "killsTallyText": "${COUNT} abates", + "killsText": "Abates", + "kioskWindow": { + "easyText": "Fácil", + "epicModeText": "Modo Épico", + "fullMenuText": "Menu Completo", + "hardText": "Difícil", + "mediumText": "Médio", + "singlePlayerExamplesText": "Exemplos de Um jogador / Cooperativo", + "versusExamplesText": "Exemplos de Versus" + }, + "languageSetText": "O idioma agora é \"${LANGUAGE}\".", + "lapNumberText": "Volta ${CURRENT}/${TOTAL}", + "lastGamesText": "(últimas ${COUNT} partidas)", + "leaderboardsText": "Classificação", + "league": { + "allTimeText": "Todos os Tempos", + "currentSeasonText": "Temporada atual (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Classificação da liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "A temporada acabou ${NUMBER} dia(s) atrás.", + "seasonEndsDaysText": "A temporada acaba em ${NUMBER} dia(s).", + "seasonEndsHoursText": "A temporada acaba em ${NUMBER} hora(s).", + "seasonEndsMinutesText": "Temporada acaba em ${NUMBER} minuto(s).", + "seasonText": "Temporada ${NUMBER}", + "tournamentLeagueText": "Você deve alcançar a liga ${NAME} para entrar neste torneio.", + "trophyCountsResetText": "A contagem de troféus reiniciará na próxima temporada.", + "upToDateBonusDescriptionText": "Os jogadores que estiverem jogando uma versão recente do\njogo recebem um bônus de ${PERCENT}% aqui.", + "upToDateBonusText": "Bônus por Estar Atualizado" + }, + "learnMoreText": "Saiba Mais", + "levelBestScoresText": "Melhores pontuações no ${LEVEL}", + "levelBestTimesText": "Melhores tempos no ${LEVEL}", + "levelIsLockedText": "${LEVEL} está bloqueado.", + "levelMustBeCompletedFirstText": "${LEVEL} deve ser concluído primeiro.", + "levelText": "Nível ${NUMBER}", + "levelUnlockedText": "Nível desbloqueado!", + "livesBonusText": "Bônus de Vida", + "loadingText": "carregando", + "loadingTryAgainText": "Carregando; tente novamente daqui a pouco...", + "macControllerSubsystemBothText": "Ambos (não recomendado)", + "macControllerSubsystemClassicText": "Clássico", + "macControllerSubsystemDescriptionText": "Tente ativar isso se os controles não estiverem funcionando", + "macControllerSubsystemMFiNoteText": "Feito para iOS/Mac controle detectado ;\nvocê pode querer ativar isso em Configurações -> Controles", + "macControllerSubsystemMFiText": "Feito para iOS/Mac", + "macControllerSubsystemTitleText": "Suporte para controle", + "mainMenu": { + "creditsText": "Créditos", + "demoMenuText": "Menu de demonstração", + "endGameText": "Terminar Jogo", + "endTestText": "Terminar Teste", + "exitGameText": "Sair do Jogo", + "exitToMenuText": "Sair para o menu?", + "howToPlayText": "Como Jogar", + "justPlayerText": "(Somente ${NAME})", + "leaveGameText": "Sair do Jogo", + "leavePartyConfirmText": "Deseja realmente sair do grupo?", + "leavePartyText": "Sair do Grupo", + "quitText": "Sair", + "resumeText": "Retomar", + "settingsText": "Configurações" + }, + "makeItSoText": "Aplicar", + "mapSelectGetMoreMapsText": "Obter Mais Mapas...", + "mapSelectText": "Selecionar...", + "mapSelectTitleText": "${GAME} mapas", + "mapText": "Mapa", + "maxConnectionsText": "Limite de Conexões", + "maxPartySizeText": "Tamanho Máximo do Grupo", + "maxPlayersText": "Limite de Jogadores", + "merchText": "Produtos BombSquad!", + "modeArcadeText": "Modo Arcade", + "modeClassicText": "Modo Clássico", + "modeDemoText": "Modo Demonstração", + "moreSoonText": "Mais novidades em breve...", + "mostDestroyedPlayerText": "Player Mais Destruído", + "mostValuablePlayerText": "Jogador Mais Valioso", + "mostViolatedPlayerText": "Jogador Mais Violado", + "mostViolentPlayerText": "Jogador Mais Violento", + "moveText": "Mover", + "multiKillText": "MATOU ${COUNT}!!!", + "multiPlayerCountText": "${COUNT} jogadores", + "mustInviteFriendsText": "Nota: você deve convidar amigos no\npainel \"${GATHER}\" ou adicionar\ncontroles para jogar no multijogador.", + "nameBetrayedText": "${NAME} traiu ${VICTIM}.", + "nameDiedText": "${NAME} morreu.", + "nameKilledText": "${NAME} espancou ${VICTIM}.", + "nameNotEmptyText": "Nome não pode estar vazio!", + "nameScoresText": "${NAME} fez um ponto!", + "nameSuicideKidFriendlyText": "${NAME} acidentalmente morreu.", + "nameSuicideText": "${NAME} cometeu suicídio.", + "nameText": "Nome", + "nativeText": "Nativo", + "newExclaimText": "Novo!", + "newPersonalBestText": "Novo recorde pessoal!", + "newTestBuildAvailableText": "Uma nova versão de teste está disponível! (${VERSION} teste ${BUILD}).\nAdquira em ${ADDRESS}", + "newText": "Novo", + "newVersionAvailableText": "Uma nova versão de ${APP_NAME} está disponível! (${VERSION})", + "nextAchievementsText": "Próximas conquistas:", + "nextLevelText": "Próximo nível", + "noAchievementsRemainingText": "- nenhum", + "noContinuesText": "(sem continuar)", + "noExternalStorageErrorText": "Armazenamento externo não encontrado", + "noGameCircleText": "Erro: não conectado no GameCircle", + "noMessagesText": "Sem mensagens.", + "noPluginsInstalledText": "Nenhum Plugin instalado", + "noScoresYetText": "Ainda sem pontuação.", + "noServersFoundText": "Servidores não encontrados.", + "noThanksText": "Não, obrigado", + "noTournamentsInTestBuildText": "Atenção: As pontuações dos torneios desta compilação de teste serão ignoradas.", + "noValidMapsErrorText": "Nenhum mapa válido encontrado para este tipo de jogo.", + "notEnoughPlayersRemainingText": "Não há jogadores suficientes sobrando; saia e comece um novo jogo.", + "notEnoughPlayersText": "Você precisa de pelo menos ${COUNT} jogadores para começar o jogo!", + "notEnoughTicketsText": "Sem bilhetes suficientes!", + "notNowText": "Agora não", + "notSignedInErrorText": "Você deve iniciar sessão primeiro.", + "notSignedInGooglePlayErrorText": "Você deve iniciar sessão no Google Play primeiro.", + "notSignedInText": "sem sessão iniciada", + "notUsingAccountText": "Aviso: Ignorando a conta ${SERVICE}.\nVá em 'Conta -> Entrar com ${SERVICE}' se quiser usá-la.", + "nothingIsSelectedErrorText": "Nada foi selecionado!", + "numberText": "#${NUMBER}", + "offText": "Desativado", + "okText": "Certo", + "onText": "Ativado", + "oneMomentText": "Um Momento...", + "onslaughtRespawnText": "${PLAYER} vai renascer na onda ${WAVE}", + "openMeText": "Abra-Me!", + "openNowText": "Abrir Agora", + "openText": "Abrir", + "orText": "${A} ou ${B}", + "otherText": "Outro...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "Sua própria bandeira deve estar\nem sua base para fazer um ponto!", + "partyWindow": { + "chatMessageText": "Mensagem do Chat", + "emptyText": "Seu grupo está vazio", + "hostText": "(anfitrião)", + "sendText": "Enviar", + "titleText": "Seu Grupo" + }, + "pausedByHostText": "(pausado pelo anfitrião)", + "perfectWaveText": "Onda Perfeita!", + "pickUpText": "Pegar", + "playModes": { + "coopText": "Cooperativo", + "freeForAllText": "Todos contra todos", + "multiTeamText": "Equipes múltiplas", + "singlePlayerCoopText": "Um jogador / Cooperativo", + "teamsText": "Equipes" + }, + "playText": "Jogar", + "playWindow": { + "oneToFourPlayersText": "1-4 jogadores", + "titleText": "Jogar", + "twoToEightPlayersText": "2-8 jogadores" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} entrará no começo da próxima rodada.", + "playerInfoText": "Info. do jogador", + "playerLeftText": "${PLAYER} saiu da partida.", + "playerLimitReachedText": "Limite de ${COUNT} jogadores atingido; entrada não permitida.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Você não pode excluir o seu perfil.", + "deleteButtonText": "Excluir\nPerfil", + "deleteConfirmText": "Excluir '${PROFILE}'?", + "editButtonText": "Editar\nPerfil", + "explanationText": "(personalize nomes e aparências do jogador para esta conta)", + "newButtonText": "Novo\nPerfil", + "titleText": "Perfis de Jogadores" + }, + "playerText": "Jogador", + "playlistNoValidGamesErrorText": "Esta playlist não contém nenhum jogo desbloqueado válido.", + "playlistNotFoundText": "playlist não encontrada", + "playlistText": "Playlist", + "playlistsText": "Playlists", + "pleaseRateText": "Se você está curtindo ${APP_NAME}, por favor, dê um tempinho\npara avaliar e comentar. Isso nos dá uma opinião útil\ne ajuda no desenvolvimento do jogo.\n\nobrigado!\n-eric", + "pleaseWaitText": "Por favor, aguarde...", + "pluginClassLoadErrorText": "Erro ao carregar a classe de um plugin '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Erro ao inicializar plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Configurações de Plugins", + "pluginsAutoEnableNewText": "Ativar Automaticamente Novos Plugins", + "pluginsDetectedText": "Novo(s) plugin(s) detetados. Reinicie o jogo para ativá-los ou configure-os nas configurações.", + "pluginsDisableAllText": "Desativar todos os Plugins!", + "pluginsEnableAllText": "Ativar todos os Plugins!", + "pluginsRemovedText": "${NUM} plugin(s) não foram encontrados.", + "pluginsText": "Plugins", + "practiceText": "Praticar", + "pressAnyButtonPlayAgainText": "Aperte qualquer botão para jogar novamente...", + "pressAnyButtonText": "Aperte qualquer botão para continuar...", + "pressAnyButtonToJoinText": "aperte qualquer botão para entrar...", + "pressAnyKeyButtonPlayAgainText": "Aperte qualquer tecla/botão para jogar novamente...", + "pressAnyKeyButtonText": "Aperte qualquer tecla/botão para continuar...", + "pressAnyKeyText": "Aperte qualquer tecla...", + "pressJumpToFlyText": "** Aperte saltar repetidamente para voar **", + "pressPunchToJoinText": "aperte SOCO para entrar...", + "pressToOverrideCharacterText": "aperte ${BUTTONS} para substituir o seu personagem", + "pressToSelectProfileText": "aperte ${BUTTONS} para selecionar um jogador", + "pressToSelectTeamText": "aperte ${BUTTONS} para selecionar uma equipe", + "promoCodeWindow": { + "codeText": "Código", + "enterText": "Entrar" + }, + "promoSubmitErrorText": "Erro ao enviar código; Verifique a sua conexão com a internet!", + "ps3ControllersWindow": { + "macInstructionsText": "Desligue a energia na parte traseira do seu PS3, verifique se\no Bluetooth do seu Mac está ativado, em seguida conecte o seu controle\nno seu Mac através de um cabo USB para emparelhar os dois. A partir daí, você\npode usar o botão home do controle para conectá-lo ao seu Mac\nseja por fio (USB) ou sem fio (Bluetooth).\n\nEm alguns Macs, uma senha pode ser solicitada ao emparelhar.\nSe isso acontecer, consulte o seguinte tutorial ou o Google para obter ajuda.\n\n\n\n\nOs controles de PS3 conectados sem fio devem aparecer na lista de\ndispositivos em Preferências do Sistema > Bluetooth. Você pode precisar remover\nda lista quando você quiser usar com o seu PS3 novamente.\n\nTambém certifique-se de desconectá-los do Bluetooth quando não estiver\nusando ou a bateria ficará acabando.\n\nBluetooth deve suportar até sete dispositivos conectados,\nembora a sua capacidade possa variar.", + "ouyaInstructionsText": "Para usar um controle de PS3 com seu OUYA, basta conectá-lo com um cabo USB\numa vez para emparelhá-lo. Fazer isso pode desconectar seus outros controles, por\nisso você deve, em seguida, reiniciar seu OUYA e desconectar o cabo USB.\n\nA partir de então você deve ser capaz de usar o botão HOME do controle para\nconectá-lo sem fio. Quando você terminar de jogar, pressione o botão HOME\npor 10 segundos para desligar o controle; caso contrário, pode permanecer ligado\ne desperdiçar bateria.", + "pairingTutorialText": "vídeo tutorial do emparelhamento", + "titleText": "Usando Controles de PS3 com ${APP_NAME}:" + }, + "punchBoldText": "SOCAR", + "punchText": "Socar", + "purchaseForText": "Compre por ${PRICE}", + "purchaseGameText": "Comprar jogo", + "purchaseNeverAvailableText": "Desculpe, as compras não estão disponíveis nesta versão.\nTente entrar em sua conta em outra plataforma e fazer compras nela", + "purchaseNotAvailableText": "Esta compra não está disponível.", + "purchasingText": "Comprando...", + "quitGameText": "Sair do ${APP_NAME}?", + "quittingIn5SecondsText": "Saindo em 5 segundos...", + "randomPlayerNamesText": "João,Maria,Anderson,Lucas,Roberto,César,Felipe,Pedro,Zézinho,Jaílson,Hélvio,Plínio,Clara,Lorena,Beatriz,Wandernilson,Marcos,Michele,Taís,Florentina,Tadeu,Teodoro,Gabriel,Joelma,Chimbinha,Lula,Dilma,Leonardo,Irene,Samanta,Gioconda,Guilhermina,Guilherme,Frederico,Bartolomeu,Dionísio,Diógenes,Haroldo,Ronaldinho,Ricardo,Selma,Bruna,Vanderlei,Danilo,Celso,Vitória,Denise,Samuel,Daniel,Gigi,Manuel,Wiz,Gretchen,Creusa,Chico,Leôncio,Leônidas,Washington,Cleusa,José,Joane,Severino,Casé,Carlos,Davi,Bianca,Clautila,Dafne,Jorge,Sandra,Armando,Basílio,Rochele,Camila,Débora,Rafael,Jonatan,Clodomiro,Clodovil,Vera,Simão,Raíssa,Toni,Tânia,Regina,Bela,Max,Maximiliano,Claudinei,Cláudio,Luciana,Anália,Aparecida,Marcelo,Flávio,Emílio,Tiago,Hebe,Ana,Beth,Gugu,Vítor,Nílton,Maurício,Marciano,Belquior,Clemente,Rosa,Rose,Rosemar,Gabriela,Sérgio,Antônio,Ben,Ivan,jamim,Abreu,Luís,Elton,Fabiana,Waldir,Wilson,Tainá,Tainara,Xuxa,Sacha,Teotônio,Téo,Valdirene,Laurindo,Priscila,Joaquim,Estevão,Gilmar,Erick,Gilson,Romário,Dunga,Ludmila,Luciano,Gilvan,Tamara,Carla,Zezé,Fernando,Fernanda,Adegesto,Acheropita,Anatalino,Lino,Araci,Marluci,Eusébio,Darcília,Dignatario,Ernesto,Cássio,Conrado,Fábio,Heitor,Ivan,Murilo,Andressa,Mateus,Otávio,Helena,Laís,Lavínia,Leila,Letícia,Nair,Henrique,Lara,Diogo,Diego,Geniclécio,Serafim,Lisa,Inri,Eusébio,Gerônimo,Bernardo,Bernadete,Henriete,Eliete,Fudêncio,Peruíbe,Tomás,Tomashedisso,Giovana,Prieto,Gabriely,Suélen,Jamily,Jamil,Geraldo,Nazareth,Forníco,Ícaro,Breno,Bruno,Cilmara,Nilza,Caio,Borges,Cleimara,Janeclécio,Iram,Tico,Teco,Genilson,Marlos,William,Nando,Nanda,Isabel,Jamal,Elias,Félix,Caroline,Carolina,Vilma,Rafaely,Tonho,Túnica,Miguel,Jones,Juan,Anastácio,Francisco,Xavier", + "randomText": "Aleatório", + "rankText": "Classificação", + "ratingText": "Avaliação", + "reachWave2Text": "Chegue a onda 2 para pontuar.", + "readyText": "pronto", + "recentText": "Recente", + "remoteAppInfoShortText": "${APP_NAME} é mais divertido quando é jogado com família e amigos.\nConecte um ou mais controles de hardware ou instale o aplicativo \n${REMOTE_APP_NAME} em telefones ou tablets para usá-los \ncomo controles.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Posição do botão", + "button_size": "Tamanho do botão", + "cant_resolve_host": "Não foi possível localizar o anfitrião.", + "capturing": "Aguardando...", + "connected": "Conectado.", + "description": "Use seu telefone ou tablet como controle com BombSquad.\nAté 8 dispositivos podem se conectar de uma vez para uma loucura épica de multijogador local em uma TV ou tablet.", + "disconnected": "Desconectado pelo servidor.", + "dpad_fixed": "fixo", + "dpad_floating": "Móvel", + "dpad_position": "Posição do direcional", + "dpad_size": "Tamanho do direcional", + "dpad_type": "Tipo de direcional", + "enter_an_address": "Insira um endereço", + "game_full": "A partida está cheia ou não aceita conexões.", + "game_shut_down": "A partida foi fechada.", + "hardware_buttons": "Botões físicos", + "join_by_address": "Entrar por endereço...", + "lag": "Lag: ${SECONDS} segundos", + "reset": "Restaurar padrão", + "run1": "Correr 1", + "run2": "Correr 2", + "searching": "Procurando partidas...", + "searching_caption": "Clique em uma partida para entrar.\nVeja se está na mesma rede Wi-Fi do jogo.", + "start": "Iniciar", + "version_mismatch": "Versão incompatível.\nCertifique-se que o BombSquad e o BombSquad Remote\nestão atualizados e tente novamente." + }, + "removeInGameAdsText": "Desbloqueie \"${PRO}\" na loja para remover anúncios dentro do jogo.", + "removeInGameAdsTokenPurchaseText": "OFERTA POR TEMPO LIMITADO: Compre QUALQUER pacote de tokens para remover anúncios no jogo.", + "renameText": "Renomear", + "replayEndText": "Terminar replay", + "replayNameDefaultText": "Replay do último jogo", + "replayReadErrorText": "Erro ao ler arquivo de replay.", + "replayRenameWarningText": "Renomeie \"${REPLAY}\" após uma partida caso queira salvá-lo; caso contrário será sobrescrito.", + "replayVersionErrorText": "Desculpe, este replay foi feito em uma versão\ndiferente do jogo e não pode ser usado.", + "replayWatchText": "Ver replay", + "replayWriteErrorText": "Erro ao gravar arquivo de replay.", + "replaysText": "Replays", + "reportPlayerExplanationText": "Use este e-mail para denunciar trapaças, linguagem inapropriada, ou outro comportamento ruim.\nPor favor, descreva abaixo:", + "reportThisPlayerCheatingText": "Trapaça", + "reportThisPlayerLanguageText": "Linguagem inapropriada", + "reportThisPlayerReasonText": "O que gostaria de denunciar?", + "reportThisPlayerText": "Denunciar este jogador", + "requestingText": "Solicitando...", + "restartText": "Reiniciar", + "retryText": "Tentar novamente", + "revertText": "Reverter", + "runText": "Correr", + "saveText": "Salvar", + "scanScriptsErrorText": "Erro(s) de verificação de scripts; consulte o registro para obter mais detalhes.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} e outro(s) módulo(s) precisam de atualizações paro o api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} precisa ser atualizado para api${API}.", + "scoreChallengesText": "Desafios de Pontuação", + "scoreListUnavailableText": "Lista de pontuação indisponível.", + "scoreText": "Pontuação", + "scoreUnits": { + "millisecondsText": "Milisegundos", + "pointsText": "Pontos", + "secondsText": "Segundos" + }, + "scoreWasText": "(foi ${COUNT})", + "selectText": "Selecionar", + "sendInfoDescriptionText": "Isto envia informações de sua conta e de estado de aplicativo para o desenvolvedor.\nPor favor inclua seu nome ou razão por ter feito isso.", + "seriesWinLine1PlayerText": "VENCEU A", + "seriesWinLine1TeamText": "VENCEU A", + "seriesWinLine1Text": "VENCEU A", + "seriesWinLine2Text": "SÉRIE!", + "settingsWindow": { + "accountText": "Conta", + "advancedText": "Avançado", + "audioText": "Áudio", + "controllersText": "Controles", + "graphicsText": "Gráficos", + "playerProfilesMovedText": "Nota: os perfis de jogador foram movidos à janela de Conta no menu principal.", + "titleText": "Configurações" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(um simples teclado virtual compatível com controles para edição de texto)", + "alwaysUseInternalKeyboardText": "Sempre usar o teclado interno", + "benchmarksText": "Benchmarks e Testes de Estresse", + "devToolsText": "Ferramentas de Desenvolvedor", + "disableCameraGyroscopeMotionText": "Desativar movimento giroscópio da câmera", + "disableCameraShakeText": "Desativar tremida de câmera", + "disableThisNotice": "(você pode desativar este aviso em configurações avançadas)", + "enterPromoCodeText": "Inserir Código", + "forTestingText": "Nota: esses valores são somente para teste e serão perdidos assim que o aplicativo for fechado.", + "helpTranslateText": "As traduções do ${APP_NAME} são sustentadas pelo esforço\npúblico da comunidade. Se você gostaria de ajudar ou corrigir\numa tradução, siga o link a abaixo. Agradeço desde já!", + "insecureConnectionsDescriptionText": "não recomendado, mas talvez permita você poder jogar online\nde países ou redes restritas", + "insecureConnectionsText": "Usar conexões inseguras", + "kickIdlePlayersText": "Expulsar jogadores inativos", + "kidFriendlyModeText": "Modo para crianças (violência reduzida, etc)", + "languageText": "Idioma", + "moddingGuideText": "Guia para Modificar o Jogo", + "moddingToolsText": "Ferramentas de Modificação", + "mustRestartText": "Você deve reiniciar o jogo para isso ter efeito.", + "netTestingText": "Teste de Conexão", + "resetText": "Redefinir", + "sendInfoText": "Enviar Informação", + "showBombTrajectoriesText": "Mostrar trajetórias da bomba", + "showDemosWhenIdleText": "Mostrar demonstrações quando ocioso", + "showDeprecatedLoginTypesText": "Mostrar tipos de logins ultrapassados", + "showDevConsoleButtonText": "Mostrar opção de desenvolvedor", + "showInGamePingText": "Mostrar latência no jogo", + "showPlayerNamesText": "Mostrar nomes dos jogadores", + "showUserModsText": "Mostrar Caminho da Pasta de Modificações", + "titleText": "Avançado", + "translationEditorButtonText": "Abrir site de Traduções do ${APP_NAME}", + "translationFetchErrorText": "estado da tradução indisponível", + "translationFetchingStatusText": "verificando estado da tradução...", + "translationInformMe": "Avise me quando meu idioma precisar de atualizações", + "translationNoUpdateNeededText": "o seu idioma está atualizado; woohoo!", + "translationUpdateNeededText": "** o seu idioma precisa de atualizações!! **", + "vrTestingText": "Teste de RV" + }, + "shareText": "Compartilhar", + "sharingText": "Compartilhando...", + "showText": "Mostrar", + "signInForPromoCodeText": "Você deve iniciar sia sessão em uma conta para que os códigos promocionais funcionem.", + "singleGamePlaylistNameText": "Somente ${GAME}", + "singlePlayerCountText": "1 jogador", + "sizeLargeText": "Grande", + "sizeMediumText": "Médio", + "sizeSmallText": "Pequeno", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Seleção de personagens", + "Chosen One": "O Escolhido", + "Epic": "Partidas no modo épico", + "Epic Race": "Corrida épica", + "FlagCatcher": "Capture a bandeira", + "Flying": "Pensamentos felizes", + "Football": "Futebol americano", + "ForwardMarch": "Assalto", + "GrandRomp": "Conquista", + "Hockey": "Hóquei", + "Keep Away": "Fique longe", + "Marching": "Casa dos degrais", + "Menu": "Menu principal", + "Onslaught": "Embate", + "Race": "Corrida", + "Scary": "Rei da Colina", + "Scores": "Tela de pontuação", + "Survival": "Eliminatória", + "ToTheDeath": "Mata-mata", + "Victory": "Tela de Pontuação Final" + }, + "spaceKeyText": "espaço", + "statsText": "Estatísticas", + "stopRemindingMeText": "Pare de me lembrar", + "storagePermissionAccessText": "É necessário acesso ao armazenamento", + "store": { + "alreadyOwnText": "Você já possui ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Remove anúncios no jogo\n• Desbloqueia mais opções do jogo\n• E também inclui:", + "buyText": "Comprar", + "charactersText": "Personagens", + "comingSoonText": "Em breve...", + "extrasText": "Extras", + "holidaySpecialText": "Especial de feriado", + "howToSwitchCharactersText": "(vá para \"${SETTINGS} -> ${PLAYER_PROFILES}\" para atribuir e personalizar personagens)", + "howToUseIconsText": "(crie perfis globais - na janela de conta - para usá-los)", + "howToUseMapsText": "(use estes mapas em suas próprias playlist de equipes/todos contra todos)", + "iconsText": "Ícones", + "loadErrorText": "Não foi possível carregar a página.\nVerifique a sua conexão com a internet.", + "loadingText": "carregando", + "mapsText": "Mapas", + "miniGamesText": "Minijogos", + "oneTimeOnlyText": "(somente uma vez)", + "purchaseAlreadyInProgressText": "A compra deste item já está em progresso.", + "purchaseConfirmText": "Comprar ${ITEM}?", + "purchaseNotValidError": "A compra não é valida.\nEntre em contato com ${EMAIL} se isso foi um erro.", + "purchaseText": "Comprar", + "saleBundleText": "Venda de pacotes!", + "saleExclaimText": "Promoção!", + "salePercentText": "(${PERCENT}% de desconto)", + "saleText": "PROMOÇÃO", + "searchText": "Buscar", + "teamsFreeForAllGamesText": "Jogos em equipes / Todos contra todos", + "totalWorthText": "*** Apenas ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Atualizar?", + "winterSpecialText": "Especial de Inverno", + "youOwnThisText": "- você tem isso -" + }, + "storeDescriptionText": "Loucura total com até 8 jogadores!\n\nExploda seus amigos (ou o computador) em um torneio de minijogos desafiadores como Capture a bandeira, Hóquei bombástico e Mata-mata em câmera lenta épica!\n\nControles normais e controles externos possibilitam jogar com até 8 pessoas no mesmo aparelho; você também pode usar outros aparelhos como controles externos usando o aplicativo grátis ‘BombSquad Remote’!\n\nCuidado com as bombas!\n\nDê uma olhada em www.froemling.net/bombsquad para ficar ligado nas novidades.", + "storeDescriptions": { + "blowUpYourFriendsText": "Exploda seus amigos.", + "competeInMiniGamesText": "Compita em minijogos que vão de corridas a voos.", + "customize2Text": "Personalize personagens, minijogos e até mesmo a trilha sonora.", + "customizeText": "Personalize personagens e crie sua própria playlist de minijogos.", + "sportsMoreFunText": "Esportes são mais divertidos com explosivos.", + "teamUpAgainstComputerText": "Una-se a outros contra o computador." + }, + "storeText": "Loja", + "submitText": "Enviar", + "submittingPromoCodeText": "Enviando código promocional...", + "successText": "Sucesso!", + "supportEmailText": "Se estiver passando por problemas com o aplicativo, \nenvie um e-mail para ${EMAIL}.", + "teamNamesColorText": "Nome/Cores das Equipes...", + "telnetAccessGrantedText": "Acesso ao Telnet ativado.", + "telnetAccessText": "Acesso ao Telnet detectado; permitir?", + "testBuildErrorText": "Esta versão de teste não é mais compatível; por favor, confira uma nova versão.", + "testBuildText": "Versão de Teste", + "testBuildValidateErrorText": "Não foi possível validar esta versão. (sem conexão com a internet?)", + "testBuildValidatedText": "Versão de Teste Validada; Divirta-se!", + "thankYouText": "Obrigado pelo seu apoio! Aproveite o jogo!!", + "threeKillText": "MATOU TRÊS!!", + "ticketsDescriptionText": "Os bilhetes podem ser usados para desbloquear personagens,\nmapas, minijogos e muito mais na loja.\n\nOs bilhetes podem ser encontrados em baús obtidos através\nde campanhas, torneios e conquistas.", + "timeBonusText": "Bônus de tempo", + "timeElapsedText": "Tempo Decorrido", + "timeExpiredText": "Tempo Expirado", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Dica", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Obter tokens", + "notEnoughTokensText": "Não há Tokens suficientes!", + "numTokensText": "${COUNT} Tokens", + "openNowDescriptionText": "Você possui tokens suficientes\npara abri-lo agora - você não\nprecisa esperar.", + "shinyNewCurrencyText": "A nova moeda brilhante do BombSquad.", + "tokenPack1Text": "Pacote de tokens pequenos", + "tokenPack2Text": "Pacote de tokens médio", + "tokenPack3Text": "Pacote Grande de Tokens", + "tokenPack4Text": "Pacote de Tokens Jumbo", + "tokensDescriptionText": "Os tokens são usados para acelerar a abertura de baús\ne para outros recursos do jogo e da conta.\n\nVocê pode ganhar tokens no jogo ou comprá-los\nem pacotes. Ou adquira um Gold Pass para tokens infinitos\ne nunca mais se preocupe com eles.", + "youHaveGoldPassText": "Você tem um Passe Dourado.\nTodas as compras de tokens são gratuitas.\nAproveite!" + }, + "topFriendsText": "Melhores amigos", + "tournamentCheckingStateText": "Verificando o estado do torneio; espere um momento...", + "tournamentEndedText": "Este torneio foi finalizado. Um novo começará em breve.", + "tournamentEntryText": "Entrada para o torneio", + "tournamentFinalStandingsText": "Classificação final", + "tournamentResultsRecentText": "Resultados recentes do torneio.", + "tournamentStandingsText": "Classificação do torneio", + "tournamentText": "Torneio", + "tournamentTimeExpiredText": "O tempo do torneio expirou.", + "tournamentsDisabledWorkspaceText": "Os torneios são desabilitados quando os espaços de trabalho estão ativos.\nPara reativar os torneios, desative seu espaço de trabalho e reinicie.", + "tournamentsText": "Torneios", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernardo", + "Bones": "Ossos", + "Butch": "Butch", + "Easter Bunny": "Coelho da Páscoa", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumboldor", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Homenzinho", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Papai Noel", + "Snake Shadow": "Serpente Sombria", + "Spaz": "Spaz", + "Taobao Mascot": "Mascote Taobao", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "Treinamento de ${GAME}", + "Infinite ${GAME}": "${GAME} Infinito", + "Infinite Onslaught": "Embate Infinito", + "Infinite Runaround": "Evasiva Infinita", + "Onslaught Training": "Embate Treinamento", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Futebol americano Pro", + "Pro Onslaught": "Embate Pro", + "Pro Runaround": "Evasiva Pro", + "Rookie ${GAME}": "${GAME} Amador", + "Rookie Football": "Futebol Americano Amador", + "Rookie Onslaught": "Embate Amador", + "The Last Stand": "O Sobrevivente", + "Uber ${GAME}": "${GAME} Elite", + "Uber Football": "Futebol Americano Elite", + "Uber Onslaught": "Embate Elite", + "Uber Runaround": "Evasiva Elite" + }, + "displayItemNames": { + "${C} Tickets": "${C} Bilhetes", + "${C} Tokens": "${C} Tokens", + "Chest": "Baú", + "L1 Chest": "Baú L1", + "L2 Chest": "Baú L2", + "L3 Chest": "Baú L3", + "L4 Chest": "Baú L4", + "L5 Chest": "Baú L5", + "L6 Chest": "Baú L6", + "Unknown Chest": "Baú Desconhecido" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Seja o escolhido por um período de tempo para vencer.\nElimine o escolhido para se tornar ele.", + "Bomb as many targets as you can.": "Bombardeie o máximo de alvos que você puder.", + "Carry the flag for ${ARG1} seconds.": "Carregue a bandeira por ${ARG1} segundos.", + "Carry the flag for a set length of time.": "Carregue a bandeira por um tempo determinado.", + "Crush ${ARG1} of your enemies.": "Esmague ${ARG1} de seus inimigos.", + "Defeat all enemies.": "Derrote todos inimigos.", + "Dodge the falling bombs.": "Esquive das bombas caindo.", + "Final glorious epic slow motion battle to the death.": "Épica gloriosa batalha final até a morte em câmera lenta.", + "Gather eggs!": "Recolha os ovos!", + "Get the flag to the enemy end zone.": "Pegue a bandeira no final da zona inimiga.", + "How fast can you defeat the ninjas?": "Quão rápido você pode derrotar os ninjas?", + "Kill a set number of enemies to win.": "Mate um determinado número de inimigos para vencer.", + "Last one standing wins.": "Último em pé vence.", + "Last remaining alive wins.": "Último sobrevivente vence.", + "Last team standing wins.": "Última equipe de pé vence.", + "Prevent enemies from reaching the exit.": "Impeça que os inimigos alcancem a saída.", + "Reach the enemy flag to score.": "Alcance a bandeira inimiga para marcar.", + "Return the enemy flag to score.": "Retorne a bandeira inimiga para marcar.", + "Run ${ARG1} laps.": "Corra ${ARG1} voltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corra ${ARG1} voltas. Toda a sua equipe precisa terminar.", + "Run 1 lap.": "Corra 1 volta.", + "Run 1 lap. Your entire team has to finish.": "Corra 1 volta. Toda a sua equipe precisa terminar.", + "Run real fast!": "Corra muito rápido!", + "Score ${ARG1} goals.": "Marque ${ARG1} gols.", + "Score ${ARG1} touchdowns.": "Marque ${ARG1} touchdowns.", + "Score a goal.": "Marque um gol.", + "Score a touchdown.": "Marque um touchdown.", + "Score some goals.": "Marque alguns gols.", + "Secure all ${ARG1} flags.": "Proteja todas as ${ARG1} bandeiras.", + "Secure all flags on the map to win.": "Proteja todas as bandeiras no mapa para vencer.", + "Secure the flag for ${ARG1} seconds.": "Proteja a bandeira por ${ARG1} segundos.", + "Secure the flag for a set length of time.": "Proteja a bandeira por um determinado período de tempo.", + "Steal the enemy flag ${ARG1} times.": "Roube a bandeira do inimigo ${ARG1} vezes.", + "Steal the enemy flag.": "Roube a bandeira do inimigo.", + "There can be only one.": "Só pode existir um.", + "Touch the enemy flag ${ARG1} times.": "Toque a bandeira inimiga ${ARG1} vezes.", + "Touch the enemy flag.": "Toque a bandeira inimiga.", + "carry the flag for ${ARG1} seconds": "carregue a bandeira por ${ARG1} segundos", + "kill ${ARG1} enemies": "mate ${ARG1} inimigos", + "last one standing wins": "último em pé vence", + "last team standing wins": "última equipe de pé vence", + "return ${ARG1} flags": "retorne ${ARG1} bandeiras.", + "return 1 flag": "retorne 1 bandeira", + "run ${ARG1} laps": "corra ${ARG1} voltas", + "run 1 lap": "corra 1 volta", + "score ${ARG1} goals": "marque ${ARG1} gols", + "score ${ARG1} touchdowns": "marque ${ARG1} touchdowns", + "score a goal": "marque um gol", + "score a touchdown": "marque um touchdown", + "secure all ${ARG1} flags": "Proteja todas ${ARG1} bandeiras", + "secure the flag for ${ARG1} seconds": "Proteja a bandeira por ${ARG1} segundos", + "touch ${ARG1} flags": "toque ${ARG1} bandeiras", + "touch 1 flag": "toque uma bandeira" + }, + "gameNames": { + "Assault": "Assalto", + "Capture the Flag": "Capture a Bandeira", + "Chosen One": "O Escolhido", + "Conquest": "Conquista", + "Death Match": "Mata-mata", + "Easter Egg Hunt": "Caça aos ovos de Páscoa", + "Elimination": "Eliminatória", + "Football": "Futebol americano", + "Hockey": "Hóquei", + "Keep Away": "Fique longe", + "King of the Hill": "Rei da colina", + "Meteor Shower": "Chuva de meteoros", + "Ninja Fight": "Luta ninja", + "Onslaught": "Embate", + "Race": "Corrida", + "Runaround": "Evasiva", + "Target Practice": "Treino de Alvo", + "The Last Stand": "O Sobrevivente" + }, + "inputDeviceNames": { + "Keyboard": "Teclado", + "Keyboard P2": "Teclado P2" + }, + "languages": { + "Arabic": "Árabe", + "Belarussian": "Bielorrusso", + "Chinese": "Chinês - Simplificado ", + "ChineseSimplified": "Chinês - Simplificado", + "ChineseTraditional": "Chinês - Tradicional", + "Croatian": "Croata", + "Czech": "Tcheco", + "Danish": "Dinamarquês", + "Dutch": "Holandês", + "English": "Inglês", + "Esperanto": "Esperanto", + "Filipino": "Filipino", + "Finnish": "Finlandês", + "French": "Francês", + "German": "Alemão", + "Gibberish": "Embromation", + "Greek": "Grego", + "Hindi": "Hindu", + "Hungarian": "Húngaro", + "Indonesian": "Indonésio", + "Italian": "Italiano", + "Japanese": "Japonês", + "Korean": "Coreano", + "Malay": "Malaio", + "Persian": "Persa", + "PirateSpeak": "Piratês", + "Polish": "Polonês", + "Portuguese": "Português", + "PortugueseBrazil": "Português - Brasil", + "PortuguesePortugal": "Português - Portugal", + "Romanian": "Romeno", + "Russian": "Russo", + "Serbian": "Sérvio", + "Slovak": "Eslovaco", + "Spanish": "Espanhol", + "SpanishLatinAmerica": "Espanhol - América Latina", + "SpanishSpain": "Espanhol - Espanha", + "Swedish": "Sueco", + "Tamil": "tâmil", + "Thai": "Tailandês", + "Turkish": "Turco", + "Ukrainian": "Ucraniano", + "Venetian": "Veneziano", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronze", + "Diamond": "Diamante", + "Gold": "Ouro", + "Silver": "Prata" + }, + "mapsNames": { + "Big G": "Grande G", + "Bridgit": "Bridgit", + "Courtyard": "Pátio", + "Crag Castle": "Castelo Crag", + "Doom Shroom": "Cogumelo da Morte", + "Football Stadium": "Estádio de Futebol", + "Happy Thoughts": "Pensamentos felizes", + "Hockey Stadium": "Estádio de hóquei", + "Lake Frigid": "Lago Frígido", + "Monkey Face": "Cara de macaco", + "Rampage": "Tumulto", + "Roundabout": "Evasiva", + "Step Right Up": "Degrau acima", + "The Pad": "The Pad", + "Tip Top": "Tip Top", + "Tower D": "Torre D", + "Zigzag": "Ziguezague" + }, + "playlistNames": { + "Just Epic": "Somente épico", + "Just Sports": "Somente esportes" + }, + "scoreNames": { + "Flags": "Bandeiras", + "Goals": "Gols", + "Score": "Placar", + "Survived": "Sobreviveu", + "Time": "Tempo", + "Time Held": "Tempo realizado" + }, + "serverResponses": { + "A code has already been used on this account.": "Um código já está sendo usado nesta conta.", + "A reward has already been given for that address.": "Uma recompensa já foi dada para este endereço.", + "Account linking successful!": "A conta foi vinculada com êxito!", + "Account unlinking successful!": "Conta desvinculada com êxito!", + "Accounts are already linked.": "As contas já estão vinculadas.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Não foi possível verificar a visualização do anúncio.\nCertifique-se de que está executando uma versão oficial e atualizada do jogo.", + "An error has occurred; (${ERROR})": "Ocorreu um erro; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ocorreu um erro; entre em contato com a assistência. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ocorreu um erro; por favor, entre em contato com support@froemling.net.", + "An error has occurred; please try again later.": "Aconteceu um erro; tente novamente mais tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Tem certeza de que deseja vincular estas contas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nIsso não poderá ser desfeito!", + "BombSquad Pro unlocked!": "BombSquado Pro desbloqueado!", + "Can't link 2 accounts of this type.": "Não é possível vincular duas contas deste tipo.", + "Can't link 2 diamond league accounts.": "Não é possível vincular duas contas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Impossível vincular; ultrapassaria o máximo de ${COUNT} contas vinculadas.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trapaça detectada; pontuação e prêmios suspensos por ${COUNT} dias.", + "Could not establish a secure connection.": "Não foi possível estabelecer uma conexão segura.", + "Daily maximum reached.": "Máximo diário atingido.", + "Daily sign-in reward": "Recompensa de inscrição diária", + "Entering tournament...": "Entrando no torneio...", + "Invalid code.": "Código invalido.", + "Invalid payment; purchase canceled.": "Pagamento inválido; compra cancelada.", + "Invalid promo code.": "Código promocional invalido.", + "Invalid purchase.": "Compra inválida.", + "Invalid tournament entry; score will be ignored.": "Entrada errada de treinamento; pontuação será ignorada.", + "Item unlocked!": "Item unlocked", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULAÇÃO NEGADA. ${ACCOUNT} contém\ndados significativos que TODOS SERÃO PERDIDOS.\nVocê pode vincular na ordem oposta se desejar\n(e em vez disso perca os dados desta conta)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vincular conta ${ACCOUNT} com essa conta?\nTodo o progresso em ${ACCOUNT} será perdido.\nIsso não pode ser desfeito. Tem certeza?", + "Longer streaks lead to better rewards.": "Sequências mais longas levam a recompensas melhores.", + "Max number of playlists reached.": "Número máximo de playlists alcançado.", + "Max number of profiles reached.": "Número máximo de perfis alcançado.", + "Maximum friend code rewards reached.": "Máximo de recompensas de códigos de amigos atingido.", + "Message is too long.": "A mensagem é muito longa.", + "New tournament result!": "Novo resultado do torneio!", + "No servers are available. Please try again soon.": "Nenhum servidor está disponível. Por favor, tente novamente mais tarde.", + "No slots available. Free a slot and try again.": "Nenhum slot disponível. Libere um slot e tente novamente.", + "Profile \"${NAME}\" upgraded successfully.": "Perfil \"${NAME}\" atualizado com sucesso.", + "Profile could not be upgraded.": "Perfil não pôde ser criado.", + "Purchase successful!": "Compra feita com êxito!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Recebeu ${COUNT} tickets por entrar.\nVolte amanhã para receber ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "A funcionalidade do servidor não é mais compatível nesta versão do jogo;\nPor favor, atualize-o para uma versão mais recente.", + "Sorry, there are no uses remaining on this code.": "Desculpe, não há mais usos remanescentes neste código.", + "Sorry, this code has already been used.": "Desculpe, este código já foi usado.", + "Sorry, this code has expired.": "Desculpe, este código já expirou.", + "Sorry, this code only works for new accounts.": "Desculpe, este código só funciona para novas contas.", + "Sorry, this has expired.": "Desculpe, isso expirou.", + "Still searching for nearby servers; please try again soon.": "Ainda à procura por servidores próximos; tente novamente mais tarde.", + "Streak: ${NUM} days": "Sequência: ${NUM} dias", + "Temporarily unavailable; please try again later.": "Não disponível; por favor, tente novamente mais tarde.", + "The tournament ended before you finished.": "O torneio acabou antes de você terminar.", + "This account cannot be unlinked for ${NUM} days.": "Esta conta não pode ser desvinculada por ${NUM} dias.", + "This code cannot be used on the account that created it.": "Este código não pode ser usado pela conta que o criou.", + "This is currently unavailable; please try again later.": "Isso está atualmente indisponível; por favor tente mais tarde.", + "This requires version ${VERSION} or newer.": "Isso requer a versão ${VERSION} ou novo.", + "Tournaments disabled due to rooted device.": "Torneios desativados devido ao dispositivo estar rooteado.", + "Tournaments require ${VERSION} or newer": "Torneios requerem ${VERSION} ou mais recente", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Desvincular ${ACCOUNT} dessa conta?\nTodo o progresso em ${ACCOUNT} será reiniciado.\n(exceto por conquistas em alguns casos)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATENÇÃO: denúncias sobre você estar usando hack foram feitas.\nContas que usam hack serão banidas. Por favor, jogue limpo.", + "Wait reduced!": "Tempo de espera reduzido!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Aviso: Esta versão do jogo é limitada a dados da conta antigos; algumas coisas podem aparecer ausentes ou desatualizadas.\nPor favor atualize para uma versão mais nova do jogo para ver os dados mais recentes da sua conta.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Gostaria de vincular a sua conta de dispositivo com esta?\n\nA sua conta de dispositivo é ${ACCOUNT1}\nEsta conta é ${ACCOUNT2}\n\nIsso permitirá que você mantenha seu progresso atual.\nAviso: isso não pode ser desfeito!", + "You already own this!": "Você já possui isso.", + "You can join in ${COUNT} seconds.": "Você poderá entrar em ${COUNT} segundos", + "You don't have enough tickets for this!": "Você não tem bilhetes suficientes para isso!", + "You don't own that.": "Você não comprou isso.", + "You got ${COUNT} tickets!": "Você obteve ${COUNT} tickets!", + "You got ${COUNT} tokens!": "Você ganhou ${COUNT} tokens!", + "You got a ${ITEM}!": "Você ganhou ${ITEM}!", + "You got a chest!": "Você ganhou um baú!", + "You got an achievement reward!": "Você ganhou uma recompensa por conquista!", + "You have been promoted to a new league; congratulations!": "Você foi promovido a uma nova liga; parabéns!", + "You lost a chest! (All your chest slots were full)": "Você perdeu um baú! (Todos os seus espaços de baú estavam cheios)", + "You must update the app to view this.": "Você deve atualizar o aplicativo para visualizar isso.", + "You must update to a newer version of the app to do this.": "Você deve atualizar para uma nova versão do aplicativo para fazer isso.", + "You must update to the newest version of the game to do this.": "Você deve atualizar para a nova versão do jogo para fazer isso.", + "You must wait a few seconds before entering a new code.": "Você deve esperar alguns segundos antes de inserir um novo código.", + "You placed #${RANK} in a tournament!": "Você ficou com #${RANK} em um torneio!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Você teve a classificação #${RANK} no último torneio. Obrigado por jogar!", + "Your account was rejected. Are you signed in?": "Sua conta foi rejeitada. Você iniciou a sessão?", + "Your ad views are not registering. Ad options will be limited for a while.": "Suas visualizações de anúncio não estão registrando. As opções de anúncio serão limitadas por um tempo.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Sua copia do jogo foi modificada.\nReverta as modificações e tente novamente.", + "Your friend code was used by ${ACCOUNT}": "Seu código de amigo foi usado por ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 minuto", + "1 Second": "1 segundo", + "10 Minutes": "10 minutos", + "2 Minutes": "2 minutos", + "2 Seconds": "2 segundos", + "20 Minutes": "20 minutos", + "4 Seconds": "4 segundos", + "5 Minutes": "5 minutos", + "8 Seconds": "8 segundos", + "Allow Negative Scores": "Permitir Pontuação Negativa", + "Balance Total Lives": "Saldo Total de Vidas", + "Bomb Spawning": "Bombas Surgindo", + "Chosen One Gets Gloves": "O escolhido obtém luvas", + "Chosen One Gets Shield": "O escolhido obtém escudo", + "Chosen One Time": "Hora do Escolhido", + "Enable Impact Bombs": "Ativar bombas de impacto", + "Enable Triple Bombs": "Ativar tribombas", + "Entire Team Must Finish": "A equipe inteira precisa terminar", + "Epic Mode": "Modo Épico", + "Flag Idle Return Time": "Tempo para Retornar a Bandeira Inativa", + "Flag Touch Return Time": "Tempo para Retornar a Bandeira", + "Hold Time": "Tempo de retenção", + "Kills to Win Per Player": "Mortes para Ganhar Por Jogador", + "Laps": "Voltas", + "Lives Per Player": "Vidas por jogador", + "Long": "Longo", + "Longer": "Mais longo", + "Mine Spawning": "Minas surgindo", + "No Mines": "Sem minas", + "None": "Nenhum", + "Normal": "Normal", + "Pro Mode": "Modo Pro", + "Respawn Times": "Contagem de Renascimentos", + "Score to Win": "Pontuação para Ganhar", + "Short": "Curto", + "Shorter": "Mais curto", + "Solo Mode": "Modo Solo", + "Target Count": "Número de Alvos", + "Time Limit": "Limite de Tempo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} está em desvantagem porque ${PLAYER} saiu", + "Killing ${NAME} for skipping part of the track!": "Matando ${NAME} por cortar o caminho!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Aviso para ${NAME}: o turbo / spam de botão faz você sair." + }, + "teamNames": { + "Bad Guys": "Inimigos", + "Blue": "Azul", + "Good Guys": "Aliados", + "Red": "Vermelho" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Se você bater, correr, pular e girar em perfeita sincronia poderá matar\nem um único golpe e garantir o respeito eterno de seus amigos.", + "Always remember to floss.": "Lembre-se de sempre usar fio dental.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crie perfis de jogadores para você e seus amigos com\nseus nomes preferidos e aparências ao invés de usar os aleatórios.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Caixas amaldiçoadas o transformam em uma bomba-relógio.\nA única cura é agarrar rapidamente um pacote de saúde.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Apesar de suas aparências, as habilidades de todos os personagens são idênticas,\nentão basta escolher qualquer um que você mais se assemelha.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Não fique muito convencido com o escudo de energia; você ainda pode ser arremessado de um penhasco.", + "Don't run all the time. Really. You will fall off cliffs.": "Não corra o tempo todo. Sério. Você vai cair de penhascos.", + "Don't spin for too long; you'll become dizzy and fall.": "Não gire por muito tempo; você vai ficar tonto e cair!", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pressione qualquer botão para correr. (Botões de gatilho funcionam bem, se os tiver)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantenha pressionado qualquer botão para correr. Você vai alcançar lugares mais\nrapidamente, mas não vai fazer curvas muito bem, por isso esteja atento para penhascos.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "As bombas de gelo não são muito poderosas, mas elas congelam\nquem for atingido, deixando-os vulneráveis ​​a estilhaçamentos.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Se alguém te levantar, soque-o e ele irá te largar.\nIsso também funciona na vida real.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Se você está sem controles, instale o aplicativo '${REMOTE_APP_NAME}'\nem seus dispositivos móveis para usá-los como controles.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Se você tiver uma bomba grudenta presa em você, salte e gire em círculos. Você pode\nsacudir a bomba para fora ou, pelo menos, seus últimos momentos serão divertidos.", + "If you kill an enemy in one hit you get double points for it.": "Se você matar um inimigo com um golpe, você obtêm o dobro de pontos por isso.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Se você pegar uma maldição, sua única esperança de sobrevivência é\nencontrar um poder de saúde nos próximos segundos.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Se você ficar em um lugar, você está frito. Corra e se esquive para sobreviver.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se você tem muitos jogadores entrando e saindo, ligue 'Expulsar Jogadores Ociosos Automaticamente'\nnas configurações no caso de alguém esquecer de deixar o jogo.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se seu dispositivo ficar muito quente ou você quiser conservar bateria,\nabaixe os \"Visuais\" ou \"Resolução\" nas Configurações-> Graficos", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se sua taxa de quadros estiver baixa, tente diminuir a resolução\nou visuais nas configurações gráficas do jogo.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Em Capture a bandeira, a sua própria bandeira deve estar em sua base para marcar. Se a outra\nequipe está prestes a marcar, roubar a sua bandeira pode ser uma boa maneira de detê-los.", + "In hockey, you'll maintain more speed if you turn gradually.": "No hóquei, você manterá mais velocidade se girar gradualmente.", + "It's easier to win with a friend or two helping.": "É mais fácil ganhar com um ou dois amigos ajudando.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Apenas salte enquanto você está arremessando para conseguir bombas até os níveis mais altos.", + "Land-mines are a good way to stop speedy enemies.": "Minas terrestres são uma boa maneira de parar inimigos rápidos.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muitas coisas podem ser apanhadas e lançadas, incluindo outros jogadores. Jogar\nos seus inimigos de penhascos pode ser uma estratégia eficaz e emocionalmente gratificante.", + "No, you can't get up on the ledge. You have to throw bombs.": "Não, você não pode levantar-se na borda. Você tem que jogar bombas.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jogadores podem entrar e sair no meio da maioria dos jogos,\ne você também pode ligar ou desligar controles quando quiser.", + "Practice using your momentum to throw bombs more accurately.": "Pratique usando a inércia para arremessar bombas com maior precisão.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Socos fazem mais danos quanto mais rápido os punhos estão se movendo,\nentão tente correr, pular e girar como um louco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corra para frente e para trás antes de arremessar uma bomba\npara 'chicoteá-la' e jogá-la longe.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimine um grupo de inimigos ao\ndesencadear uma bomba perto de uma caixa de TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "A cabeça é a área mais vulnerável, portanto uma bomba grudenta\nna cuca geralmente significa fim de jogo.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nível nunca termina, mas uma alta pontuação aqui\nfaz você ganhar respeito eterno por todo o mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Força de arremesso baseia-se na direção em que você está pressionando.\nPara arremessar algo suavemente na sua frente, não pressione qualquer direção.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Cansado das músicas? Troque-as pelas suas próprias!\nVeja em Configurações-> Áudio-> Músicas", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Experimente 'cozinhar' bombas por um segundo ou dois antes de jogá-las.", + "Try tricking enemies into killing eachother or running off cliffs.": "Tente enganar inimigos para se matarem ou se jogarem do precipício.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Use o botão pegar para pegar a bandeira < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Balance para trás e para frente para fazer arremessos distantes..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Você pode 'mirar' seus socos girando para esquerda ou direita.\nIsso é útil para derrubar inimigos das beiradas ou marcar no hóquei.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Você pode avaliar quando uma bomba vai explodir baseado na\ncor das faíscas do pavio: amarelo..laranja..vermelho..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Você pode jogar as bombas mais alto ao saltar logo antes de arremessar.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Você se fere quando você bate sua cabeça em coisas,\nassim tente não bater sua cabeça em coisas.", + "Your punches do much more damage if you are running or spinning.": "Seus socos causam muito mais dano se você estiver correndo ou girando." + } + }, + "trophiesRequiredText": "Isso necessita de pelo menos ${NUMBER} troféus.", + "trophiesText": "Troféus", + "trophiesThisSeasonText": "Troféus nesta temporada", + "tutorial": { + "cpuBenchmarkText": "Rodando o tutorial numa velocidade MUITO baixa (para testar o processador)", + "phrase01Text": "Olá!", + "phrase02Text": "Bem-vindo ao ${APP_NAME}!", + "phrase03Text": "Aqui estão algumas dicas para controlar seu personagem:", + "phrase04Text": "Muitas coisas no ${APP_NAME} são baseadas na física.", + "phrase05Text": "Por exemplo, quando você soca,..", + "phrase06Text": "..o dano é baseado na velocidade de seus punhos.", + "phrase07Text": "Viu? Nós não estávamos nos movendo então mal fez cócegas no ${NAME}.", + "phrase08Text": "Agora vamos pular e girar para ganhar mais velocidade.", + "phrase09Text": "Ah, assim é melhor.", + "phrase10Text": "Correr ajuda também.", + "phrase11Text": "Mantenha QUALQUER botão pressionado para correr.", + "phrase12Text": "Para socos adicionais incríveis, tente correr e girar.", + "phrase13Text": "Ops! foi mal aí, ${NAME}.", + "phrase14Text": "Você pode pegar e jogar coisas como bandeiras.. ou ${NAME}.", + "phrase15Text": "Por último, há bombas.", + "phrase16Text": "Arremessar bombas requer prática.", + "phrase17Text": "Ai! Não foi um arremesso muito bom.", + "phrase18Text": "Movimentar-se te ajuda a arremessar mais longe.", + "phrase19Text": "Saltar ajuda você a arremessar mais alto.", + "phrase20Text": "Gire e corra e suas bombas irão ainda mais longe.", + "phrase21Text": "Calcular o tempo da explosão pode ser complicado.", + "phrase22Text": "Droga!", + "phrase23Text": "Tente deixar o pavio queimar por um ou dois segundos.", + "phrase24Text": "Eba! No tempo ideal.", + "phrase25Text": "Bem, acho que é só isso.", + "phrase26Text": "Agora vai lá e arrebenta!", + "phrase27Text": "Lembre-se do seu treinamento e você voltará vivo!", + "phrase28Text": "...bem, talvez...", + "phrase29Text": "Boa sorte!", + "randomName1Text": "Fernando", + "randomName2Text": "Henrique", + "randomName3Text": "Guilherme", + "randomName4Text": "Carlos", + "randomName5Text": "Felipe", + "skipConfirmText": "Você deseja realmente pular o tutorial? Toque ou aperte confirmar.", + "skipVoteCountText": "${COUNT}/${TOTAL} votos para pular", + "skippingText": "pulando o tutorial...", + "toSkipPressAnythingText": "(pressione qualquer coisa para pular o tutorial)" + }, + "twoKillText": "MATOU DOIS!", + "uiScaleText": "Tamanho da Interface", + "unavailableText": "indisponível", + "unclaimedPrizesText": "Você possui prêmios não resgatados!", + "unconfiguredControllerDetectedText": "Controle não configurado detectado:", + "unlockThisInTheStoreText": "Isto deve ser desbloqueado na loja.", + "unlockThisProfilesText": "Para criar mais que ${NUM} perfis, você precisa:", + "unlockThisText": "Para desbloquear isso:", + "unsupportedControllerText": "Desculpe, o controlador \"${NAME}\" não é compatível.", + "unsupportedHardwareText": "Desculpe, este hardware não é suportado por esta versão do jogo.", + "upFirstText": "Em primeiro lugar:", + "upNextText": "O próximo jogo em ${COUNT}:", + "updatingAccountText": "Atualizando sua conta...", + "upgradeText": "Aprimorar", + "upgradeToPlayText": "Atualize para \"${PRO}\" na loja para jogar.", + "useDefaultText": "Usar Padrão", + "userSystemScriptsCreateText": "Criar Scripts do Sistema do Usuário", + "userSystemScriptsDeleteText": "Deletar Scripts do Sistema do Usuário", + "usesExternalControllerText": "Este jogo usa um controle externo para entrada.", + "usingItunesText": "Usando o app de música para a trilha sonora", + "v2AccountLinkingInfoText": "Para vincular contas V2, use o botão 'Gerenciar conta'.", + "v2AccountRequiredText": "Isso requer uma conta V2. Atualize sua conta e tente novamente.", + "validatingTestBuildText": "Validando Versão de Teste...", + "viaText": "via", + "victoryText": "Vitória!", + "voteDelayText": "Você não pode começar outra votação por ${NUMBER} segundo(s)", + "voteInProgressText": "Uma votação já está em progresso.", + "votedAlreadyText": "Você já votou", + "votesNeededText": "${NUMBER} votos necessários", + "vsText": "vs.", + "waitingForHostText": "(esperando ${HOST} continuar)", + "waitingForPlayersText": "esperando os jogadores entrarem...", + "waitingInLineText": "Esperando na fila (o grupo está cheio)...", + "watchAVideoText": "Ver um vídeo", + "watchAnAdText": "Assistir uma propaganda.", + "watchWindow": { + "deleteConfirmText": "Excluir \"${REPLAY}\"?", + "deleteReplayButtonText": "Excluir\nReplay", + "myReplaysText": "Meus replays", + "noReplaySelectedErrorText": "Nenhum replay selecionado.", + "playbackSpeedText": "Velocidade de reprodução: ${SPEED}", + "renameReplayButtonText": "Renomear\nReplay", + "renameReplayText": "Renomear \"${REPLAY}\" para:", + "renameText": "Renomear", + "replayDeleteErrorText": "Erro ao excluir o replay.", + "replayNameText": "Nome do replay", + "replayRenameErrorAlreadyExistsText": "Um replay com este nome já existe.", + "replayRenameErrorInvalidName": "Não foi possível renomear; nome invalido.", + "replayRenameErrorText": "Erro ao renomear replay.", + "sharedReplaysText": "Replays compartilhados", + "titleText": "Assistir", + "watchReplayButtonText": "Assistir\nReplay" + }, + "waveText": "Onda", + "wellSureText": "Claro!", + "whatIsThisText": "Oque é isto?", + "winsPlayerText": "${NAME} venceu!", + "winsTeamText": "${NAME} venceu!", + "winsText": "${NAME} ganhou!", + "workspaceSyncErrorText": "Erro ao sincronizar ${WORKSPACE}. Veja o log para mais detalhes.", + "workspaceSyncReuseText": "Não pôde sincronizar ${WORKSPACE}. Reusando uma versão anterior sincronizada.", + "worldScoresUnavailableText": "Pontuações mundiais indisponíveis.", + "worldsBestScoresText": "Melhores Pontuações do Mundo", + "worldsBestTimesText": "Melhores Tempos do Mundo", + "yesAllowText": "Sim, Permitir!", + "yourBestScoresText": "Suas Melhores Pontuações", + "yourBestTimesText": "Seus Melhores Tempos", + "yourPrizeText": "Seu prêmio:" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/romanian.json b/dist/ba_data/data/languages/romanian.json index 0b007396..7e2d6ede 100644 --- a/dist/ba_data/data/languages/romanian.json +++ b/dist/ba_data/data/languages/romanian.json @@ -8,7 +8,9 @@ "changeOncePerSeason": "Acest lucru poate fi schimbat o singură dată pe sezon.", "changeOncePerSeasonError": "Trebuie să aștepți până la următorul sezon (timp de ${NUM} (de) zile) dacă vrei să schimbi acest lucru din nou", "customName": "Nume Personalizat", + "deleteAccountText": "Șterge contul", "deviceSpecificAccountText": "Foloseşti un cont specific dispozitivului: ${NAME}", + "googlePlayGamesAccountSwitchText": "Dacă doriți să utilizați un alt cont Google,\nutilizați aplicația Jocuri Google Play pentru a comuta.", "linkAccountsEnterCodeText": "Introdu Codul", "linkAccountsGenerateCodeText": "Generează Codul", "linkAccountsInfoText": "(împărtășeşte-ți progresul făcut pe platforme diferite)", @@ -16,6 +18,7 @@ "linkAccountsInstructionsText": "Pentru a conecta 2 conturi, generează un cod pe\nunul din ele şi introdu acelmcod pe celălalt.\nProgresul şi inventarul tău vor fi combinate.\nPoți conecta până la ${COUNT} conturi.\n\nAi grijă; acest lucru nu poate fi şters!", "linkAccountsText": "Conectează Conturi", "linkedAccountsText": "Conturi Conectate:", + "manageAccountText": "Gestionează contul", "nameChangeConfirm": "Vrei să schimbi numele contului tău în ${NAME}?", "resetProgressConfirmNoAchievementsText": "Această acțiune îți va reseta progresul co-op\nși high-score-urile locale (dar nu și biletele).\nAcest lucru nu este reversibil. Sigur vrei să continui?", "resetProgressConfirmText": "Această acțiune îți va reseta progresul\nco-op, realizările și high-score-urile\n(dar nu și biletele). Acest lucru nu\neste reversibil. Ești sigur(ă) că vrei să continui?", @@ -24,14 +27,16 @@ "setAccountNameDesc": "Scrie un nume dorit de tine care vrei să se afișeze pe contul tău.\nPoți folosi și numele unui alt cont conectat de tine\nsau poți să creezi un nume unic personalizat.", "signInInfoText": "Conectează-te cu un cont pentru a colecta bilete, a concura online,\nşi pentru a te juca cu acelaşi cont pe dispozitive diferite.", "signInText": "Conectează-te", + "signInWithAnEmailAddressText": "Conectați-vă cu o adresă de e-mail", "signInWithDeviceInfoText": "(un cont automat care este disponibil doar pe acest dispozitiv)", "signInWithDeviceText": "Conectează-te cu contul dispozitivului", "signInWithGameCircleText": "Conectează-te cu Game Circle", "signInWithGooglePlayText": "Conectează-te cu Google Play", "signInWithTestAccountInfoText": "(tip de cont normal; foloseşte conturile de tip 'dispozitiv' şi cele noi)", "signInWithTestAccountText": "Conectează-te cu un cont de test", + "signInWithText": "Conectați-vă alb ${SERVICE}", "signInWithV2InfoText": "(un cont care funcționează pe toate platformele)", - "signInWithV2Text": "Conectează-te cu un cont Bombsquad", + "signInWithV2Text": "Conectați-vă cu un cont ${APP_NAME}", "signOutText": "Deconectează-te", "signingInText": "Se conectează...", "signingOutText": "Se deconectează...", @@ -42,6 +47,7 @@ "titleText": "Contul tău", "unlinkAccountsInstructionsText": "Selectează un cont pentru a-l deconecta", "unlinkAccountsText": "Deconectează Conturi", + "unlinkLegacyV1AccountsText": "Deconectați conturile vechi (V1).", "v2LinkInstructionsText": "Folosește acest link pentru a creea un cont sau pentru a te autentifica.", "viaAccount": "(prin contul ${NAME})", "youAreSignedInAsText": "Ești conectat ca și:" @@ -335,9 +341,14 @@ "getMoreGamesText": "Ia mai multe MiniJocuri...", "titleText": "Adaugă un joc" }, + "addToFavoritesText": "Adauga la favorite", + "addedToFavoritesText": "S-a adăugat '${NAME}' la Favorite.", + "allText": "Toate", "allowText": "Permite", "alreadySignedInText": "Contul tău este deja conectat de pe un alt dispozitiv;\nte rog să schimbi conturile sau să închizi jocul de pe\nalte dispozitive și să încerci din nou.", "apiVersionErrorText": "Nu se poate încărca modulul ${NAME}; acesta țintește versiunea API ${VERSION_USED}, iar versiunea ${VERSION_REQUIRED} nu îl mai suportă.", + "applyText": "Aplicați", + "areYouSureText": "Sunteți sigur?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" activează asta doar când căștile sunt conectate)", "headRelativeVRAudioText": "Audio VR relativ capului", @@ -360,7 +371,7 @@ "boostText": "Crește", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} este configurat în aplicația în sine.", "buttonText": "buton", - "canWeDebugText": "Ai vrea ca BombSquad să trimită automat bug-uri,\ncrash-uri și informații de bază programatorului jocului?\n\nAceste informații nu conțin date personale, ci doar\najută la îmbunătățirea jocului.", + "canWeDebugText": "Doriți ca ${APP_NAME} să raporteze automat bug-uri,\ncrash-uri și informații de bază pentru dezvoltator?\n\nAceste informații nu conțin date personale, ci doar\najută la îmbunătățirea jocului.", "cancelText": "Anulează", "cantConfigureDeviceText": "Scuze, dar ${DEVICE} nu este configurabil.", "challengeEndedText": "Acest concurs s-a terminat.", @@ -368,6 +379,8 @@ "chatMutedText": "Chat-ul Este Amuțit", "chatUnMuteText": "Dezamuțește Chat-ul", "choosingPlayerText": "", + "claimText": "Revendică", + "codesExplainText": "Codurile sunt furnizate de dezvoltator pentru\ndiagnosticați și corectați problemele legate de cont.", "completeThisLevelToProceedText": "Trebuie să completezi\nacest nivel pentru a continua!", "completionBonusText": "Bonus De Completare", "configControllersWindow": { @@ -448,6 +461,7 @@ "swipeText": "glisare", "titleText": "Configurează Touchscreen-ul" }, + "configureDeviceInSystemSettingsText": "${DEVICE} poate fi configurat în Setări.", "configureItNowText": "Vrei să îl configurezi acum?", "configureText": "Configurează", "connectMobileDevicesWindow": { @@ -502,6 +516,7 @@ "welcome2Text": "Mai poți primi bilete şi prin alte activități de acelaşi fel.\nBiletele se pot folosi pentru a debloca charactere, hărți,\nmini-jocuri, pentru a intra în concursurii, şi multe altele.", "yourPowerRankingText": "Rankul tău de Putere:" }, + "copyConfirmText": "Copiat în clipboard.", "copyOfText": "Copie de ${NAME}", "copyText": "Copiază", "createEditPlayerText": "", @@ -548,7 +563,10 @@ "deleteText": "Șterge", "demoText": "Demo", "denyText": "Refuză", + "deprecatedText": "Depreciat", + "descriptionText": "Descriere", "desktopResText": "Rezoluție Desktop", + "deviceAccountUpgradeText": "Avertizare:\nSunteți conectat cu un cont de dispozitiv (${NAME}).\nConturile de dispozitiv vor fi eliminate într-o actualizare viitoare.\nFaceți upgrade la un cont V2 dacă doriți să vă păstrați progresul.", "difficultyEasyText": "Ușor", "difficultyHardOnlyText": "Numai pe \"Greu\"", "difficultyHardText": "Greu", @@ -557,6 +575,10 @@ "disableRemoteAppConnectionsText": "Dezactivează conexiunile de pe Remote-App", "disableXInputDescriptionText": "Permite mai mult de 4 controlere dar nu va merge chiar așa de bine.", "disableXInputText": "Dezactivează XInput", + "disabledText": "Dezactivat", + "discardText": "Înlătură", + "discordFriendsText": "Vrei să gasești oameni noi cu care să te joci?\nAlăturați-vă Serverul de Discord al nostru și găsiți noi prieteni!", + "discordJoinText": "Alăturați-vă Discordului", "doneText": "Gata", "drawText": "Remiză", "duplicateText": "Multiplică", @@ -590,6 +612,7 @@ "localProfileText": "(profil local)", "nameDescriptionText": "Numele Jucătorului", "nameText": "Nume", + "profileAlreadyExistsText": "Un profil cu acest nume există deja.", "randomText": "auto-generat", "titleEditText": "Editează profilul", "titleNewText": "Profil nou", @@ -625,12 +648,13 @@ "useMusicFolderText": "Dosar cu Fişiere Audio" }, "editText": "Editează", + "enabledText": "Activat", "endText": "Sfârșește", "enjoyText": "Bucură-te!", "epicDescriptionFilterText": "${DESCRIPTION} În slow motion epic.", "epicNameFilterText": "${NAME} Epic", "errorAccessDeniedText": "acces respins", - "errorDeviceTimeIncorrectText": "Ceasul dispozitivului tău este dat înainte sau înapoi cu ${HOURS} ore.\nAcestu lucru ar putea cauza niște probleme.\nTe rog să verifici setările ceasului și ale fusului orar.", + "errorDeviceTimeIncorrectText": "Ceasul dispozitivului tău este incorrect cu ${HOURS} ore.\nAcest lucru ar putea cauza niște probleme.\nTe rog să verifici setările ceasului și ale fusului orar.", "errorOutOfDiskSpaceText": "ai rămas fără memorie", "errorSecureConnectionFailText": "Nu s-a putut stabili o conexiune sigură cloud; funcționalitatea internetului ar putea eșua.", "errorText": "Eroare", @@ -670,6 +694,8 @@ "duplicateText": "Duplică\nLista de Jocuri", "editText": "Editează\nLista de Jocuri", "newText": "Listă de Jocuri\nNouă", + "pointsToWinText": "Puncte pentru a câștiga", + "seriesLengthText": "Lungimea seriei", "showTutorialText": "Arată Tutorialul", "shuffleGameOrderText": "Jocuri Aleatorii", "titleText": "Particularizează Listele de Jocuri de tip \"${TYPE}\"" @@ -743,6 +769,7 @@ "manualYourLocalAddressText": "Adresa ta locală:", "nearbyText": "Din apropiere", "noConnectionText": "", + "noPartiesAddedText": "Nu au fost adăugate părți", "otherVersionsText": "(alte versiuni)", "partyCodeText": "Codul Server-ului", "partyInviteAcceptText": "Acceptă", @@ -807,17 +834,26 @@ "youHaveShortText": "ai ${COUNT}", "youHaveText": "ai ${COUNT} (de) bilete" }, + "goldPass": { + "desc1InfTokensText": "Jetoane infinite.", + "desc2NoAdsText": "Fără reclame.", + "desc3ForeverText": "Pentru totdeauna.", + "goldPassText": "Pass de Aur" + }, "googleMultiplayerDiscontinuedText": "Ne pare rău, serviciul multiplayer de pe Google nu mai este disponibil.\nLucrez la un înlocuitor cât mai repede posibil.\nPână atunci, te rog să încerci o altă metodă de conectare.\n-Eric", "googlePlayPurchasesNotAvailableText": "Achizițiile de pe Google Play nu sunt disponibile.\nÎncearcă să actualizezi Magazin Play și să încerci din nou.", + "googlePlayServicesNotAvailableText": "Serviciile Google Play nu sunt disponibile.\nEste posibil ca unele funcționalități ale aplicației să fie dezactivate.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Întotdeauna", "fullScreenCmdText": "Fullscreen (Cmd+F)", "fullScreenCtrlText": "Fullscreen (Ctrl+F)", + "fullScreenText": "Ecran complet", "gammaText": "Luminozitate", "highText": "Înalte", "higherText": "Mai Înalte", "lowText": "Slabe", + "maxFPSText": "Maxim de FPS", "mediumText": "Medii", "neverText": "Niciodată", "resolutionText": "Rezoluție", @@ -879,6 +915,7 @@ "importText": "Importă", "importingText": "Se importă...", "inGameClippedNameText": "va arăta astfel\n\"${NAME}\"", + "inboxText": "Mesaje", "installDiskSpaceErrorText": "EROARE: Nu s-a putut completa instalarea.\nSe poate să fi rămas fără spațiu pe dispozitiv.\nEliberează niște spațiu și încearcă din nou.", "internal": { "arrowsToExitListText": "Apasă ${LEFT} sau ${RIGHT} pentru a ieși din listă", @@ -987,6 +1024,7 @@ "tournamentLeagueText": "Trebuie să ajungi în liga ${NAME} dacă vrei să intri în acest turneu.", "trophyCountsResetText": "Numărul de trofee se va reseta la sfârșitul sezonului." }, + "learnMoreText": "Află mai multe", "levelBestScoresText": "Cele mai bune scoruri din ${LEVEL}", "levelBestTimesText": "Cele mai scurte timpuri din ${LEVEL}", "levelFastestTimesText": "Cel mai rapid timp pe ${LEVEL}", @@ -1008,6 +1046,7 @@ "creditsText": "Credite", "demoMenuText": "Meniu Demonstrativ", "endGameText": "Sfârșește Jocul", + "endTestText": "Încheierea testului", "exitGameText": "Ieși Din Joc", "exitToMenuText": "Revii la meniu?", "howToPlayText": "Cum se Joacă?", @@ -1027,6 +1066,7 @@ "maxConnectionsText": "Număr De Locuri", "maxPartySizeText": "Număr Maxim De Locuri", "maxPlayersText": "Locuri", + "merchText": "Merch!", "modeArcadeText": "Mod Pentru Arcade", "modeClassicText": "Modul Clasic", "modeDemoText": "Modul Demonstrativ", @@ -1046,6 +1086,7 @@ "nameSuicideText": "${NAME} s-a sinucis.", "nameText": "Numele", "nativeText": "Nativă", + "newExclaimText": "Nou!", "newPersonalBestText": "Un nou record personal a fost atins!", "newTestBuildAvailableText": "O nouă versiune de test a fost lansată: (${VERSION} build ${BUILD}).\nIa-o de pe ${ADDRESS}", "newText": "Nou", @@ -1056,17 +1097,22 @@ "noContinuesText": "(fără continuări)", "noExternalStorageErrorText": "Nu a fost găsită nicio stocare externă pe acest dispozitiv.", "noGameCircleText": "Eroare: nu eşti logat cu GameCircle", + "noMessagesText": "Niciun mesaj.", + "noPluginsInstalledText": "Nu au fost instalate pluginuri", "noProfilesErrorText": "Nu ai niciun Profil de Jucător, deci eşti blocat cu '${NAME}'.\nDute la Setări->Profile de Jucător pentru a-ți face un profil.", "noScoresYetText": "Niciun scor deocamdată.", + "noServersFoundText": "Nu au fost găsite servere.", "noThanksText": "Nu Mulțumesc", "noTournamentsInTestBuildText": "ATENȚIE: Scorurile obținute în turnee vor fi ignorate în această versiune de test.", "noValidMapsErrorText": "Nu sunt hărți disponibile pentru acest mod de joc.", "notEnoughPlayersRemainingText": "Nu mai sunt destui jucători; ieși din joc și creează altul nou.", "notEnoughPlayersText": "Ai nevoie de cel puțin ${COUNT} jucători pentru a începe acest joc!", + "notEnoughTicketsText": "Bilete insuficiente!", "notNowText": "Nu Acum", "notSignedInErrorText": "Trebuie să fi conectat cu un cont dacă vrei să faci asta.", "notSignedInGooglePlayErrorText": "Trebuie să fii conectat cu Google Play dacă vrei să faci asta.", "notSignedInText": "nu te-ai conectat cu nici un cont", + "notUsingAccountText": "Notă: ignorând contul ${SERVICE}.\nAccesați „Cont -> Conectați-vă cu ${SERVICE}” dacă doriți să îl utilizați.", "nothingIsSelectedErrorText": "Nu ai selectat nimic!", "numberText": "#${NUMBER}", "offText": "Oprit", @@ -1125,7 +1171,11 @@ "pleaseWaitText": "Te rog să aștepți...", "pluginClassLoadErrorText": "Nu s-a putut încărca plugin-ul '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Nu s-a putut iniția plugin-ul '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Setări Plugin", + "pluginsAutoEnableNewText": "Activați Automat Noile Pluginuri", "pluginsDetectedText": "Plugin(uri) noi detectate. Restartează jocul pentru a le activa / configura în setări.", + "pluginsDisableAllText": "Dezactivați Toate Pluginurile", + "pluginsEnableAllText": "Activați Toate Pluginurile", "pluginsRemovedText": "${NUM} plugin(uri) nu mai există.", "pluginsText": "Plugin-uri", "practiceText": "Antrenament", @@ -1158,6 +1208,8 @@ "punchText": "Pumn", "purchaseForText": "Cumpără pentru ${PRICE}", "purchaseGameText": "Cumpără Jocul", + "purchaseNeverAvailableText": "Ne pare rău, achizițiile nu sunt disponibile pentru această versiune.\nÎncercați să vă conectați la contul dvs. pe o altă platformă și să faceți achiziții de acolo.", + "purchaseNotAvailableText": "Această achiziție nu este disponibilă.", "purchasingText": "Se cumpără...", "quitGameText": "Ieși din ${APP_NAME}?", "quittingIn5SecondsText": "Se iese în 5 secunde...", @@ -1220,6 +1272,8 @@ "runText": "Pentru a fugi", "saveText": "Salvează", "scanScriptsErrorText": "Una sau mai multe erori au fost detectate în timpul scanării scripturilor; vezi jurnalul de activități pentru detalii.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} și alte ${NUM} module trebuie să fie actualizate pentru api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} trebuie actualizat pentru api ${API}.", "scoreChallengesText": "Provocări de Scor", "scoreListUnavailableText": "Lista de Scoruri este indisponibilă.", "scoreText": "Scor", @@ -1230,6 +1284,7 @@ }, "scoreWasText": "(a fost ${COUNT})", "selectText": "Selectează", + "sendInfoDescriptionText": "Trimite dezvoltatorului informații despre starea contului și a aplicației.\nVă rugăm să includeți numele sau motivul trimiterii.", "seriesWinLine1PlayerText": "CÂŞTIGĂ", "seriesWinLine1TeamText": "CÂŞTIGĂ", "seriesWinLine1Text": "CÂŞTIGĂ", @@ -1248,6 +1303,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(o tastatură simplă, folositoare pentru controllere, care ajută la editarea textului)", "alwaysUseInternalKeyboardText": "Foloseşte Mereu Tastatura Internală", "benchmarksText": "Teste-Stres & Referințe", + "devToolsText": "Instrumente de dezvoltare", "disableCameraGyroscopeMotionText": "Oprește Mișcarea Camerei De Tip Giroscop", "disableCameraShakeText": "Dezactivează Cutremurarea Camerei", "disableThisNotice": "(Poți dezactiva această notificare în setările avansate)", @@ -1256,14 +1312,22 @@ "enterPromoCodeText": "Introdu un cod", "forTestingText": "Notă: aceste valori sunt doar pentru teste şi vor fi resetate când jocul va fi închis.", "helpTranslateText": "Translațiile din ${APP_NAME} sunt un efort depus de comunitate.\nDacă ai dori să te implici la translatarea/corectarea unei limbi,\nurmează linkul de mai jos. Mulțumiri anticipate!", + "insecureConnectionsDescriptionText": "nerecomandat, dar poate permite joaca online \ndin țări și network-uri restricționate", + "insecureConnectionsText": "Folosește conexiuni nesigure", "kickIdlePlayersText": "Dă Afară Jucătorii Inactivi", "kidFriendlyModeText": "Modul Pentru Copii (mai puțină violență, etc)", "languageText": "Limbă", "moddingGuideText": "Ghid pentru Modare", + "moddingToolsText": "Instrumente de modificare", "mustRestartText": "Va trebui să restartezi jocul dacă vrei ca acest lucru să își facă efectul.", "netTestingText": "Testarea Internetului", "resetText": "Resetează", + "sendInfoText": "Trimiteți informații", "showBombTrajectoriesText": "Arată Traiectoriile Bombelor", + "showDemosWhenIdleText": "Afișați demo-uri când este inactiv", + "showDeprecatedLoginTypesText": "Afișați tipurile de conectare învechite", + "showDevConsoleButtonText": "Afișați dev console button", + "showInGamePingText": "Afișează ping-ul în joc", "showPlayerNamesText": "Arată Numele Jucătorilor", "showUserModsText": "Arată Folderul Pentru Moduri", "titleText": "Avansat", @@ -1282,6 +1346,9 @@ "signInWithGameCenterText": "Pentru a folosi un cont Game Center\nconectează-te folosind aplicația Game Center.", "singleGamePlaylistNameText": "Doar ${GAME}", "singlePlayerCountText": "1 jucător", + "sizeLargeText": "Mare", + "sizeMediumText": "Mediu", + "sizeSmallText": "Mic", "soloNameFilterText": "${NAME} Solo", "soundtrackTypeNames": { "CharSelect": "Selecția Caracterului", @@ -1357,6 +1424,8 @@ "storeText": "Magazin", "submitText": "Trimite", "submittingPromoCodeText": "Se trimite Codul...", + "successText": "Succes!", + "supportEmailText": "Dacă întâmpinați probleme cu\naplicația, vă rugăm să trimiteți un e-mail la ${EMAIL}.", "teamNamesColorText": "Numele/Culorile Echipelor", "telnetAccessGrantedText": "Acces la Telnet permis.", "telnetAccessText": "Acces Telnet detectat; îl permiți?", @@ -1376,6 +1445,17 @@ "tipText": "Sfat", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Obțineți jetoane", + "notEnoughTokensText": "Insuficiente jetoane!", + "numTokensText": "${COUNT} Jetoane", + "shinyNewCurrencyText": "Noua monedă strălucitoare a BombSquad-ului.", + "tokenPack1Text": "Pachet mic de jetoane", + "tokenPack2Text": "Pachet mediu de jetoane", + "tokenPack3Text": "Pachet mare de jetoane", + "tokenPack4Text": "Pachet de jetoane Jumbo", + "youHaveGoldPassText": "Ai un permis de aur.\nToate achizițiile de jetoane sunt gratuite.\nBucurați-vă!" + }, "topFriendsText": "Prieteni de Top", "tournamentCheckingStateText": "Se verifică starea campionatului; aşteaptă...", "tournamentEndedText": "Acest turneu s-a terminat. Altul nou va începe în curând.", @@ -1384,6 +1464,7 @@ "tournamentStandingsText": "Clasamentele Turneului", "tournamentText": "Turneu", "tournamentTimeExpiredText": "Timpul Turneului a Expirat", + "tournamentsDisabledWorkspaceText": "Turneele sunt dezactivate atunci când spațiile de lucru sunt active.\nPentru a reactiva turneele, dezactivați spațiul de lucru și reporniți.", "tournamentsText": "Turnee", "translations": { "characterNames": { @@ -1536,7 +1617,9 @@ "Italian": "Italiană", "Japanese": "Japoneză", "Korean": "Coreană", + "Malay": "Malaeză", "Persian": "Persană", + "PirateSpeak": "Limba Piraților", "Polish": "Poloneză", "Portuguese": "Portugheză", "Romanian": "Română", @@ -1650,6 +1733,7 @@ "You got ${COUNT} tickets!": "Ai primit ${COUNT} (de) bilete!", "You got a ${ITEM}!": "Ai primit 1 ${ITEM}!", "You have been promoted to a new league; congratulations!": "Ai fost promovat la o ligă noua; felicitări!", + "You must update the app to view this.": "Trebuie să actualizezi aplicația pentru a vedea asta.", "You must update to a newer version of the app to do this.": "Trebuie să-ți actualizezi aplicația la o versiune mai nouă pentru a face asta.", "You must update to the newest version of the game to do this.": "Trebuie să-ți actualizezi jocul la o versiune mai nouă pentru a face asta.", "You must wait a few seconds before entering a new code.": "Va trebui să aştepți câteva secunde înainte să introduci un cod nou.", @@ -1804,11 +1888,13 @@ "toSkipPressAnythingText": "(apasă orice buton pentru a trece peste tutorial)" }, "twoKillText": "DUBLU OMOR!", + "uiScaleText": "Mărime Interfață", "unavailableText": "indisponibil", "unconfiguredControllerDetectedText": "Controller neconfigurat detectat:", "unlockThisInTheStoreText": "Acest lucru trebuie deblocat din magazin.", "unlockThisProfilesText": "Că să creezi mai mult de ${NUM} profile, va trebui să ai:", "unlockThisText": "Pentru a debloca acest lucru, vei avea nevoie de:", + "unsupportedControllerText": "Ne pare rau, controller-ul \"${NAME}\" nu este suportat", "unsupportedHardwareText": "Scuze, acest hardware nu este suportat de această versiune a jocului.", "upFirstText": "Primul joc:", "upNextText": "Următorul joc cu numărul ${COUNT} este:", @@ -1816,10 +1902,15 @@ "upgradeText": "Îmbunătățeşte", "upgradeToPlayText": "Deblochează \"${PRO}\" în magazinul din joc pentru a juca această hartă.", "useDefaultText": "Folosește Setările Prestabilite", + "userSystemScriptsCreateText": "Creați scripturi de sistem utilizator", + "userSystemScriptsDeleteText": "Ștergeți scripturile de sistem utilizator", "usesExternalControllerText": "Acest joc folosește un controller extern ca dispozitiv de intrare.", "usingItunesText": "Se folosește Aplicația de Muzică pentru soundtrack...", "usingItunesTurnRepeatAndShuffleOnText": "Fii sigur(ă) că shuffle e activat și repeat e pus pe ALL în iTunes.", + "v2AccountLinkingInfoText": "Pentru a conecta conturile V2, utilizați butonul „Gestionați contul\".", + "v2AccountRequiredText": "Acest lucru necesită un cont V2. Actualizați-vă contul și încercați din nou.", "validatingTestBuildText": "Se Validează Versiunea De Test...", + "viaText": "prin", "victoryText": "Victorie!", "voteDelayText": "Poți începe alt vot peste ${NUMBER} (de) secunde", "voteInProgressText": "Un vot este deja în progres.", @@ -1851,6 +1942,7 @@ }, "waveText": "Valul", "wellSureText": "Sigur!", + "whatIsThisText": "Ce este asta?", "wiimoteLicenseWindow": { "titleText": "Copyright de către DarwiinRemote" }, @@ -1878,7 +1970,7 @@ "xbox360ControllersWindow": { "getDriverText": "Instalează Driver-ul.", "macInstructions2Text": "Pentru a folosi controllerele fără fir, vei avea nevoie de un receptor\ncare vine cu pachetul 'Xbox 360 Wireless Controller for Windows'.\nFiecare receptor te lasă să conectezi până la 4 controllere.\n\nImportant: Receptoare de tip 3rd-party nu vor funcționa cu acest driver;\nAsigură-te că pe receptor scrie 'Microsoft', nu 'XBOX 360'.\nMicrosoft nu mai le vinde separat, deci va trebui să iei unul\nîmpreună cu controllerul sau de pe un site, cum ar fi Ebay.\n\nDacă ai găsit acest mesaj folositor, consideră faptul să-i donezi programatorului\ndriverului pe site-ul lui.", - "macInstructionsText": "Pentru a folosi controllere de Xbox 360, va trebui să instalezi \ndriver-ul pentru Mac disponibil din link-ul de mai jos. \nFuncționează pentru controalele cu/fără fir.", + "macInstructionsText": "Pentru a folosi controllere de Xbox 360, va trebui să instalezi \ndriver-ul pentru Mac disponibil din link-ul de mai jos. \nFuncționează pentru controalele cu/fără fir. ", "ouyaInstructionsText": "Pentru a folosi controllere de Xbox 360 cu fir, pur și simplu\nconectează-le la un port USB. Poți folosi un USB-hub pentru a\nconecta mai multe controllere.\n\nPentru a folosi controllere fără fir vei avea nevoie de un receptor\nwireless, valabil ca parte a pachetului \"Xbox 360 wireless controller\nfor Windows\" sau vândut separat. Fiecare receptor intră într-un port\nUSB și te lasă să conectezi până la 4 controllere.", "titleText": "Se folosesc controllere de Xbox 360 cu ${APP_NAME}:" }, diff --git a/dist/ba_data/data/languages/russian.json b/dist/ba_data/data/languages/russian.json index 6c285922..00c52983 100644 --- a/dist/ba_data/data/languages/russian.json +++ b/dist/ba_data/data/languages/russian.json @@ -7,12 +7,14 @@ "campaignProgressText": "Прогресс кампании [Сложный режим]: ${PROGRESS}", "changeOncePerSeason": "Вы можете изменить это только раз в сезон.", "changeOncePerSeasonError": "Вы должны подождать до следующего сезона, чтобы изменить это снова (${NUM} дней)", - "customName": "Имя аккаунта", + "createAnAccountText": "Создать аккаунт", + "customName": "Имя пользователя", + "deleteAccountText": "Удалить аккаунт", "deviceSpecificAccountText": "Сейчас используется аккаунт имениустройства: ${NAME}", - "googlePlayGamesAccountSwitchText": "Если хотите сменить внутриигровой аккаунт Google, используйте приложение Google Play.", + "googlePlayGamesAccountSwitchText": "Если хотите сменить внутриигровой аккаунт Google,\nиспользуйте приложение Google Play.", "linkAccountsEnterCodeText": "Введите код", "linkAccountsGenerateCodeText": "Сгенерировать код", - "linkAccountsInfoText": "(делиться достижениями с другими платформами)", + "linkAccountsInfoText": "(поделитесь достижениями с другими платформами)", "linkAccountsInstructionsNewText": "Чтобы связать два аккаунта, сгенерируйте код на первом\nи введите этот код на втором. Данные из\nвторого аккаунта будут распределены между ними.\n(Данные из первого будут потеряны)\n\nВы можете связать ${COUNT} аккаунтов.\n\nВАЖНО: связывайте только собственные аккаунты;\nЕсли вы свяжетесь с аккаунтами друзей, вы не сможете\nодновременно играть онлайн.", "linkAccountsInstructionsText": "Для связки двух аккаунтов, создайте код на одном\nиз них и введите код на другом.\nПрогресс и инвентарь будут объединены.\nВы можете связать до ${COUNT} аккаунтов.", "linkAccountsText": "Связать акаунты", @@ -23,18 +25,20 @@ "resetProgressConfirmNoAchievementsText": "Это сбросит весь ваш кооперативный прогресс\nи локальные рекорды (но не билеты).\nЭтот процесс необратим. Вы уверены?", "resetProgressConfirmText": "Это сбросит весь ваш кооперативный\nпрогресс, достижения и локальные рекорды\n(кроме билетов). Этот процесс необратим.\nВы уверены?", "resetProgressText": "Сбросить прогресс", - "setAccountName": "Задать имя аккаунта", + "setAccountName": "Напишите имя аккаунта", "setAccountNameDesc": "Выберите имя для отображения своего аккаунта.\nВы можете использовать имя одного из ваших связанных аккаунтов или создать уникальное имя аккаунта.", "signInInfoText": "Войдите в аккаунт, чтобы собирать билеты, \nсоревноваться онлайн и делиться успехами.", "signInText": "Войти", + "signInWithAnEmailAddressText": "Войти через электронную почту", "signInWithDeviceInfoText": "(стандартный аккаунт только для этого устройства)", "signInWithDeviceText": "Войти через аккаунт устройства", "signInWithGameCircleText": "Войти через Game Circle", "signInWithGooglePlayText": "Войти через Google Play", "signInWithTestAccountInfoText": "(устаревший тип аккаунта; в дальнейшем используйте аккаунт устройства)", "signInWithTestAccountText": "Войти через тестовый аккаунт", + "signInWithText": "Войти при помощи ${SERVICE}", "signInWithV2InfoText": "(аккаунт, который работает на всех платформах)", - "signInWithV2Text": "Войти через аккаунт BombSquad", + "signInWithV2Text": "Войти через аккаунт ${APP_NAME}", "signOutText": "Выйти", "signingInText": "Вход...", "signingOutText": "Выход...", @@ -45,7 +49,7 @@ "titleText": "Аккаунт", "unlinkAccountsInstructionsText": "Выберите аккаунт, который хотите отвязать", "unlinkAccountsText": "Отвязать аккаунты", - "unlinkLegacyV1AccountsText": "Разблокируйте устаревшие (V1) аккаунты", + "unlinkLegacyV1AccountsText": "Отвязать устаревшие (V1) аккаунты", "v2LinkInstructionsText": "Используйте эту ссылку чтобы создать аккаунт или войти", "viaAccount": "(через аккаунт ${NAME})", "youAreLoggedInAsText": "Вы зашли как:", @@ -58,7 +62,7 @@ "description": "Убейте 3 негодяев с помощью TNT", "descriptionComplete": "С помощью TNT убито 3 негодяев", "descriptionFull": "Убейте 3 негодяев с помощью TNT на уровне ${LEVEL}", - "descriptionFullComplete": "3 негодяя убито с помощью TNT на уровне ${LEVEL}", + "descriptionFullComplete": "3 негодяев убито с помощью TNT на уровне ${LEVEL}", "name": "Динамит делает “БУМ”!" }, "Boxer": { @@ -75,7 +79,7 @@ }, "Flawless Victory": { "description": "Победите не получив урона", - "descriptionComplete": "Победа без получения урона", + "descriptionComplete": "Победил без получения урона", "descriptionFull": "Пройдите уровень ${LEVEL} не получив урона", "descriptionFullComplete": "Уровень ${LEVEL} пройден без урона", "name": "Чистая победа" @@ -126,18 +130,18 @@ "name": "Волшебник уровня ${LEVEL}" }, "Mine Games": { - "description": "Убейте 3 плохих парней с помощью мин", - "descriptionComplete": "С помощью мин убито 3 негодяя", + "description": "Убейте 3 негодяев с помощью мин", + "descriptionComplete": "С помощью мин убита тройка плохих парней", "descriptionFull": "Убейте 3 негодяев с помощью мин на уровне ${LEVEL}", "descriptionFullComplete": "С помощью мин убито 3 негодяя на уровне ${LEVEL}", "name": "Игры с минами" }, "Off You Go Then": { - "description": "Сбросьте 3 негодяев с карты", - "descriptionComplete": "С карты сброшено 3 негодяя", - "descriptionFull": "Сбросьте 3 негодяев с карты на уровне ${LEVEL}", - "descriptionFullComplete": "3 негодяя сброшено с карты на уровне ${LEVEL}", - "name": "Пора учится летать" + "description": "Сбросьте 3 плохих парней с карты", + "descriptionComplete": "С карты сброшено 3 плохих парней", + "descriptionFull": "Сбросьте 3 плохих парней с карты на уровне ${LEVEL}", + "descriptionFullComplete": "3 плохих парней сброшено с карты на уровне ${LEVEL}", + "name": "Пора учится летать!" }, "Onslaught God": { "description": "Наберите 5000 очков", @@ -186,7 +190,7 @@ "descriptionComplete": "Уровень был пройден всухую", "descriptionFull": "Выиграйте матч ${LEVEL} всухую", "descriptionFullComplete": "Победа в матче ${LEVEL} всухую", - "name": "${LEVEL} всухую" + "name": "${LEVEL} Всухую" }, "Pro Football Victory": { "description": "Выиграйте матч", @@ -197,7 +201,7 @@ }, "Pro Onslaught Victory": { "description": "Победите все волны", - "descriptionComplete": "Пройдены все волны", + "descriptionComplete": "Все волны пройдены!", "descriptionFull": "Победите все волны на уровне ${LEVEL}", "descriptionFullComplete": "Пройдены все волны на ${LEVEL}", "name": "Победа на уровне ${LEVEL}" @@ -218,7 +222,7 @@ }, "Rookie Football Victory": { "description": "Выиграйте матч", - "descriptionComplete": "Матч пройден в вашу пользу", + "descriptionComplete": "Вы одержали победу в матче!", "descriptionFull": "Выиграйте матч ${LEVEL}", "descriptionFullComplete": "Выигран матч ${LEVEL}", "name": "Победа в матче ${LEVEL}" @@ -252,8 +256,8 @@ "name": "Волшебник уровня ${LEVEL}" }, "Sharing is Caring": { - "descriptionFull": "Успешно поделиться игрой с другом", - "descriptionFullComplete": "Игра успешно передана другу", + "descriptionFull": "Успешно поделитесь игрой с другом", + "descriptionFullComplete": "Игра успешно поделена с другом", "name": "Делиться - значит заботиться" }, "Stayin' Alive": { @@ -304,7 +308,7 @@ "name": "Стена" }, "Uber Football Shutout": { - "description": "Выиграйте в сухую", + "description": "Выиграйте всухую", "descriptionComplete": "Победа в сухую", "descriptionFull": "Выиграйте матч ${LEVEL} в сухую", "descriptionFullComplete": "Победа в матче ${LEVEL} в сухую", @@ -337,12 +341,17 @@ "achievementsUnavailableForOldSeasonsText": "К сожалению, подробности достижений не доступны для старых сезонов.", "activatedText": "${THING} активировано.", "addGameWindow": { - "getMoreGamesText": "Еще игры", + "getMoreGamesText": "Больше игр...", "titleText": "Добавить игру" }, + "addToFavoritesText": "Добавить в избранное", + "addedToFavoritesText": "Добавлен '${NAME}' в избранное.", + "allText": "Все", "allowText": "Разрешить", "alreadySignedInText": "С вашего аккаунта играют на другом устройстве;\nпожалуйста зайдите с другого аккаунта или закройте\nигру на другом устройстве и попытайтесь снова.", "apiVersionErrorText": "Невозможно загрузить модуль ${NAME}; он предназначен для API версии ${VERSION_USED}; здесь требуется версия ${VERSION_REQUIRED}.", + "applyText": "Применить", + "areYouSureText": "Вы уверены?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(Режим \"Авто\" активируется только при подключении наушников)", "headRelativeVRAudioText": "Позиционно-зависимое VR-аудио", @@ -367,14 +376,24 @@ "boostText": "Увеличение", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} настраивается в самом приложении.", "buttonText": "кнопка", - "canWeDebugText": "Хотите, чтобы BombSquad автоматически сообщал разработчику\nоб ошибках, сбоях и основную информацию об использовании?\n\nЭти данные не содержат никакой личной информации и помогают\nподдерживать игру в рабочем состоянии без сбоев и ошибок.", + "canWeDebugText": "Хотите, чтобы ${APP_NAME} автоматически сообщал разработчику\nоб ошибках, сбоях и основную информацию об использовании?\n\nЭти данные не содержат никакой личной информации и помогают\nподдерживать игру в рабочем состоянии без сбоев и ошибок.", "cancelText": "Отмена", "cantConfigureDeviceText": "Извините, ${DEVICE} невозможно настроить.", "challengeEndedText": "Это состязание завершено.", "chatMuteText": "Заглушить чат", "chatMutedText": "Чат заглушен", "chatUnMuteText": "Включить чат", + "chests": { + "prizeOddsText": "Награды", + "reduceWaitText": "Ускорить открытие", + "slotDescriptionText": "В этом слоте может находиться сундук.\n\nПолучайте сундуки за уровни кампании, \nместа в турнирах и выполнение \nдостижений.", + "slotText": "Слот сундука ${NUM}", + "slotsFullWarningText": "ВНИМАНИЕ: Ваш инвентарь заполнен.\nЛюбые сундуки, которые вы получите, будут утеряны.", + "unlocksInText": "Отпирается в" + }, "choosingPlayerText": "<выбор игрока>", + "claimText": "Забрать", + "codesExplainText": "Коды предоставлены разработчиком, чтобы\nвыявлять и исправлять ошибки с аккаунтом.", "completeThisLevelToProceedText": "Чтобы продолжить, нужно\nпройти этот уровень!", "completionBonusText": "Бонус за прохождение", "configControllersWindow": { @@ -391,7 +410,7 @@ }, "configGamepadSelectWindow": { "androidNoteText": "Внимание: поддержка геймпада различается в зависимости от устройства и версии Android.", - "pressAnyButtonText": "Нажмите любую кнопку на геймпаде,\n которую хотите настроить...", + "pressAnyButtonText": "Нажмите любую кнопку на геймпаде,\n Что-бы настроить геймпад...", "titleText": "Настроить геймпад" }, "configGamepadWindow": { @@ -408,7 +427,7 @@ "extraStartButtonText": "Настроить дополнительную кнопку \"Start\"", "ifNothingHappensTryAnalogText": "Если ничего не происходит, попробуйте вместо этого присвоить аналоговому стику.", "ifNothingHappensTryDpadText": "Если ничего не происходит, попробуйте вместо этого присвоить D-Pad.", - "ignoreCompletelyDescriptionText": "(запретить геймпаду воздействовать на игру, или меню)", + "ignoreCompletelyDescriptionText": "(запретить геймпаду управлять на игрой, или менюшкой)", "ignoreCompletelyText": "Игнорировать полностью", "ignoredButton1Text": "Игнорируемая кнопка 1", "ignoredButton2Text": "Игнорируемая кнопка 2", @@ -431,7 +450,7 @@ "secondaryText": "Второй геймпад", "startButtonActivatesDefaultDescriptionText": "(выключить, если ваша кнопка \"старт\" работает в качестве кнопки \"меню\")", "startButtonActivatesDefaultText": "Кнопка Старт активирует стандартный виджет", - "titleText": "Настройка геймпада", + "titleText": "Настройка джойстика", "twoInOneSetupText": "Настройка геймпада 2-в-1", "uiOnlyDescriptionText": "(Запретить этому контроллеру присоединяться к игре)", "uiOnlyText": "Ограничить только для меню", @@ -447,7 +466,7 @@ "configTouchscreenWindow": { "actionControlScaleText": "Размеры кнопок действия", "actionsText": "Действия", - "buttonsText": "кнопки", + "buttonsText": "Кнопки", "dragControlsText": "< чтобы передвинуть элементы управления, перетащите их >", "joystickText": "джойстик", "movementControlScaleText": "Размеры кнопок движения", @@ -459,6 +478,7 @@ "titleText": "Настройка сенсорного экрана", "touchControlsScaleText": "Шкала сенсоров" }, + "configureDeviceInSystemSettingsText": "${DEVICE} может быть настроен в приложении системных настроек.", "configureItNowText": "Настроить сейчас?", "configureText": "Настроить", "connectMobileDevicesWindow": { @@ -512,12 +532,12 @@ "totalText": "всего", "tournamentInfoText": "Добейся высокого результата с\nдругими игроками твоей лиги.\n\nНаграды вручаются самым крутым\nпо окончании турнира.", "welcome1Text": "Добро пожаловать в ${LEAGUE}. Вы можете\nповысить свою лигу получая звёзды, получая \nдостижения и выигрывая трофеи в турнирах.", - "welcome2Text": "Вы также можете заработать билеты от многих из тех же видов деятельности.\nБилеты могут быть использованы , чтобы разблокировать новые персонажи , карты и\nмини -игры, чтобы войти турниры, и многое другое.", + "welcome2Text": "Вы также можете заработать билеты от многих из тех же видов деятельности.\nБилеты могут быть использованы, чтобы разблокировать новых персонажей, карты и\nмини-игры, для участия в турнирах, и многое другое.", "yourPowerRankingText": "Ваш ранг:" }, "copyConfirmText": "Скопировано в буфер обмена", "copyOfText": "Копия ${NAME}", - "copyText": "Копировать", + "copyText": "Скопировать", "copyrightText": "© 2013 Eric Froemling", "createAPlayerProfileText": "Создать профиль игрока?", "createEditPlayerText": "<Создание / редактирование игрока>", @@ -525,7 +545,7 @@ "creditsWindow": { "additionalAudioArtIdeasText": "Дополнительное аудио, предварительные иллюстрации и идеи: ${NAME}", "additionalMusicFromText": "Дополнительная музыка: ${NAME}", - "allMyFamilyText": "Всем моим друзьям и семье, которые помогли играть тестовую версию", + "allMyFamilyText": "Всем моим друзьям и семье, которые тестировали игру", "codingGraphicsAudioText": "Программирование, графика и аудио: ${NAME}", "languageTranslationsText": "Языковые переводы:", "legalText": "Юридическая информация:", @@ -551,12 +571,12 @@ "runMediaReloadBenchmarkText": "Запустить тест производительности загрузки медиа", "runStressTestText": "Выполнить тест-нагрузку", "stressTestPlayerCountText": "Количество игроков", - "stressTestPlaylistDescriptionText": "Плей-лист нагрузочного испытания", - "stressTestPlaylistNameText": "Название плей-листа", - "stressTestPlaylistTypeText": "Тип плей-листа", + "stressTestPlaylistDescriptionText": "Плейлист нагрузочного испытания", + "stressTestPlaylistNameText": "Название плейлиста", + "stressTestPlaylistTypeText": "Тип плейлиста", "stressTestRoundDurationText": "Продолжительность раунда", "stressTestTitleText": "Тест-нагрузка", - "titleText": "Тесты производительности и тесты-нагрузки", + "titleText": "Отладочная и Стресс Тесты", "totalReloadTimeText": "Общее время перезагрузки: ${TIME} (подробности см. в логе)", "unlockCoopText": "Разблокировать кооперативные уровни" }, @@ -569,17 +589,22 @@ "deleteText": "Удалить", "demoText": "Демонстрация", "denyText": "Отклонить", - "deprecatedText": "Устарело>=", + "deprecatedText": "Устарело", + "descriptionText": "Описание", "desktopResText": "Разреш. экрана", - "deviceAccountUpgradeText": "Внимание!\nВы заригестрированы как (${NAME})!\nДанный аккаунт будет удален в следующем обновлении!\nОбновите его до аккаунта Google Play, если не хотите потерять прогресс!", + "deviceAccountUpgradeText": "Внимание!\nВы зарегистрированы как (${NAME})!\nДанный аккаунт будет удален в следующем обновлении!\nОбновите его до аккаунта нового типа (V2), если не хотите потерять прогресс!", "difficultyEasyText": "Легкий", "difficultyHardOnlyText": "Только в трудном режиме", "difficultyHardText": "Трудный", - "difficultyHardUnlockOnlyText": "Этот уровень может быть открыт только в сложном режиме.\nДумаете, сможете!?!?!", + "difficultyHardUnlockOnlyText": "Этот уровень может быть открыт только в сложном режиме.\nДумаете, сможете это сделать!?!?!", "directBrowserToURLText": "Пожалуйста, направьте веб-браузер по следующему адресу:", "disableRemoteAppConnectionsText": "Отключить соединения RemoteApp", - "disableXInputDescriptionText": "Позволяет подключение более 4 контроллеров, но может не очень хорошо работать.", + "disableXInputDescriptionText": "Позволяет подключить более 4 контроллеров, но может не очень хорошо работать.", "disableXInputText": "Отключить XInput", + "disabledText": "Отключено", + "discardText": "Отклонить", + "discordFriendsText": "Желаете поискать новых людей с которыми можно поиграть?\nПрисоединяйтесь к нашему Discord серверу и находите новых друзей!", + "discordJoinText": "Присоединиться к Discord", "doneText": "Готово", "drawText": "Ничья", "duplicateText": "Дублировать", @@ -604,7 +629,7 @@ "characterText": "персонаж", "checkingAvailabilityText": "Проверка доступности для \"${NAME}\"...", "colorText": "цвет", - "getMoreCharactersText": "Еще персонажей...", + "getMoreCharactersText": "Больше персонажей...", "getMoreIconsText": "Еще иконок...", "globalProfileInfoText": "Глобальным профилям игроков гарантированы уникальные\nимена. У них также есть дополнительные иконки.", "globalProfileText": "(глобальный профиль)", @@ -614,6 +639,7 @@ "localProfileText": "(локальный профиль)", "nameDescriptionText": "Имя игрока", "nameText": "Имя", + "profileAlreadyExistsText": "Профиль с таким именем уже существует", "randomText": "случайное", "titleEditText": "Изменение профиля", "titleNewText": "Новый профиль", @@ -633,10 +659,10 @@ "defaultSoundtrackNameText": "Стандартный саундтрек", "deleteConfirmText": "Удалить саундтрек:\n\n${NAME}'?", "deleteText": "Удалить\nсаундтрек", - "duplicateText": "Копировать\nсаундтрек", + "duplicateText": "Сделать копию\nСаундтрека", "editSoundtrackText": "Редактор саундтрека", "editText": "Изменить\nсаундтрек", - "fetchingITunesText": "загрузка плей-листов Music App…", + "fetchingITunesText": "загрузка плейлистов...", "musicVolumeZeroWarning": "Внимание: громкость музыки установлена на 0", "nameText": "Название", "newSoundtrackNameText": "Мой саундтрек ${COUNT}", @@ -653,6 +679,7 @@ "useMusicFolderText": "Папка с музыкой" }, "editText": "Редактировать", + "enabledText": "Включено", "endText": "Конец", "enjoyText": "Удачи!", "epicDescriptionFilterText": "${DESCRIPTION} в эпическом замедленном действии.", @@ -664,6 +691,8 @@ "errorText": "Ошибка", "errorUnknownText": "неизвестная ошибка", "exitGameText": "Выйти из ${APP_NAME}?", + "expiredAgoText": "Истёк ${T} назад", + "expiresInText": "Истекает через ${T}", "exportSuccessText": "'${NAME}' экспортирован.", "externalStorageText": "Внешняя память", "failText": "Провал", @@ -676,7 +705,7 @@ }, "filterText": "Поиск", "finalScoreText": "Финальные очки", - "finalScoresText": "Финальные очки", + "finalScoresText": "Финальный результат", "finalTimeText": "Финальное время", "finishingInstallText": "Завершается установка, минутку...", "fireTVRemoteWarningText": "* Для лучшего результата используйте\nгеймпады или установите\nприложение '${REMOTE_APP_NAME}'\nна ваших телефонах и планшетах.", @@ -700,6 +729,8 @@ "editText": "Изменить\nплей-лист", "gameListText": "Список игр", "newText": "Новый\nплей-лист", + "pointsToWinText": "Очки до победы", + "seriesLengthText": "Продолжительность сессии", "showTutorialText": "Показать обучение", "shuffleGameOrderText": "Смешать порядок игр", "titleText": "Настроить плей-листы '${TYPE}'" @@ -728,6 +759,7 @@ "copyCodeConfirmText": "Код скопирован в буфер обмена.", "copyCodeText": "Копировать код", "dedicatedServerInfoText": "Для лучшего результата создайте отдельный сервер. Смотри bombsquadgame.com/server чтобы узнать как.", + "descriptionShortText": "Используйте окно мультиплеера, чтобы присоединиться к лобби.", "disconnectClientsText": "Это отключит ${COUNT} игроков\nв вашем лобби. Вы уверены?", "earnTicketsForRecommendingAmountText": "Друзья получат ${COUNT} билетов, если они активируют ваш код\n(а вы будете получать ${YOU_COUNT} билетов за каждую активацию)", "earnTicketsForRecommendingText": "Поделись игрой\nПолучи билеты...", @@ -740,10 +772,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} билетов от ${NAME}", "friendPromoCodeAwardText": "Вы получите ${COUNT} билетов за каждую активацию.", "friendPromoCodeExpireText": "Код действителен в течении ${EXPIRE_HOURS} часов и только для новых игроков.", - "friendPromoCodeInstructionsText": "Для активации в ${APP_NAME} зайдите в\n\"Настройки->Дополнительно->Ввести промо-код\". Перейди на сайт bombsquadgame.com, чтобы скачать версию игры для своей платформы.", + "friendPromoCodeInstructionsText": "Для активации в ${APP_NAME} зайдите в\n\"Настройки->Дополнительно->Прислать информацию\". Перейдите на сайт bombsquadgame.com, чтобы скачать версию игры для своей платформы.", "friendPromoCodeRedeemLongText": "Каждая активация принесет ${COUNT} билетов до ${MAX_USES} игрокам.", "friendPromoCodeRedeemShortText": "Он принесет ${COUNT} билетов в игре.", - "friendPromoCodeWhereToEnterText": "(в \"Настройках->Дополнительно->Ввести код\")", + "friendPromoCodeWhereToEnterText": "(в \"Настройках->Дополнительно->Прислать информацию\")", "getFriendInviteCodeText": "Получить промо-код", "googlePlayDescriptionText": "Пригласить игроков Google Play в ваше лобби:", "googlePlayInviteText": "Пригласить", @@ -757,7 +789,7 @@ "internetText": "Интернет", "inviteAFriendText": "Друзья еще не играют? Пригласи их\nпопробовать и они получат ${COUNT} билетов.", "inviteFriendsText": "Пригласить друзей", - "joinPublicPartyDescriptionText": "Присоединитесь к публичному лобби", + "joinPublicPartyDescriptionText": "Публичные лобби", "localNetworkDescriptionText": "Присоединяйтесь к ближайшему лобби (локальная сеть, Bluetooth, и т.д.)", "localNetworkText": "Локальная сеть", "makePartyPrivateText": "Сделать мое лобби приватным", @@ -775,6 +807,7 @@ "manualYourLocalAddressText": "Ваш локальный адрес:", "nearbyText": "Поблизости", "noConnectionText": "<нет соединения>", + "noPartiesAddedText": "Партии Не Добавлены", "otherVersionsText": "(другие версии)", "partyCodeText": "Код лобби", "partyInviteAcceptText": "Принять", @@ -782,13 +815,13 @@ "partyInviteGooglePlayExtraText": "(смотрите вкладку 'Google Play' в разделе 'Собрать')", "partyInviteIgnoreText": "Игнорировать", "partyInviteText": "${NAME} пригласил\nвас в его лобби!", - "partyNameText": "Имя команды", + "partyNameText": "Название лобби", "partyServerRunningText": "Твой сервер для лобби работает.", - "partySizeText": "Игроки", + "partySizeText": "Размер лобби", "partyStatusCheckingText": "Проверка...", - "partyStatusJoinableText": "Ваша команда доступна через интернет", + "partyStatusJoinableText": "Ваше лобби теперь доступно для подключения через интернет", "partyStatusNoConnectionText": "Невозможно подключиться к серверу", - "partyStatusNotJoinableText": "Ваше лобби недоступно через интернет", + "partyStatusNotJoinableText": "Подключение к вашему лобби недоступно через интернет", "partyStatusNotPublicText": "Ваше лобби не публично", "pingText": "Пинг", "portText": "Порт", @@ -797,9 +830,9 @@ "privatePartyJoinText": "Присоединиться к частному лобби", "privateText": "Частный", "publicHostRouterConfigText": "Это может потребовать настройки переадресации портов на вашем маршрутизаторе. Для более легкого варианта организуйте частное лобби.", - "publicText": "Открытый", + "publicText": "Публичный", "requestingAPromoCodeText": "Запрашиваем код...", - "sendDirectInvitesText": "Послать приглашение", + "sendDirectInvitesText": "Отправить приглашение", "shareThisCodeWithFriendsText": "Поделись кодом с друзьями:", "showMyAddressText": "Показать мой адрес", "startAdvertisingText": "Включить доступ", @@ -848,6 +881,12 @@ "youHaveShortText": "у вас ${COUNT}", "youHaveText": "У вас ${COUNT} билетов" }, + "goldPass": { + "desc1InfTokensText": "Неограниченные жетоны.", + "desc2NoAdsText": "Без рекламы.", + "desc3ForeverText": "Навсегда.", + "goldPassText": "Золотой пропуск" + }, "googleMultiplayerDiscontinuedText": "Простите, сервис многопользовательской игры Google больше не поддерживается.\nЯ работаю над заменой так быстро, насколько это возможно.\nДо тех пор, пожалуйста выберете другой способ подключения.\n-Эрик", "googlePlayPurchasesNotAvailableText": "Покупки в Google Play недоступны.\nВозможно, вам необходимо обновить приложение магазина.", "googlePlayServicesNotAvailableText": "Сервисы Google Play недоступны.\nНекоторый функционал игры могут быть отключены.", @@ -856,19 +895,21 @@ "alwaysText": "Всегда", "fullScreenCmdText": "Полноэкранный (Cmd-F)", "fullScreenCtrlText": "Полноэкранный (Ctrl-F)", + "fullScreenText": "Полный экран", "gammaText": "Гамма", "highText": "Высокий", "higherText": "Ультра", "lowText": "Низкий", + "maxFPSText": "Максимальный FPS", "mediumText": "Средний", "neverText": "Никогда", "resolutionText": "Разрешение", "showFPSText": "Показывать FPS", "texturesText": "Текстуры", "titleText": "Графика", - "tvBorderText": "Граница телевизора", - "verticalSyncText": "Вертикальная синхронизация (V-Sync)", - "visualsText": "Визуальные эффекты" + "tvBorderText": "Граница экрана", + "verticalSyncText": "Вертикальная синхронизация", + "visualsText": "Видеоряд" }, "helpWindow": { "bombInfoText": "- Бомба -\nСильнее ударов, но может привести\nк смертельным повреждениям. Для\nнаилучших результатов бросать в\nпротивника пока не догорел фитиль.", @@ -884,7 +925,7 @@ "controlsText": "Управление", "devicesInfoText": "В VR-версию ${APP_NAME} можно играть по сети с обычной версией,\nтак что вытаскивайте свои дополнительные телефоны, планшеты\nи компьютеры, и играйте на них. Можно даже подключить\nобычную версию игры к VR-версии, чтобы позволить\nостальным наблюдать за действием.", "devicesText": "Устройства", - "friendsGoodText": "Бывают полезны. В ${APP_NAME} веселее играть с несколькими игроками;\nподдерживается до 8 игроков одновременно, что приводит нас к:", + "friendsGoodText": "Бывают полезны. ${APP_NAME} веселее всего с несколькими игроками\nи поддерживает до 8 одновременно, что приводит нас к:", "friendsText": "Друзья", "jumpInfoText": "- Прыжок -\nПрыгайте для перескакивания,\nшвыряния предметов подальше\nили для выражения радости.", "orPunchingSomethingText": "Или ударить, сбросить с обрыва и взорвать бомбой-липучкой по дороге вниз.", @@ -895,28 +936,28 @@ "powerupCurseNameText": "Проклятие", "powerupHealthDescriptionText": "Ни за что не догадаетесь.\nВозвращает полное здоровье.", "powerupHealthNameText": "Аптечка", - "powerupIceBombsDescriptionText": "Слабее, чем обычные бомбы\nно оставляет врагов заморожеными\nи чрезвычайно хрупкими.", + "powerupIceBombsDescriptionText": "Слабее, чем обычные бомбы\nно оставляет врагов заморожеными\nи в частности хрупкими.", "powerupIceBombsNameText": "Ледяные бомбы", - "powerupImpactBombsDescriptionText": "Чуть слабее обычных бомб,\nно взрываются при ударе.", + "powerupImpactBombsDescriptionText": "Чуть слабее обычных бомб,\nно взрываются при соприкосновении.", "powerupImpactBombsNameText": "Моментальные бомбы", "powerupLandMinesDescriptionText": "Выдаются по 3 штуки.\nПолезны для защиты базы или\nусмирения быстроногих врагов.", "powerupLandMinesNameText": "Мины", "powerupPunchDescriptionText": "Делают ваши удары быстрее,\nлучше, сильнее.", "powerupPunchNameText": "Боксерские перчатки", - "powerupShieldDescriptionText": "Немного поглощает урон,\nвместо вас.", + "powerupShieldDescriptionText": "Немного поглощает повреждения,\nчтобы тебе не пришлось.", "powerupShieldNameText": "Энергетический щит", "powerupStickyBombsDescriptionText": "Липнут ко всему, чего касаются.\nИ начинается веселье.", "powerupStickyBombsNameText": "Бомбы-липучки", "powerupsSubtitleText": "Конечно, ни одна игра не обходится без усилителей:", "powerupsText": "Усилители", "punchInfoText": "- Удар -\nЧем быстрее двигаются кулаки -\nтем cильнее удар. Так что бегайте\nи крутитесь как ненормальные.", - "runInfoText": "- Бег -\nДля бега удерживайте нажатой ЛЮБУЮ кнопку. Для этого хороши верхние триггеры\nили плечевые кнопки, если они у вас есть. Бегом передвигаться быстрее,\nно труднее поворачивать, так что осторожно с обрывами.", + "runInfoText": "- Бег -\nДля бега удерживайте нажатой ЛЮБУЮ кнопку. Для этого хороши триггеры и верхние кнопки, если они у вас есть.\nБегом передвигаться быстрее, но труднее поворачивать, так что смотри за обрывами.", "someDaysText": "Иногда просто хочется что-нибудь ударить. Или взорвать.", "titleText": "Справка ${APP_NAME}", "toGetTheMostText": "Чтобы выжать максимум из этой игры, вам необходимо:", "welcomeText": "Добро пожаловать в ${APP_NAME}!" }, - "holdAnyButtonText": "<держать любую кнопку>", + "holdAnyButtonText": "<удерживать любую кнопку>", "holdAnyKeyText": "<держать любую клавишу>", "hostIsNavigatingMenusText": "- ${HOST} в меню навигации как босс -", "importPlaylistCodeInstructionsText": "Используйте показанный код, чтобы импортировать этот плейлист где-то ещё:", @@ -924,19 +965,20 @@ "importText": "Импорт", "importingText": "Импортирую...", "inGameClippedNameText": "В игре будет\n\"${NAME}\"", + "inboxText": "Почта", "installDiskSpaceErrorText": "ОШИБКА: не удалось завершить установку. Может быть,\nне хватает свободного места на вашем устройстве.\nОсвободите место и попробуйте еще раз.", "internal": { "arrowsToExitListText": "чтобы выйти из списка нажмите ${LEFT} или ${RIGHT}", "buttonText": "кнопка", "cantKickHostError": "Невозможно кикнуть создателя.", - "chatBlockedText": "${NAME} заблокирован на ${TIME} секунд.", + "chatBlockedText": "Игроку ${NAME} заблокирован чат на ${TIME} секунд.", "connectedToGameText": "Вошел в игру '${NAME}'", "connectedToPartyText": "Вошел в лобби ${NAME}!", "connectingToPartyText": "Идет соединение...", "connectionFailedHostAlreadyInPartyText": "Соединение не удалось; хост находится в другом лобби.", "connectionFailedPartyFullText": "Соединение не удалось; группа полная", "connectionFailedText": "Соединение не удалось.", - "connectionFailedVersionMismatchText": "Соединение не удалось; хост использует другую версию игры.\nУбедитесь, что версии обеих сторон обновлены, и попытайтесь снова.", + "connectionFailedVersionMismatchText": "Соединение не удалось; хост использует другую версию игры.\nУбедитесь, что версии обеих сторон совпадают, и попытайтесь снова.", "connectionRejectedText": "Соединение отклонено.", "controllerConnectedText": "${CONTROLLER} подключен.", "controllerDetectedText": "Обнаружен 1 контроллер.", @@ -950,9 +992,9 @@ "corruptFileText": "Обнаружены поврежденные файлы. Попытайтесь переустановить или обратитесь к ${EMAIL}", "errorPlayingMusicText": "Ошибка воспроизведения музыки: ${MUSIC}", "errorResettingAchievementsText": "Не удается сбросить онлайн-медали, пожалуйста, попробуйте позже.", - "hasMenuControlText": "${NAME} контролирует меню", + "hasMenuControlText": "Меню контролирует ${NAME}.", "incompatibleNewerVersionHostText": "Хост использует более новую версию игры.\nОбновитесь до последней версии и попробуйте снова.", - "incompatibleVersionHostText": "Хост использует другую версию игры.\nУбедитесь, что обе ваши версии обновлены, и попытайтесь снова.", + "incompatibleVersionHostText": "Хост использует другую версию игры.\nУбедитесь, что ваши версии совпадают, и попытайтесь снова.", "incompatibleVersionPlayerText": "${NAME} использует другую версию игры и не может соединится.\nУбедитесь, что обе ваши версии обновлены, и попытайтесь снова.", "invalidAddressErrorText": "Ошибка: неправильный адрес.", "invalidNameErrorText": "Ошибка: некорректное имя.", @@ -970,28 +1012,30 @@ "playerJoinedPartyText": "${NAME} вошел в лобби!", "playerLeftPartyText": "${NAME} покинул лобби.", "rejectingInviteAlreadyInPartyText": "Приглашение отклонено (уже в лобби).", - "serverRestartingText": "Сервер перезагружается. Попробуйте позже...", + "serverRestartingText": "Сервер перезагружается. Пожалуйста, перезайдите...", "serverShuttingDownText": "Сервер выключается...", "signInErrorText": "Ошибка входа.", "signInNoConnectionText": "Невозможно войти. (нет интернет соединения?)", "teamNameText": "Команда ${NAME}", - "telnetAccessDeniedText": "ОШИБКА: пользователь не предоставил доступ Telnet.", + "telnetAccessDeniedText": "ОШИБКА: Пользователь не предоставил доступ Telnet.", "timeOutText": "(осталось ${TIME} секунд)", "touchScreenJoinWarningText": "Вы присоединились с сенсорным экраном.\nЕсли это была ошибка, нажмите 'Меню->Покинуть игру'.", "touchScreenText": "Сенсорный экран", "trialText": "проба", - "unableToResolveHostText": "Ошибка: невозможно достичь хоста.", + "unableToCompleteTryAgainText": "Нельзя выполнить это сейчас.\nПожалуйста попробуйте ещё раз", + "unableToResolveHostText": "Ошибка: невозможно определить хост.", "unavailableNoConnectionText": "Сейчас это недоступно (нет интернет соединения?)", "vrOrientationResetCardboardText": "Используйте это, чтобы сбросить ориентации VR.\nЧтобы играть в игру, вам понадобится внешний контроллер.", "vrOrientationResetText": "Сброс ориентации VR.", "willTimeOutText": "(время выйдет при бездействии)" }, + "inventoryText": "Инвентарь", "jumpBoldText": "ПРЫЖОК", - "jumpText": "Прыгнуть", + "jumpText": "Прыжок", "keepText": "Оставить", "keepTheseSettingsText": "Оставить эти настройки?", "keyboardChangeInstructionsText": "Нажмите на пробел два раза, чтобы сменить раскладку.", - "keyboardNoOthersAvailableText": "Нету других раскладок.", + "keyboardNoOthersAvailableText": "Отсутствуют другие раскладки.", "keyboardSwitchText": "Раскладка изменена на \"${NAME}\".", "kickOccurredText": "${NAME} исключили.", "kickQuestionText": "Исключить ${NAME}?", @@ -999,16 +1043,16 @@ "kickVoteCantKickAdminsText": "Администраторов нельзя исключить.", "kickVoteCantKickSelfText": "Вы не можете исключить самого себя (но можете выйти).", "kickVoteFailedNotEnoughVotersText": "Недостаточно игроков для голосования.", - "kickVoteFailedText": "Голосование на вылет не удалось.", - "kickVoteStartedText": "Начато голосование за вылет ${NAME}.", - "kickVoteText": "Голосовать за вылет", - "kickVotingDisabledText": "Голосование за вылет отключено.", + "kickVoteFailedText": "Голосование на исключение не удалось.", + "kickVoteStartedText": "Начато голосование за исключение ${NAME}.", + "kickVoteText": "Голосовать за исключение", + "kickVotingDisabledText": "Голосование за исключение отключено.", "kickWithChatText": "Наберите ${YES} для согласия или ${NO} для отказа.", "killsTallyText": "Убито ${COUNT}", "killsText": "Убито", "kioskWindow": { "easyText": "Легкий", - "epicModeText": "Эпический режим", + "epicModeText": "Замедленный режим", "fullMenuText": "Полное меню", "hardText": "Трудный", "mediumText": "Средний", @@ -1032,8 +1076,11 @@ "seasonEndsMinutesText": "Сезон завершится через ${NUMBER} минут.", "seasonText": "Сезон ${NUMBER}", "tournamentLeagueText": "Чтобы участвовать в этом турнире, вы должны достичь лиги ${NAME}.", - "trophyCountsResetText": "Трофеи будут сброшены в следующем сезоне." + "trophyCountsResetText": "Трофеи будут сброшены в следующем сезоне.", + "upToDateBonusDescriptionText": "Игроки, использующие последнюю версию игры\nполучают бонус ${PERCENT}% к очкам.", + "upToDateBonusText": "Бонус за обновление" }, + "learnMoreText": "Подробнее", "levelBestScoresText": "Лучший рекорд на ${LEVEL}", "levelBestTimesText": "Лучшее время на ${LEVEL}", "levelFastestTimesText": "Лучшее время уровня ${LEVEL}", @@ -1042,7 +1089,7 @@ "levelMustBeCompletedFirstText": "Сначала должен быть пройден ${LEVEL}.", "levelText": "Уровень ${NUMBER}", "levelUnlockedText": "Уровень разблокирован!", - "livesBonusText": "Бонус жизней", + "livesBonusText": "Бонус оставшихся жизней", "loadingText": "Загрузка", "loadingTryAgainText": "Загрузка; попробуй снова через несколько секунд...", "macControllerSubsystemBothText": "Оба (не рекомендуется)", @@ -1052,7 +1099,7 @@ "macControllerSubsystemMFiText": "Сделано для iOS/Mac", "macControllerSubsystemTitleText": "Поддержка контроллера", "mainMenu": { - "creditsText": "Благодарности", + "creditsText": "Участвовали в создании", "demoMenuText": "Меню демо", "endGameText": "Закончить игру", "endTestText": "Завершить тест", @@ -1069,21 +1116,23 @@ "settingsText": "Настройки" }, "makeItSoText": "Да будет так", - "mapSelectGetMoreMapsText": "Ещё карт...", + "mapSelectGetMoreMapsText": "Больше карт...", "mapSelectText": "Выбрать...", "mapSelectTitleText": "Карты игры ${GAME}", "mapText": "Карта", "maxConnectionsText": "Максимум соединений", - "maxPartySizeText": "Размер группы", + "maxPartySizeText": "Размер лобби", "maxPlayersText": "Максимум игроков", - "merchText": "Мерч с символикой Bomb squad!", + "merchText": "Мерч с символикой BombSquad!", "modeArcadeText": "Аркадный режим", "modeClassicText": "Обычный режим", "modeDemoText": "Демонстрационный режим", + "moreSoonText": "Скоро будет больше...", + "mostDestroyedPlayerText": "Самый побежденный игрок", "mostValuablePlayerText": "Самый ценный игрок", "mostViolatedPlayerText": "Самый побитый игрок", "mostViolentPlayerText": "Самый буйный игрок", - "moveText": "Движение", + "moveText": "Двигаться", "multiKillText": "${COUNT} ЗА РАЗ!!!", "multiPlayerCountText": "${COUNT} игроков", "mustInviteFriendsText": "Примечание: вы должны пригласить друзей\nна панели \"${GATHER}\" или присоединить\nконтроллеры для совместной игры.", @@ -1092,10 +1141,11 @@ "nameKilledText": "${NAME} убил ${VICTIM}.", "nameNotEmptyText": "Имя не может быть пустым!", "nameScoresText": "${NAME} ведет!", - "nameSuicideKidFriendlyText": "${NAME} случайно убился.", + "nameSuicideKidFriendlyText": "${NAME} случайно умер.", "nameSuicideText": "${NAME} совершил суицид.", "nameText": "Имя", "nativeText": "Разрешение устройства", + "newExclaimText": "Новинка!", "newPersonalBestText": "Новый личный рекорд!", "newTestBuildAvailableText": "Доступна новая тестовая версия! (${VERSION} сборка ${BUILD}).\nОбновить: ${ADDRESS}", "newText": "Новый", @@ -1103,31 +1153,38 @@ "nextAchievementsText": "Следующие достижения:", "nextLevelText": "Следующий уровень", "noAchievementsRemainingText": "- нет", - "noContinuesText": "(без продолжений)", + "noContinuesText": "(без продолжения)", "noExternalStorageErrorText": "На данном устройстве не найдено внешней памяти", "noGameCircleText": "Ошибка: не вошли в GameCircle", "noJoinCoopMidwayText": "К кооперативным играм нельзя присоединиться посреди игры.", + "noMessagesText": "Пусто.", + "noPluginsInstalledText": "Отсутствуют установленные плагины", "noProfilesErrorText": "У вас нет профиля игрока, так что вас будут звать '${NAME}'.\nСоздать профиль можно перейдя в 'Настройки' > 'Профили игроков'.", - "noScoresYetText": "Счета пока нет.", + "noScoresYetText": "Результатов пока нет.", + "noServersFoundText": "Серверы не найдены.", "noThanksText": "Нет, спасибо", "noTournamentsInTestBuildText": "ВНИМАНИЕ: Турнирные очки из этой тестовой сборки будут не засчитаны.", "noValidMapsErrorText": "Для данного типа игры не найдено корректных карт.", "notEnoughPlayersRemainingText": "Не осталось достаточно игроков; выйдите и начните новую игру.", - "notEnoughPlayersText": "Для начала этой игры нужно как минимум ${COUNT} игрока!", + "notEnoughPlayersText": "Для начала игры нужно как минимум ${COUNT} игрока(ов)!", + "notEnoughTicketsText": "Недостаточно билетов!", "notNowText": "Не сейчас", "notSignedInErrorText": "Войдите в аккаунт для начала.", - "notSignedInGooglePlayErrorText": "Войдите сначала в Google Play, а там посмотрим.", + "notSignedInGooglePlayErrorText": "Для этого Вам необходимо войти с помощью Google Play.", "notSignedInText": "(вы не вошли)", "notUsingAccountText": "Рекомендация: вы не используете аккаунт ${SERVICE}.\nЗайдите в 'Аккаунт' => 'зайти в ${SERVICE}', чтобы зайти в ${SERVICE}.", "nothingIsSelectedErrorText": "Ничего не выбрано!", "numberText": "${NUMBER}", "offText": "Выкл", - "okText": "Oк", + "okText": "Ок", "onText": "Вкл", - "oneMomentText": "Один момент…", + "oneMomentText": "Минутку...", "onslaughtRespawnText": "${PLAYER} возродится в ${WAVE} волне", + "openMeText": "Открой меня!", + "openNowText": "Открыть сейчас", + "openText": "Открыть", "orText": "${A} или ${B}", - "otherText": "Другие...", + "otherText": "Другое...", "outOfText": "(${RANK} из ${ALL})", "ownFlagAtYourBaseWarning": "Чтобы набрать очки, ваш собственный\nфлаг должен быть на вашей базе!", "packageModsEnabledErrorText": "Сетевая игра запрещена, когда включены моды локального пакета (см. Настройки->Дополнительно)", @@ -1153,10 +1210,10 @@ "playWindow": { "coopText": "Кооператив", "freeForAllText": "Каждый за себя", - "oneToFourPlayersText": "1-4 игрока", + "oneToFourPlayersText": "1-4 игрок(а)", "teamsText": "Команды", "titleText": "Играть", - "twoToEightPlayersText": "2-8 игроков" + "twoToEightPlayersText": "2-8 игрока(ов)" }, "playerCountAbbreviatedText": "${COUNT}и", "playerDelayedJoinText": "${PLAYER} присоединится в следующем раунде.", @@ -1171,7 +1228,7 @@ "editButtonText": "Изменить\nпрофиль", "explanationText": "(настраивайте имена и внешний вид игрока)", "newButtonText": "Новый\nпрофиль", - "titleText": "Профили игроков" + "titleText": "Ваши профили" }, "playerText": "Игрок", "playlistNoValidGamesErrorText": "Этот плейлист содержит неоткрытые игры.", @@ -1183,8 +1240,8 @@ "pluginClassLoadErrorText": "Ошибка при попытке загрузить класс плагина '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Ошибка при инициализации плагина '${PLUGIN}': ${ERROR}", "pluginSettingsText": "Настройки плагина", - "pluginsAutoEnableNewText": "Автоматически включать плагины", - "pluginsDetectedText": "Обнаружены новые плагины! Перезапустите игру, чтобы активировать их, или настройте их в настройках.", + "pluginsAutoEnableNewText": "Автоматически включать новые плагины", + "pluginsDetectedText": "Обнаружен(ы) новый(е) плагин(ы)! Перезапустите игру чтобы активировать, или отредактируйте в настройках.", "pluginsDisableAllText": "Выключить все плагины", "pluginsEnableAllText": "Включить все плагины", "pluginsRemovedText": "${NUM} плагин(ов) больше не найдены.", @@ -1219,10 +1276,12 @@ "punchText": "Ударить", "purchaseForText": "Купить за ${PRICE}", "purchaseGameText": "Купить игру", + "purchaseNeverAvailableText": "Извините, покупки недоступны на вашем устройстве.\nПопробуйте зайти в ваш аккаунт с другого устройства и выполнить транзакцию с него.", + "purchaseNotAvailableText": "Эта покупка недоступна.", "purchasingText": "Покупка...", "quitGameText": "Выйти из ${APP_NAME}?", "quittingIn5SecondsText": "Выход через 5 секунд...", - "randomPlayerNamesText": "Дима, Кузя, Вован, Маха, Русский, Какуля, Бибер, Борька, Няшка, Толян, Ержан, Дибисяра, Вася, Морген, Серёга, Ваня, Кеша, Жорик, Стёпа, Эдгар, Цыган, Олег, Егор, Ёршик", + "randomPlayerNamesText": "Каратель, Подрывник, Вован, Маха, Русский, Псих, Бибер, Борька, Няшка, Мастер, Люцифер, Взрыватель, Морген, Джинджер, Крушитель, Лавелас, Леонидас, Гангстер, Ломатель, Волк, Хитрец, Счастливчик, Везунчик, Стратег, Рустам", "randomText": "Случайный", "rankText": "Ранг", "ratingText": "Рейтинг", @@ -1237,10 +1296,10 @@ "button_position": "Положение кнопки", "button_size": "Размер кнопки", "cant_resolve_host": "Сервер не найден.", - "capturing": "Слушаю...", + "capturing": "Ловлю...", "connected": "Соединено.", "description": "Используйте Ваш телефон или планшет как контроллер BombSquad.\nДо 8 устройств могут быть одновременно подключены для эпических битв в мультиплеере на одном ТВ или планшете.", - "disconnected": "Выброшен сервером.", + "disconnected": "Отключен сервером.", "dpad_fixed": "неподвижный", "dpad_floating": "плавающий", "dpad_position": "Расположение D-Pad", @@ -1261,6 +1320,7 @@ "version_mismatch": "Несовпадение версий.\nУбедитесь, что BombSquad и контроллер BombSquad\nобновлены до последней версии и повторите попытку." }, "removeInGameAdsText": "Разблокируйте \"${PRO}\" в магазине, чтобы убрать рекламу в игре.", + "removeInGameAdsTokenPurchaseText": "ОГРАНИЧЕННОЕ ПРЕДЛОЖЕНИЕ: Купите ЛЮБОЙ пакет жетонов, чтобы убрать рекламу в игре.", "renameText": "Переименовать", "replayEndText": "Завершить просмотр записи", "replayNameDefaultText": "Запись последней игры", @@ -1281,7 +1341,9 @@ "revertText": "Восстановить", "runText": "Бежать", "saveText": "Сохранить", - "scanScriptsErrorText": "Ошибка(и) сканирования скриптов; посмотри лог для подробностей.", + "scanScriptsErrorText": "Ошибка(и) сканирования скриптов. Ознакомтесь с логом для подробностей.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} и ${NUM} других мод(ов) нужно обновить до ${API}", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} Нужно обновить до ${API}", "scoreChallengesText": "Медали за очки", "scoreListUnavailableText": "Список очков недоступен.", "scoreText": "Очки", @@ -1292,6 +1354,7 @@ }, "scoreWasText": "(было ${COUNT})", "selectText": "Выбрать", + "sendInfoDescriptionText": "Отправьте информацию об вашей учётной записи и состоянии приложения непосредственно разработчику.\nПожалуйста, не забудь указать ваше имя и причину отправки.", "seriesWinLine1PlayerText": "ПОБЕДИЛ В", "seriesWinLine1TeamText": "ПОБЕДИЛИ В", "seriesWinLine1Text": "ПОБЕДИЛ В", @@ -1308,25 +1371,33 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(простая, удобная для контроллера виртуальная клавиатура для ввода текста)", - "alwaysUseInternalKeyboardText": "Всегда использовать встроенную клавиатуру", + "alwaysUseInternalKeyboardText": "Всегда использовать ТОЛЬКО встроенную клавиатуру", "benchmarksText": "Тест производительности и тест-нагрузка", - "disableCameraGyroscopeMotionText": "Отключить движение камеры с помощью гироскопа", - "disableCameraShakeText": "Отключить тряску камеры", + "devToolsText": "Инструменты разработчиков", + "disableCameraGyroscopeMotionText": "Убрать тряску и движение камеры при помощи гироскопа", + "disableCameraShakeText": "Отключить тряску камеры.", "disableThisNotice": "(вы можете отключить это уведомление в настройках)", "enablePackageModsDescriptionText": "(позволяет дополнительные возможности для моддинга, но отключает сетевую игру)", "enablePackageModsText": "Включить моды локального пакета", "enterPromoCodeText": "Введите промо-код", "forTestingText": "Примечание: эти значения используются только для тестирования и будут потеряны, когда приложение завершит работу.", - "helpTranslateText": "Переводы игры ${APP_NAME} с английского совершён общественными\nусилиями. Если вы хотите предложить или исправить\nперевод, следуйте по ссылке ниже. Заранее спасибо!", - "kickIdlePlayersText": "Выкидывать бездействующих игроков", + "helpTranslateText": "Неанглоязычные переводы ${APP_NAME} являются общественным\nусилием. Если вы хотите внести вклад или исправить\nперевод, перейдите по ссылке ниже. Заранее спасибо!", + "insecureConnectionsDescriptionText": "не рекомендуется, но может разрешить игру \nонлайн в недоступных странах или сетях", + "insecureConnectionsText": "Использовать незащищённые подключения", + "kickIdlePlayersText": "Исключать бездействующих игроков", "kidFriendlyModeText": "Семейный режим (меньше насилия, и т.д.)", "languageText": "Язык", "moddingGuideText": "Руководство по моддингу", + "moddingToolsText": "Настройки модов", "mustRestartText": "Необходимо перезапустить игру, чтобы изменения вступили в силу.", "netTestingText": "Тестирование сети", "resetText": "Сбросить", + "sendInfoText": "Отправить информацию (обратная связь с разработчиком).", "showBombTrajectoriesText": "Показывать траекторию бомбы", - "showInGamePingText": "Показать Ping", + "showDemosWhenIdleText": "Показать Демо-Версию в режиме ожидания.", + "showDeprecatedLoginTypesText": "Показывать устаревшие типы входа в систему", + "showDevConsoleButtonText": "Показать кнопку консоли", + "showInGamePingText": "Показать пинг (Задержку действий на сервере).", "showPlayerNamesText": "Показывать имена игроков", "showUserModsText": "Показать папку модов", "titleText": "Дополнительно", @@ -1334,8 +1405,8 @@ "translationFetchErrorText": "статус перевода недоступен", "translationFetchingStatusText": "проверка статуса перевода...", "translationInformMe": "Сообщите мне, если мой язык нуждается в обновлениях", - "translationNoUpdateNeededText": "данный язык полностью обновлен, ура!", - "translationUpdateNeededText": "** данный язык нуждается в обновлениях!! **", + "translationNoUpdateNeededText": "Данный язык полностью обновлен, ура!", + "translationUpdateNeededText": "** Установленный язык требует обновлений!!!**", "vrTestingText": "Тестирование VR" }, "shareText": "Поделиться", @@ -1345,11 +1416,14 @@ "signInWithGameCenterText": "Чтобы использовать аккаунт GameCenter,\nвойдите через GameCenter.", "singleGamePlaylistNameText": "Просто ${GAME}", "singlePlayerCountText": "1 игрок", + "sizeLargeText": "Гигантский", + "sizeMediumText": "Средний", + "sizeSmallText": "Крошечный", "soloNameFilterText": "${NAME} соло", "soundtrackTypeNames": { "CharSelect": "Выбор персонажа", "Chosen One": "Избранный", - "Epic": "Игры в эпическом режиме", + "Epic": "Игры в замедленном режиме", "Epic Race": "Эпическая гонка", "FlagCatcher": "Захват флага", "Flying": "Счастливые мысли", @@ -1370,6 +1444,7 @@ }, "spaceKeyText": "пробел", "statsText": "Статистика", + "stopRemindingMeText": "Не напоминай мне", "storagePermissionAccessText": "Это требует доступа к хранилищу", "store": { "alreadyOwnText": "У вас уже есть ${NAME}!", @@ -1403,24 +1478,26 @@ "salePercentText": "(Скидка ${PERCENT}%)", "saleText": "СКИДКА", "searchText": "Поиск", - "teamsFreeForAllGamesText": "Командные игры / Каждый сам за себя", - "totalWorthText": "*** ${TOTAL_WORTH} значение! ***", + "teamsFreeForAllGamesText": "Командные / Каждый сам за себя игры", + "totalWorthText": "*** Общая стоимость набора - ${TOTAL_WORTH}! ***", "upgradeQuestionText": "Обновить?", "winterSpecialText": "Зимняя акция", "youOwnThisText": "- у вас это уже есть -" }, - "storeDescriptionText": "Игровое безумие с 8 игроками!\n\nВзрывайте своих друзей (или ботов) в турнире взрывных мини-игр, таких как Захват флага и Эпический смертельный бой замедленного действия!\n\nС простым управлением и расширенной поддержкой контроллеров 8 человек могут присоединиться к действию, можно даже использовать мобильные устройства как контроллеры через бесплатное приложение 'BombSquad Remote'!\n\nВ атаку!\n\nСм. www.froemling.net/BombSquad для дополнительной информации.", + "storeDescriptionText": "Игровое безумие с 8 игроками!\n\nВзрывайте своих друзей (или ботов) в турнире взрывных мини-игр, таких как захват флага, хоккея с взрывчаткой и смертельного боя замедленного действия!\n\nС простым управлением и расширенной поддержкой контроллеров возможно присоединиться вплоть до 8 человек к игре, можно даже использовать мобильные устройства как контроллеры через бесплатное приложение 'BombSquad Remote'!\n\nВ атаку!\n\nСм. www.froemling.net/BombSquad для дополнительной информации.", "storeDescriptions": { "blowUpYourFriendsText": "Взорви друзей.", - "competeInMiniGamesText": "Соревнуйтесь в мини-играх от гонок до левитации.", + "competeInMiniGamesText": "Соревнуйтесь в мини-играх от гонок до полёта.", "customize2Text": "Настройка персонажей, мини-игр и даже саундтрека.", "customizeText": "Настройка персонажей и создание своих собственных плей-листов мини-игр.", - "sportsMoreFunText": "Спорт веселее со взрывчаткой.", - "teamUpAgainstComputerText": "Команды против компьютера." + "sportsMoreFunText": "Спорт куда веселее со взрывчаткой.", + "teamUpAgainstComputerText": "Объединитесь против ботов." }, "storeText": "Магазин", "submitText": "Отправить", "submittingPromoCodeText": "Активация кода....", + "successText": "Успех!", + "supportEmailText": "Если вы испытываете какие-то проблемы с приложением,\nпожалуйста, напишите на почту ${EMAIL}.", "teamNamesColorText": "имена/цвета команд", "teamsText": "Команды", "telnetAccessGrantedText": "Доступ Telnet включен.", @@ -1431,7 +1508,8 @@ "testBuildValidatedText": "Тестовая сборка проверена. Наслаждайтесь!", "thankYouText": "Спасибо за вашу поддержку! Веселой игры!!", "threeKillText": "ТРЕХ ЗА РАЗ!!", - "timeBonusText": "Бонус времени", + "ticketsDescriptionText": "Билеты можно использовать для открытия\nперсонажей, карт, мини-игр и множество\nдругого в магазине.\n\nБилеты можно найти в сундуках, полученные в кампании и за достижения, а так же выигранные в турнирах.", + "timeBonusText": "Бонус за время", "timeElapsedText": "Прошло времени", "timeExpiredText": "Время вышло", "timeSuffixDaysText": "${COUNT}д", @@ -1440,11 +1518,25 @@ "timeSuffixSecondsText": "${COUNT}с", "tipText": "Подсказка", "titleText": "BombSquad", - "titleVRText": "BombSquad ВР", + "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Получить токены", + "notEnoughTokensText": "Недостаточно токенов!", + "numTokensText": "${COUNT} Токенов", + "openNowDescriptionText": "У тебя достаточно жетонов\nчтобы открыть сундук сейчас - \nтебе не нужно больше ждать.", + "shinyNewCurrencyText": "Блестяще новая валюта в BombSquad!", + "tokenPack1Text": "Небольшой набор токенов", + "tokenPack2Text": "Средний набор токенов", + "tokenPack3Text": "Огромный набор токенов", + "tokenPack4Text": "Огромный набор токенов", + "tokensDescriptionText": "Токены используются для ускорения открытия\nсундуков и для остальных функций игры/аккаунта.\n\nВы можете выиграть токены в игре или купить\nих в магазине. Или же купите Золотой Пропуск\nдля бесконечных токенов и не думайте о них.", + "youHaveGoldPassText": "У вас имеется Золотой Пропуск.\nВсе покупки за токены бесплатны.\nНаслаждайтесь!" + }, "topFriendsText": "Топ друзей", "tournamentCheckingStateText": "Проверка статуса турнира, пожалуйста, подождите...", "tournamentEndedText": "Турнир закончился. Скоро начнется новый.", "tournamentEntryText": "Вход в турнир", + "tournamentFinalStandingsText": "Финальный результат", "tournamentResultsRecentText": "Последние Результаты турнира", "tournamentStandingsText": "Позиции в турнире", "tournamentText": "Турнир", @@ -1456,11 +1548,11 @@ "Agent Johnson": "Агент Джонсон", "B-9000": "B-9000", "Bernard": "Бернард", - "Bones": "Костяшка", + "Bones": "Скелет", "Butch": "Силач", "Easter Bunny": "Пасхальный кролик", "Flopsy": "Флопси", - "Frosty": "Снежный", + "Frosty": "Снеговик", "Gretel": "Гретель", "Grumbledorf": "Грамблдорф", "Jack Morgan": "Джек Морган", @@ -1501,13 +1593,13 @@ "${GAME} Training": "${GAME}: тренировка", "Infinite ${GAME}": "Бесконечный уровень ${GAME}", "Infinite Onslaught": "Бесконечная атака", - "Infinite Runaround": "Бесконечная беготня", + "Infinite Runaround": "Бесконечный побег", "Onslaught": "Бесконечная атака", "Onslaught Training": "Атака: тренировка", "Pro ${GAME}": "${GAME} профи", "Pro Football": "Регби профи", "Pro Onslaught": "Атака профи", - "Pro Runaround": "Беготня профи", + "Pro Runaround": "Побег профи", "Rookie ${GAME}": "${GAME} для новичков", "Rookie Football": "Регби для новичков", "Rookie Onslaught": "Атака для новичков", @@ -1516,17 +1608,29 @@ "Uber ${GAME}": "Убер ${GAME}", "Uber Football": "Убер регби", "Uber Onslaught": "Убер атака", - "Uber Runaround": "Убер беготня" + "Uber Runaround": "Убер побег" + }, + "displayItemNames": { + "${C} Tickets": "${C} Билетов", + "${C} Tokens": "${C} Токенов", + "Chest": "Сундук", + "L1 Chest": "Сундук 1го уровня", + "L2 Chest": "Сундук 2го уровня", + "L3 Chest": "Сундук 3го уровня", + "L4 Chest": "Сундук 4го уровня", + "L5 Chest": "Сундук 5го уровня", + "L6 Chest": "Сундук 6го уровня", + "Unknown Chest": "Неизвестный сундук" }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Чтобы победить, стань избранным на некоторое время.\nЧтобы стать избранным, убей избранного.", "Bomb as many targets as you can.": "Взорвите столько мишеней, сколько сможете.", "Carry the flag for ${ARG1} seconds.": "Пронесите флаг в течение ${ARG1} секунд.", "Carry the flag for a set length of time.": "Пронесите флаг в течение заданного времени.", - "Crush ${ARG1} of your enemies.": "Разбейте ${ARG1} врагов.", + "Crush ${ARG1} of your enemies.": "Победите ${ARG1} врагов.", "Defeat all enemies.": "Победите всех врагов.", "Dodge the falling bombs.": "Увернитесь от падающих бомб.", - "Final glorious epic slow motion battle to the death.": "Финальная эпическая смертельная битва в замедленном действии.", + "Final glorious epic slow motion battle to the death.": "Финальная смертельная битва в замедленном действии.", "Gather eggs!": "Соберите яйца!", "Get the flag to the enemy end zone.": "Отнесите флаг в зону защиты противника.", "How fast can you defeat the ninjas?": "Как быстро вы сможете победить ниндзя?", @@ -1590,7 +1694,7 @@ "Ninja Fight": "Бой с ниндзя", "Onslaught": "Атака", "Race": "Гонка", - "Runaround": "Обход", + "Runaround": "Побег", "Target Practice": "Стрельба по мишеням", "The Last Stand": "Последний рубеж" }, @@ -1602,7 +1706,8 @@ "Arabic": "Арабский", "Belarussian": "Белорусский", "Chinese": "Китайский упрощенный", - "ChineseTraditional": "Китайский традиционный", + "ChineseSimplified": "Китайский - упрощённый", + "ChineseTraditional": "Китайский - традиционный", "Croatian": "Хорватский", "Czech": "Чешский", "Danish": "Датский", @@ -1623,13 +1728,18 @@ "Korean": "Корейский", "Malay": "Малайский", "Persian": "Персидский", + "PirateSpeak": "Пиратский язык", "Polish": "Польский", "Portuguese": "Португальский", + "PortugueseBrazil": "Португальский - Бразилия", + "PortuguesePortugal": "Португальский", "Romanian": "Румынский", "Russian": "Русский", "Serbian": "Сербский", "Slovak": "Словацкий", "Spanish": "Испанский", + "SpanishLatinAmerica": "Испанский - Латинская Америка", + "SpanishSpain": "Испанский", "Swedish": "Шведский", "Tamil": "Тамильский", "Thai": "Тайский", @@ -1664,7 +1774,7 @@ "Zigzag": "Зигзаг" }, "playlistNames": { - "Just Epic": "Только эпический", + "Just Epic": "Только замедленный", "Just Sports": "Только спорт" }, "promoCodeResponses": { @@ -1689,14 +1799,15 @@ "An error has occurred; please contact support. (${ERROR})": "произошла ошибка;Пожалуйста обратитесь в службу поддержки. (${ERROR})", "An error has occurred; please contact support@froemling.net.": "Произошла ошибка; пожалуйста, свяжитесь с support@froemling.net.", "An error has occurred; please try again later.": "Произошла ошибка, пожалуйста, повторите попытку позже.", - "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Точно хотите связать аккаунты?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nОтменить будет нельзя!", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Вы точно хотите связать аккаунты?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nДействие нельзя будет отменить!", "BombSquad Pro unlocked!": "BombSquad Pro разблокирован!", "Can't link 2 accounts of this type.": "Невозможно связать 2 аккаунта этого типа.", "Can't link 2 diamond league accounts.": "Невозможно связать 2 аккаунта бриллиантовой лиги.", "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Невозможно связать; будет превышен максимум ${COUNT} связанных аккаунтов.", - "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Ах ты, читер; Очки и награды заморожены на ${COUNT} дней.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Жульничать нехорошо! Очки и награды заморожены на ${COUNT} дней.", "Could not establish a secure connection.": "Не удалось установить безопасное соединение.", - "Daily maximum reached.": "Хватит на сегодня.", + "Daily maximum reached.": "Суточный предел достигнут.", + "Daily sign-in reward": "Ежедневная награда за вход", "Entering tournament...": "Вход в турнир...", "Invalid code.": "Неверный код.", "Invalid payment; purchase canceled.": "Что-то пошло не так. Покупка отменена.", @@ -1706,11 +1817,14 @@ "Item unlocked!": "Предмет разблокирован!!!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "СВЯЗКА ЗАПРЕЩЕНА. ${ACCOUNT} содержит \nважные данные, которые БУДУТ ПОТЕРЯНЫ.\nВы можете связать в обратном порядке\n(и потерять данные ЭТОГО аккаунта)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Связать этот ${ACCOUNT} аккаунт с этим?\nВсе существующие данные на ${ACCOUNT} будут потеряны.\nЭто действие не может быть отменено. Вы уверены?", + "Longer streaks lead to better rewards.": "Чем дольше дней вы заходите в игру подряд, тем лучше награды.", "Max number of playlists reached.": "Достигнуто максимальное количество плейлистов.", "Max number of profiles reached.": "Достигнуто максимальное количество профилей.", "Maximum friend code rewards reached.": "Достигнут лимит кодов.", "Message is too long.": "Сообщение слишком длинное.", + "New tournament result!": "Новый результат турнира!", "No servers are available. Please try again soon.": "Нет доступных серверов. Пожалуйста попробуйте позднее.", + "No slots available. Free a slot and try again.": "Все места заняты. Освободите место и попробуйте ещё раз.", "Profile \"${NAME}\" upgraded successfully.": "Профиль \"${NAME}\" обновлен успешно.", "Profile could not be upgraded.": "Профиль не может быть обновлен.", "Purchase successful!": "Успешная транзакция!", @@ -1720,7 +1834,9 @@ "Sorry, this code has already been used.": "Упс, этот код уже использован.", "Sorry, this code has expired.": "Упс, время действия кода истекло.", "Sorry, this code only works for new accounts.": "Упс, этот код работает только для новых аккаунтов.", + "Sorry, this has expired.": "Упс, время истекло.", "Still searching for nearby servers; please try again soon.": "Ведётся поиск ближайших серверов; пожалуйста попробуйте позднее.", + "Streak: ${NUM} days": "Промежуток: ${NUM} дней", "Temporarily unavailable; please try again later.": "Временно недоступно; Пожалуйста, повторите попытку позже.", "The tournament ended before you finished.": "Турнир закончился прежде, чем вы закончили.", "This account cannot be unlinked for ${NUM} days.": "Этот аккаунт невозможно отвязать в течение ${NUM} дней.", @@ -1730,21 +1846,30 @@ "Tournaments disabled due to rooted device.": "Турниры отключены из-за рутированного устройства.", "Tournaments require ${VERSION} or newer": "Для турниров требуется версия ${VERSION} или выше.", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Отвязать ${ACCOUNT} от этого аккаунта?\nВсе данные на ${ACCOUNT} будут сброшены.\n(за исключением достижений в некоторых случаях)", - "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ПРЕДУПРЕЖДЕНИЕ: жалобы на хакерство были выданы на вашу учетную запись.\nУчетные записи, которые считаются взломанными, будут заблокированы. Пожалуйста, играйте честно.", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ПРЕДУПРЕЖДЕНИЕ: на Ваш аккаунт поступили жалобы о жульничестве.\nАккаунты, использующиеся для жульничества будут заблокированы. Пожалуйста, играйте честно.", + "Wait reduced!": "Время ожидания уменьшено!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Предупреждение: эта версия игры ограничена старыми данными учетной записи; некоторые данные могут отсутствовать или быть устаревшими.\nПожалуйста, обновите игру до более новой версии, чтобы увидеть последние данные учетной записи.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Желаете связать аккаунт устройства вот c этим?\n\nАккаунт устройства ${ACCOUNT1}\nТекущий аккаунт ${ACCOUNT2}\n\nЭто позволит сохранить ваши нынешние достижения.\nВнимание: отмена невозможна!", "You already own this!": "Вы это уже приобрели!", - "You can join in ${COUNT} seconds.": "Ты можешь войти через ${COUNT} секунд", + "You can join in ${COUNT} seconds.": "Вы можете войти через ${COUNT} секунд.", "You don't have enough tickets for this!": "У вас недостаточно билетов для этой покупки!", - "You don't own that.": "У вас этого нету.", + "You don't own that.": "У вас этого нет.", "You got ${COUNT} tickets!": "Вы получили ${COUNT} билетов!", + "You got ${COUNT} tokens!": "У вас ${COUNT} токенов!", "You got a ${ITEM}!": "Вы получили ${ITEM}!", + "You got a chest!": "Вы получили сундук!", + "You got an achievement reward!": "Вы получили награду за достижение!", "You have been promoted to a new league; congratulations!": "Вас повысили и перевели в новую лигу; поздравляем!", + "You lost a chest! (All your chest slots were full)": "Вы потеряли сундук! (Ваш инвентарь полон)", + "You must update the app to view this.": "Вы должны обновить игру чтобы увидеть это.", "You must update to a newer version of the app to do this.": "Чтобы это сделать, вы должны обновить приложение.", "You must update to the newest version of the game to do this.": "Вы должны обновиться до новейшей версии игры, чтобы сделать это.", "You must wait a few seconds before entering a new code.": "Подождите несколько секунд, прежде чем вводить новый код.", + "You placed #${RANK} in a tournament!": "Вы заняли #${RANK} в турнире!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ваш ранг в последнем турнире: ${RANK}! Спасибо за игру!", "Your account was rejected. Are you signed in?": "Ваш аккаунт отклонён. Вы вошли в систему?", - "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версия игры была модифицирована.\nУберите все изменения и попробуйте снова.", + "Your ad views are not registering. Ad options will be limited for a while.": "Ваши просмотры рекламы не регистрируются. Функция рекламы будет ограничена какое-то время.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версия игры модифицирована.\nУберите все изменения (в т.ч. плагины) и попробуйте снова.", "Your friend code was used by ${ACCOUNT}": "Ваш код был использован ${ACCOUNT}" }, "settingNames": { @@ -1766,13 +1891,13 @@ "Enable Impact Bombs": "Включить ударные бомбы", "Enable Triple Bombs": "Включить тройные бомбы", "Entire Team Must Finish": "Вся команда должна финишировать", - "Epic Mode": "Эпический режим", + "Epic Mode": "Замедленный режим", "Flag Idle Return Time": "Время возврата брошенного флага", "Flag Touch Return Time": "Время захвата флага", "Hold Time": "Время удержания", "Kills to Win Per Player": "Убийств на игрока до победы", "Laps": "Круги", - "Lives Per Player": "Жизней на игрока", + "Lives Per Player": "Кол-во жизней на игрока", "Long": "Долго", "Longer": "Дольше", "Mine Spawning": "Минирование", @@ -1791,7 +1916,7 @@ "statements": { "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} дисквалифицирована потому что ${PLAYER} вышел", "Killing ${NAME} for skipping part of the track!": "Ликвидация ${NAME} за срезание трассы!", - "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Предупреждение для ${NAME}: за турбо / быстрое повторное нажатие кнопки можно вырубится." + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Предупреждение для ${NAME}: за быстрое повторное нажатие кнопки(ок) можно уснуть." }, "teamNames": { "Bad Guys": "Негодяи", @@ -1856,7 +1981,7 @@ "trophiesText": "Трофеев", "trophiesThisSeasonText": "Трофеи за этот Сезон", "tutorial": { - "cpuBenchmarkText": "Прогон тьюториала на безумной скорости (проверяет скорость процессора)", + "cpuBenchmarkText": "Запуск обучения на безумной скорости (проверяет скорость процессора)", "phrase01Text": "Привет!", "phrase02Text": "Добро пожаловать в ${APP_NAME}!", "phrase03Text": "Несколько советов по управлению персонажем:", @@ -1886,35 +2011,42 @@ "phrase27Text": "Не забывай эти советы, и ТОЧНО вернешься живым!", "phrase28Text": "...может быть...", "phrase29Text": "Удачи!", - "randomName1Text": "Вася", - "randomName2Text": "Петя", - "randomName3Text": "Иннокентий", - "randomName4Text": "Шурик", - "randomName5Text": "Виталик", - "skipConfirmText": "Пропустить тьюториал? Коснитесь или нажмите кнопку для подтверждения.", + "randomName1Text": "Фрэд", + "randomName2Text": "Гарри", + "randomName3Text": "Билл", + "randomName4Text": "Чак", + "randomName5Text": "Фил", + "skipConfirmText": "Пропустить обучение? Коснитесь или нажмите кнопку для подтверждения.", "skipVoteCountText": "${COUNT}/${TOTAL} голосов за пропуск", "skippingText": "пропуск обучения...", - "toSkipPressAnythingText": "(коснитесь или нажмите что-нибудь чтобы пропустить тьюториал)" + "toSkipPressAnythingText": "(коснитесь или нажмите что-нибудь чтобы пропустить обучение)" }, "twoKillText": "ДВОИХ ЗА РАЗ!", + "uiScaleText": "Размер UI", "unavailableText": "недоступно", + "unclaimedPrizesText": "У вас есть не полученные призы!", "unconfiguredControllerDetectedText": "Обнаружен ненастроенный геймпад:", "unlockThisInTheStoreText": "Это должно быть разблокировано в магазине.", "unlockThisProfilesText": "Чтобы создать более ${NUM} профиль, Вам необходимо:", "unlockThisText": "Чтобы разблокировать это, вам нужно:", + "unsupportedControllerText": "К сожалению, контроллер \"${NAME}\" не поддерживается.", "unsupportedHardwareText": "К сожалению, это оборудование не поддерживается в этой сборке игры.", "upFirstText": "Для начала:", "upNextText": "Далее в игре ${COUNT}:", - "updatingAccountText": "Обновление вашего аккаунта", + "updatingAccountText": "Обновление вашего аккаунта...", "upgradeText": "Обновление", "upgradeToPlayText": "Разблокируйте \"${PRO}\" в магазине что-бы играть в это.", "useDefaultText": "Использовать стандартные", + "userSystemScriptsCreateText": "Создать Свои Скрипты", + "userSystemScriptsDeleteText": "Стереть Свои Скрипты", "usesExternalControllerText": "Эта игра может использовать внешний контроллер для управления.", "usingItunesText": "Использование музыкального приложения для саундтрека...", "usingItunesTurnRepeatAndShuffleOnText": "Убедитесь, что в iTunes включен случайный порядок, и повтор установлен на 'все'.", - "v2AccountLinkingInfoText": "Чтобы обьединить старый и новый аккаунты, используйте кнопку 'Обьединить аккаунты'", + "v2AccountLinkingInfoText": "Чтобы обьединить V2 аккаунты, используйте кнопку 'Обьединить аккаунты'", + "v2AccountRequiredText": "Для этого требуется учетная запись V2. Обновите свою учетную запись и повторите попытку.", "validatingBetaText": "Валидация бета-версии...", "validatingTestBuildText": "Проверка тестовой сборки...", + "viaText": "используя", "victoryText": "Победа!", "voteDelayText": "Невозможно начать новое голосование еще ${NUMBER} секунд", "voteInProgressText": "Голосование уже в процессе.", @@ -1924,7 +2056,7 @@ "waitingForHostText": "(ожидание ${HOST} чтобы продолжить)", "waitingForLocalPlayersText": "ожидание локальных игроков...", "waitingForPlayersText": "ожидание присоединения игроков...", - "waitingInLineText": "Подожди немного (комната заполнена)...", + "waitingInLineText": "Подождите немного (лобби заполнено)...", "watchAVideoText": "Смотреть видео", "watchAnAdText": "Смотреть рекламу", "watchWindow": { @@ -1968,8 +2100,8 @@ "winsText": "${NAME} выиграл!", "workspaceSyncErrorText": "Ошибка при попытке синхронизации ${WORKSPACE}. Посмотрите лог для информации.", "workspaceSyncReuseText": "Не получается синхронизировать ${WORKSPACE}. Используется прошлая синхронизация.", - "worldScoresUnavailableText": "Мировые результаты недоступны.", - "worldsBestScoresText": "Лучшие в мире очки", + "worldScoresUnavailableText": "Мировые рекорды не доступны", + "worldsBestScoresText": "Лучшие в мире результаты", "worldsBestTimesText": "Лучшее в мире время", "xbox360ControllersWindow": { "getDriverText": "Скачать драйвер", @@ -1981,5 +2113,6 @@ }, "yesAllowText": "Да, разрешить!", "yourBestScoresText": "Ваши лучшие очки", - "yourBestTimesText": "Ваше лучшее время" + "yourBestTimesText": "Ваше лучшее время", + "yourPrizeText": "Ваш приз:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/serbian.json b/dist/ba_data/data/languages/serbian.json index 2ea8600e..e3555917 100644 --- a/dist/ba_data/data/languages/serbian.json +++ b/dist/ba_data/data/languages/serbian.json @@ -8,6 +8,8 @@ "changeOncePerSeason": "Ово можеш променити само једном током сезоне.", "changeOncePerSeasonError": "Мораш сачекати следећу сезону да би ово опет променио (${NUM} дан/а)", "customName": "Сопствено име", + "deleteAccountText": "избрисати налог", + "googlePlayGamesAccountSwitchText": "Ако желите да користите други Гоогле налог,\nкористите апликацију Гоогле Плаи игре за пребацивање.", "linkAccountsEnterCodeText": "Унеси код", "linkAccountsGenerateCodeText": "Генериши код", "linkAccountsInfoText": "(подели напредак на више резличитих уређаја)", @@ -15,6 +17,7 @@ "linkAccountsInstructionsText": "Da povežeš dva profila, generiši kod sa jednog \nod njih i unesi kod na drugi.\nNapredak i inventar će biti spojeni.\nMožeš povezati najviše ${COUNT} profila.\n\nPAŽNJA:Samo poveži naloge koje poseduješ!\nAko povežeš naloge sa prijateljima onda\nnećeš biti u mogućnosti da igraš u isto vreme!\n\nVAŽNO:Ovo se trenutno ne može poništiti, zato budi pažljiv!", "linkAccountsText": "Повежи налоге", "linkedAccountsText": "Повезани налози:", + "manageAccountText": "Управљајте налогом", "nameChangeConfirm": "Промени име налога у ${NAME}?", "resetProgressConfirmNoAchievementsText": "Ово ће твој кооперативни напредак и локалне \nрекорде вратити на почетак (али не и тикете).\nОво се не може поништити. Да ли си сигуран?", "resetProgressConfirmText": "Ово ће твој кооперативни напредак,\nдостигнућа и локалне рекорде (али не\nи тикете) вратити на почетак. Ово се\nне може поништити. Да ли си сигуран?", @@ -23,14 +26,16 @@ "setAccountNameDesc": "Изабери име које ће се приказивати на твом налогу.\nМожеш користити име са једног од твоји повезаних\nналога или направити ново јединствено име.", "signInInfoText": "Пријави се да зарађујеш тикете, такмичиш на мрежи\nи делиш напредак на више различитих уређаја.", "signInText": "Пријави се", + "signInWithAnEmailAddressText": "Пријавите се помоћу адресе е-поште", "signInWithDeviceInfoText": "(аутоматски налог достпупан једино са овог уређаја)", "signInWithDeviceText": "Пријави се налогом уређаја", "signInWithGameCircleText": "Пријави се преко Гејм Сркла.", "signInWithGooglePlayText": "Пријави се преко Гугл Плеја", "signInWithTestAccountInfoText": "(налог за тестирање нових ствари које ће ускоро изаћи)", "signInWithTestAccountText": "Пријави се са тест профилом", + "signInWithText": "Пријавите се помоћу ${SERVICE}", "signInWithV2InfoText": "(налог који функционише на свим платформама)", - "signInWithV2Text": "Улогуј се помоћу Bombsquad налога", + "signInWithV2Text": "Улогуј се помоћу ${APP_NAME} налога", "signOutText": "Одјави се", "signingInText": "Пријављивање...", "signingOutText": "Одјављивање...", @@ -40,6 +45,7 @@ "titleText": "Налог", "unlinkAccountsInstructionsText": "Изабери налог за раздвајање", "unlinkAccountsText": "Раздвоји налоге", + "unlinkLegacyV1AccountsText": "Прекините везу са старим (V1) налозима", "v2LinkInstructionsText": "Искористи овај линк да направиш налог или да се улогујеш.", "viaAccount": "(преко налога ${NAME})", "youAreSignedInAsText": "Пријављен си као:" @@ -333,9 +339,11 @@ "getMoreGamesText": "Додај више игри...", "titleText": "Додај игру" }, + "addToFavoritesText": "Додај у фаворите", "allowText": "Дозволи", "alreadySignedInText": "Овај налог је тренутно пријављен на другом уређају;\nмолимо вас да замените налог или искључите игру на\nдругом уређају и покушате поново.", "apiVersionErrorText": "Не можемо учитати мод ${NAME}; он тражи верзију ${VERSION_USED}; ми користимо ${VERSION_REQUIRED}.", + "areYouSureText": "Јесте ли сигурни?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Аутоматски\" активира само када су прикључене слушалице)", "headRelativeVRAudioText": "Виртуелни аудио у простору", @@ -623,6 +631,7 @@ "useMusicFolderText": "Фолдер са музичким фајловима" }, "editText": "Измени", + "enabledText": "Омогућено", "endText": "Крај", "enjoyText": "Уживај!", "epicDescriptionFilterText": "${DESCRIPTION} у епско успореној игри.", @@ -1809,6 +1818,7 @@ "upgradeText": "Надогради", "upgradeToPlayText": "Откључај \"${PRO}\" у продавници игре да играш ово.", "useDefaultText": "Користи подразумевано", + "userSystemScriptsCreateText": "Креирајте корисничке системске скрипте", "usesExternalControllerText": "Ова игра користи спољашњи контролер за унос.", "usingItunesText": "Коришћење музичке апликације за листу звукова...", "validatingTestBuildText": "Потврђивање система за тестирање...", @@ -1843,6 +1853,7 @@ }, "waveText": "Рунда", "wellSureText": "Наравно!", + "whatIsThisText": "шта је ово?", "wiimoteLicenseWindow": { "titleText": "Дарвин Римоут права задржана" }, diff --git a/dist/ba_data/data/languages/slovak.json b/dist/ba_data/data/languages/slovak.json index 8acf13b2..09df88d2 100644 --- a/dist/ba_data/data/languages/slovak.json +++ b/dist/ba_data/data/languages/slovak.json @@ -8,6 +8,8 @@ "changeOncePerSeason": "Toto môžete zmeniť len raz za sezónu.", "changeOncePerSeasonError": "Musíte počkať do ďalšej sezóny aby ste mohli toto znova zmeniť (${NUM} days)", "customName": "Vlastný názov", + "deleteAccountText": "Zmazať Účet", + "googlePlayGamesAccountSwitchText": "Ak chcete použiť iný účet Google,\nna jeho výmenu použite aplikáciu hry Google Play.", "linkAccountsEnterCodeText": "Vložte kód", "linkAccountsGenerateCodeText": "Vygenerovať kód", "linkAccountsInfoText": "(zdielajte postup medzi rôznymi platformami)", @@ -25,14 +27,16 @@ "setAccountNameDesc": "Vyberte meno, ktoré sa bude zobrazovať na vašom účte.\nMôžete použiť meno jedného zo svojich prepojených \núčtov alebo si vytvorte svoje vlastné meno.", "signInInfoText": "Prihláste sa, abyste zbierali tickety, dokončite online \na zdielajte postup medzi zariadeními.", "signInText": "Prihlasujem", + "signInWithAnEmailAddressText": "Prihláste sa s e-mailovým účtom", "signInWithDeviceInfoText": "(iba automatický účet je dostupný pre toto zariadenie)", "signInWithDeviceText": "Prihláste sa s účtom na zariadení", "signInWithGameCircleText": "Prihlásiť sa s Game Circle", "signInWithGooglePlayText": "Príhlásit sa s Google Play", "signInWithTestAccountInfoText": "(starý typ účtu; v budúcnosti používajte účty zariadení)", "signInWithTestAccountText": "Prihlásit sa s testovacím účtom", + "signInWithText": "Prihlás sa s ${SERVICE}", "signInWithV2InfoText": "(účet, ktorý funguje na všetkých platformách)", - "signInWithV2Text": "Prihláste sa pomocou účtu BombSquad", + "signInWithV2Text": "Prihláste sa pomocou účtu ${APP_NAME}", "signOutText": "Odhlasujem", "signingInText": "Prihlasujem", "signingOutText": "Odhlasujem", @@ -42,6 +46,7 @@ "titleText": "Konto", "unlinkAccountsInstructionsText": "Vyberte účet, s ktorým chcete zrušiť prepojenie", "unlinkAccountsText": "Zrušiť prepojenie účtov", + "unlinkLegacyV1AccountsText": "Odpojiť Staré (V1) Účty", "v2LinkInstructionsText": "Pomocou tohto odkazu si vytvorte účet alebo sa prihláste.", "viaAccount": "(cez účet ${NAME})", "youAreLoggedInAsText": "Si prihlásený ako:", @@ -336,9 +341,14 @@ "getMoreGamesText": "Viac Hier...", "titleText": "Pridať Hru" }, + "addToFavoritesText": "Pridať do Obľúbených", + "addedToFavoritesText": "'${NAME}' pridané do Obľúbených.", + "allText": "Všetko", "allowText": "Povol", "alreadySignedInText": "Tvoj účet je prihlásený z iného zariadenia;\nprosím prepni si účty alebo ukonči hru na\ntvojich ostatných zariadeniach a skús to znovu.", "apiVersionErrorText": "Nemožno načítať modul ${NAME}; používa api-verziu ${VERSION_USED}; my potrebujeme ${VERSION_REQUIRED}.", + "applyText": "Uložiť Zmeny", + "areYouSureText": "Ste si istý?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Automatika\" toto povolí len keď sú slúchadlá zapojené)", "headRelativeVRAudioText": "Head-Relative VR Audio", @@ -360,7 +370,7 @@ "boostText": "Pridať", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} je nastavené v aplikácii", "buttonText": "tlačidlo", - "canWeDebugText": "Chcel by si, aby Bombsquad automaticky nahlasovalo\nbugy, crashe, a základné informácie o použití vývojárovi?\n\nToto data neobsahuje žiadne osobné informácie a pomáha\nnechávať hru bežať hladko a bez bugov.", + "canWeDebugText": "Chcel by si, aby ${APP_NAME}\nautomaticky nahlasovalo bugy, \ncrashe, \na základné informácie\no použití vývojárovi?", "cancelText": "Zrušiť", "cantConfigureDeviceText": "Prepáč, ${DEVICE} nie je konfigurovateľný", "challengeEndedText": "Táto challenge skončila.", @@ -368,6 +378,7 @@ "chatMutedText": "Čet Zablokovaný", "chatUnMuteText": "Odblokovať Čet", "choosingPlayerText": "", + "codesExplainText": "Kódy sú poskytované vývojárovi \nk diagnostike a oprave problémov s účtom.", "completeThisLevelToProceedText": "Musíš dokončiť\ntento level pre postup!", "completionBonusText": "Bonus za Dokončenie", "configControllersWindow": { @@ -448,6 +459,7 @@ "swipeText": "posúvanie", "titleText": "Konfigurovať Obrazovku" }, + "configureDeviceInSystemSettingsText": "${DEVICE} možno nakonfigurovať v systémových nastaveniach aplikácie.", "configureItNowText": "Konfigurovať teraz?", "configureText": "Konfigurovať", "connectMobileDevicesWindow": { @@ -549,7 +561,10 @@ "deleteText": "Vymazať", "demoText": "Demo", "denyText": "odmietnuť", + "deprecatedText": "Zastaralé", + "descriptionText": "Popis", "desktopResText": "Desktop Res", + "deviceAccountUpgradeText": "Upozornenie:\nSte pripojený v účte (${NAME}) typu zariarenie.\nÚčty takého typu budú odstránené v budúcej aktualizácii.\nAktualizujte to na V2 Účet keď chcete zachovať váš pokrok.", "difficultyEasyText": "Jednoduchá", "difficultyHardOnlyText": "Len Ťažký Mód", "difficultyHardText": "Ťažké", @@ -558,6 +573,10 @@ "disableRemoteAppConnectionsText": "Zakázať Remote-App Pripojenia", "disableXInputDescriptionText": "Povolí viac ako 4 ovládače ale nemusí fungovať dobre.", "disableXInputText": "Zakázať XInput", + "disabledText": "Vypnuté", + "discardText": "Odhodiť", + "discordFriendsText": "Chcete nájsť nových ľudí na hranie?\nPripojte sa na náš Discord a nájdite nových priateľov!", + "discordJoinText": "Pripojiť na Diskord", "doneText": "Hotovo", "drawText": "Remíza", "duplicateText": "Duplikovať", @@ -590,6 +609,7 @@ "localProfileText": "(lokálny profil)", "nameDescriptionText": "Meno Hráča", "nameText": "Meno", + "profileAlreadyExistsText": "Profil s týmto menom už existuje.", "randomText": "náhodne", "titleEditText": "Upraviť Profil", "titleNewText": "Nový Profil", @@ -625,6 +645,7 @@ "useMusicFolderText": "Zložka Súborov Hudby" }, "editText": "Upraviť", + "enabledText": "Povolené", "endText": "Ukončiť", "enjoyText": "Užite si to!", "epicDescriptionFilterText": "${DESCRIPTION} Spomalene.", @@ -670,6 +691,8 @@ "duplicateText": "Duplikovať\nPlaylist", "editText": "Upraviť\nPlaylist", "newText": "Nový\nPlaylist", + "pointsToWinText": "Body ku výhre", + "seriesLengthText": "Dĺžka Série", "showTutorialText": "Ukázať Tutoriál", "shuffleGameOrderText": "Náhodné Poradie Hier", "titleText": "Upraviť ${TYPE} Playlisty" @@ -710,7 +733,7 @@ "friendPromoCodeInstructionsText": "Ak ho chceš použiť, otvor ${APP_NAME} a choď do \"Settings->Advanced->Enter Code\".\nPozri bombsquadgame.com pre download linky pre všetky podporované platformy.", "friendPromoCodeRedeemLongText": "Môže byť uplatnený za ${COUNT} tiketov až pre ${MAX_USES} ľudí.", "friendPromoCodeRedeemShortText": "Môže byť uplatnený za ${COUNT} tiketov v hre.", - "friendPromoCodeWhereToEnterText": "(v časti „Nastavenia-> Pokročilé-> Zadať kód“)", + "friendPromoCodeWhereToEnterText": "(V časti „Nastavenia-> Pokročilé-> Poslať info\")", "getFriendInviteCodeText": "Zohnať Pozvánku", "googlePlayDescriptionText": "Pozvi Google Play hráčov do párty:", "googlePlayInviteText": "Pozvať", @@ -742,6 +765,7 @@ "manualYourLocalAddressText": "Tvoja lokálna adresa:", "nearbyText": "Neďaleko", "noConnectionText": "<žiadne pripojenie>", + "noPartiesAddedText": "Žiadne Párty nie sú pridané", "otherVersionsText": "(ostatné verzie)", "partyCodeText": "Párty kód", "partyInviteAcceptText": "Potvrdiť", @@ -805,6 +829,12 @@ "youHaveShortText": "máš ${COUNT}", "youHaveText": "máš ${COUNT} tiketov" }, + "goldPass": { + "desc1InfTokensText": "Nekonečné tokeny.", + "desc2NoAdsText": "Žiadné reklamy.", + "desc3ForeverText": "Navždy.", + "goldPassText": "Zlatá Priepustka." + }, "googleMultiplayerDiscontinuedText": "Prepáč, Google multiplayer už viac nie je dostupný.\nSnažím sa to prehodiť čo najskôr. Dovtedy prosím\nskús inú metódu pripojenia.\n-Eric", "googlePlayPurchasesNotAvailableText": "Nákupy Google Play nie sú dostupné.\nAsi musíte aktualizovať svoju obchodnú aplikáciu.", "googlePlayServicesNotAvailableText": "Služby Google Play nie sú dostupné.\nNiektoré funkčnosti aplikácie môžu byť vypnuté.", @@ -813,10 +843,12 @@ "alwaysText": "Stále", "fullScreenCmdText": "Celá Obrazovka (Cmd+F)", "fullScreenCtrlText": "Celá Obrazovka (Ctrl+F)", + "fullScreenText": "Na celú obrazovku", "gammaText": "Gamma", "highText": "Vysoko", "higherText": "Vyššie", "lowText": "Nízko", + "maxFPSText": "Maximálny počet FPS", "mediumText": "Stredne", "neverText": "Nikdy", "resolutionText": "Rozlíšenie", @@ -1024,6 +1056,7 @@ "maxConnectionsText": "Maximum Pripojení", "maxPartySizeText": "Maximálna Veľkosť Párty", "maxPlayersText": "Maximum Hráčov", + "merchText": "Merch!", "modeArcadeText": "Arkádový režim", "modeClassicText": "Klasický režim", "modeDemoText": "Demo režim", @@ -1043,6 +1076,7 @@ "nameSuicideText": "${NAME} spáchal samovraždu.", "nameText": "Meno", "nativeText": "Prírodné", + "newExclaimText": "Nové!", "newPersonalBestText": "Nový osobný rekord!", "newTestBuildAvailableText": "Novšia testovacia verzia je dostupná! (${VERSION} test ${BUILD}).\nZožeň ho na ${ADDRESS}", "newText": "Nový", @@ -1053,7 +1087,10 @@ "noContinuesText": "(žiadne pokračovania)", "noExternalStorageErrorText": "Žiadne úložisko sa v tomto zariadení nenašlo", "noGameCircleText": "Error: nie si prihlásený do GameCircle", + "noMessagesText": "Žiadné Správy.", + "noPluginsInstalledText": "Žiadne nainštalované doplnky", "noScoresYetText": "Zatiaľ žiadne skóre.", + "noServersFoundText": "Nenašiel sa žiadny server.", "noThanksText": "Nie Vďaka", "noTournamentsInTestBuildText": "UPOZORNENIE: Výsledky turnajov z tejto testovacej zostavy budú ignorované.", "noValidMapsErrorText": "Žiadne platné mapy sa pre tento typ hry nenašli.", @@ -1063,6 +1100,7 @@ "notSignedInErrorText": "Ak toto chceš urobiť, musíš sa prihlásiť.", "notSignedInGooglePlayErrorText": "Ak chceš toto urobiť, musíš sa prihlásiť do Google Play.", "notSignedInText": "nie si prihlásený", + "notUsingAccountText": "Poznámka: ignoruje sa ${SERVICE} účet.\nChoďte na 'Účet -> Prihlásiť sa s ${SERVICE}' pokiaľ to chcete použiť.", "nothingIsSelectedErrorText": "Nič nie je vybraté!", "numberText": "#${NUMBER}", "offText": "Vypnúť", @@ -1121,7 +1159,11 @@ "pleaseWaitText": "Prosím počkaj...", "pluginClassLoadErrorText": "Chyba pri načítaní triedy doplnku '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Chyba pri iniciovaní doplnku '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Nastavenia Pluginov", + "pluginsAutoEnableNewText": "Automaticky Aktivovať Nové Pluginy", "pluginsDetectedText": "Bol zistený nový doplnok(ky). Reštartujte aby sa aktivovali, alebo ich nakonfigurte v nastaveniach.", + "pluginsDisableAllText": "Deaktivovať Všetky Pluginy", + "pluginsEnableAllText": "Aktivovať Všetky Pluginy", "pluginsRemovedText": "${NUM} doplnok(ky) nebol najdený.", "pluginsText": "Pluginy", "practiceText": "Tréning", @@ -1212,7 +1254,9 @@ "revertText": "Späť", "runText": "Bežať", "saveText": "Uložiť", - "scanScriptsErrorText": "Error pri skenovaní skriptov; pozri zápis pre detaily.", + "scanScriptsErrorText": "Chyba pri skenovaní skriptov. Pozri zápis pre detaily.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} a ${NUM} ďalšie moduly je potrebné aktualizovať pre api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} je potrebné aktualizovať pre api ${API}.", "scoreChallengesText": "Challenge pre Skóre", "scoreListUnavailableText": "List pre skóre je nedostupné.", "scoreText": "Skóre", @@ -1238,7 +1282,7 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(jednoduchá, podporujúca-ovládač na-obrazovke-klávesnica pre písanie textu)", - "alwaysUseInternalKeyboardText": "Stále Používať Klávesnicu v Programe", + "alwaysUseInternalKeyboardText": "Stále používať klávesnicu v programe", "benchmarksText": "Benchmarky & Stres-Testy", "disableCameraGyroscopeMotionText": "Zakázať pohyb gyroskopu fotoaparátu", "disableCameraShakeText": "Zakázať otrasy fotoaparátu", @@ -1256,6 +1300,9 @@ "netTestingText": "Testovanie Internetu", "resetText": "Resetovať", "showBombTrajectoriesText": "Ukázovať Trajektóriu Bomby", + "showDemosWhenIdleText": "Zobraziť Ukážky Pri Nečinnosti", + "showDevConsoleButtonText": "Zobraziť Tlačidlo Konzoly Zariadenia", + "showInGamePingText": "Ukázať Ping v Hre", "showPlayerNamesText": "Ukazovať Mená Hráčov", "showUserModsText": "Ukázať Zložku pre Módy", "titleText": "Pokročilé", @@ -1274,6 +1321,9 @@ "signInWithGameCenterText": "Ak chceš použiť GameCircle účet,\nprihlás sa s Game Center aplikáciou.", "singleGamePlaylistNameText": "Len ${GAME}", "singlePlayerCountText": "1 hráč", + "sizeLargeText": "Velké", + "sizeMediumText": "Stredné", + "sizeSmallText": "Malé", "soloNameFilterText": "Sólo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Výber Charakteru", @@ -1346,6 +1396,8 @@ "storeText": "Obchod", "submitText": "Poslať", "submittingPromoCodeText": "Overujem Kód...", + "successText": "Úspech!", + "supportEmailText": "Ak sa vyskytujú nejaké problémy s aplikáciou,\npošlite e-mail na adresu ${EMAIL}.", "teamNamesColorText": "Mená/Farby tímov", "telnetAccessGrantedText": "Telnet povolené.", "telnetAccessText": "Telnet detekovaný; povoliť?", @@ -1526,6 +1578,7 @@ "Italian": "Taliančina", "Japanese": "Japončina", "Korean": "Kórejčina", + "Malay": "Malajčina", "Persian": "Perzština", "Polish": "Poľština", "Portuguese": "Portugálčina", @@ -1798,6 +1851,7 @@ "unlockThisInTheStoreText": "Toto musí byť odomknuté v obchode.", "unlockThisProfilesText": "Ak chceš vytvoriť viac ako ${NUM} profilov, potrebuješ:", "unlockThisText": "Ak chceš toto odomknúť, potrebuješ:", + "unsupportedControllerText": "Je nám ľúto, ovládač \"${NAME}\" nie je podporovaný.", "unsupportedHardwareText": "Prepáč, tento hardware nie je podporovaný pre túto verziu hry.", "upFirstText": "Ako prvé ide:", "upNextText": "Ďalej v hre ${COUNT}:", @@ -1807,7 +1861,9 @@ "useDefaultText": "Použiť Štandartné", "usesExternalControllerText": "Táto hra používa ako vstup externý ovládač.", "usingItunesText": "Používam Music App ako soundtrack...", + "v2AccountLinkingInfoText": "Na prepojenie V2 účtov, použi tlačidlo 'Spravovať Účet'.", "validatingTestBuildText": "Overujem Testovaciu Verziu...", + "viaText": "ako", "victoryText": "Výhra!", "voteDelayText": "Nemôžeš začať ďalšie hlasovanie v podobe ${NUMBER} sekúnd", "voteInProgressText": "Hlasovanie už prebieha.", @@ -1839,6 +1895,7 @@ }, "waveText": "Vlna", "wellSureText": "Jasné!", + "whatIsThisText": "Toto je čo?", "wiimoteLicenseWindow": { "titleText": "DarwiinRemote Copyright" }, diff --git a/dist/ba_data/data/languages/spanish.json b/dist/ba_data/data/languages/spanish.json index c2f9bb09..7d8c601d 100644 --- a/dist/ba_data/data/languages/spanish.json +++ b/dist/ba_data/data/languages/spanish.json @@ -1,40 +1,42 @@ { "accountSettingsWindow": { - "accountNameRules": "Los nombres no deben contener emojis o caracteres especiales", + "accountNameRules": "Los nombres de cuentas no pueden contener emojis o otros caracteres especiales", "accountProfileText": "(Perfil de la cuenta)", "accountsText": "Cuentas", "achievementProgressText": "Logros: ${COUNT} de ${TOTAL}", - "campaignProgressText": "Progreso de campaña [Difícil]: ${PROGRESS}", - "changeOncePerSeason": "Solamente puedes cambiarlo una vez por temporada.", + "campaignProgressText": "Progreso De La Campaña [Difícil]: ${PROGRESS}", + "changeOncePerSeason": "Solo puedes cambiarlo una vez por temporada.", "changeOncePerSeasonError": "Debes esperar hasta la siguiente temporada para cambiarlo de nuevo (en ${NUM} día/s)", - "customName": "Nombre personalizado", + "customName": "Nombre Personalizado", "deviceSpecificAccountText": "Actualmente usando una cuenta específica de dispositivo: ${NAME}", - "googlePlayGamesAccountSwitchText": "Si quieres cambiar a otra cuenta de Google,\nusa Google Play para cambiar tu cuenta.", - "linkAccountsEnterCodeText": "Registrar Código", + "googlePlayGamesAccountSwitchText": "Si quieres usar una cuenta diferente de Google,\nusa la app Google Play Juegos para cambiarla.", + "linkAccountsEnterCodeText": "Introducir Código", "linkAccountsGenerateCodeText": "Generar Código", "linkAccountsInfoText": "(compartir progreso a través de diferentes plataformas)", - "linkAccountsInstructionsNewText": "Para enlazar dos cuentas, genera un código en la primera cuenta\ne introduce el código en la segunda. \nLos datos de la segunda cuenta serán compartidos con la primera.\n\n(Los datos de la primera cuenta se perderán).\n\nPuedes vincular hasta ${COUNT} cuentas.\n\nIMPORTANTE: enlaza cuentas tuyas;\nSi enlazas cuentas de tus amigos, no podrán jugar online al mismo tiempo.", + "linkAccountsInstructionsNewText": "Para vincular dos cuentas, genera un código en la primera \ne introduzca el código en la segunda. Los datos de \nla segunda cuenta se compartirán entre ambos.\n(Los datos de la primera cuenta se perderán).\n\nPuedes vincular hasta ${COUNT} cuentas.\n\nIMPORTANTE: Solo vincula cuentas tuyas; \nSi vinculas cuentas de tus amigos no serán \ncapaces de jugar en línea al mismo tiempo.", "linkAccountsInstructionsText": "Para enlazar dos cuentas, genera un código en una\n de ellas y escribe el código en la otra.\nEl progreso e accesorios se combinarán.\nPuedes enlazar hasta ${COUNT} cuentas. \n\nIMPORTANTE: Solo enlaza cuentas tuyas!\n\nSi enlazas cuentas con tus amigos no podrán jugar al mismo tiempo!\n\nTambién: esto no se puede deshacer actualmente, así que se cuidadoso!", - "linkAccountsText": "Enlazar Cuentas", - "linkedAccountsText": "Cuentas enlazadas:", + "linkAccountsText": "Vincular Cuentas", + "linkedAccountsText": "Cuentas Vinculadas:", "manageAccountText": "Administrar Cuenta", - "nameChangeConfirm": "¿Cambiar tu nombre a ${NAME}?", + "nameChangeConfirm": "¿Cambiar tu nombre de cuenta a ${NAME}?", "notLoggedInText": "", - "resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso en el modo\ncooperativo y tus puntajes (A excepción de tus tickets).\nNo podrás recuperar los cambios. ¿Estás seguro?", + "resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso cooperativo y \ntus puntajes locales (a excepción de tus boletos).\nEsto no puede deshacerse. ¿Estás seguro?", "resetProgressConfirmText": "Esto reiniciará tus logros, récords\ny progreso en el modo cooperativo.\nLos cambios no se pueden deshacer.\n¿Estás seguro?", - "resetProgressText": "Reiniciar progreso", - "setAccountName": "Establecer nombre de la cuenta", + "resetProgressText": "Reiniciar Progreso", + "setAccountName": "Establecer Nombre De Cuenta", "setAccountNameDesc": "Selecciona el nombre a mostrar para tu cuenta. \nPuedes usar el nombre de tu cuenta asociada\no crear un nombre personalizado.", - "signInInfoText": "Inicia sesión para obtener tickets, competir en línea\ny compartir tu progreso en otras plataformas.", - "signInText": "Iniciar sesión", + "signInInfoText": "Inicia sesión para obtener boletos, competir en línea\ny compartir tu progreso a través de plataformas.", + "signInText": "Iniciar Sesión", + "signInWithAnEmailAddressText": "Iniciar sesión con una dirección de correo electrónico", "signInWithDeviceInfoText": "(una cuenta automática disponible únicamente en este dispositivo)", "signInWithDeviceText": "Iniciar sesión con cuenta del dispositivo", "signInWithGameCircleText": "Iniciar sesión con Game Circle", "signInWithGooglePlayText": "Iniciar sesión con Google Play", - "signInWithTestAccountInfoText": "(Cuenta de prueba, usa la cuenta del dispositivo para avanzar)", - "signInWithTestAccountText": "Registrarse con una Cuenta de Prueba", + "signInWithTestAccountInfoText": "(tipo de cuenta heredada; usa las cuentas de dispositivos más adelante)", + "signInWithTestAccountText": "Iniciar sesión con cuenta de prueba", + "signInWithText": "Iniciar sesion con ${SERVICE}", "signInWithV2InfoText": "(una cuenta que funciona en todas las plataformas)", - "signInWithV2Text": "Inicia sesión con tu cuenta de BombSquad", + "signInWithV2Text": "Iniciar sesión con una cuenta de BombSquad", "signOutText": "Cerrar Sesión", "signingInText": "Iniciando sesión...", "signingOutText": "Cerrando sesión...", @@ -43,322 +45,325 @@ "testAccountWarningText": "Advertencia: te estás registrando con una cuenta de\nprueba. Esta cuenta está vinculada a este dispositivo y\npuede que se reinicie periódicamente. (Así que no\ngastes mucho tiempo coleccionando/desbloqueando objetos)\n\nJuega una versión pública del juego y usa una \"cuenta real\"\n(Game-Center, Google Plus, etc.) Esto también te dejará\nguardar tu progreso en la nube y poder compartirlo con\ndiferentes dispositivos.", "ticketsText": "Boletos: ${COUNT}", "titleText": "Cuenta", - "unlinkAccountsInstructionsText": "Selecciona una cuenta para dejar de enlazar con ella", - "unlinkAccountsText": "Desenlazar Cuentas", - "unlinkLegacyV1AccountsText": "Desvincular Cuenta Heredada (V1)", - "v2LinkInstructionsText": "Usa este enlace para crearte una cuenta o para iniciar sesión", - "viaAccount": "(por cuenta ${NAME})", + "unlinkAccountsInstructionsText": "Selecciona una cuenta para desvincular", + "unlinkAccountsText": "Desvincular Cuentas", + "unlinkLegacyV1AccountsText": "Desvincular Cuentas (V1) Heredadas", + "v2LinkInstructionsText": "Usa este enlace para crearte una cuenta o para iniciar sesión.", + "viaAccount": "(cuenta vía ${NAME})", "youAreLoggedInAsText": "Estás conectado como:", "youAreSignedInAsText": "Has iniciado sesión como:" }, - "achievementChallengesText": "Logros de desafíos", + "achievementChallengesText": "Desafios De Los Logros", "achievementText": "Logro", "achievements": { "Boom Goes the Dynamite": { - "description": "Elimina 3 enemigos con una caja de TNT", - "descriptionComplete": "Eliminaste a 3 enemigos con una caja de TNT", - "descriptionFull": "Elimina 3 enemigos con una caja de TNT en ${LEVEL}", - "descriptionFullComplete": "Eliminaste 3 enemigos con una caja de TNT en ${LEVEL}", - "name": "La dinamita hace Boom!" + "description": "Mata a 3 chicos malos con TNT", + "descriptionComplete": "Mató a 3 chicos malos con TNT", + "descriptionFull": "Mata a 3 chicos malos con TNT en ${LEVEL}", + "descriptionFullComplete": "Mató a 3 chicos malos con TNT en ${LEVEL}", + "name": "La Dinamita Hace Boom" }, "Boxer": { "description": "Gana sin usar bombas", - "descriptionComplete": "Ganaste sin usar ninguna bomba", + "descriptionComplete": "Ganó sin usar bombas", "descriptionFull": "Completa ${LEVEL} sin usar bombas", - "descriptionFullComplete": "Completaste ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completó ${LEVEL} sin usar bombas", "name": "Boxeador" }, "Dual Wielding": { "descriptionFull": "Conecta 2 controles (de hardware o de aplicación)", - "descriptionFullComplete": "2 controles conectados (de hardware o de aplicación)", - "name": "Juego Doble" + "descriptionFullComplete": "Conectó 2 controles (de hardware o de aplicación)", + "name": "Doble Empuñadura" }, "Flawless Victory": { - "description": "Gana sin haber recibido ningún golpe", - "descriptionComplete": "Ganaste sin ser golpeado", + "description": "Gana sin ser golpeado", + "descriptionComplete": "Ganó sin ser golpeado", "descriptionFull": "Gana ${LEVEL} sin ser golpeado", - "descriptionFullComplete": "Ganaste ${LEVEL} sin ser golpeado", - "name": "Victoria Perfecta" + "descriptionFullComplete": "Ganó ${LEVEL} sin ser golpeado", + "name": "Victoria Impecable" }, "Free Loader": { "descriptionFull": "Empieza un juego de Todos-Contra-Todos con 2 o más jugadores", - "descriptionFullComplete": "Has empezado un juego de Todos-Contra-Todos con 2 o más jugadores", + "descriptionFullComplete": "Empezó un juego de Todos-Contra-Todos con 2 o más jugadores", "name": "Cargador Libre" }, "Gold Miner": { - "description": "Elimina 6 enemigos con minas", - "descriptionComplete": "Eliminaste 6 enemigos con minas", - "descriptionFull": "Elimina 6 enemigos con minas en ${LEVEL}", - "descriptionFullComplete": "Eliminaste 6 enemigos con minas en ${LEVEL}", - "name": "Minero de Oro" + "description": "Mata a 6 chicos malos con minas terrestres", + "descriptionComplete": "Mató a 6 chicos malos con minas terrestres", + "descriptionFull": "Mata a 6 chicos malos con minas terrestres en ${LEVEL}", + "descriptionFullComplete": "Mató a 6 chicos malos con minas terrestres en ${LEVEL}", + "name": "Minero De Oro" }, "Got the Moves": { - "description": "Gana sin usar golpes o bombas", - "descriptionComplete": "Ganaste sin usar golpes o bombas", - "descriptionFull": "Gana ${LEVEL} sin usar golpes o bombas", - "descriptionFullComplete": "Ganaste ${LEVEL} sin usar golpes o bombas", - "name": "Tú si sabes como moverte!" + "description": "Gana sin usar golpes ni bombas", + "descriptionComplete": "Ganó sin usar golpes ni bombas", + "descriptionFull": "Gana ${LEVEL} sin golpes ni bombas", + "descriptionFullComplete": "Ganó ${LEVEL} sin golpes ni bombas", + "name": "Tengo los Movimientos" }, "In Control": { "descriptionFull": "Conecta un control (de hardware o de aplicación)", - "descriptionFullComplete": "Conectado un control (de hardware o de aplicación)", + "descriptionFullComplete": "Conectó un control. (de hardware o de aplicación)", "name": "En Control" }, "Last Stand God": { "description": "Anota 1000 puntos", - "descriptionComplete": "Anotaste 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", "descriptionFull": "Anota 1000 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 1000 puntos en ${LEVEL}", - "name": "Dios del ${LEVEL}" + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Dios De ${LEVEL}" }, "Last Stand Master": { "description": "Anota 250 puntos", - "descriptionComplete": "Anotaste 250 puntos", + "descriptionComplete": "Anotó 250 puntos", "descriptionFull": "Anota 250 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 250 puntos en ${LEVEL}", - "name": "Maestro de ${LEVEL}" + "descriptionFullComplete": "Anotó 250 puntos en ${LEVEL}", + "name": "Maestro De ${LEVEL}" }, "Last Stand Wizard": { "description": "Anota 500 puntos", - "descriptionComplete": "Anotaste 500 puntos", + "descriptionComplete": "Anotó 500 puntos", "descriptionFull": "Anota 500 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 500 puntos en ${LEVEL}", - "name": "Mago de ${LEVEL}" + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Mago De ${LEVEL}" }, "Mine Games": { - "description": "Elimina 3 enemigos con minas", - "descriptionComplete": "Eliminaste 3 enemigos con minas", - "descriptionFull": "Elimina 3 enemigos con minas en ${LEVEL}", - "descriptionFullComplete": "Eliminaste 3 enemigos con minas en ${LEVEL}", - "name": "Juegos de minas" + "description": "Mata a 3 chicos malos con minas terrestres", + "descriptionComplete": "Mató a 3 chicos malos con minas terrestres", + "descriptionFull": "Mata a 3 chicos malos con minas terrestres en ${LEVEL}", + "descriptionFullComplete": "Mató a 3 chicos con minas terrestres en ${LEVEL}", + "name": "Juegos De Minas" }, "Off You Go Then": { - "description": "Arroja 3 enemigos al precipicio", - "descriptionComplete": "Arrojaste 3 enemigos al precipicio", - "descriptionFull": "Arroja 3 enemigos al precipicio en ${LEVEL}", - "descriptionFullComplete": "Arrojaste 3 enemigos al precipicio en ${LEVEL}", - "name": "Te vas abajo entonces" + "description": "Arroja a 3 chicos malos fuera del mapa", + "descriptionComplete": "Arrojó a 3 chicos malos fuera del mapa", + "descriptionFull": "Arroja a 3 chicos malos fuera del mapa en ${LEVEL}", + "descriptionFullComplete": "Arrojó a 3 chicos malos fuera del mapa en ${LEVEL}", + "name": "Te Vas Abajo Entonces" }, "Onslaught God": { "description": "Anota 5000 puntos", - "descriptionComplete": "Anotaste 5000 puntos", + "descriptionComplete": "Anotó 5000 puntos", "descriptionFull": "Anota 5000 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 5000 puntos en ${LEVEL}", - "name": "Dios de ${LEVEL}" + "descriptionFullComplete": "Anotó 5000 puntos en ${LEVEL}", + "name": "Dios De La ${LEVEL}" }, "Onslaught Master": { "description": "Anota 500 puntos", - "descriptionComplete": "Anotaste 500 puntos", + "descriptionComplete": "Anotó 500 puntos", "descriptionFull": "Anota 500 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 500 puntos en ${LEVEL}", - "name": "Maestro de ${LEVEL}" + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Maestro De La ${LEVEL}" }, "Onslaught Training Victory": { - "description": "Vence todas las hordas", - "descriptionComplete": "Venciste todas las hordas", - "descriptionFull": "Vence todas las hordas en ${LEVEL}", - "descriptionFullComplete": "Venciste todas las hordas en ${LEVEL}", + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", "name": "Victoria en ${LEVEL}" }, "Onslaught Wizard": { "description": "Anota 1000 puntos", - "descriptionComplete": "Anotaste 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", "descriptionFull": "Anota 1000 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 1000 puntos en ${LEVEL}", - "name": "Mago de ${LEVEL}" + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Mago De La ${LEVEL}" }, "Precision Bombing": { - "description": "Gana sin usar poderes", - "descriptionComplete": "Ganaste sin usar poderes", - "descriptionFull": "Gana ${LEVEL} sin usar poderes", - "descriptionFullComplete": "Ganaste ${LEVEL} sin usar poderes", - "name": "Bombardeo preciso" + "description": "Gana sin potenciadores", + "descriptionComplete": "Ganó sin potenciadores", + "descriptionFull": "Gana ${LEVEL} sin potenciadores", + "descriptionFullComplete": "Ganó ${LEVEL} sin potenciadores", + "name": "Bombardeo De Precisión" }, "Pro Boxer": { "description": "Gana sin usar bombas", - "descriptionComplete": "Ganaste sin usar bombas", + "descriptionComplete": "Ganó sin usar bombas", "descriptionFull": "Completa ${LEVEL} sin usar bombas", - "descriptionFullComplete": "Completaste ${LEVEL} sin usar bombas", - "name": "Boxeador Pro" + "descriptionFullComplete": "Completó ${LEVEL} sin usar bombas", + "name": "Boxeador Profesional" }, "Pro Football Shutout": { - "description": "Gana sin que los enemigos anoten", - "descriptionComplete": "Ganaste sin que los enemigos anotaran", - "descriptionFull": "Gana ${LEVEL} sin que los enemigos anoten", - "descriptionFullComplete": "Ganaste ${LEVEL} sin que los enemigos anotaran", - "name": "Balón de oro en ${LEVEL}" + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo En ${LEVEL}" }, "Pro Football Victory": { "description": "Gana el partido", - "descriptionComplete": "Ganaste el partido", + "descriptionComplete": "Ganó el partido", "descriptionFull": "Gana el partido en ${LEVEL}", - "descriptionFullComplete": "Ganaste el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", "name": "Victoria en ${LEVEL}" }, "Pro Onslaught Victory": { - "description": "Vence todas las hordas", - "descriptionComplete": "Venciste todas las hordas", - "descriptionFull": "Vence todas las hordas de ${LEVEL}", - "descriptionFullComplete": "Venciste todas las hordas de ${LEVEL}", + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas de ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas de ${LEVEL}", "name": "Victoria en ${LEVEL}" }, "Pro Runaround Victory": { - "description": "Supera todas las hordas", - "descriptionComplete": "Superaste a todas las hordas", - "descriptionFull": "Supera todas las hordas en ${LEVEL}", - "descriptionFullComplete": "Supera todas las hordas en ${LEVEL}", + "description": "Completa todas las oleadas", + "descriptionComplete": "Completó todas las oleadas", + "descriptionFull": "Completa todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", "name": "Victoria en ${LEVEL}" }, "Rookie Football Shutout": { - "description": "Gana sin que los enemigos anoten", - "descriptionComplete": "Ganaste sin que los enemigos anotaran", - "descriptionFull": "Gana ${LEVEL} sin que los enemigos anoten", - "descriptionFullComplete": "Ganaste ${LEVEL} sin que los enemigos anotaran", - "name": "Balón de oro en ${LEVEL}" + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo En ${LEVEL}" }, "Rookie Football Victory": { "description": "Gana el partido", - "descriptionComplete": "Ganaste el partido", + "descriptionComplete": "Ganó el partido", "descriptionFull": "Gana el partido en ${LEVEL}", - "descriptionFullComplete": "Ganaste el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", "name": "Victoria en ${LEVEL}" }, "Rookie Onslaught Victory": { - "description": "Vence todas las hordas", - "descriptionComplete": "Venciste todas las hordas", - "descriptionFull": "Vence todas las hordas en ${LEVEL}", - "descriptionFullComplete": "Venciste todas las hordas en ${LEVEL}", + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", "name": "Victoria en ${LEVEL}" }, "Runaround God": { "description": "Anota 2000 puntos", - "descriptionComplete": "Anotaste 2000 puntos", + "descriptionComplete": "Anotó 2000 puntos", "descriptionFull": "Anota 2000 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 2000 puntos en ${LEVEL}", - "name": "Dios de ${LEVEL}" + "descriptionFullComplete": "Anotó 2000 puntos en ${LEVEL}", + "name": "Dios De La ${LEVEL}" }, "Runaround Master": { "description": "Anota 500 puntos", - "descriptionComplete": "Anotaste 500 puntos", + "descriptionComplete": "Anotó 500 puntos", "descriptionFull": "Anota 500 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 500 puntos en ${LEVEL}", - "name": "Maestro de ${LEVEL}" + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Maestro De La ${LEVEL}" }, "Runaround Wizard": { "description": "Anota 1000 puntos", - "descriptionComplete": "Anotaste 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", "descriptionFull": "Anota 1000 puntos en ${LEVEL}", - "descriptionFullComplete": "Anotaste 1000 puntos en ${LEVEL}", - "name": "Gran Sabio de ${LEVEL}" + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Mago De La ${LEVEL}" }, "Sharing is Caring": { "descriptionFull": "Comparte exitosamente el juego con un amigo", - "descriptionFullComplete": "Compartido exitosamente el juego con un amigo", + "descriptionFullComplete": "Compartió exitosamente el juego con un amigo", "name": "Compartir es Amar" }, "Stayin' Alive": { - "description": "Gana sin ser eliminado", - "descriptionComplete": "Ganaste sin ser eliminado", - "descriptionFull": "Gana ${LEVEL} sin ser eliminado", - "descriptionFullComplete": "Ganaste ${LEVEL} sin ser eliminado", - "name": "¡Sobreviviendo!" + "description": "Gana sin morir", + "descriptionComplete": "Ganó sin morir", + "descriptionFull": "Gana ${LEVEL} sin morir", + "descriptionFullComplete": "Ganó ${LEVEL} sin morir", + "name": "Sobreviviendo" }, "Super Mega Punch": { "description": "Inflige 100% de daño con un solo golpe", - "descriptionComplete": "Infligiste 100% de daño con un solo golpe", - "descriptionFull": "Inflige 100% de daño con un solo golpe en ${LEVEL}", - "descriptionFullComplete": "Infligiste 100% de daño con un solo golpe en ${LEVEL}", - "name": "¡Súper mega golpe!" + "descriptionComplete": "Infligió 100% de daño con un solo golpe", + "descriptionFull": "Inflige 100% de daño con un golpe en ${LEVEL}", + "descriptionFullComplete": "Infligió 100% de daño con un golpe en ${LEVEL}", + "name": "Súper Mega Golpe" }, "Super Punch": { - "description": "Inflige 50% de daño con un solo golpe", - "descriptionComplete": "Infligiste 50% de daño con un solo golpe", - "descriptionFull": "Inflige 50% de daño con un solo golpe en ${LEVEL}", - "descriptionFullComplete": "Infligiste 50% de daño con un solo golpe en ${LEVEL}", - "name": "¡Super golpe!" + "description": "Inflige 50% de daño con un golpe", + "descriptionComplete": "Infligió 50% de daño con un golpe", + "descriptionFull": "Inflige 50% de daño con un golpe en ${LEVEL}", + "descriptionFullComplete": "Infligió 50% de daño con un golpe en ${LEVEL}", + "name": "Súper Golpe" }, "TNT Terror": { - "description": "Elimina 6 enemigos con TNT", - "descriptionComplete": "Eliminaste 6 enemigos con TNT", - "descriptionFull": "Elimina 6 enemigos con TNT en ${LEVEL}", - "descriptionFullComplete": "Eliminaste 6 enemigos con TNT en ${LEVEL}", - "name": "¡Pirómano!" + "description": "Mata a 6 chicos malos con TNT", + "descriptionComplete": "Mató a 6 chicos malos con TNT", + "descriptionFull": "Mata a 6 chicos malos con TNT en ${LEVEL}", + "descriptionFullComplete": "Mató a 6 chicos malos con TNT en ${LEVEL}", + "name": "Pirómano" }, "Team Player": { "descriptionFull": "Empieza un juego de Equipos con 4 o más jugadores", - "descriptionFullComplete": "Has empezado un juego de Equipos con 4 o más jugadores", - "name": "Jugador de Equipo" + "descriptionFullComplete": "Empezó un juego de Equipos con 4 o más jugadores", + "name": "Jugador De Equipo" }, "The Great Wall": { - "description": "Detén todos los enemigos", - "descriptionComplete": "Detuviste todos los enemigos", - "descriptionFull": "Detén todos los enemigos en ${LEVEL}", - "descriptionFullComplete": "Detuviste todos los enemigos en ${LEVEL}", + "description": "Detén a cada uno de los chicos malos", + "descriptionComplete": "Detuvo a cada uno de los chicos malos", + "descriptionFull": "Detén a cada uno de los chicos malos en ${LEVEL}", + "descriptionFullComplete": "Detuvo a cada uno de los chicos malos en ${LEVEL}", "name": "La Gran Muralla" }, "The Wall": { - "description": "Detén a todos los enemigos", - "descriptionComplete": "Detuviste a todos los enemigos", - "descriptionFull": "Detén a todos los enemigos en ${LEVEL}", - "descriptionFullComplete": "Detuviste a todos los enemigos en ${LEVEL}", + "description": "Detén a cada uno de los chicos malos", + "descriptionComplete": "Detuvo a cada uno de los chicos malos", + "descriptionFull": "Detén a cada uno de los chicos malos en ${LEVEL}", + "descriptionFullComplete": "Detuvo a cada uno de los chicos malos en ${LEVEL}", "name": "La Muralla" }, "Uber Football Shutout": { - "description": "Gana sin que los enemigos anoten", - "descriptionComplete": "Ganaste sin que los enemigos anotaran", - "descriptionFull": "Gana ${LEVEL} sin que los enemigos anoten", - "descriptionFullComplete": "Ganaste ${LEVEL} sin que los enemigos anotaran", - "name": "Balón de oro ${LEVEL}" + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo En ${LEVEL}" }, "Uber Football Victory": { "description": "Gana el partido", - "descriptionComplete": "Ganaste el partido", + "descriptionComplete": "Ganó el partido", "descriptionFull": "Gana el partido en ${LEVEL}", - "descriptionFullComplete": "Ganaste el partido en ${LEVEL}", - "name": "Victoria en ${LEVEL}" + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria En ${LEVEL}" }, "Uber Onslaught Victory": { - "description": "Vence todas las hordas", - "descriptionComplete": "Venciste todas las hordas", - "descriptionFull": "Vence todas las hordas en ${LEVEL}", - "descriptionFullComplete": "Venciste todas las hordas en ${LEVEL}", - "name": "Victoria en ${LEVEL}" + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria En ${LEVEL}" }, "Uber Runaround Victory": { - "description": "Vence a todas las hordas", - "descriptionComplete": "Terminaste con todas las hordas", - "descriptionFull": "Vence a todas las hordas en ${LEVEL}", - "descriptionFullComplete": "Terminaste con todas las hordas en ${LEVEL}", - "name": "Victoria en ${LEVEL}" + "description": "Completa todas las oleadas", + "descriptionComplete": "Completó todas las oleadas", + "descriptionFull": "Completa todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", + "name": "Victoria En ${LEVEL}" } }, - "achievementsRemainingText": "Logros pendientes:", + "achievementsRemainingText": "Logros Pendientes:", "achievementsText": "Logros", - "achievementsUnavailableForOldSeasonsText": "Lo sentimos, los logros específicos no están disponibles para temporadas anteriores.", + "achievementsUnavailableForOldSeasonsText": "Disculpe, los logros específicos no están disponibles para temporadas anteriores.", "activatedText": "${THING} activado.", "addGameWindow": { - "getMoreGamesText": "Más Juegos...", + "getMoreGamesText": "Conseguir Más Juegos...", "titleText": "Agregar Juego" }, + "addToFavoritesText": "Añadir a Favoritos", + "addedToFavoritesText": "'${NAME}' añadido a Favoritos.", + "allText": "Todo", "allowText": "Permitir", "alreadySignedInText": "Tu cuenta está registrada en otro dispositivo;\npor favor cambia de cuentas o cierra el juego en tu \notro dispositivo e inténtalo de nuevo.", "apiVersionErrorText": "No se puede cargar el módulo ${NAME}; se dirige a la versión-api ${VERSION_USED}; necesitamos la ${VERSION_REQUIRED}.", "audioSettingsWindow": { - "headRelativeVRAudioInfoText": "(\"Auto\" se activa solo si tiene audífonos conectados)", - "headRelativeVRAudioText": "Audio VR de Cabeza", - "musicVolumeText": "Volumen de la Música", - "soundVolumeText": "Volumen del Sonido", - "soundtrackButtonText": "Canciones de fondo/Bandas Sonoras", + "headRelativeVRAudioInfoText": "(\"Auto\" se activa solo cuando los audífonos estan conectados)", + "headRelativeVRAudioText": "Audio VR Relativo a la Cabeza", + "musicVolumeText": "Volumen De La Música", + "soundVolumeText": "Volumen Del Sonido", + "soundtrackButtonText": "Bandas Sonoras", "soundtrackDescriptionText": "(usa tu propia música para reproducir durante los juegos)", - "titleText": "Sonido" + "titleText": "Audio" }, "autoText": "Auto", "backText": "Atrás", - "banThisPlayerText": "Expulsar a Este Jugador", - "bestOfFinalText": "El mejor de ${COUNT}", - "bestOfSeriesText": "Mejor serie de ${COUNT}:", + "banThisPlayerText": "Banear A Este Jugador", + "bestOfFinalText": "Mejor-de-${COUNT} Finales", + "bestOfSeriesText": "Mejor de ${COUNT} series:", "bestOfUseFirstToInstead": 0, - "bestRankText": "Tu mejor clasificación es #${RANK}", + "bestRankText": "Tu mejor rango es #${RANK}", "bestRatingText": "Tu mejor clasificación es ${RATING}", "betaErrorText": "Esta versión beta está caducada, por favor actualizala.", "betaValidateErrorText": "Imposible validar beta. (¿Tienes conexión a internet?)", @@ -366,62 +371,63 @@ "bombBoldText": "BOMBA", "bombText": "Bomba", "boostText": "Potenciar", - "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} se configura en la propia aplicación.", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} se configura en la misma aplicación.", "buttonText": "botón", "canWeDebugText": "¿Te gustaría que BombSquad enviara errores, accidentes, e\ninformación de uso básico al desarrollador de forma automática?\n\nLa información no contendrá datos personales y ayudará a\nmantener el juego funcionando sin errores y libre de problemas.", "cancelText": "Cancelar", - "cantConfigureDeviceText": "Perdón, pero ${DEVICE} no es configurable.", + "cantConfigureDeviceText": "Lo sentimos, ${DEVICE} no es configurable.", "challengeEndedText": "Este desafío ha terminado.", "chatMuteText": "Silenciar Chat", "chatMutedText": "Chat Silenciado", - "chatUnMuteText": "Desmutear Chat", + "chatUnMuteText": "Desilenciar Chat", "choosingPlayerText": "", + "codesExplainText": "Los códigos son proporcionados por el desarrollador para\ndiagnosticar y corregir problemas de la cuenta.", "completeThisLevelToProceedText": "¡Debes completar\neste nivel para avanzar!", - "completionBonusText": "Bono extra por Acabar", + "completionBonusText": "Bono Por Completar", "configControllersWindow": { - "configureControllersText": "Configuración de Controles", + "configureControllersText": "Configurar Controles", "configureGamepadsText": "Configurar controles", - "configureKeyboard2Text": "Configurar Teclado P2", + "configureKeyboard2Text": "Configurar Teclado J2", "configureKeyboardText": "Configurar Teclado", "configureMobileText": "Dispositivos Móviles como Controles", "configureTouchText": "Configurar Pantalla Táctil", - "ps3Text": "Controles de PS3", + "ps3Text": "Controles De PS3", "titleText": "Controles", - "wiimotesText": "Wii Remotes", - "xbox360Text": "Controles de Xbox 360" + "wiimotesText": "Wiimotes", + "xbox360Text": "Controles De Xbox 360" }, "configGamepadSelectWindow": { "androidNoteText": "Nota: el soporte de controles varía según el dispositivo y la versión de Android.", "pressAnyButtonText": "Pulsa cualquier botón del control\n que desees configurar...", - "titleText": "Configurar tu control" + "titleText": "Configurar Controles" }, "configGamepadWindow": { "advancedText": "Avanzado", - "advancedTitleText": "Configuración Avanzada del Control", + "advancedTitleText": "Configuración Avanzada Del Control", "analogStickDeadZoneDescriptionText": "(súbele si tu personaje 'derrapa' cuando sueltas la palanca)", - "analogStickDeadZoneText": "Zona Muerta del Stick Analógico", + "analogStickDeadZoneText": "Zona Muerta De La Palanca Analógica", "appliesToAllText": "(aplica a todos los controles de este tipo)", "autoRecalibrateDescriptionText": "(habilita esta opción si tu personaje no se mueve a toda velocidad)", - "autoRecalibrateText": "Auto-Calibrar Stick Analógico", + "autoRecalibrateText": "Auto-Recalibrar Palanca Analógica", "axisText": "eje", "clearText": "vaciar", - "dpadText": "DPad", - "extraStartButtonText": "Botón Extra de Inicio", - "ifNothingHappensTryAnalogText": "Si no ocurre nada, intenta asignar al stick analógico.", - "ifNothingHappensTryDpadText": "Si no ocurre nada, intenta asignar al DPad.", - "ignoreCompletelyDescriptionText": "(evita que este controlador impacte el juego y/o menus)", + "dpadText": "dpad", + "extraStartButtonText": "Botón Extra De Inicio", + "ifNothingHappensTryAnalogText": "Si no pasa nada, intenta asignar la palanca analógica en cambio.", + "ifNothingHappensTryDpadText": "Si no pasa nada, intenta asignar el d-pad en cambio.", + "ignoreCompletelyDescriptionText": "(evita que este control este afectando el juego y/o menus)", "ignoreCompletelyText": "Ignorar Completamente", "ignoredButton1Text": "Botón 1 Ignorado", - "ignoredButton2Text": "Botón 2 ignorado", + "ignoredButton2Text": "Botón 2 Ignorado", "ignoredButton3Text": "Botón 3 Ignorado", "ignoredButton4Text": "Botón 4 Ignorado", "ignoredButtonDescriptionText": "(usa esto para prevenir que los botones de 'inicio' o 'sincronización' afecten la interfaz visual)", "ignoredButtonText": "Botón de inicio", - "pressAnyAnalogTriggerText": "Pulsa cualquier gatillo analógico...", - "pressAnyButtonOrDpadText": "Pulsa cualquier botón o DPad...", - "pressAnyButtonText": "Pulsa cualquier botón...", - "pressLeftRightText": "Pulsa izquierda o derecha...", - "pressUpDownText": "Pulsa arriba o abajo...", + "pressAnyAnalogTriggerText": "Presiona cualquier gatillo analógico...", + "pressAnyButtonOrDpadText": "Presiona cualquier botón o dpad...", + "pressAnyButtonText": "Presiona cualquier botón...", + "pressLeftRightText": "Presiona izquierda o derecha...", + "pressUpDownText": "Presiona arriba o abajo...", "runButton1Text": "Botón para Correr 1", "runButton2Text": "Botón para Correr 2", "runTrigger1Text": "Gatillo para Correr 1", @@ -461,13 +467,14 @@ "titleText": "Configura la Pantalla Táctil", "touchControlsScaleText": "Ampliador de controles táctiles" }, + "configureDeviceInSystemSettingsText": "${DEVICE} se puede configurar en la aplicación Configuración del Sistema.", "configureItNowText": "Configurar ahora?", "configureText": "Configurar", "connectMobileDevicesWindow": { "amazonText": "Appstore de Amazon", "appStoreText": "App Store", "bestResultsScale": 0.65, - "bestResultsText": "Para mejores resultados necesitas una red inalámbrica rápida. Puedes\nreducir el retraso wifi apagando otros dispositivos inalámbricos,\njugando cerca de tu router inalámbrico, y conectando el\njuego anfitrión directamente a la red a través del cable Ethernet.", + "bestResultsText": "Para mejores resultados necesitas una red inalámbrica rápida. Puedes\nreducir el retraso wifi apagando otros dispositivos inalámbricos,\njugando cerca de tu router inalámbrico y conectando el\njuego anfitrión directamente a la red a través del cable Ethernet.", "explanationScale": 0.8, "explanationText": "Para utilizar tus dispositivos móviles como controles, \ninstala la app \"${REMOTE_APP_NAME}\" en ellos. Conecta todos\ntus dispositivos con ${APP_NAME} a través de tu red Wi-fi, ¡es gratis!.", "forAndroidText": "para Android:", @@ -480,15 +487,15 @@ "continueText": "Continuar", "controlsText": "Controles", "coopSelectWindow": { - "activenessAllTimeInfoText": "Esto no aplica en los rankings de 'Todo el tiempo'.", + "activenessAllTimeInfoText": "Esto no aplica a las clasificaciones de todo-el-tiempo.", "activenessInfoText": "Este multiplicador aumenta en los días que juegas\ny disminuye cuando no juegas.", "activityText": "Actividad", "campaignText": "Campaña", "challengesInfoText": "Gana premios por completar los mini-juegos.\n\nLos premios y la dificultad de los niveles incrementa\ncada vez que se completa y\ndecrece cuando uno expira o no se cumple.", "challengesText": "Desafíos", - "currentBestText": "Mejor del Momento", + "currentBestText": "Mejor Actual", "customText": "Personalizado", - "entryFeeText": "Precio", + "entryFeeText": "Entrada", "forfeitConfirmText": "¿Renunciar a este desafío?", "forfeitNotAllowedYetText": "Todavía no puedes abandonar este desafío.", "forfeitText": "Abandonar", @@ -504,18 +511,18 @@ "powerRankingPointsMultText": "(x ${NUMBER} pts)", "powerRankingPointsText": "${NUMBER} pts", "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", - "powerRankingText": "Clasificación de Poder", + "powerRankingText": "Clasificación De Poder", "prizesText": "Premios", "proMultInfoText": "Los jugadores con la mejora ${PRO}\nreciben una bonificación del ${PERCENT}% de puntos.", - "seeMoreText": "Ver más...", - "skipWaitText": "Saltar la Espera", + "seeMoreText": "Más...", + "skipWaitText": "Omitir La Espera", "timeRemainingText": "Tiempo Restante", "titleText": "Modo cooperativo", "toRankedText": "Para Clasificar", "totalText": "total", "tournamentInfoText": "Compite por puntajes altos con\notros jugadores en tu liga.\n\nLos premios los obtienen los jugadores\ncon mejor puntaje al acabarse el torneo.", - "welcome1Text": "Bienvenido/a a ${LEAGUE}. Puedes mejorar tu\nposición en la liga ganando estrellas, completando\nlogros, y ganando trofeos en desafíos.", - "welcome2Text": "También puedes ganar tickets desde varias actividades similares.\nLos tickets pueden ser usados para desbloquear nuevos personajes,\nmapas y mini juegos, entrar a torneos, y más.", + "welcome1Text": "Bienvenido/a a ${LEAGUE}. Puedes mejorar tu\nposición en la liga ganando estrellas, completando\nlogros y ganando trofeos en desafíos.", + "welcome2Text": "También puedes ganar boletos desde varias actividades similares.\nLos boletos pueden ser usados para desbloquear nuevos personajes,\nmapas y mini juegos, entrar a torneos y más.", "yourPowerRankingText": "Tu Clasificación de Poder:" }, "copyConfirmText": "Copiado al portapapeles.", @@ -531,15 +538,15 @@ "codingGraphicsAudioText": "Código, gráficas y audio por ${NAME}", "languageTranslationsText": "Traducciones:", "legalText": "Legal:", - "publicDomainMusicViaText": "Música de dominio público a través de ${NAME}", + "publicDomainMusicViaText": "Música de dominio público vía ${NAME}", "softwareBasedOnText": "Este software está basado parcialmente en el trabajo de ${NAME}", "songCreditText": "${TITLE} interpretada por ${PERFORMER}\nCompuesta por ${COMPOSER}, arreglos por ${ARRANGER}, publicada por ${PUBLISHER},\nCortesía de ${SOURCE}", - "soundAndMusicText": "Sonido y música:", + "soundAndMusicText": "Sonido & Música:", "soundsText": "Sonidos (${SOURCE}):", "specialThanksText": "Agradecimientos Especiales:", "thanksEspeciallyToText": "Gracias especialmente a ${NAME}", "titleText": "Créditos de ${APP_NAME}", - "whoeverInventedCoffeeText": "A quien haya inventado el café" + "whoeverInventedCoffeeText": "A quien inventó el café" }, "currentStandingText": "Tu puesto actual es #${RANK}", "customizeText": "Personalizar...", @@ -552,51 +559,55 @@ "runGPUBenchmarkText": "Ejecutar Punto de Referencia del GPU", "runMediaReloadBenchmarkText": "Ejecutar Punto de Referencia del Media-Reload", "runStressTestText": "Ejecutar prueba de resistencia", - "stressTestPlayerCountText": "Conteo de jugadores", - "stressTestPlaylistDescriptionText": "Prueba de Resistencia de Lista de Audio", - "stressTestPlaylistNameText": "Nombre de lista", - "stressTestPlaylistTypeText": "Tipo de lista", - "stressTestRoundDurationText": "Redondear duración", - "stressTestTitleText": "Prueba de resistencia", - "titleText": "Pruebas de Resistencia y Rendimiento.", - "totalReloadTimeText": "Tiempo total de recarga: ${TIME} (Ver log para detalles)", + "stressTestPlayerCountText": "Conteo de Jugadores", + "stressTestPlaylistDescriptionText": "Lista de juegos de Prueba de Estrés", + "stressTestPlaylistNameText": "Nombre de la Lista de juegos", + "stressTestPlaylistTypeText": "Tipo de Lista de juegos", + "stressTestRoundDurationText": "Redondear Duración", + "stressTestTitleText": "Prueba de Estrés", + "titleText": "Pruebas de Estrés & Rendimiento.", + "totalReloadTimeText": "Tiempo total de recarga: ${TIME} (ver registro para detalles)", "unlockCoopText": "Desbloquear niveles cooperativos" }, "defaultFreeForAllGameListNameText": "Pelea libre (predeterminado)", - "defaultGameListNameText": "Lista ${PLAYMODE} por Defecto", + "defaultGameListNameText": "Lista de juegos ${PLAYMODE} Por defecto", "defaultNewFreeForAllGameListNameText": "Mis Matanzas Libres", - "defaultNewGameListNameText": "Mi lista ${PLAYMODE}", + "defaultNewGameListNameText": "Mi Lista de juegos ${PLAYMODE}", "defaultNewTeamGameListNameText": "Mis Juegos en equipo", "defaultTeamGameListNameText": "Juego en equipo (predeterminado)", "deleteText": "Borrar", - "demoText": "Versión de prueba", - "denyText": "Rechazar", + "demoText": "Demo", + "denyText": "Denegar", "deprecatedText": "Obsoleto", - "desktopResText": "Resolución del escritorio", - "deviceAccountUpgradeText": "Advertencia:\nEstás conectado con una cuenta de dispositivo\n(${NAME}).\nLas cuentas de dispositivo serán removidas en una próxima actualización", + "descriptionText": "Descripción", + "desktopResText": "Resolución De Escritorio", + "deviceAccountUpgradeText": "Advertencia:\nIniciaste sesión con una cuenta de dispositivo (${NAME}).\nLas cuentas de dispositivo serán removidas en una futura actualización.\nActualiza a una cuenta V2 si quieres conservar tu progreso.", "difficultyEasyText": "Fácil", "difficultyHardOnlyText": "Solo Modo Difícil", "difficultyHardText": "Difícil", "difficultyHardUnlockOnlyText": "Este nivel solo puede ser desbloqueado en modo difícil.\n¡¿¡¿¡Piensas tener lo que se necesita!?!?!", "directBrowserToURLText": "Por favor abre la siguiente URL en tu navegador:", - "disableRemoteAppConnectionsText": "Desactivar conexiones remotas de aplicación", + "disableRemoteAppConnectionsText": "Deshabilitar Conexiones Remotas De La Aplicación", "disableXInputDescriptionText": "Permite más de 4 controladores pero puede que no funcione bien.", - "disableXInputText": "Desactivar XInput", + "disableXInputText": "Deshabilitar XInput", + "disabledText": "Deshabilitado", + "discordFriendsText": "¿Quieres buscar gente nueva con quien jugar?\n¡Únete a nuestro Discord y encuentra nuevos amigos!", + "discordJoinText": "Únete a el Discord", "doneText": "Hecho", "drawText": "Empate", "duplicateText": "Duplicar", "editGameListWindow": { "addGameText": "Añadir\nJuego", - "cantOverwriteDefaultText": "¡No puedes sobrescribir la lista predeterminada!", - "cantSaveAlreadyExistsText": "¡Ya existe una lista con ese nombre!", - "cantSaveEmptyListText": "¡No puedes guardar una lista vacía!", + "cantOverwriteDefaultText": "¡No puedes sobrescribir la lista de juegos por defecto!", + "cantSaveAlreadyExistsText": "¡Ya existe una lista de juegos con ese nombre!", + "cantSaveEmptyListText": "¡No puedes guardar una lista de juegos vacía!", "editGameText": "Editar\nJuego", "gameListText": "Lista de juegos", - "listNameText": "Nombre de Lista", + "listNameText": "Nombre De La Lista De Juegos", "nameText": "Nombre", "removeGameText": "Remover\nJuego", - "saveText": "Guardar", - "titleText": "Editor de Listas" + "saveText": "Guardar Lista", + "titleText": "Editor De Lista De Juegos" }, "editProfileWindow": { "accountProfileInfoText": "Este perfil de jugador especial tiene un nombre\ny un icono basado en tu cuenta.\n\n${ICONS}\n\nCrea perfiles personalizados si quieres usar\ndiferentes nombres o iconos personalizados.", @@ -606,16 +617,17 @@ "characterText": "personaje", "checkingAvailabilityText": "Revisando la disponibilidad para \"${NAME}\"...", "colorText": "color", - "getMoreCharactersText": "Consigue Más Personajes...", + "getMoreCharactersText": "Conseguir Más Personajes...", "getMoreIconsText": "Conseguir Más Iconos...", "globalProfileInfoText": "Los perfiles globales tienen un nombre único\na nivel mundial. También tienen iconos personalizados.", "globalProfileText": "(perfil global)", "highlightText": "resalte", "iconText": "icono", - "localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía\nque los nombres sean únicos. Obtén un perfil global\npara reservar un nombre único y tengas un icono personalizado.", + "localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía\nque los nombres sean únicos. Crea un perfil global\npara reservar un nombre único y tengas un icono personalizado.", "localProfileText": "(perfil local)", - "nameDescriptionText": "Nombre de Jugador", + "nameDescriptionText": "Nombre Del Jugador", "nameText": "Nombre", + "profileAlreadyExistsText": "Ya existe un perfil con ese nombre", "randomText": "aleatorio", "titleEditText": "Editar Perfil", "titleNewText": "Nuevo Perfil", @@ -625,42 +637,43 @@ }, "editProfilesAnyTimeText": "(edita tu perfil en cualquier momento bajo 'ajustes')", "editSoundtrackWindow": { - "cantDeleteDefaultText": "No puedes eliminar la pista de audio predeterminada.", - "cantEditDefaultText": "No puedes editar la pista de audio predeterminada. Duplica o crea una nueva.", + "cantDeleteDefaultText": "No puedes borrar la banda sonora predeterminada.", + "cantEditDefaultText": "No puedes editar la banda sonora predeterminada. Duplicala o crea una nueva.", "cantEditWhileConnectedOrInReplayText": "No puedes editar listas de audio mientras juegas con alguien o en repeticiones.", - "cantOverwriteDefaultText": "No puedes sobreescribir la pista de audio predeterminada", + "cantOverwriteDefaultText": "No puedes sobreescribir la banda sonora predeterminada", "cantSaveAlreadyExistsText": "¡Ya existe una banda sonora con ese nombre!", - "defaultGameMusicText": "", - "defaultSoundtrackNameText": "Pista de Audio Predeterminada", - "deleteConfirmText": "Eliminar pista de audio:\n\n'${NAME}'?", - "deleteText": "Eliminar\nPista de Audio", - "duplicateText": "Duplicar\nPista de Audio", - "editSoundtrackText": "Editor de Pistas de Audio", - "editText": "Editar\nPista de Audio", - "fetchingITunesText": "buscando listas de reproducción de aplicaciones de música...", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Banda Sonora Predeterminada", + "deleteConfirmText": "Borrar Banda Sonora:\n\n'${NAME}'?", + "deleteText": "Borrar\nBanda Sonora", + "duplicateText": "Duplicar\nBanda Sonora", + "editSoundtrackText": "Editor de Banda Sonora", + "editText": "Editar\nBanda Sonora", + "fetchingITunesText": "buscando playlists en la App De Música...", "musicVolumeZeroWarning": "Advertencia: el volumen de la música está en 0", "nameText": "Nombre", - "newSoundtrackNameText": "Mi Lista de Audio ${COUNT}", - "newSoundtrackText": "Nueva Pista de Audio:", - "newText": "Nueva\nPista de Audio", - "selectAPlaylistText": "Elige una Lista de Reproducción", - "selectASourceText": "Fuente de la Música", + "newSoundtrackNameText": "Mi Banda Sonora ${COUNT}", + "newSoundtrackText": "Nueva Banda Sonora:", + "newText": "Nueva\nBanda Sonora", + "selectAPlaylistText": "Selecciona Una Playlist", + "selectASourceText": "Fuente De La Música", "soundtrackText": "pista de audio", - "testText": "escuchar", - "titleText": "Pistas de Audio", - "useDefaultGameMusicText": "Música por Defecto", - "useITunesPlaylistText": "Lista de reproducción de la aplicación de música", - "useMusicFileText": "Archivo de Audio (MP3, etc)", + "testText": "prueba", + "titleText": "Bandas Sonoras", + "useDefaultGameMusicText": "Música Del Juego Por Defecto", + "useITunesPlaylistText": "Playlist De La App De Música", + "useMusicFileText": "Archivo De Música (mp3, etc)", "useMusicFolderText": "Carpeta de Archivos de Audio" }, "editText": "Editar", + "enabledText": "Habilitado", "endText": "Fin", - "enjoyText": "Diviértete!", + "enjoyText": "¡Diviértete!", "epicDescriptionFilterText": "${DESCRIPTION} En cámara lenta épica.", "epicNameFilterText": "${NAME} - Modo épico", "errorAccessDeniedText": "acceso negado", - "errorDeviceTimeIncorrectText": "La hora actual de tu dispositivo está incorrecta por ${HOURS} horas.\nEsto podría causar problemas.\nPor favor verifica la hora y zona horaria en ajustes.", - "errorOutOfDiskSpaceText": "insuficiente espacio en disco", + "errorDeviceTimeIncorrectText": "La hora actual de tu dispositivo está incorrecta por ${HOURS} horas.\nEsto podría causar algunos problemas.\nPor favor verifica la hora y zona horaria en ajustes.", + "errorOutOfDiskSpaceText": "espacio insuficiente en el disco", "errorSecureConnectionFailText": "No se puede establecer una conexión segura en la nube; La red podría estar fallando", "errorText": "Error", "errorUnknownText": "error desconocido", @@ -668,7 +681,7 @@ "exportSuccessText": "'${NAME}' exportado.", "externalStorageText": "Almacenamiento Externo", "failText": "Fallaste", - "fatalErrorText": "Uh oh, ¡algo está mal por aquí!\nPor favor intenta reinstalar la app o\ncontacta a ${EMAIL} para ayuda.", + "fatalErrorText": "Oh oh; algo está mal por aquí.\nPor favor intenta reinstalar la app o\ncontacta a ${EMAIL} para recibir ayuda.", "fileSelectorWindow": { "titleFileFolderText": "Elige un Archivo o Carpeta", "titleFileText": "Elige un Archivo", @@ -678,143 +691,146 @@ "filterText": "Filtro", "finalScoreText": "Puntaje Final", "finalScoresText": "Puntajes Finales", - "finalTimeText": "Tiempo final", + "finalTimeText": "Tiempo Final", "finishingInstallText": "Instalación casi lista; espera un momento...", "fireTVRemoteWarningText": "* Para una mejor experiencia, \nutiliza controles o instala la\napp '${REMOTE_APP_NAME}' en tus\ndispositivos móviles.", - "firstToFinalText": "Primero de ${COUNT} Final", - "firstToSeriesText": "Primero de ${COUNT} Serie", + "firstToFinalText": "Primero de ${COUNT} Finales", + "firstToSeriesText": "Primero de ${COUNT} Series", "fiveKillText": "¡¡¡COMBO QUÍNTUPLE!!!", - "flawlessWaveText": "¡Horda perfecta!", + "flawlessWaveText": "¡Oleada Perfecta!", "fourKillText": "¡¡¡COMBO CUÁDRUPLE!!!", "freeForAllText": "Pelea libre", "friendScoresUnavailableText": "Puntaje no disponible.", "gameCenterText": "GameCenter", "gameCircleText": "GameCircle", - "gameLeadersText": "Líderes del juego ${COUNT}", + "gameLeadersText": "Líderes Del Juego ${COUNT}", "gameListWindow": { - "cantDeleteDefaultText": "No puedes eliminar la lista predeterminada.", - "cantEditDefaultText": "¡No puedes editar la lista predeterminada! Duplicala o crea una nueva.", - "cantShareDefaultText": "No puedes compartir la lista de reproducción por defecto", + "cantDeleteDefaultText": "No puedes borrar la playlist predeterminada.", + "cantEditDefaultText": "¡No puedes editar la playlist predeterminada! Duplicala o crea una nueva.", + "cantShareDefaultText": "No puedes compartir la playlist predeterminada.", "deleteConfirmText": "¿Borrar \"${LIST}\"?", - "deleteText": "Borrar\nLista", - "duplicateText": "Duplicar\nLista", - "editText": "Editar\nLista", + "deleteText": "Borrar\nPlaylist", + "duplicateText": "Duplicar\nPlaylist", + "editText": "Editar\nPlaylist", "gameListText": "Lista de juego", - "newText": "Nueva\nLista", + "newText": "Nueva\nPlaylist", + "pointsToWinText": "Puntos para Ganar", + "seriesLengthText": "Duración de la Serie", "showTutorialText": "Ver Tutorial", - "shuffleGameOrderText": "Orden de juego al azar", - "titleText": "Personaliza listas de ${TYPE}" + "shuffleGameOrderText": "Orden de Juego Aleatorio", + "titleText": "Personalizar Playlists de ${TYPE}" }, "gameSettingsWindow": { - "addGameText": "Agrega juego" + "addGameText": "Agregar Juego" }, "gamepadDetectedText": "1 control detectado.", "gamepadsDetectedText": "${COUNT} controles detectados.", "gamesToText": "${WINCOUNT} juegos a ${LOSECOUNT}", "gatherWindow": { "aboutDescriptionLocalMultiplayerExtraText": "Recuerda: cualquier dispositivo en la fiesta puede\ntener más de un jugador si tienen controles suficientes.", - "aboutDescriptionText": "Usa estas pestañas para crear una fiesta.\n\nLas fiestas te permiten jugar y competir con\ntus amigos con sus propios dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu fiesta.\n(En el control, presiona ${BUTTON} mientras estés en el menú)", - "aboutText": "Acerca de", + "aboutDescriptionText": "Usa estas pestañas para armar una partida.\n\nLas partidas te permiten jugar y competir con\ntus amigos a través de diferentes dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu partida.\n(En el control, presiona ${BUTTON} mientras estés en el menú)", + "aboutText": "Acerca De", "addressFetchErrorText": "", "appInviteInfoText": "Invita amigos a probar BombSquad y recibirán\n${COUNT} ticketes gratis. Tu obtendrás\n${YOU_COUNT} por cada amigo que acepte.", "appInviteMessageText": "${NAME} te envió ${COUNT} boletos en ${APP_NAME}", - "appInviteSendACodeText": "Enviales un código", - "appInviteTitleText": "Invitación de ${APP_NAME}", - "bluetoothAndroidSupportText": "(Funciona con cualquier dispositivo Android con Bluetooth)", - "bluetoothDescriptionText": "Crea/únete a una fiesta vía Bluetooth:", - "bluetoothHostText": "Crea vía Bluetooth", - "bluetoothJoinText": "Únete vía Bluetooth", + "appInviteSendACodeText": "Envíales Un Código", + "appInviteTitleText": "Invitación De La Aplicación ${APP_NAME}", + "bluetoothAndroidSupportText": "(funciona con cualquier dispositivo Android con Bluetooth)", + "bluetoothDescriptionText": "Alojar/unirse a una partida vía Bluetooth:", + "bluetoothHostText": "Alojar vía Bluetooth", + "bluetoothJoinText": "Unirse vía Bluetooth", "bluetoothText": "Bluetooth", "checkingText": "revisando...", "copyCodeConfirmText": "Se ha copiado en el portapapeles.", - "copyCodeText": "Copiar", + "copyCodeText": "Copiar Código", "dedicatedServerInfoText": "Para mejores resultados, crea un servidor dedicado. Visita bombsquadgame.com/server para aprender cómo hacerlo", - "disconnectClientsText": "Esto desconectará a ${COUNT} jugador(es) de\ntu fiesta. ¿Estás seguro?", + "disconnectClientsText": "Esto desconectará a ${COUNT} jugador(es) de\ntu partida. ¿Estás seguro?", "earnTicketsForRecommendingAmountText": "Tus amigos recibirán ${COUNT} boletos si prueban el juego\n(Y recibirás ${YOU_COUNT} boletos por cada amigo que pruebe el juego)", "earnTicketsForRecommendingText": "Comparte el juego\na cambio de boletos gratis...", - "emailItText": "Enviar correo", - "favoritesSaveText": "Guardar como favorito", + "emailItText": "Envíar Correo", + "favoritesSaveText": "Guardar Como Favorito", "favoritesText": "Favoritos", - "freeCloudServerAvailableMinutesText": "El siguiente server estara disponible en ${MINUTES} minutos", - "freeCloudServerAvailableNowText": "Servidor gratuito disponible!", - "freeCloudServerNotAvailableText": "No hay servidores gratis disponibles ahora", - "friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos ${APP_NAME} de ${NAME}", + "freeCloudServerAvailableMinutesText": "El siguiente servidor estará disponible en ${MINUTES} minutos.", + "freeCloudServerAvailableNowText": "¡Servidor en la nube gratuito disponible!", + "freeCloudServerNotAvailableText": "No hay servidores en la nube gratuitos disponibles.", + "friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos de ${APP_NAME} de ${NAME}", "friendPromoCodeAwardText": "Recibirás ${COUNT} boletos cada vez que lo uses.", - "friendPromoCodeExpireText": "El código expirará en ${EXPIRE_HOURS} horas y solo lo podrán usar jugadores nuevos.", - "friendPromoCodeInstructionsText": "Para usarlo, abre ${APP_NAME} y ve a \"Ajustes-> Avanzado-> Ingresar código\"\nVisita bombsquadgame.com para enlaces de descarga de todas las plataformas disponibles.", + "friendPromoCodeExpireText": "El código expirará en ${EXPIRE_HOURS} horas y solo funciona para jugadores nuevos.", + "friendPromoCodeInstructionsText": "Para usarlo, abre ${APP_NAME} y ve a \"Ajustes->Avanzado->Ingresar Código\"\nVisita bombsquadgame.com para enlaces de descarga de todas las plataformas disponibles", "friendPromoCodeRedeemLongText": "Se puede canjear por ${COUNT} boletos gratis hasta ${MAX_USES} personas.", "friendPromoCodeRedeemShortText": "Puede ser canjeado por ${COUNT} boletos en el juego.", - "friendPromoCodeWhereToEnterText": "(en \"Configuración-> Avanzado-> Introducir código\")", - "getFriendInviteCodeText": "Genera código para un amigo", - "googlePlayDescriptionText": "Invita a jugadores de Google Play a tu fiesta:", + "friendPromoCodeWhereToEnterText": "39739117", + "getFriendInviteCodeText": "Obtener Código De Invitación De Amigo", + "googlePlayDescriptionText": "Invitar jugadores de Google Play a tu partida:", "googlePlayInviteText": "Invitar", "googlePlayReInviteText": "Hay ${COUNT} jugadores de Google Play en tu fiesta\nque se desconectarán si creas una nueva invitación.\nInclúyelos en la nueva invitación para tenerlos de vuelta.", - "googlePlaySeeInvitesText": "Ver invitaciones", + "googlePlaySeeInvitesText": "Ver Invitaciones", "googlePlayText": "Google Play", "googlePlayVersionOnlyText": "(Versión Android / Google Play)", - "hostPublicPartyDescriptionText": "Crear una Fiesta Pública", + "hostPublicPartyDescriptionText": "Alojar una Partida Pública", "hostingUnavailableText": "Alojamiento No Disponible", - "inDevelopmentWarningText": "Nota:\n\nJugar en Red es una función todavía en desarrollo.\nPor ahora, es altamente recomendado que todos\nlos jugadores estén en la misma red Wi-Fi", + "inDevelopmentWarningText": "Nota:\n\nJugar en red es una función todavía en desarrollo.\nPor ahora, es altamente recomendado que todos\nlos jugadores estén en la misma red Wi-Fi.", "internetText": "Internet", "inviteAFriendText": "¿Tus amigos no tienen el juego? Invítalos a\nprobarlo y recibirán ${COUNT} boletos gratis.", - "inviteFriendsText": "Invita a amigos", - "joinPublicPartyDescriptionText": "Entrar en una fiesta publica", - "localNetworkDescriptionText": "Unirse a una fiesta en tu red", + "inviteFriendsText": "Invitar Amigos", + "joinPublicPartyDescriptionText": "Unirse a una Partida Pública", + "localNetworkDescriptionText": "Unirse a una Partida Cercana (LAN, Bluetooth, etc.)", "localNetworkText": "Red Local", - "makePartyPrivateText": "Crea mi Fiesta Privada", - "makePartyPublicText": "Crea mi Fiesta Pública", + "makePartyPrivateText": "Hacer Mi Partida Privada", + "makePartyPublicText": "Hacer Mi Partida Pública", "manualAddressText": "Dirección", "manualConnectText": "Conectar", - "manualDescriptionText": "Únete a una fiesta usando la dirección IP:", - "manualJoinSectionText": "Unirse por dirección", - "manualJoinableFromInternetText": "¿Se te pueden unir vía Internet?", + "manualDescriptionText": "Unirse a una partida por dirección:", + "manualJoinSectionText": "Unirse Por Dirección", + "manualJoinableFromInternetText": "¿Se pueden unir desde internet?:", "manualJoinableNoWithAsteriskText": "NO*", - "manualJoinableYesText": "SI", - "manualRouterForwardingText": "*para arreglarlo, configura en tu router que redireccione el puerto UDP ${PORT} a tu dirección local", + "manualJoinableYesText": "SÍ", + "manualRouterForwardingText": "*para arreglarlo, configura tu router para que redireccione el puerto UDP ${PORT} a tu dirección local", "manualText": "Manual", "manualYourAddressFromInternetText": "Tu dirección desde internet:", "manualYourLocalAddressText": "Tu dirección local:", "nearbyText": "Cerca", "noConnectionText": "", - "otherVersionsText": "(Otras versiones)", - "partyCodeText": "Código de fiesta", + "noPartiesAddedText": "Sin Fiestas Añadidas", + "otherVersionsText": "(otras versiones)", + "partyCodeText": "Código De La Partida", "partyInviteAcceptText": "Aceptar", "partyInviteDeclineText": "Denegar", - "partyInviteGooglePlayExtraText": "(Busca la pestaña 'Google Play' en la ventana 'Reúne'", + "partyInviteGooglePlayExtraText": "(busca la pestaña 'Google Play' en la ventana 'Reúne')", "partyInviteIgnoreText": "Ignorar", - "partyInviteText": "${NAME} te ha invitado\na unirse a su fiesta!", - "partyNameText": "Nombre de la fiesta", - "partyServerRunningText": "Tu servidor de fiesta está en línea", - "partySizeText": "Tamaño de la fiesta", - "partyStatusCheckingText": "Comprobando estado...", - "partyStatusJoinableText": "ya se pueden conectar a tu fiesta por internet", - "partyStatusNoConnectionText": "Incapaz de conectar al servidor", - "partyStatusNotJoinableText": "No se van a poder conectar a tu fiesta por internet", - "partyStatusNotPublicText": "Tu fiesta no es publica", - "pingText": "Ping", + "partyInviteText": "${NAME} te ha invitado\na unirse a su partida!", + "partyNameText": "Nombre De La Partida", + "partyServerRunningText": "Tu servidor de partida se esta ejecutando.", + "partySizeText": "tamaño de partida", + "partyStatusCheckingText": "comprobando estado...", + "partyStatusJoinableText": "ahora se pueden unir a tu partida desde internet", + "partyStatusNoConnectionText": "incapaz de conectarse al servidor", + "partyStatusNotJoinableText": "no se pueden unir a tu partida desde internet", + "partyStatusNotPublicText": "tu partida no es pública", + "pingText": "ping", "portText": "Puerto", - "privatePartyCloudDescriptionText": "Fiestas privadas se ejecutan en la nube; no requiere configuración del router.", - "privatePartyHostText": "Hacer una Fiesta privada", - "privatePartyJoinText": "Únete a una fiesta privada", + "privatePartyCloudDescriptionText": "Las partidas privadas se ejecutan en la nube; no requieren configuración del router.", + "privatePartyHostText": "Ajolar una Partida Privada", + "privatePartyJoinText": "Unirse a una Partida Privada", "privateText": "Privado", - "publicHostRouterConfigText": "Está opción requiere una configuración de puerto en tu router para una opción más fácil crea una fiesta privada", - "publicText": "Publico", - "requestingAPromoCodeText": "Pidiendo código...", - "sendDirectInvitesText": "Enviar directamente la invitación", + "publicHostRouterConfigText": "Esto puede requerir configurar el reenvío de puertos en tu router. Para una opción más fácil, aloja una partida privada.", + "publicText": "Público", + "requestingAPromoCodeText": "Pidiendo un código...", + "sendDirectInvitesText": "Enviar Directamente La Invitación", "shareThisCodeWithFriendsText": "Comparte este código con tus amigos:", - "showMyAddressText": "Mostrar mi dirección", - "startHostingPaidText": "Anfitrión Ahora Por ${COST}", - "startHostingText": "Anfitrión", + "showMyAddressText": "Mostrar Mi Dirección", + "startHostingPaidText": "Alojar Ahora Por ${COST}", + "startHostingText": "Alojar", "startStopHostingMinutesText": "Puede iniciar y detener el alojamiento de forma gratuita durante los próximos ${MINUTES} minutos.", - "stopHostingText": "Dejar de alojar", + "stopHostingText": "Dejar De Alojar", "titleText": "Reúne", - "wifiDirectDescriptionBottomText": "Si todo los dispositivos disponen de 'Wi-fi Directo', deberían poder utilizarlo para\nencontrar y conectarse entre ellos. Cuando todos estén conectados, puedes formar \nfiestas, usando la pestaña 'Red Local', como si estuvieran en la misma red Wi-fi.\n\nPara mejores resultados, el host de Wi-fi Directo también debe de ser el host de la fiesta en ${APP_NAME}.", + "wifiDirectDescriptionBottomText": "Si todo los dispositivos disponen de 'Wi-fi Directo', deberían poder utilizarlo para\nencontrar y conectarse entre ellos. Cuando todos estén conectados, puedes formar \npartidas, usando la pestaña 'Red Local', como si estuvieran en la misma red Wi-fi.\n\nPara mejores resultados, el alojador del Wi-fi Directo también debe de ser el alojador de la partida en ${APP_NAME}.", "wifiDirectDescriptionTopText": "Wi-Fi Directo puede ser utilizado para conectar dispositivos Android sin\ntener que utilizar una red Wi-Fi. Esto funciona mejor de Android 4.2 o mas nuevo.\n\nPara utilizarlo, abre los ajustes de Wi-Fi y busca 'Wi-Fi Directo' en el menú.", - "wifiDirectOpenWiFiSettingsText": "Abrir Ajustes Wi-Fi", + "wifiDirectOpenWiFiSettingsText": "Abrir Ajustes De Wi-Fi", "wifiDirectText": "Wi-Fi Directo", "worksBetweenAllPlatformsText": "(funciona con todas las plataformas)", - "worksWithGooglePlayDevicesText": "(funciona con dispositivos que corran la versión Google Play (Android) del juego)", - "youHaveBeenSentAPromoCodeText": "Has enviado un código de ${APP_NAME}:" + "worksWithGooglePlayDevicesText": "(funciona con dispositivos que ejecuten la versión Google Play (Android) del juego)", + "youHaveBeenSentAPromoCodeText": "Has enviado un código promocional de ${APP_NAME}:" }, "getCoinsWindow": { "coinDoublerText": "Duplicador de monedas", @@ -825,165 +841,167 @@ }, "getTicketsWindow": { "freeText": "¡GRATIS!", - "freeTicketsText": "Tickets Gratis", + "freeTicketsText": "Boletos Gratis", "inProgressText": "Ya hay una transacción en progreso; por favor inténtalo mas tarde.", - "purchasesRestoredText": "Compras Restauradas.", - "receivedTicketsText": "¡${COUNT} boletos recibidos!", + "purchasesRestoredText": "Compras restauradas.", + "receivedTicketsText": "¡Recibiste ${COUNT} boletos!", "restorePurchasesText": "Restaurar Compras", "ticketDoublerText": "Duplicador de Tiquetes", - "ticketPack1Text": "Paquete de Boletos Pequeño", - "ticketPack2Text": "Paquete de Boletos Mediano", - "ticketPack3Text": "Paquete de Boletos Grande", - "ticketPack4Text": "Paquete de Boletos Jumbo", - "ticketPack5Text": "Paquete de Boletos Mamut", - "ticketPack6Text": "Paquete de Boletos Supremo", - "ticketsFromASponsorText": "Obtén ${COUNT} boletos\nde un patrocinador", + "ticketPack1Text": "Paquete De Boletos Pequeño", + "ticketPack2Text": "Paquete De Boletos Mediano", + "ticketPack3Text": "Paquete De Boletos Grande", + "ticketPack4Text": "Paquete De Boletos Jumbo", + "ticketPack5Text": "Paquete De Boletos Mamut", + "ticketPack6Text": "Paquete De Boletos Supremo", + "ticketsFromASponsorText": "Ver un anuncio\na cambio de ${COUNT} boletos", "ticketsText": "${COUNT} Boletos", - "titleText": "Obtén Boletos", - "unavailableLinkAccountText": "Lo sentimos, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.", + "titleText": "Conseguir Boletos", + "unavailableLinkAccountText": "Disculpe, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.", "unavailableTemporarilyText": "No disponible por el momento; por favor inténtalo más tarde.", - "unavailableText": "Lo sentimos, no se encuentra disponible.", - "versionTooOldText": "Lo sentimos, esta versión está demasiado atrasada; por favor actualiza el juego.", + "unavailableText": "Disculpe, esto no esta disponible.", + "versionTooOldText": "Lo sentimos, esta versión del juego es muy antigua; por favor actualízala a una nueva versión.", "youHaveShortText": "tienes ${COUNT}", "youHaveText": "tienes ${COUNT} boletos" }, - "googleMultiplayerDiscontinuedText": "Lo siento, Google's multijugador servicio ya no esta mas disponible.\nEstoy trabajando en un reemplazo lo mas rapido posible.\nHasta entonces, por favor intente con otro metodo de conexión.\n-Eric", - "googlePlayPurchasesNotAvailableText": "Las compras de Google Play no están disponibles.\nEs posible que deba actualizar la aplicación de su tienda.", - "googlePlayServicesNotAvailableText": "Servicios de Google Play no disponibles.\nAlgunas funciones de la aplicación pueden estar deshabilitadas.", + "googleMultiplayerDiscontinuedText": "Lo siento, el servicio multijugador de Google ya no está disponible.\nEstoy trabajando en un reemplazo lo más rapido posible.\nHasta entonces, por favor intenta otro método de conexión.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Las compras de Google Play no están disponibles.\nEs posible que debas actualizar la aplicación de tu tienda.", + "googlePlayServicesNotAvailableText": "Los Servicios De Google Play no están disponibles.\nAlgunas funciones de la aplicación pueden estar deshabilitadas.", "googlePlayText": "Google Play", "graphicsSettingsWindow": { "alwaysText": "Siempre", "fullScreenCmdText": "Pantalla completa (Cmd-F)", "fullScreenCtrlText": "Pantalla completa (Ctrl-F)", - "gammaText": "Gamma", + "fullScreenText": "Pantalla completa", + "gammaText": "Gama", "highText": "Alta", - "higherText": "Superior", + "higherText": "Muy Alta", "lowText": "Baja", + "maxFPSText": "FPS Máximos", "mediumText": "Mediana", "neverText": "Nunca", "resolutionText": "Resolución", "showFPSText": "Mostrar FPS", "texturesText": "Texturas", "titleText": "Gráficos", - "tvBorderText": "Marco de TV", - "verticalSyncText": "Sincronización vertical", + "tvBorderText": "Borde de TV", + "verticalSyncText": "Sincronización Vertical", "visualsText": "Visuales" }, "helpWindow": { - "bombInfoText": "- Bomba -\nMas fuerte que los golpes, pero puede\nresultar en auto-lesiones bastante graves.\nPara mejores resultados, tírala hacia tus\noponentes antes de que explote.", + "bombInfoText": "- Bomba -\nMás fuerte que los golpes, pero puede\nresultar en autolesiones bastante graves.\nPara mejores resultados, tírala hacia tus\noponentes antes de que explote.", "bombInfoTextScale": 0.57, "canHelpText": "${APP_NAME} te puede ayudar.", - "controllersInfoText": "Puedes jugar ${APP_NAME} con tus amigos en una red, o todos pueden\njugar en el mismo dispositivo si se tienen varios controles.\n${APP_NAME} soporta una gran variedad de ellos; incluso puedes utilizar\ntus dispositivos móviles como controles instalando la app '${REMOTE_APP_NAME}'.\nVe a 'Ajustes-> Controles' para más información.", + "controllersInfoText": "Puedes jugar ${APP_NAME} con tus amigos en una red o todos pueden\njugar en el mismo dispositivo si se tienen varios controles.\n${APP_NAME} soporta una gran variedad de ellos; incluso puedes utilizar\ntus dispositivos móviles como controles instalando la app '${REMOTE_APP_NAME}'.\nVe a 'Ajustes-> Controles' para más información.", "controllersInfoTextFantasia": "Un jugador puede usar el mando a distancia para jugar, pero\nse recomienda usar gamepads. También puedes usar dispositivos\niOS o Android como controles con la app \"BombSquad Remote\".\nRevisa la sección \"Controles\" en los Ajustes para más información.", "controllersInfoTextMac": "Uno o dos jugadores pueden usar el teclado, pero BombSquad es mejor\ncon controles. BombSquad puede usar controles USB, controles de PS3,\ncontroles de Xbox 360, controles Wii y dispositivos iOS/Android para\ncontrolar los personajes. Espero que tengas algunos de ellos a la mano. \nConsulta 'Controles' bajo 'Ajustes' para más información.", "controllersInfoTextOuya": "Puedes usar controles OUYA, controles de PS3, controles de Xbox\n360, y muchos de otros controles USB y Bluetooth con BombSquad.\nPuedes usar también dispositivos iOS/Android como controles con la aplicación \n'BombSquad Remote'. Consulta 'Controles' bajo 'Ajustes' para más información.", - "controllersInfoTextRemoteOnly": "Tu puedes jugar ${APP_NAME} con tus amigos en la red, o pueden\njugar todos en el mismo dispositivo usando los teléfonos\ncomo controles libres con la aplicación '${REMOTE_APP_NAME}'", + "controllersInfoTextRemoteOnly": "Tu puedes jugar ${APP_NAME} con tus amigos en la red o pueden\njugar todos en el mismo dispositivo usando los teléfonos\ncomo controles libres con la aplicación '${REMOTE_APP_NAME}'", "controllersText": "Controles", "controllersTextScale": 0.67, - "controlsSubtitleText": "Tu personaje de ${APP_NAME} tiene algunas acciones básicas:", + "controlsSubtitleText": "Tu amistoso personaje de ${APP_NAME} tiene algunas acciones básicas:", "controlsSubtitleTextScale": 0.7, "controlsText": "Controles", "controlsTextScale": 1.4, - "devicesInfoText": "La version VR de ${APP_NAME} se puede jugar en red con la versión \nregular, así que saca tus celulares, tablets y PCs extra y que \nempieze el juego. Es muy útil conectar un dispositivo con la versión\nregular a uno con la versión VR para que todos los que esten fuera\npuedan ver la acción.", + "devicesInfoText": "La versión VR de ${APP_NAME} se puede jugar en red con la versión \nregular, así que saca tus celulares, tablets y computadoras extras y que \nempieze el juego. Es muy útil conectar un dispositivo con la versión\nregular a uno con la versión VR para que todos los que estén fuera\npuedan ver la acción.", "devicesText": "Dispositivos", "friendsGoodText": "Cuantos más, mejor. ${APP_NAME} es más divertido con muchos \namigos y soporta hasta 8 a la vez, lo que nos lleva a:", "friendsGoodTextScale": 0.62, "friendsText": "Amigos", "friendsTextScale": 0.67, - "jumpInfoText": "- Salto -\nSalta para cruzar pequeños\nespacios, tirar cosas más lejos,\ny para expresar alegría.", + "jumpInfoText": "- Saltar -\nSalta para cruzar pequeños espacios, \npara tirar cosas más lejos y \npara expresar sentimientos de alegría.", "jumpInfoTextScale": 0.6, - "orPunchingSomethingText": "O golpear algo, tirarlo por un precipicio, y explotarlo en plena caída con una bomba pegajosa.", + "orPunchingSomethingText": "O golpear algo, tirarlo por un precipicio y explotarlo en plena caída con una bomba pegajosa.", "orPunchingSomethingTextScale": 0.51, - "pickUpInfoText": "- Levanta -\nAlza banderas, enemigos, o cualquier\notra cosa no atornillada al suelo.\nPulsa de nuevo para lanzar.", + "pickUpInfoText": "- Recoger -\nAgarra banderas, enemigos o cualquier\notra cosa no atornillada al suelo.\nPresiona de nuevo para lanzar.", "pickUpInfoTextScale": 0.6, "powerupBombDescriptionText": "Te permite sacar tres bombas\nen una fila en lugar de solo una.", "powerupBombNameText": "Bombas Triples", - "powerupCurseDescriptionText": "Probablemente quieras evitar estos.\n ...¿o quizás tú?", + "powerupCurseDescriptionText": "Probablemente querrás evitar estos.\n ...¿o quizás no?", "powerupCurseNameText": "Maldición", "powerupHealthDescriptionText": "Te restaura a la salud completa.\nNunca lo habrías adivinado.", "powerupHealthNameText": "Botiquín", "powerupIceBombsDescriptionText": "Más débiles que las bombas normales\npero dejan a tus enemigos congelados\ny particularmente frágiles.", - "powerupIceBombsNameText": "Bombas de Hielo", + "powerupIceBombsNameText": "Bombas De Hielo", "powerupImpactBombsDescriptionText": "Levemente más débiles que las bombas\nregulares, pero explotan al impacto.", - "powerupImpactBombsNameText": "Bombas de Gatillo", + "powerupImpactBombsNameText": "Insta-Bombas", "powerupLandMinesDescriptionText": "Estas vienen en grupos de 3;\nSon buenas para defensa territorial\no para detener enemigos veloces.", "powerupLandMinesNameText": "Minas Terrestres", - "powerupPunchDescriptionText": "Hacen que tus golpes sean más duros,\nmás rápidos, mejores, y más fuertes.", - "powerupPunchNameText": "Guantes de Boxeo", - "powerupShieldDescriptionText": "Absorbe un poco de daño\npara que no tengas que hacerlo.", - "powerupShieldNameText": "Escudo de Energía", - "powerupStickyBombsDescriptionText": "Se adhieren a cualquier cosa.\nProducen hilaridad.", + "powerupPunchDescriptionText": "Hacen que tus golpes sean más duros,\nmás rápidos, mejores y más fuertes.", + "powerupPunchNameText": "Guantes De Boxeo", + "powerupShieldDescriptionText": "Absorbe un poco de daño\npara que tú no tengas que hacerlo.", + "powerupShieldNameText": "Electro-Escudo", + "powerupStickyBombsDescriptionText": "Se adhieren a todo lo que toquen.\nProducen hilaridad.", "powerupStickyBombsNameText": "Bombas Pegajosas", "powerupsSubtitleText": "Por supuesto, ningún juego está completo sin potenciadores:", "powerupsSubtitleTextScale": 0.8, "powerupsText": "Potenciadores", "powerupsTextScale": 1.4, - "punchInfoText": "- Golpe -\nEntre más rápido te muevas más\nimpacto causan tus golpes, así que\ncorre, salta y da vueltas como loco.", + "punchInfoText": "- Golpear -\nLos golpes hacen más daño cuanto\nmás rápido se muevan tus puños, así que\ncorre, salta y gira como un loco.", "punchInfoTextScale": 0.6, - "runInfoText": "- Correr -\nSostén CUALQUIER botón para correr. Los botones gatillos o traseros funcionan bien si los tienes.\nCorrer te hace llegar más rápido pero es más difícil girar, así que ten cuidado con los barrancos.", + "runInfoText": "- Correr -\nMantén CUALQUIER botón para correr. Los gatillos o botones traseros funcionan bien si los tienes.\nCorrer te lleva a lugares más rápido pero es más difícil girar, así que ten cuidado con los barrancos.", "runInfoTextScale": 0.6, - "someDaysText": "Hay días cuando sientes ganas de romper algo. O explotarlo.", + "someDaysText": "Hay días en los que sientes ganas de golpear algo. O volar algo.", "someDaysTextScale": 0.66, "titleText": "Ayuda ${APP_NAME}", "toGetTheMostText": "Para sacar el máximo partido a este juego, necesitas:", "toGetTheMostTextScale": 1.0, "welcomeText": "¡Bienvenido a ${APP_NAME}!" }, - "holdAnyButtonText": "", - "holdAnyKeyText": "", - "hostIsNavigatingMenusText": "- ${HOST} navega los menús como todo un pro -", - "importPlaylistCodeInstructionsText": "Usa el siguiente código para importar esta lista de reproducción en otra parte", + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} está navegando los menús como todo un pro -", + "importPlaylistCodeInstructionsText": "Usa el siguiente código para importar esta lista de reproducción en otra parte:", "importPlaylistSuccessText": "Lista de reproducción '${NAME}' importada ${TYPE}", "importText": "Importar", "importingText": "Importando...", "inGameClippedNameText": "en el juego será\n\"${NAME}\"", - "installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación\nPuede que te hayas quedado sin espacio.\nLibera un poco de tu espacio e intenta de nuevo.", + "installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación.\nPuede que te hayas quedado sin espacio.\nLibera un poco de tu espacio e intenta de nuevo.", "internal": { "arrowsToExitListText": "pulsa ${LEFT} o ${RIGHT} para salir de la lista", "buttonText": "botón", - "cantKickHostError": "No puedes expulsar al host", - "chatBlockedText": "A ${NAME} le hemos bloqueado el chat por ${TIME} segundos.", - "connectedToGameText": "'${NAME}' se unió", - "connectedToPartyText": "¡Unido a la fiesta de ${NAME}!", + "cantKickHostError": "No puedes expulsar al anfitrión.", + "chatBlockedText": "${NAME} está bloqueado del chat por ${TIME} segundos.", + "connectedToGameText": "Unido a '${NAME}'", + "connectedToPartyText": "¡Unido a la partida de ${NAME}!", "connectingToPartyText": "Conectando...", - "connectionFailedHostAlreadyInPartyText": "Conexión fallida; Host esta en otra fiesta.", - "connectionFailedPartyFullText": "Conexión fallida; la fiesta está llena.", + "connectionFailedHostAlreadyInPartyText": "Conexión fallida; el anfitrión está en otra partida.", + "connectionFailedPartyFullText": "Conexión fallida; la partida está llena.", "connectionFailedText": "Conexión fallida.", - "connectionFailedVersionMismatchText": "Conexión fallida; Host corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "connectionFailedVersionMismatchText": "Conexión fallida; el anfitrión corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", "connectionRejectedText": "Conexión rechazada.", "controllerConnectedText": "${CONTROLLER} conectado.", "controllerDetectedText": "1 control detectado.", "controllerDisconnectedText": "${CONTROLLER} desconectado.", "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Intenta conectarlo de nuevo.", - "controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menus.", + "controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menús.", "controllerReconnectedText": "${CONTROLLER} reconectado.", "controllersConnectedText": "${COUNT} controles conectados.", "controllersDetectedText": "${COUNT} controles detectados.", "controllersDisconnectedText": "${COUNT} controles desconectados.", - "corruptFileText": "Archivos corruptos detectados. Por favor reinstala el juego o contacta ${EMAIL}", - "errorPlayingMusicText": "Error al reproducir música: ${MUSIC}", - "errorResettingAchievementsText": "No se pudieron reiniciar los logros; por favor inténtalo de nuevo.", - "hasMenuControlText": "${NAME} Tiene control del menú.", - "incompatibleNewerVersionHostText": "El host está corriendo una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.", - "incompatibleVersionHostText": "Host corre una versión diferente del juego; imposible conectar.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", - "incompatibleVersionPlayerText": "${NAME} está corriendo una versión diferente del juego y no se ha podido conectar.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", - "invalidAddressErrorText": "Error: Dirección inválida.", - "invalidNameErrorText": "Error: Nombre invalido", - "invalidPortErrorText": "Error: Puerto inválido.", + "corruptFileText": "Archivo(s) corrupto(s) detectado(s). Por favor intenta reinstalar o contáctate con ${EMAIL}", + "errorPlayingMusicText": "Error reproduciendo música: ${MUSIC}", + "errorResettingAchievementsText": "Incapaz de reiniciar los logros; por favor inténtalo de nuevo más tarde.", + "hasMenuControlText": "${NAME} tiene el control del menú.", + "incompatibleNewerVersionHostText": "El anfitrión está ejecutando una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.", + "incompatibleVersionHostText": "El anfitrión está ejecutando una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "incompatibleVersionPlayerText": "${NAME} está ejecutando una versión diferente del juego.\nAsegúrate de que ambos estén actualizados y vuelve a intentarlo.", + "invalidAddressErrorText": "Error: dirección inválida.", + "invalidNameErrorText": "Error: nombre inválido.", + "invalidPortErrorText": "Error: puerto inválido.", "invitationSentText": "Invitación enviada.", "invitationsSentText": "${COUNT} invitaciones enviadas.", - "joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta\nVe a 'Jugar' para iniciar el juego", + "joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta.\nVe a 'Jugar' para iniciar un juego.", "keyboardText": "Teclado", - "kickIdlePlayersKickedText": "Sacando a ${NAME} por no mostrar movimiento.", - "kickIdlePlayersWarning1Text": "${NAME} será sacado en ${COUNT} segundos si no presenta movimiento.", + "kickIdlePlayersKickedText": "Expulsando a ${NAME} por estar inactivo.", + "kickIdlePlayersWarning1Text": "${NAME} será expulsado en ${COUNT} segundos si sigue inactivo.", "kickIdlePlayersWarning2Text": "(puedes apagar esto en Ajustes -> Avanzado)", - "leftGameText": "'${NAME}' salió", - "leftPartyText": "Dejó la fiesta de ${NAME}.", + "leftGameText": "Abandonó '${NAME}'.", + "leftPartyText": "Abandonó la partida de ${NAME}.", "noMusicFilesInFolderText": "La carpeta no contiene archivos de audio.", - "playerJoinedPartyText": "¡${NAME} se unió a la fiesta!", - "playerLeftPartyText": "${NAME} se fue de la fiesta.", - "rejectingInviteAlreadyInPartyText": "Rechazando invitación (Ya en una fiesta).", - "serverRestartingText": "El servidor se está reiniciando. Conéctese en un momento...", + "playerJoinedPartyText": "¡${NAME} se unió a la partida!", + "playerLeftPartyText": "${NAME} abandonó la partida.", + "rejectingInviteAlreadyInPartyText": "Rechazando invitación (Ya estás en una partida).", + "serverRestartingText": "El servidor se está reiniciando. Por favor vuelva a unirse en un momento...", "serverShuttingDownText": "El servidor está fuera de servicio...", "signInErrorText": "Error iniciando sesión.", "signInNoConnectionText": "Imposible iniciar sesión (¿No hay conexión a internet?)", @@ -991,16 +1009,16 @@ "telnetAccessDeniedText": "ERROR: El usuario no concedió acceso telnet.", "timeOutText": "(tiempo fuera en ${TIME} segundos)", "touchScreenJoinWarningText": "Te uniste con la pantalla táctil.\nSi este fue un error, presiona 'Menú->Dejar juego' con ella.", - "touchScreenText": "Pantalla táctil", + "touchScreenText": "Pantalla Táctil", "trialText": "prueba", - "unableToResolveHostText": "Error: no se ha podido resolver el host", + "unableToResolveHostText": "Error: incapaz de encontrar el anfitrión.", "unavailableNoConnectionText": "No disponible por el momento (¿No tienes conexión a internet?)", - "vrOrientationResetCardboardText": "Usa esto para reiniciarr la orientación del VR.\nPara jugar el juego necesitarás un control externo.", - "vrOrientationResetText": "Orientación VR reseteada.", + "vrOrientationResetCardboardText": "Usa esto para reiniciar la orientación VR.\nPara jugar el juego necesitarás un control externo.", + "vrOrientationResetText": "Orientación VR reiniciada.", "willTimeOutText": "(caducará si está inactivo)" }, - "jumpBoldText": "SALTA", - "jumpText": "Brinca", + "jumpBoldText": "SALTAR", + "jumpText": "Saltar", "keepText": "Mantener", "keepTheseSettingsText": "¿Mantener estos ajustes?", "keyboardChangeInstructionsText": "Presiona dos veces el espacio para cambiar los teclados.", @@ -1009,34 +1027,34 @@ "kickOccurredText": "${NAME} ha sido expulsado.", "kickQuestionText": "¿Expulsar a ${NAME}?", "kickText": "Expulsar", - "kickVoteCantKickAdminsText": "El administrador no puede ser expulsado", - "kickVoteCantKickSelfText": "No puedes expulsarte a ti mismo", + "kickVoteCantKickAdminsText": "Los administradores no pueden ser expulsados.", + "kickVoteCantKickSelfText": "No puedes expulsarte a ti mismo.", "kickVoteFailedNotEnoughVotersText": "No hay suficientes jugadores para votar.", - "kickVoteFailedText": "Votación de expulsión fallida", - "kickVoteStartedText": "Han iniciado una votación para expulsar a '${NAME}'.", - "kickVoteText": "Vota para expulsar", - "kickVotingDisabledText": "El voto para expulsar no está disponible", + "kickVoteFailedText": "Votación de expulsión fallida.", + "kickVoteStartedText": "Se ha iniciado una votación de expulsión para '${NAME}'.", + "kickVoteText": "Votar para Expulsar", + "kickVotingDisabledText": "El voto para expulsar no está disponible.", "kickWithChatText": "Escribe ${YES} en el chat para \"Si\" y ${NO} para \"No\".", - "killsTallyText": "eliminó ${COUNT}", - "killsText": "Víctimas", + "killsTallyText": "${COUNT} asesinatos", + "killsText": "Asesinatos", "kioskWindow": { "easyText": "Fácil", "epicModeText": "Modo Épico", "fullMenuText": "Menú Completo", "hardText": "Difícil", "mediumText": "Medio", - "singlePlayerExamplesText": "Ejemplos 1 Jugador / Varios jugadores", - "versusExamplesText": "Ejemplos Versus" + "singlePlayerExamplesText": "Ejemplos de 1 Jugador / Modo Cooperativo", + "versusExamplesText": "Ejemplos de Versus" }, "languageSetText": "El lenguaje es ahora \"${LANGUAGE}\".", "lapNumberText": "Vuelta ${CURRENT}/${TOTAL}", "lastGamesText": "(últimos ${COUNT} juegos)", "leaderboardsText": "Clasificaciones", "league": { - "allTimeText": "De todo el tiempo", - "currentSeasonText": "Temporada en curso (${NUMBER})", + "allTimeText": "Todo El Tiempo", + "currentSeasonText": "Temporada Actual (${NUMBER})", "leagueFullText": "Liga ${NAME}", - "leagueRankText": "Liga Rank", + "leagueRankText": "Rango De Liga", "leagueText": "Liga", "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", "seasonEndedDaysAgoText": "La temporada terminó hace ${NUMBER} día(s).", @@ -1054,59 +1072,59 @@ "levelIsLockedText": "${LEVEL} está bloqueado.", "levelMustBeCompletedFirstText": "${LEVEL} debe completarse primero.", "levelText": "Nivel ${NUMBER}", - "levelUnlockedText": "¡Nivel desbloqueado!", - "livesBonusText": "Bono de vidas", + "levelUnlockedText": "¡Nivel Desbloqueado!", + "livesBonusText": "Bono De Vidas", "loadingText": "cargando", "loadingTryAgainText": "Cargando; vuelve a intentarlo en un momento...", "macControllerSubsystemBothText": "Ambos (no recomendado)", "macControllerSubsystemClassicText": "Clásico", - "macControllerSubsystemDescriptionText": "(Intenta cambiar esto si tus controladores no están funcionando)", + "macControllerSubsystemDescriptionText": "(intenta cambiar esto si tus controladores no están funcionando)", "macControllerSubsystemMFiNoteText": "Control hecho para iOS/Mac detectado;\nTal vez quieras activar esto en Configuracion -> Controles", "macControllerSubsystemMFiText": "Creado-para-iOS/Mac", - "macControllerSubsystemTitleText": "Soporte de controladores", + "macControllerSubsystemTitleText": "Soporte De Controladores", "mainMenu": { "creditsText": "Créditos", "demoMenuText": "Menú Demo", - "endGameText": "Salir del juego", - "endTestText": "Prueba final", - "exitGameText": "Salir del juego", + "endGameText": "Terminar Juego", + "endTestText": "Terminar Prueba", + "exitGameText": "Salir Del Juego", "exitToMenuText": "¿Salir al menú?", - "howToPlayText": "Cómo jugar", + "howToPlayText": "Cómo Jugar", "justPlayerText": "(Solo ${NAME})", - "leaveGameText": "Dejar Juego", - "leavePartyConfirmText": "¿Seguro que deseas dejar la fiesta?", - "leavePartyText": "Dejar Fiesta", + "leaveGameText": "Abandonar Juego", + "leavePartyConfirmText": "¿Realmente deseas abandonar la partida?", + "leavePartyText": "Abandonar Partida", "leaveText": "Abandonar", "quitText": "Salir", "resumeText": "Reanudar", "settingsText": "Ajustes" }, "makeItSoText": "Que así sea", - "mapSelectGetMoreMapsText": "Conseguir más Mapas...", + "mapSelectGetMoreMapsText": "Conseguir Más Mapas...", "mapSelectText": "Seleccionar…", - "mapSelectTitleText": "Pistas: ${GAME}", - "mapText": "Pista", - "maxConnectionsText": "Conexiones máximas", - "maxPartySizeText": "Capacidad máxima de la fiesta", - "maxPlayersText": "Jugadores máximos", - "merchText": "Mercado!", + "mapSelectTitleText": "Mapas Para ${GAME}", + "mapText": "Mapa", + "maxConnectionsText": "Máximo De Conexiones", + "maxPartySizeText": "Capacidad Máxima De La Partida", + "maxPlayersText": "Máximo De Jugadores", + "merchText": "¡Mercancía!", "modeArcadeText": "Modo Arcade", "modeClassicText": "Modo Clásico", - "modeDemoText": "Modo De Demostración", - "mostValuablePlayerText": "Jugador más Valorado", - "mostViolatedPlayerText": "Jugador más Violado", - "mostViolentPlayerText": "Jugador más Matador", + "modeDemoText": "Modo Demo", + "mostValuablePlayerText": "Jugador Más Valioso", + "mostViolatedPlayerText": "Jugador Más Violado", + "mostViolentPlayerText": "Jugador Más Violento", "moveText": "Mover", - "multiKillText": "¡¡¡${COUNT}-COMBO!!!", + "multiKillText": "¡¡¡COMBO DE ${COUNT}!!!", "multiPlayerCountText": "${COUNT} jugadores", "mustInviteFriendsText": "Nota: debes invitar a tus amigos en\nel panel \"${GATHER}\" o conectar\ncontroles para jugar multijugador.", "nameBetrayedText": "${NAME} traicionó a ${VICTIM}.", "nameDiedText": "${NAME} ha muerto.", "nameKilledText": "${NAME} mató a ${VICTIM}.", "nameNotEmptyText": "¡El nombre no puede quedar vacío!", - "nameScoresText": "¡${NAME} anotó!", + "nameScoresText": "¡${NAME} Anotó!", "nameSuicideKidFriendlyText": "${NAME} murió por accidente.", - "nameSuicideText": "${NAME} se a suicidado.", + "nameSuicideText": "${NAME} cometió suicidio.", "nameText": "Nombre", "nativeText": "Nativo", "newPersonalBestText": "¡Nuevo récord personal!", @@ -1114,52 +1132,54 @@ "newText": "Nuevo", "newVersionAvailableText": "¡Una nueva version de ${APP_NAME} está disponible! (${VERSION})", "nextAchievementsText": "Siguientes Logros:", - "nextLevelText": "Próximo nivel", + "nextLevelText": "Siguiente Nivel", "noAchievementsRemainingText": "- ninguno", "noContinuesText": "(sin re-intentos)", "noExternalStorageErrorText": "No se encontraron almacenamientos externos en este dispositivo", - "noGameCircleText": "Error: No has autenticado con GameCircle", + "noGameCircleText": "Error: no registrado en GameCircle", "noJoinCoopMidwayText": "Jugadores no pueden unirse en mitad de un juego.", + "noPluginsInstalledText": "Sin Complementos Instalados", "noProfilesErrorText": "No haz creado ningún perfil, por lo que tendrás que llamarte '${NAME}'.\nVe a Ajustes>Perfiles para que te hagas un perfil.", - "noScoresYetText": "Sin puntuaciones aún.", - "noThanksText": "No gracias", + "noScoresYetText": "Sin puntajes aún.", + "noServersFoundText": "No se encontraron servidores.", + "noThanksText": "No Gracias", "noTournamentsInTestBuildText": "ADVERTENCIA: los puntajes de los torneos en esta versión de prueba serán ignorados.", - "noValidMapsErrorText": "No hay pistas para este tipo de juego.", + "noValidMapsErrorText": "Mapas válidos no encontrados para este tipo de juego.", "notEnoughPlayersRemainingText": "Cantidad necesaria de jugadores no coincide; inicia un juego nuevo.", "notEnoughPlayersText": "¡Necesitas por lo menos ${COUNT} jugadores para comenzar!", - "notNowText": "Ahora no", - "notSignedInErrorText": "Necesitas registrarte para hacer esto.", + "notNowText": "Ahora No", + "notSignedInErrorText": "Debes iniciar sesión para hacer esto.", "notSignedInGooglePlayErrorText": "Debes iniciar sesión con Google Play para hacer esto.", "notSignedInText": "No registrado", - "notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Ingresar con ${SERVICE}' si quieres usarla", + "notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Ingresar con ${SERVICE}' si quieres usarla.", "nothingIsSelectedErrorText": "¡No hay nada seleccionado!", "numberText": "#${NUMBER}", - "offText": "Apagado", + "offText": "Apagar", "okText": "Aceptar", - "onText": "Encendido", - "oneMomentText": "Un momento...", - "onslaughtRespawnText": "${PLAYER} reaparecerá en la horda ${WAVE}", + "onText": "Encender", + "oneMomentText": "Un Momento...", + "onslaughtRespawnText": "${PLAYER} reaparecerá en la oleada ${WAVE}", "orText": "${A} o ${B}", "otherText": "Otros...", "outOfText": "(#${RANK} de ${ALL})", - "ownFlagAtYourBaseWarning": "Tu misma bandera debe estar\nen su lugar para anotar!", + "ownFlagAtYourBaseWarning": "¡Su propia bandera debe estar\nen su base para anotar!", "packageModsEnabledErrorText": "Juegos de red no están permitidos mientras paquetes modificadores estén habilitados (ver Ajustes->Avanzado)", "partyWindow": { - "chatMessageText": "Mensaje del Chat", - "emptyText": "Tu fiesta está vacía", + "chatMessageText": "Mensaje Del Chat", + "emptyText": "Tu partida está vacía", "hostText": "(host)", "sendText": "Enviar", - "titleText": "Tu Fiesta" + "titleText": "Tu Partida" }, - "pausedByHostText": "(pausado por host)", - "perfectWaveText": "¡Horda perfecta!", + "pausedByHostText": "(pausado por el host)", + "perfectWaveText": "¡Oleada Perfecta!", "pickUpBoldText": "LEVANTAR", - "pickUpText": "Levantar", + "pickUpText": "Recoger", "playModes": { "coopText": "Cooperativo", - "freeForAllText": "Todos contra Todos", - "multiTeamText": "Múltiples Equipos", - "singlePlayerCoopText": "Solo un Jugador / Co-op", + "freeForAllText": "Todos-contra-Todos", + "multiTeamText": "Múlti-Equipo", + "singlePlayerCoopText": "Solo Un Jugador / Cooperativo", "teamsText": "Equipos" }, "playText": "Jugar", @@ -1173,47 +1193,47 @@ }, "playerCountAbbreviatedText": "${COUNT}j", "playerDelayedJoinText": "${PLAYER} entrará al comienzo de la siguiente ronda.", - "playerInfoText": "Información del Jugador", - "playerLeftText": "${PLAYER} abandonó la partida", + "playerInfoText": "Información Del Jugador", + "playerLeftText": "${PLAYER} abandonó el juego.", "playerLimitReachedText": "Límite de ${COUNT} jugadores alcanzado; no se permiten más.", "playerLimitReachedUnlockProText": "Mejora a \"${PRO}\" en la tienda para jugar con más de ${COUNT} jugadores.", "playerProfilesWindow": { "cantDeleteAccountProfileText": "No puedes borrar el perfil de tu cuenta.", "deleteButtonText": "Borrar\nPerfil", - "deleteConfirmText": "Borrar '${PROFILE}'?", + "deleteConfirmText": "¿Borrar '${PROFILE}'?", "editButtonText": "Editar\nPerfil", "explanationText": "(nombres de jugadores personalizados y apariencias para esta cuenta)", "newButtonText": "Nuevo\nPerfil", - "titleText": "Perfil de jugadores" + "titleText": "Perfiles Del Jugador" }, "playerText": "Jugador", "playlistNoValidGamesErrorText": "Esta lista de juegos contiene juegos desbloqueables no válidos.", "playlistNotFoundText": "lista no encontrada", - "playlistText": "Lista de reproducción", - "playlistsText": "Listas de Juego", + "playlistText": "Lista de juegos", + "playlistsText": "Listas de juegos", "pleaseRateText": "Si te gusta ${APP_NAME}, por favor tomate un momento\npara calificar o escribir una reseña. Esto proporcionará\ninformación útil y ayuda al soporte del futuro desarrollo del juego.\n\n¡gracias!\n-eric", "pleaseWaitText": "Por favor, espera...", - "pluginClassLoadErrorText": "Error al cargar la clase del plugin '${PLUGIN}': ${ERROR}", - "pluginInitErrorText": "Error al iniciar el plugin '${PLUGIN}': ${ERROR}", - "pluginSettingsText": "Ajustes del Plugin", - "pluginsAutoEnableNewText": "Activar Plugins automáticamente", - "pluginsDetectedText": "Nuevos complemento(s) detectados. Reinicie para activarlos, o configúrelos en la configuración", - "pluginsDisableAllText": "Desactivar todos los Plugins", - "pluginsEnableAllText": "Activar todos los Plugins", - "pluginsRemovedText": "${NUM} plugin(s) ya no se encuentran.", - "pluginsText": "Plugins", + "pluginClassLoadErrorText": "Error cargando el complemento '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Error iniciando complemento '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Ajustes De Complementos", + "pluginsAutoEnableNewText": "Auto Habilitar Nuevos Complementos", + "pluginsDetectedText": "Complemento detectado(s). Reinicia el juego o ve a ajustes para configurarlo.", + "pluginsDisableAllText": "Deshabilitar Todos Los Complementos", + "pluginsEnableAllText": "Habilitar Todos Los Complementos", + "pluginsRemovedText": "${NUM} complemento(s) ya no se encuentra(n).", + "pluginsText": "Complementos", "practiceText": "Práctica", - "pressAnyButtonPlayAgainText": "Oprime cualquier botón jugar de nuevo...", - "pressAnyButtonText": "Oprime cualquier botón para continuar...", - "pressAnyButtonToJoinText": "Oprime cualquier botón para unirse al juego...", - "pressAnyKeyButtonPlayAgainText": "Oprime cualquier botón/tecla para jugar de nuevo...", - "pressAnyKeyButtonText": "Oprime cualquier botón/tecla para continuar...", - "pressAnyKeyText": "Oprime cualquier tecla...", - "pressJumpToFlyText": "** Salta repetidamente para volar **", - "pressPunchToJoinText": "Pulsa GOLPE para unirse al juego...", - "pressToOverrideCharacterText": "Presiona ${BUTTONS} para cambiar de personaje", - "pressToSelectProfileText": "Presiona ${BUTTONS} para seleccionar tu perfil", - "pressToSelectTeamText": "Presiona ${BUTTONS} para seleccionar un equipo", + "pressAnyButtonPlayAgainText": "Presiona cualquier botón para jugar de nuevo...", + "pressAnyButtonText": "Presiona cualquier botón para continuar...", + "pressAnyButtonToJoinText": "presiona cualquier botón para unirse al juego...", + "pressAnyKeyButtonPlayAgainText": "Presiona cualquier botón/tecla para jugar de nuevo...", + "pressAnyKeyButtonText": "Presiona cualquier botón/tecla para continuar...", + "pressAnyKeyText": "Presiona cualquier tecla...", + "pressJumpToFlyText": "** Presiona saltar repetidamente para volar **", + "pressPunchToJoinText": "presiona GOLPEAR para unirse...", + "pressToOverrideCharacterText": "presiona ${BUTTONS} para cambiar de personaje", + "pressToSelectProfileText": "presiona ${BUTTONS} para seleccionar tu perfil", + "pressToSelectTeamText": "presiona ${BUTTONS} para seleccionar un equipo", "profileInfoText": "Crear perfiles para ti y tus amigos para que\npersonalices sus nombres, personajes y colores.", "promoCodeWindow": { "codeText": "Código", @@ -1230,14 +1250,14 @@ "titleText": "Para usar controles de PS3 con ${APP_NAME}:" }, "publicBetaText": "BETA PUBLICA", - "punchBoldText": "GOLPE", - "punchText": "Golpe", - "purchaseForText": "Comprar por este precio : ${PRICE}", + "punchBoldText": "GOLPEAR", + "punchText": "Golpear", + "purchaseForText": "Comprar por ${PRICE}", "purchaseGameText": "Comprar Juego", "purchasingText": "Comprando...", - "quitGameText": "¿Cerrar ${APP_NAME}?", - "quittingIn5SecondsText": "Abandonando en 5 segundos...", - "randomPlayerNamesText": "DEFAULT_NAMES, Pablo, Fulanito, Menganita, Martín, Franco, Pancho, Tomás, Bruno, Federico, Juan, Joaquín, Huevoduro", + "quitGameText": "¿Salir de ${APP_NAME}?", + "quittingIn5SecondsText": "Saliendo en 5 segundos...", + "randomPlayerNamesText": "DEFAULT_NAMES, Pablo, Fulanito, Menganita, Martín, Franco, Pancho, Tomás, Bruno, Federico, Juan, Joaquín, Huevo Duro, Chico Rico", "randomText": "Generar", "rankText": "Rango", "ratingText": "Valoración", @@ -1249,22 +1269,22 @@ "remote_app": { "app_name": "Control Remoto BombSquad", "app_name_short": "BSRemoto", - "button_position": "Posición de los botones", - "button_size": "Tamaño de los botones", - "cant_resolve_host": "No se encuentra el host.", + "button_position": "Posición De Los Botones", + "button_size": "Tamaño De Los Botones", + "cant_resolve_host": "No se encuentra el anfitrión.", "capturing": "Captando...", "connected": "Conectado.", "description": "Usa tu teléfono o tableta como control para BombSquad.\nHasta 8 dispositivos pueden conectarse a la vez para un épico caos multijugador local en un solo TV o tableta", "disconnected": "Desconectado por el servidor.", - "dpad_fixed": "Fijo", - "dpad_floating": "Flotante", - "dpad_position": "Posición del D-Pad", - "dpad_size": "Tamaño del D-Pad", - "dpad_type": "Tipo de D-Pad", + "dpad_fixed": "fijo", + "dpad_floating": "flotante", + "dpad_position": "Posición Del D-Pad", + "dpad_size": "Tamaño Del D-Pad", + "dpad_type": "Tipo De D-Pad", "enter_an_address": "Ingresa una dirección", "game_full": "El juego está lleno o no acepta conexiones.", "game_shut_down": "El juego se ha cerrado.", - "hardware_buttons": "Botones de Hardware", + "hardware_buttons": "Botones Del Hardware", "join_by_address": "Unirse por dirección...", "lag": "Lag: ${SECONDS} segundos", "reset": "Reestablecer a predeterminado", @@ -1283,9 +1303,9 @@ "replayRenameWarningText": "Renombra \"${REPLAY}\" despues de un juego si quieres quedarte con el; o sino será reemplazado.", "replayVersionErrorText": "Lo sentimos, esta repetición fue hecha en una\nversión diferente del juego y no se puede usar.", "replayWatchText": "Ver Repetición", - "replayWriteErrorText": "Error creando archivo de repetición", + "replayWriteErrorText": "Error creando archivo de repetición.", "replaysText": "Repeticiones", - "reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje ofensivo, u otro mal comportamiento.\nPor favor, describelo aquí abajo:", + "reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje inapropiado, u otro mal comportamiento.\nPor favor, describelo aquí abajo:", "reportThisPlayerCheatingText": "Trampas", "reportThisPlayerLanguageText": "Lenguaje Inapropiado", "reportThisPlayerReasonText": "¿Qué vas a reportar?", @@ -1296,10 +1316,12 @@ "revertText": "Deshacer", "runText": "Correr", "saveText": "Guardar", - "scanScriptsErrorText": "Error (s) escaneando scripts; ver el registro para más detalles.", - "scoreChallengesText": "Desafíos de Puntuación", - "scoreListUnavailableText": "La lista de puntuaciones no está disponible.", - "scoreText": "Puntuación", + "scanScriptsErrorText": "Error(s) escaneando scripts; Vea el registro para más detalles.", + "scanScriptsMultipleModulesNeedUpdatesText": "Los ${PATH} y ${NUM} y otros módulo(s) se deberán actualizar para el api ${API}", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} se deberá actualizar para el api ${API}", + "scoreChallengesText": "Desafíos De Puntuación", + "scoreListUnavailableText": "La lista de puntajes no está disponible.", + "scoreText": "Puntaje", "scoreUnits": { "millisecondsText": "Milisegundos", "pointsText": "Puntos", @@ -1307,6 +1329,7 @@ }, "scoreWasText": "(era ${COUNT})", "selectText": "Elegir", + "sendInfoDescriptionText": "Envía información del estado de la cuenta y de la aplicación al desarrollador.\nPor favor incluya su nombre o el motivo del envío.", "seriesWinLine1PlayerText": "GANA LA", "seriesWinLine1TeamText": "GANA LA", "seriesWinLine1Text": "¡GANA LA", @@ -1323,36 +1346,42 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(un teclado simple y amigable con controles para editar textos)", - "alwaysUseInternalKeyboardText": "Siempre Usar el Teclado Interno", - "benchmarksText": "Puntos de Referencia y Pruebas de Resistencia", - "disableCameraGyroscopeMotionText": "Desactivar el movimiento giróscopico de la cámara", - "disableCameraShakeText": "Desactivar el temblor de la cámara", - "disableThisNotice": "(Puedes desactivar este aviso en configuraciones avanzadas)", + "alwaysUseInternalKeyboardText": "Siempre usar el teclado interno", + "benchmarksText": "Puntos De Referencia & Pruebas De Estrés", + "devToolsText": "Herramientas de Desarrollo", + "disableCameraGyroscopeMotionText": "Deshabilitar el movimiento del giroscopio de la cámara", + "disableCameraShakeText": "Deshabilitar el temblor de la cámara", + "disableThisNotice": "(puedes deshabilitar este aviso en ajustes avanzados)", "enablePackageModsDescriptionText": "(enciende modificaciones pero apaga juegos vía red)", "enablePackageModsText": "Encender Modificaciones Locales", "enterPromoCodeText": "Ingresar Código", "forTestingText": "Notas: estos datos son solo para pruebas y se reiniciarán cuando se abra la app de nuevo.", "helpTranslateText": "Las traducciones de ${APP_NAME} son un esfuerzo\napoyado por la comunidad. Si deseas aportar o corregir una\ntraducción, utiliza el siguiente enlace. ¡Gracias de antemano!", "helpTranslateTextScale": 1.0, - "kickIdlePlayersText": "Expulsar Jugadores Inactivos", + "kickIdlePlayersText": "Expulsar a jugadores inactivos", "kidFriendlyModeText": "Modo Niños (reduce violencia, etc)", "languageText": "Idioma", "languageTextScale": 1.0, - "moddingGuideText": "Guía de Mods", + "moddingGuideText": "Guía De Modificación", + "moddingToolsText": "Herramientas de modificación", "mustRestartText": "Tienes que reiniciar el juego para que tome efecto.", - "netTestingText": "Prueba de Red", + "netTestingText": "Prueba De Red", "resetText": "Reiniciar", - "showBombTrajectoriesText": "Mostrar trayectorias", - "showInGamePingText": "Visualizar Ping en el juego", - "showPlayerNamesText": "Mostrar Nombres de los Jugadores", - "showUserModsText": "Mostrar Carpeta de Mods", + "sendInfoText": "Enviar Información", + "showBombTrajectoriesText": "Mostrar Trayectorias De Las Bombas", + "showDemosWhenIdleText": "Mostrar demostraciones cuando esté inactivo", + "showDeprecatedLoginTypesText": "Mostrar tipos de inicio de sesión obsoletos", + "showDevConsoleButtonText": "Mostrar botón de consola de desarrollador", + "showInGamePingText": "Mostrar ping en el juego", + "showPlayerNamesText": "Mostrar Nombres De Los Jugadores", + "showUserModsText": "Mostrar Carpeta De Mods", "titleText": "Avanzado", - "translationEditorButtonText": "Editor de Traducción de ${APP_NAME}", + "translationEditorButtonText": "Editor De Traducción De ${APP_NAME}", "translationFetchErrorText": "estado de traducción no disponible", "translationFetchingStatusText": "viendo estado de traducción...", - "translationInformMe": "Informarme cuando mi idioma necesite actualizaciones.", - "translationNoUpdateNeededText": "el idioma actual está actualizado; woohoo!", - "translationUpdateNeededText": "** ¡¡el idioma actual necesita actualizarse!! **", + "translationInformMe": "Informarme cuando mi idioma necesite actualizaciones", + "translationNoUpdateNeededText": "El idioma actual está actualizado; ¡wuju!", + "translationUpdateNeededText": "** ¡¡El idioma actual necesita actualizarse!! **", "vrTestingText": "Prueba VR" }, "shareText": "Compartir", @@ -1362,16 +1391,19 @@ "signInWithGameCenterText": "Para usar una cuenta de Game Center,\ningresa con la aplicación Game Center.", "singleGamePlaylistNameText": "Solo ${GAME}", "singlePlayerCountText": "1 jugador", + "sizeLargeText": "Grande", + "sizeMediumText": "Medium", + "sizeSmallText": "pequeñ@", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { - "CharSelect": "Selección de Personajes", + "CharSelect": "Selección De Personajes", "Chosen One": "El Elegido", - "Epic": "Juegos Épicos", + "Epic": "Juegos en Modo Épico", "Epic Race": "Carrera Épica", "FlagCatcher": "Captura la Bandera", - "Flying": "Sueños Dulces", + "Flying": "Pensamientos Felices", "Football": "Fútbol", - "ForwardMarch": "Carnicería", + "ForwardMarch": "Asalto", "GrandRomp": "Conquista", "Hockey": "Hockey", "Keep Away": "Aléjate", @@ -1380,16 +1412,16 @@ "Onslaught": "Matanza", "Race": "Carrera", "Scary": "Rey de la Colina", - "Scores": "Pantalla de Puntuaciones", + "Scores": "Pantalla De Puntuaciones", "Survival": "Eliminación", "ToTheDeath": "Combate Mortal", - "Victory": "Pantalla de Puntuaciones Finales" + "Victory": "Pantalla De Puntuaciones Finales" }, "spaceKeyText": "espacio", - "statsText": "Estad.", + "statsText": "Estadísticas", "storagePermissionAccessText": "Esto requiere acceso de almacenamiento", "store": { - "alreadyOwnText": "¡Ya compraste ${NAME}!", + "alreadyOwnText": "¡Ya tienes ${NAME}!", "bombSquadProDescriptionText": "• Doble de tickets recibidos en el juego.\n• Remueve los anuncios del juego.\n• Incluye ${COUNT} tickets de bonus.\n• +${PERCENT}% de bonus en la puntuación de la liga.\n• Desbloquea los niveles cooperativos ${INF_ONSLAUGHT}\n y ${INF_RUNAROUND}. ", "bombSquadProFeaturesText": "Características:", "bombSquadProNameText": "${APP_NAME} Pro", @@ -1398,10 +1430,10 @@ "charactersText": "Personajes", "comingSoonText": "Próximamente...", "extrasText": "Extras", - "freeBombSquadProText": "BombSquad ahora es gratis, pero ya que compraste el juego recibirás\nla mejora de BombSquad Pro y ${COUNT} tickets como agradecimiento.\n¡Disfruta de las nuevas funciones, y gracias por tu soporte!\n-Eric", + "freeBombSquadProText": "BombSquad es gratis, pero ya que compraste el juego recibirás\nla mejora de BombSquad Pro y ${COUNT} boletos como agradecimiento.\n¡Disfruta de las nuevas funciones y gracias por tu apoyo!\n-Eric", "gameUpgradesText": "Mejoras", "getCoinsText": "Obtén monedas", - "holidaySpecialText": "¡Especial de Temporada!", + "holidaySpecialText": "¡Especial De Temporada!", "howToSwitchCharactersText": "(ve a \"${SETTINGS} -> ${PLAYER_PROFILES}\" para asignar y personalizar avatares)", "howToUseIconsText": "(crea perfiles globales de jugador (en la ventana de cuenta) para usarlos)", "howToUseMapsText": "(usa estos mapas en tus listas de juego por equipos y todos contra todos)", @@ -1415,57 +1447,59 @@ "purchaseConfirmText": "¿Comprar ${ITEM}?", "purchaseNotValidError": "Compra inválida.\nContacte ${EMAIL} si esto es un error.", "purchaseText": "Comprar", - "saleBundleText": "¡Paquete en Oferta!", + "saleBundleText": "¡Paquete En Oferta!", "saleExclaimText": "¡Oferta!", "salePercentText": "(${PERCENT}% menos)", "saleText": "OFERTA", "searchText": "Buscar", - "teamsFreeForAllGamesText": "En Equipos / Todos contra Todos", + "teamsFreeForAllGamesText": "Juegos de Equipos / Todos-para-Todos", "totalWorthText": "*** ¡${TOTAL_WORTH} de valor! ***", - "upgradeQuestionText": "¿Comprar BombSquad Pro?", - "winterSpecialText": "Especial de Invierno", + "upgradeQuestionText": "¿Mejorar?", + "winterSpecialText": "Especial De Invierno", "youOwnThisText": "- ya posees esto -" }, - "storeDescriptionText": "¡Juego en grupo de 8 jugadores!\n\n¡Revienta a tus amigos (o a la computadora) en un torneo de minijuegos explosivos como Captura la Bandera, Hockey-Bomba, y Combate Mortal Épico en cámara lenta!\n\nControles sencillos y un amplio apoyo de controles hacen que sea fácil que 8 personas entren en la acción; ¡incluso puedes usar tus dispositivos móviles como controles a través de la aplicación gratuita 'BombSquad Remote'!\n\n¡Bombas fuera!\n\nEcha un vistazo en www.froemling.net/bombsquad para más información.", + "storeDescriptionText": "¡Juego en grupo de 8 jugadores!\n\n¡Revienta a tus amigos (o a la computadora) en un torneo de minijuegos explosivos como Captura la Bandera, Hockey-Bomba y Combate Mortal Épico en cámara lenta!\n\nControles sencillos y un amplio apoyo de controles hacen que sea fácil que 8 personas entren en la acción; ¡incluso puedes usar tus dispositivos móviles como controles a través de la aplicación gratuita 'Control Remoto BombSquad'!\n\n¡Bombas Fuera!\n\nEcha un vistazo en www.froemling.net/bombsquad para más información.", "storeDescriptions": { "blowUpYourFriendsText": "Revienta a tus amigos.", "competeInMiniGamesText": "Compite en juegos de carreras, vuelo y mucho más.", - "customize2Text": "Modifica personajes, mini-juegos, e incluso la banda sonora.", + "customize2Text": "Personaliza personajes, mini-juegos, e incluso la banda sonora.", "customizeText": "Modifica personajes y crea tus propias listas de mini-juegos.", - "sportsMoreFunText": "Los deportes son más divertidos con minas.", - "teamUpAgainstComputerText": "Sobrevive contra la computadora." + "sportsMoreFunText": "Los deportes son más divertidos con explosivos.", + "teamUpAgainstComputerText": "Forma un equipo contra la computadora." }, "storeText": "Tienda", "submitText": "Enviar", "submittingPromoCodeText": "Enviando Código...", - "teamNamesColorText": "Nombres de equipo/colores...", + "successText": "¡Éxito!", + "supportEmailText": "Si estás teniendo algún problema con la\napp, por favor, manda un email a ${EMAIL}.", + "teamNamesColorText": "Nombres De Equipos/Colores...", "teamsText": "Equipos", "telnetAccessGrantedText": "Acceso a Telnet activado.", "telnetAccessText": "Acceso a Telnet detectado; ¿permitir?", "testBuildErrorText": "Esta versión de prueba ya no es activa; busca una versión más nueva.", - "testBuildText": "Versión de Prueba", - "testBuildValidateErrorText": "Imposible validar esta versión de prueba (¿no tienes conexión a internet?)", - "testBuildValidatedText": "Versión de Prueba Validada; ¡Disfruta!", + "testBuildText": "Compilación De Prueba", + "testBuildValidateErrorText": "Incapaz de validar esta compilación de prueba (¿no tienes conexión a internet?)", + "testBuildValidatedText": "Compilación De Prueba Validada; ¡Disfruta!", "thankYouText": "¡Gracias por tu ayuda! ¡¡Disfruta el juego!!", - "threeKillText": "¡¡¡Triple Combo!!!", - "timeBonusText": "Bono de Tiempo", + "threeKillText": "¡¡COMBO TRIPLE!!", + "timeBonusText": "Bono De Tiempo", "timeElapsedText": "Tiempo Transcurrido", - "timeExpiredText": "Se Acabó el Tiempo", + "timeExpiredText": "Tiempo Expirado", "timeSuffixDaysText": "${COUNT}d", "timeSuffixHoursText": "${COUNT}h", "timeSuffixMinutesText": "${COUNT}m", "timeSuffixSecondsText": "${COUNT}s", - "tipText": "Sugerencia", + "tipText": "Consejo", "titleText": "BombSquad", "titleVRText": "BombSquad VR", "topFriendsText": "Mejores Amigos", "tournamentCheckingStateText": "Buscando estado del campeonato; espere por favor...", "tournamentEndedText": "Este torneo ha acabado. Uno nuevo comenzará pronto.", - "tournamentEntryText": "Inscripción al Torneo", - "tournamentResultsRecentText": "Resultados Torneos Recientes", - "tournamentStandingsText": "Puestos del Torneo", + "tournamentEntryText": "Entrada Al Torneo", + "tournamentResultsRecentText": "Resultados De Torneos Recientes", + "tournamentStandingsText": "Puestos Del Torneo", "tournamentText": "Torneo", - "tournamentTimeExpiredText": "Tiempo del Torneo Expirado", + "tournamentTimeExpiredText": "Tiempo Del Torneo Expirado", "tournamentsDisabledWorkspaceText": "Los torneos están deshabilitados cuando los espacios de trabajo están activos.\nPara volver a habilitar los torneos, deshabilite su espacio de trabajo y reinicie el juego.", "tournamentsText": "Torneos", "translations": { @@ -1475,17 +1509,17 @@ "Bernard": "Bernard", "Bones": "Huesos", "Butch": "Butch", - "Easter Bunny": "Conejo de Pascua", - "Flopsy": "Flopsy", + "Easter Bunny": "Conejo De Pascua", + "Flopsy": "Pelusa", "Frosty": "Frosty", "Gretel": "Gretel", "Grumbledorf": "Grumbledorf", "Jack Morgan": "Jack Morgan", "Kronk": "Kronk", "Lee": "Lee", - "Lucky": "Lucky", + "Lucky": "Suertudo", "Mel": "Mel", - "Middle-Man": "Intermediario", + "Middle-Man": "Hombre Intermedio", "Minimus": "Minimus", "Pascal": "Pascal", "Pixel": "Pixel", @@ -1493,7 +1527,7 @@ "Santa Claus": "Papá Noel", "Snake Shadow": "Serpiente Sombría", "Spaz": "Spaz", - "Taobao Mascot": "Mascota Taobao", + "Taobao Mascot": "Mascota De Taobao", "Todd": "Todd", "Todd McBurton": "Todd McBurton", "Xara": "Xara", @@ -1515,49 +1549,49 @@ "Uber\nRunaround": "Evasiva\nUltra" }, "coopLevelNames": { - "${GAME} Training": "${GAME} Entrenamiento", + "${GAME} Training": "Entrenamiento De ${GAME}", "Infinite ${GAME}": "${GAME} Infinito/a", "Infinite Onslaught": "Matanza Infinita", "Infinite Runaround": "Evasiva Infinita", "Onslaught": "Matanza Infinita", - "Onslaught Training": "Entrenamiento de Matanza", - "Pro ${GAME}": "Pro ${GAME}", - "Pro Football": "Fútbol Pro", + "Onslaught Training": "Entrenamiento De Matanza", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Rugby Pro", "Pro Onslaught": "Matanza Pro", "Pro Runaround": "Evasiva Pro", "Rookie ${GAME}": "Novato ${GAME}", "Rookie Football": "Fútbol Novato", "Rookie Onslaught": "Matanza Novato", "Runaround": "Evasiva Infinita", - "The Last Stand": "Batalla Final", - "Uber ${GAME}": "Uber ${GAME}", + "The Last Stand": "La Batalla Final", + "Uber ${GAME}": "${GAME} Ultra", "Uber Football": "Fútbol Ultra", "Uber Onslaught": "Matanza Ultra", "Uber Runaround": "Evasiva Ultra" }, "gameDescriptions": { - "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sé el elegido durante el tiempo designado para ganar.\nElimina al Elegido para convertirte en El Elegido.", - "Bomb as many targets as you can.": "Lanza bombas a tantos blancos como puedas.", + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sé el elegido durante el tiempo designado para ganar.\nMata al elegido para convertirte en el.", + "Bomb as many targets as you can.": "Bombardea tantos blancos como puedas.", "Carry the flag for ${ARG1} seconds.": "Carga la bandera por ${ARG1} segundos.", "Carry the flag for a set length of time.": "Carga la bandera por un determinado tiempo.", "Crush ${ARG1} of your enemies.": "Elimina ${ARG1} de tus enemigos.", "Defeat all enemies.": "Elimina todos los enemigos.", "Dodge the falling bombs.": "Esquiva las bombas.", - "Final glorious epic slow motion battle to the death.": "Gloriosa batalla final en cámara lenta épica.", + "Final glorious epic slow motion battle to the death.": "Gloriosa batalla final épica en cámara lenta hasta la muerte.", "Gather eggs!": "¡Recolecta huevos!", "Get the flag to the enemy end zone.": "Lleva la bandera enemiga a tu zona.", "How fast can you defeat the ninjas?": "¿Cuán rápido puedes derrotar a los ninjas?", - "Kill a set number of enemies to win.": "Elimina a un número determinado \nde enemigos para ganar.", - "Last one standing wins.": "El último de pie gana.", + "Kill a set number of enemies to win.": "Mata a un número determinado de enemigos para ganar.", + "Last one standing wins.": "El último en pie gana.", "Last remaining alive wins.": "El último en quedar vivo gana.", "Last team standing wins.": "El último equipo en pie gana.", "Prevent enemies from reaching the exit.": "Evita que los enemigos lleguen a la salida.", "Reach the enemy flag to score.": "Toca la bandera enemiga para anotar.", "Return the enemy flag to score.": "Devuelve la bandera enemiga para anotar.", - "Run ${ARG1} laps.": "Da ${ARG1} vueltas.", - "Run ${ARG1} laps. Your entire team has to finish.": "Da ${ARG1} vueltas. Todo tu equipo debe cruzar la meta.", - "Run 1 lap.": "Da 1 vuelta.", - "Run 1 lap. Your entire team has to finish.": "Da 1 vuelta. Todo tu equipo debe cruzar la meta.", + "Run ${ARG1} laps.": "Corre ${ARG1} vueltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corre ${ARG1} vueltas. Todo tu equipo debe cruzar la meta.", + "Run 1 lap.": "Corre 1 vuelta.", + "Run 1 lap. Your entire team has to finish.": "Corre 1 vuelta. Todo tu equipo debe cruzar la meta.", "Run real fast!": "¡Corre muy rápido!", "Score ${ARG1} goals.": "Anota ${ARG1} goles.", "Score ${ARG1} touchdowns.": "Anota ${ARG1} touchdowns.", @@ -1568,19 +1602,19 @@ "Secure all flags on the map to win.": "Asegura todas las banderas en el mapa para ganar.", "Secure the flag for ${ARG1} seconds.": "Asegura la bandera por ${ARG1} segundos.", "Secure the flag for a set length of time.": "Asegura la bandera por un tiempo determinado.", - "Steal the enemy flag ${ARG1} times.": "Roba la bandera del enemigo ${ARG1} veces.", - "Steal the enemy flag.": "Roba la bandera del enemigo.", + "Steal the enemy flag ${ARG1} times.": "Roba la bandera enemiga ${ARG1} veces.", + "Steal the enemy flag.": "Roba la bandera enemiga.", "There can be only one.": "Solo puede haber uno.", - "Touch the enemy flag ${ARG1} times.": "Toca la bandera del enemigo ${ARG1} veces.", - "Touch the enemy flag.": "Toca la bandera del enemigo.", + "Touch the enemy flag ${ARG1} times.": "Toca la bandera enemiga ${ARG1} veces.", + "Touch the enemy flag.": "Toca la bandera enemiga.", "carry the flag for ${ARG1} seconds": "carga la bandera por ${ARG1} segundos.", - "kill ${ARG1} enemies": "elimina a ${ARG1} enemigos", + "kill ${ARG1} enemies": "mata a ${ARG1} enemigos", "last one standing wins": "el último en pie gana", - "last team standing wins": "el último equipo en caer gana", + "last team standing wins": "el último equipo en pie gana", "return ${ARG1} flags": "devuelve ${ARG1} banderas", "return 1 flag": "devuelve 1 bandera", "run ${ARG1} laps": "da ${ARG1} vueltas", - "run 1 lap": "da 1 vuelta", + "run 1 lap": "corre 1 vuelta", "score ${ARG1} goals": "anota ${ARG1} goles", "score ${ARG1} touchdowns": "anota ${ARG1} touchdowns", "score a goal": "anota un gol", @@ -1596,19 +1630,19 @@ "Chosen One": "El Elegido", "Conquest": "Conquista", "Death Match": "Combate Mortal", - "Easter Egg Hunt": "Búsqueda de Huevos de Pascua", + "Easter Egg Hunt": "Búsqueda De Huevos De Pascua", "Elimination": "Eliminación", "Football": "Fútbol", "Hockey": "Hockey", "Keep Away": "Aléjate", "King of the Hill": "Rey de la Colina", - "Meteor Shower": "Lluvia de Meteoritos", + "Meteor Shower": "Lluvia De Meteoritos", "Ninja Fight": "Pelea Ninja", "Onslaught": "Matanza", "Race": "Carrera", "Runaround": "Evasiva", - "Target Practice": "Blanco de Práctica", - "The Last Stand": "Batalla Final" + "Target Practice": "Blanco De Práctica", + "The Last Stand": "La Batalla Final" }, "inputDeviceNames": { "Keyboard": "Teclado", @@ -1625,7 +1659,7 @@ "Dutch": "Holandés", "English": "Inglés", "Esperanto": "Esperanto", - "Filipino": "filipino", + "Filipino": "Filipino", "Finnish": "Finlandés", "French": "Francés", "German": "Alemán", @@ -1651,7 +1685,7 @@ "Thai": "Tailandés", "Turkish": "Turco", "Ukrainian": "Ucraniano", - "Venetian": "Veneciana", + "Venetian": "Veneciano", "Vietnamese": "Vietnamita" }, "leagueNames": { @@ -1664,16 +1698,16 @@ "Big G": "Gran G", "Bridgit": "Puentecito", "Courtyard": "Patio Real", - "Crag Castle": "Castillo del Risco", - "Doom Shroom": "Hongo de la Muerte", - "Football Stadium": "Estadio de Fútbol", + "Crag Castle": "Castillo Del Risco", + "Doom Shroom": "Hongo De La Muerte", + "Football Stadium": "Estadio De Fútbol", "Happy Thoughts": "Pensamientos Felices", - "Hockey Stadium": "Estadio de Hockey", + "Hockey Stadium": "Estadio De Hockey", "Lake Frigid": "Lago Frígido", - "Monkey Face": "Cara de Mono", - "Rampage": "Rampa", + "Monkey Face": "Cara De Mono", + "Rampage": "Medio Tubo", "Roundabout": "Rotonda", - "Step Right Up": "Paso al Frente", + "Step Right Up": "Paso Al Frente", "The Pad": "La Plataforma", "Tip Top": "Punta Superior", "Tower D": "Torre D", @@ -1689,78 +1723,78 @@ "scoreNames": { "Flags": "Banderas", "Goals": "Goles", - "Score": "Puntuación", + "Score": "Puntaje", "Survived": "Sobrevivió", "Time": "Tiempo", "Time Held": "Tiempo Mantenido" }, "serverResponses": { - "A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta", + "A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta.", "A reward has already been given for that address.": "Ya se le ha dado una recompensa a esa dirección.", - "Account linking successful!": "¡Enlace de Cuenta exitoso!", - "Account unlinking successful!": "¡Desenlace de cuenta realizado!", - "Accounts are already linked.": "Las cuentas ya se encuentran enlazadas.", + "Account linking successful!": "¡Vinculación de cuenta exitosa!", + "Account unlinking successful!": "¡Desvinculación de cuenta exitosa!", + "Accounts are already linked.": "Las cuentas ya están vinculadas.", "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No se pudo verificar la vista del anuncio. \nPor favor asegúrese de estar ejecutando una versión oficial y actualizada del juego.", - "An error has occurred; (${ERROR})": "Se ha producido un error; (${ERROR})", - "An error has occurred; please contact support. (${ERROR})": "Se ha producido un error; por favor contácte con soporte. (${ERROR})", - "An error has occurred; please contact support@froemling.net.": "Ha ocurrido un error; contacta a support@froemling.net.", - "An error has occurred; please try again later.": "Un error ha ocurrido; por favor intenta más tarde.", - "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres enlazar estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!", + "An error has occurred; (${ERROR})": "Un error ha ocurrido; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Un error ha ocurrido; por favor contacta al soporte. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Un error ha ocurrido; por favor contacta a support@froemling.net.", + "An error has occurred; please try again later.": "Un error ha ocurrido; por favor intentalo más tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres vincular estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!", "BombSquad Pro unlocked!": "¡BombSquad Pro desbloqueado!", - "Can't link 2 accounts of this type.": "No puedes enlazar dos cuentas de este tipo.", - "Can't link 2 diamond league accounts.": "No pueden enlazar dos cuentas de liga diamante.", - "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo enlazar; sobrepasaría el máximo de ${COUNT} cuentas enlazadas.", + "Can't link 2 accounts of this type.": "No se pueden vincular 2 cuentas de este tipo.", + "Can't link 2 diamond league accounts.": "No se pueden vincular 2 cuentas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo vincular; sobrepasaría el máximo de cuentas vinculadas de ${COUNT}.", "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trampa detectada; puntajes y premios suspendidos por ${COUNT} días.", "Could not establish a secure connection.": "No se pudo establecer una conexión segura.", "Daily maximum reached.": "Máximo diario conseguido.", - "Entering tournament...": "Entrando a torneo...", + "Entering tournament...": "Entrando al torneo...", "Invalid code.": "Código inválido.", "Invalid payment; purchase canceled.": "Pago inválido; compra cancelada.", "Invalid promo code.": "Código promocional inválido.", "Invalid purchase.": "Compra inválida.", "Invalid tournament entry; score will be ignored.": "Entrada de torneo inválida; el puntaje será ignorado.", - "Item unlocked!": "¡Objeto desbloqueado!", - "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACÍON DENEGADO. ${ACCOUNT} contiene\ndatos significativos que TODOS SERÍAN PERDIDOS.\nPuede vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)", - "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Enlazar ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?", - "Max number of playlists reached.": "Número máximo de listas de reproducción alcanzado.", + "Item unlocked!": "¡Artículo desbloqueado!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACIÓN DENEGADA. ${ACCOUNT} contiene\ndatos significativos que podrían PERDERSE EN SU TOTALIDAD.\nPuedes vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Vincular ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?", + "Max number of playlists reached.": "Número máximo de playlits alcanzado.", "Max number of profiles reached.": "Número máximo de perfiles alcanzado.", "Maximum friend code rewards reached.": "Máximo de premios por códigos de amigos alcanzado.", "Message is too long.": "El Mensaje es muy largo.", - "No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor intenta después.", + "No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor inténtalo después.", "Profile \"${NAME}\" upgraded successfully.": "El perfil \"${NAME}\" se ha mejorado satisfactoriamente.", "Profile could not be upgraded.": "El perfil no pudo ser mejorado.", "Purchase successful!": "¡Compra exitosa!", - "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} tickets recibidos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} tickets.", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} boletos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} boletos.", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funcionalidad del servidor ya no es compatible en esta versión del juego;\nActualiza a una versión más reciente.", - "Sorry, there are no uses remaining on this code.": "Perdón, pero no quedan usos disponibles de este código.", - "Sorry, this code has already been used.": "Perdón, este código ya ha sido usado.", - "Sorry, this code has expired.": "Perdón, este código ha expirado.", - "Sorry, this code only works for new accounts.": "Este código solo sirve para cuentas nuevas.", + "Sorry, there are no uses remaining on this code.": "Disculpe, pero no quedan usos disponibles de este código.", + "Sorry, this code has already been used.": "Disculpe, este código ya ha sido usado.", + "Sorry, this code has expired.": "Disculpe, este código ha expirado.", + "Sorry, this code only works for new accounts.": "Disculpe, este código solo funciona para cuentas nuevas.", "Still searching for nearby servers; please try again soon.": "Todavía buscando por servidores cercanos; intente de nuevo más tarde.", - "Temporarily unavailable; please try again later.": "Temporalmente desactivado; por favor, inténtalo luego.", + "Temporarily unavailable; please try again later.": "Temporalmente indisponible; por favor inténtalo más tarde.", "The tournament ended before you finished.": "El torneo terminó antes de que terminaras.", - "This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desenlazada por ${NUM} días.", + "This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desvinculada por ${NUM} días.", "This code cannot be used on the account that created it.": "Este código no puede ser usado en la misma cuenta que ha sido creado.", - "This is currently unavailable; please try again later.": "Esto Está No Disponible actualmente; por favor inténtelo más tarde", - "This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más nueva.", - "Tournaments disabled due to rooted device.": "Los torneos han sido desactivados debido a que tu dispositivo es root", - "Tournaments require ${VERSION} or newer": "El torneo requiere la versión ${VERSION} o versiones recientes", - "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desenlazar ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán\n(excepto los logros en algunos casos).", - "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: se han emitido reclamaciones de piratería contra tu cuenta.\nLas cuentas que se encuentren pirateadas serán prohibidas. Por favor, juega limpio.", - "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres enlazar tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!", + "This is currently unavailable; please try again later.": "Esto esta indisponible actualmente; por favor inténtelo más tarde", + "This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más reciente.", + "Tournaments disabled due to rooted device.": "Los torneos han sido deshabilitados debido a que tú dispositivo esta rooteado.", + "Tournaments require ${VERSION} or newer": "Los torneos requieren la versión ${VERSION} o una más nueva", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desvincular ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán.\n(excepto los logros en algunos casos)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: se han emitido reclamaciones de hacks contra tu cuenta.\nLas cuentas que se encuentren pirateadas serán prohibidas. Por favor juega limpio.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres vincular tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!", "You already own this!": "¡Ya posees esto!", "You can join in ${COUNT} seconds.": "Puedes unirte en ${COUNT} segundos.", - "You don't have enough tickets for this!": "¡No tienes suficientes tickets para esto!", + "You don't have enough tickets for this!": "¡No tienes suficientes boletos para esto!", "You don't own that.": "No tienes eso.", - "You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} tickets!", - "You got a ${ITEM}!": "¡Recibiste un ${ITEM}!", - "You have been promoted to a new league; congratulations!": "¡Has sido ascendido a una nueva liga! ¡Felicidades!", + "You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} boletos!", + "You got a ${ITEM}!": "¡Conseguiste un ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Has sido ascendido a una nueva liga; ¡felicitaciones!", "You must update to a newer version of the app to do this.": "Debes actualizar la aplicación a una versión más reciente para hacer esto.", "You must update to the newest version of the game to do this.": "Necesitas actualizar a la versión más reciente del juego para hacer esto.", "You must wait a few seconds before entering a new code.": "Debes esperar unos segundos antes de ingresar un código nuevo.", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Quedaste en la posición #${RANK} en el campeonato. ¡Gracias por jugar!", "Your account was rejected. Are you signed in?": "Tu cuenta fue rechazada. ¿Estas registrado?", - "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo.", "Your friend code was used by ${ACCOUNT}": "Tu código de amigo fue usado por ${ACCOUNT}" }, "settingNames": { @@ -1775,39 +1809,39 @@ "8 Seconds": "8 Segundos", "Allow Negative Scores": "Permitir Puntajes Negativos", "Balance Total Lives": "Repartir Vidas Totales", - "Bomb Spawning": "Aparición de Bombas", - "Chosen One Gets Gloves": "El Elegido Tiene Guantes de Boxeo", - "Chosen One Gets Shield": "El Elegido Tiene Electro-Escudo", + "Bomb Spawning": "Aparecer Bombas", + "Chosen One Gets Gloves": "El Elegido Consigue Guantes De Boxeo", + "Chosen One Gets Shield": "El Elegido Consigue Electro-Escudo", "Chosen One Time": "Tiempo Del Elegido", - "Enable Impact Bombs": "Permitir Impacto de Bombas", - "Enable Triple Bombs": "Permitir Bombas Triples", + "Enable Impact Bombs": "Habilitar Insta-Bombas", + "Enable Triple Bombs": "Habilitar Bombas Triples", "Entire Team Must Finish": "Todo el Equipo Debe Terminar", "Epic Mode": "Modo Épico", - "Flag Idle Return Time": "Tiempo de Regreso de Bandera Inactiva", - "Flag Touch Return Time": "Tiempo de Bandera Sin Tocar", + "Flag Idle Return Time": "Tiempo De Retorno de Bandera Inactiva", + "Flag Touch Return Time": "Retorno de Bandera con Toque", "Hold Time": "Retención", - "Kills to Win Per Player": "Víctimas por Jugador", + "Kills to Win Per Player": "Asesinatos para Ganar Por Jugador", "Laps": "Vueltas", - "Lives Per Player": "Vidas por Jugador", + "Lives Per Player": "Vidas Por Jugador", "Long": "Largo", "Longer": "Más Largo", - "Mine Spawning": "Regenerar Minas", + "Mine Spawning": "Aparecer Minas", "No Mines": "Sin Minas", "None": "Ninguno", "Normal": "Normal", "Pro Mode": "Modo Pro", - "Respawn Times": "Tiempo de Reaparición", + "Respawn Times": "Tiempo De Reaparición", "Score to Win": "Puntos para Ganar", "Short": "Corto", "Shorter": "Más Corto", - "Solo Mode": "Modo de Un Jugador", - "Target Count": "Número de Objetivos", - "Time Limit": "Límite de Tiempo" + "Solo Mode": "Modo Solo", + "Target Count": "Número De Objetivos", + "Time Limit": "Límite De Tiempo" }, "statements": { - "${TEAM} is disqualified because ${PLAYER} left": "El equipo ${TEAM} ha sido descalificado porque ${PLAYER} se ha ido.", + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} ha sido descalificado porque ${PLAYER} se ha ido", "Killing ${NAME} for skipping part of the track!": "¡Matando a ${NAME} por saltarse un pedazo de la pista!", - "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / El spameo de botones te noqueará." + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / spam de botones te noqueará." }, "teamNames": { "Bad Guys": "Chicos Malos", @@ -1816,55 +1850,55 @@ "Red": "Rojo" }, "tips": { - "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un 'corre-salta-gira-golpea' puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.", + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un corre-salta-gira-golpea perfecto puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.", "Always remember to floss.": "Siempre acuérdate de cepillar tus dientes.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea perfiles para ti y tus amigos con nombres\ny colores personalizados en vez de usar aleatorios.", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Las cajas de maldición te convierten en una bomba de tiempo.\nLa única cura es agarrar rápidamente un botiquín.", - "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de su apariencia, las habilidades de todos los personajes\nson idénticas, así que escoge el que más se parezca a ti.", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No te pongas demasiado engreído(a) con ese escudo de energía; todavía puedes caerte de un acantilado.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de sus apariencias, las habilidades de todos los personajes\nson idénticas, así que escoge el que más se parezca a ti.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No eres invencible con ese electro-escudo; todavía puedes caerte de un acantilado.", "Don't run all the time. Really. You will fall off cliffs.": "No corras todo el tiempo. En serio. Te vas a caer.", "Don't spin for too long; you'll become dizzy and fall.": "No gires por un largo tiempo; puedes marearte y caer.", - "Hold any button to run. (Trigger buttons work well if you have them)": "Sostén cualquier botón para correr. (Los botones de gatillo son para eso)", - "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén pulsado cualquier botón para correr. Llegarás a lugares rápido\npero no girarás muy bien, así que ten cuidado con los acantilados.", - "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.", - "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te levanta, golpéalos y ellos te soltarán.\nTambién funciona en la vida real.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Mantén cualquier botón para correr. (Los botones de gatillo son para eso)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén pulsado cualquier botón para correr. Llegarás a lugares más rápido\npero no girarás muy bien, así que ten cuidado con los acantilados.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de Hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te recoge, dale un golpe y te soltará.\nTambién funciona en la vida real.", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si no tienes suficientes controles, instala la aplicación '${REMOTE_APP_NAME}'\nen tus dispositivos móviles para utilizarlos como controles.", "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Te faltan controles? Instala la aplicación 'BombSquad Remote'\nen tu dispositivo iOS o Android para usarlo como control.", - "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Si te adhieres a una bomba pegajosa, salta y da muchas vueltas. Es posible que sacudas\nla bomba pegada, o sin nada más, tus últimos momentos serán entretenidos.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Si te adhieres a una bomba pegajosa, salta y da muchas vueltas. Es posible que sacudas\nla bomba pegada o sin nada más tus últimos momentos serán entretenidos.", "If you kill an enemy in one hit you get double points for it.": "Si matas a un enemigo de un solo golpe obtendrás puntos dobles.", "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si tomaste una maldición, tu única esperanza es\nencontrar un botiquín en tus últimos segundos.", "If you stay in one place, you're toast. Run and dodge to survive..": "Si te quedas quieto, estás frito. Corre y esquiva para sobrevivir...", "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si tienes muchos jugadores yendo y viniendo, activa 'expulsar jugadores inactivos'\nen ajustes en caso de que alguien se olvide de abandonar el juego.", - "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o \"Resolución\" en configuración->Gráficos", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o \"Resolución\" en Configuración->Gráficos", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si la imagen va lenta, intenta reducir la resolución\no los visuales en los ajustes gráficos del juego.", "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Captura la Bandera, la tuya debe estar en tu base para que anotes.\nSi el otro equipo está a punto de anotar, el arrebatar su bandera evitará que lo hagan.", "In hockey, you'll maintain more speed if you turn gradually.": "En hockey, mantendrás tu impulso si giras gradualmente.", - "It's easier to win with a friend or two helping.": "Es más fácil ganar con un amigo.", - "Jump just as you're throwing to get bombs up to the highest levels.": "Salta antes de lanzar una bomba para que alcance lugares altos.", - "Land-mines are a good way to stop speedy enemies.": "Las minas terrestres son una buena manera para detener a los enemigos veloces.", + "It's easier to win with a friend or two helping.": "Es más fácil ganar con un amigo o dos ayudando.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Salta antes de tirar una bomba para que alcance lugares altos.", + "Land-mines are a good way to stop speedy enemies.": "Las minas-terrestres son una buena manera para detener enemigos veloces.", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muchas cosas se pueden recoger y lanzar, incluyendo a otros jugadores.\nArroja a tus enemigos por los precipicios. Te sentirás mejor.", "No, you can't get up on the ledge. You have to throw bombs.": "No, no puedes subir a la cornisa. Tienes que lanzar bombas.", - "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes poner o quitar controles en cualquier momento.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Los jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes poner o quitar controles en cualquier momento.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Los jugadores pueden unirse y abandonar en el transcurso del juego,\ny también puedes conectar y desconectar controles cuando quieras.", "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Los poderes sólo tienen tiempo límite en juego cooperativo.\nEn los equipos y Pelea libre son tuyos hasta que seas eliminado.", - "Practice using your momentum to throw bombs more accurately.": "Practica con tu impulso para lanzar bombas con más precisión.", - "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Tus golpes harán más daño dependiendo de que tan rápido tus puños se muevan,\nasí que intenta correr, saltar, y girar como un loco.", - "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba de 'latigazo' para lanzarla lejos.", + "Practice using your momentum to throw bombs more accurately.": "Practica usando tu impulso para tirar bombas con más precisión.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Los golpes hacen más daño cuanto más rápido se mueven tus puños,\nasí que intenta correr, saltar, y girar como un loco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba para 'latiguearla' y lanzarla lejos.", "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimina un gran cantidad de enemigos\nal detonar una bomba cerca de una caja TNT.", "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La cabeza es la zona más vulnerable, una bomba pegajosa\na la cabeza usualmente significa game-over.", "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nivel no tiene fin, pero un alto puntaje aquí\nte hará ganar el respeto eterno por todo el mundo.", "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "La fuerza de tiro se basa en la dirección que estás sosteniendo.\nPara arrojar algo justo delante de ti, no sostengas ninguna dirección.", "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "¿Cansado de la pista de audio? ¡Reemplázala con tu música!\nVe a Ajustes->Audio->Banda Sonora", - "Try 'Cooking off' bombs for a second or two before throwing them.": "'Cocina tus Bombas' por un segundo o dos antes de tirarlas.", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Intenta 'Cocinar' bombas por un segundo o dos antes de tirarlas.", "Try tricking enemies into killing eachother or running off cliffs.": "Engaña a tus enemigos para que se eliminen entre sí o para que corran a los acantilados.", - "Use the pick-up button to grab the flag < ${PICKUP} >": "Usa el botón de 'levantar' para llevar la bandera < ${PICKUP} >", - "Whip back and forth to get more distance on your throws..": "Bate de un lado a otro para tirar las bombas más lejos..", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Usa el botón de 'recoger' para agarrar la bandera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Azota de un lado a otro para conseguir más distancia en tus tiros..", "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Puedes 'dirigir' tus golpes girando a la izquierda o derecha. Esto\nes útil para tirar a los enemigos al vacío o para anotar en el hockey.", - "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Puedes juzgar si una bomba va a explotar según el color de\nlas chispas de la mecha: amarillo...naranja...rojo...¡BUM!", - "You can throw bombs higher if you jump just before throwing.": "Puedes lanzar bombas más alto si saltas justo antes de tirarlas.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Puedes juzgar si una bomba va a explotar basado en el \ncolor de las chispas de su mecha: amarillo...naranja...rojo...¡BUM!", + "You can throw bombs higher if you jump just before throwing.": "Puedes tirar bombas más alto si saltas justo antes de tirarlas.", "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "No necesitas editar tu perfil para cambiar de personaje; sólo presiona el botón\nsuperior (levantar) cuando te unas a un partido para cambiar el predeterminado.", - "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Te haces daño si golpeas tu cabeza contra cosas, así\nque trata de no golpear tu cabeza contra cosas.", - "Your punches do much more damage if you are running or spinning.": "Tus golpes harán mucho más impacto si estás corriendo o girando." + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Te haces daño si golpeas tu cabeza contra cosas, \nasí que trata de no golpear tu cabeza contra cosas.", + "Your punches do much more damage if you are running or spinning.": "Tus golpes hacen mucho más daño si estás corriendo o girando." } }, "trialPeriodEndedText": "Tu periodo de prueba se terminó. ¿Deseas\ncomprar BombSquad y seguir jugando?", @@ -1875,102 +1909,107 @@ "cpuBenchmarkText": "Corriendo tutorial en velocidad ridícula (pruebas de velocidad de CPU)", "phrase01Text": "¡Hey, hola!", "phrase02Text": "¡Bienvenido a ${APP_NAME}!", - "phrase03Text": "Aquí van unos consejos para manejar a tu personaje:", + "phrase03Text": "Aquí van algunos consejos para controlar tu personaje:", "phrase04Text": "Muchas cosas en ${APP_NAME} se basan en FÍSICAS.", - "phrase05Text": "Por ejemplo, cuando pegas un puñetazo...", - "phrase06Text": "...el daño se basa en la velocidad de tus puños.", - "phrase07Text": "¿Has visto? No nos estábamos moviendo, por eso casi \nno hemos hecho daño a ${NAME}.", - "phrase08Text": "Ahora, saltemos y giremos para conseguir más velocidad.", - "phrase09Text": "Ah, eso está mejor.", + "phrase05Text": "Por ejemplo, cuando golpeas...", + "phrase06Text": "..el daño se basa en la velocidad de tus puños.", + "phrase07Text": "¿Ves? No nos estábamos moviendo, así que eso apenas lastimó a ${NAME}.", + "phrase08Text": "Ahora vamos a saltar y girar para conseguir más velocidad.", + "phrase09Text": "Ah, mucho mejor.", "phrase10Text": "Correr también ayuda.", "phrase11Text": "Mantén pulsado CUALQUIER botón para correr.", - "phrase12Text": "Para dar superpuñetazos, prueba a correr Y girar.", - "phrase13Text": "¡Ups! Lo siento por eso, ${NAME}.", - "phrase14Text": "Puedes coger y lanzar cosas como banderas... o ${NAME}s.", + "phrase12Text": "Para golpes extra-asombrosos, intenta correr Y girar.", + "phrase13Text": "Ups; lo siento por eso ${NAME}.", + "phrase14Text": "Puedes recoger y lanzar cosas como banderas.. o ${NAME}.", "phrase15Text": "Por último, hay bombas.", - "phrase16Text": "Tirar bombas bien requiere práctica.", - "phrase17Text": "¡Vaya! No ha llegado muy lejos.", + "phrase16Text": "Lanzar bombas bien requiere práctica.", + "phrase17Text": "¡Auch! No fue un buen tiro.", "phrase18Text": "Moverte ayuda a lanzarlas más lejos.", - "phrase19Text": "Saltar te permitirá lanzarlas más alto.", - "phrase20Text": "Girar también te permitirá hacer lanzamientos más lejanos.", + "phrase19Text": "Saltar ayuda a lanzarlas más alto.", + "phrase20Text": "\"Latiguea\" tus bombas para hacer lanzamientos aún más lejanos.", "phrase21Text": "Hacer que exploten donde tú quieres puede ser complicado.", - "phrase22Text": "Vaya...", - "phrase23Text": "Probemos a 'cocinarla' dos segundos antes de lanzarla...", - "phrase24Text": "¡Toma ya! Así es como se hace.", + "phrase22Text": "Rayos.", + "phrase23Text": "Intentemos \"cocinar\" la mecha por un segundo o dos.", + "phrase24Text": "¡Hurra! Así es como se hace.", "phrase25Text": "Bueno, eso es todo.", - "phrase26Text": "Ahora, ¡a por ellos, campeón!", - "phrase27Text": "Recuerda tu entrenamiento, ¡y volverás con vida!", + "phrase26Text": "¡Ahora ve por ellos, campeón!", + "phrase27Text": "Recuerda tu entrenamiento, ¡y VOLVERÁS con vida!", "phrase28Text": "...o a lo mejor...", - "phrase29Text": "¡Buena suerte!", - "randomName1Text": "Fred", - "randomName2Text": "Javi", - "randomName3Text": "Carlos", - "randomName4Text": "Pablo", - "randomName5Text": "Nerea", - "skipConfirmText": "¿Realmente quieres saltar el tutorial? Toca o presiona para confirmar.", - "skipVoteCountText": "votos para saltarnos el tutorial ${COUNT}/${TOTAL}", - "skippingText": "saltándonos el tutorial...", - "toSkipPressAnythingText": "(pulsa cualquier botón para saltarte el tutorial)" + "phrase29Text": "¡Buena Suerte!", + "randomName1Text": "Federico", + "randomName2Text": "Enrique", + "randomName3Text": "Guillermo", + "randomName4Text": "Carlos", + "randomName5Text": "Felipe", + "skipConfirmText": "¿Realmente quieres omitir el tutorial? Toca o presiona para confirmar.", + "skipVoteCountText": "${COUNT}/${TOTAL} votos para omitir", + "skippingText": "omitiendo el tutorial...", + "toSkipPressAnythingText": "(pulsa cualquier botón para omitir el tutorial)" }, - "twoKillText": "¡¡Doble Combo!!", + "twoKillText": "¡COMBO DOBLE!", + "uiScaleText": "Escala de interfaz de usuario", "unavailableText": "no disponible", "unconfiguredControllerDetectedText": "Control desconfigurado detectado:", "unlockThisInTheStoreText": "Esto debe ser desbloqueado en la tienda.", "unlockThisProfilesText": "Para crear más de ${NUM} cuentas, necesitas:", - "unlockThisText": "Para desbloquear esto, tú necesitas:", - "unsupportedHardwareText": "Lo sentimos, este dispositivo no soporta esta versión del juego.", + "unlockThisText": "Para desbloquear esto, necesitas:", + "unsupportedControllerText": "Lo sentimos, el controlador \"${NAME}\" no es compatible.", + "unsupportedHardwareText": "Disculpe, este dispositivo no soporta esta compilación del juego.", "upFirstText": "A continuación:", - "upNextText": "A continuación en juego ${COUNT}:", + "upNextText": "A continuación en el juego ${COUNT}:", "updatingAccountText": "Actualizando tu cuenta...", "upgradeText": "Mejorar", "upgradeToPlayText": "Desbloquea \"${PRO}\" en la tienda para jugar esto.", - "useDefaultText": "Usar botón por defecto", + "useDefaultText": "Usar Por Defecto", + "userSystemScriptsCreateText": "Crear scripts del sistema de usuario", + "userSystemScriptsDeleteText": "Eliminar scripts del sistema de usuario", "usesExternalControllerText": "Este juego usa un control externo como entrada.", - "usingItunesText": "Usando la aplicación de música para la banda sonora...", + "usingItunesText": "Usando Aplicación De Música para la banda sonora...", "usingItunesTurnRepeatAndShuffleOnText": "Asegúrate de que mezclar esté ENCENDIDO y repetir TODOS esté activado en iTunes.", - "v2AccountLinkingInfoText": "Para vincular las cuentas V2, utilice el botón \"Administrar cuenta\".", + "v2AccountLinkingInfoText": "Para vincular cuentas V2, usa el botón \"Administrar Cuenta\".", "validatingBetaText": "Validando Beta…", - "validatingTestBuildText": "Validando versión de prueba...", + "validatingTestBuildText": "Validando Compilación De Prueba...", + "viaText": "a través de", "victoryText": "¡Victoria!", "voteDelayText": "No puedes iniciar otra votación por ${NUMBER} segundos.", "voteInProgressText": "Ya hay una votación en progreso.", - "votedAlreadyText": "Ya has votado.", - "votesNeededText": "Se requiere ${NUMBER} votos", + "votedAlreadyText": "Ya votaste", + "votesNeededText": "${NUMBER} votos necesarios", "vsText": "vs.", "waitingForHostText": "(esperando a que ${HOST} continúe)", "waitingForLocalPlayersText": "Esperando jugadores locales...", - "waitingForPlayersText": "esperando a jugadores para unirse...", - "waitingInLineText": "Esperando en línea (la fiesta está llena)...", + "waitingForPlayersText": "esperando jugadores para unirse...", + "waitingInLineText": "Esperando en línea (la partida está llena)...", "watchAVideoText": "Ver un Vídeo", - "watchAnAdText": "Mira un Anuncio", + "watchAnAdText": "Ver un Anuncio", "watchWindow": { "deleteConfirmText": "¿Borrar \"${REPLAY}\"?", "deleteReplayButtonText": "Borrar\nRepetición", "myReplaysText": "Mis Repeticiones", "noReplaySelectedErrorText": "Ninguna Repetición Seleccionada", - "playbackSpeedText": "Velocidad de reproducción: ${SPEED}", + "playbackSpeedText": "Velocidad De Reproducción: ${SPEED}", "renameReplayButtonText": "Renombrar\nRepetición", "renameReplayText": "Renombrar \"${REPLAY}\" a:", "renameText": "Renombrar", "replayDeleteErrorText": "Error borrando la repetición.", - "replayNameText": "Nombre de la Repetición", + "replayNameText": "Nombre De Repetición", "replayRenameErrorAlreadyExistsText": "Una repetición con ese nombre ya existe.", - "replayRenameErrorInvalidName": "No se puede renombrar la repetición: Nombre inválido.", + "replayRenameErrorInvalidName": "No se puede renombrar la repetición; nombre inválido.", "replayRenameErrorText": "Error renombrando repetición.", "sharedReplaysText": "Repeticiones Compartidas", "titleText": "Ver", "watchReplayButtonText": "Ver\nRepetición" }, - "waveText": "Horda", - "wellSureText": "¡Pues claro!", - "whatIsThisText": "Qué es esto?", + "waveText": "Oleada", + "wellSureText": "¡Pues Claro!", + "whatIsThisText": "¿Qué es esto?", "wiimoteLicenseWindow": { "titleText": "Marca registrada DarwiinRemote" }, "wiimoteListenWindow": { "listeningText": "Esperando controles Wii...", "pressText": "Presiona los botones 1 y 2 simultáneamente.", - "pressText2": "En controles Wii más nuevos con Motion Plus integrado, pulsa mejor el botón 'sinc' rojo en la parte trasera.", + "pressText2": "En controles Wii más nuevos con Motion Plus integrado, pulsa mejor el botón 'sync' rojo en la parte trasera.", "pressText2Scale": 0.55, "pressTextScale": 1.0 }, @@ -1978,31 +2017,31 @@ "copyrightText": "Marca registrada DarwiinRemote", "copyrightTextScale": 0.6, "listenText": "Escuchar", - "macInstructionsText": "Asegúrate de que tu Wii esté apagado y el Bluetooth esté activado en\ntu Mac, a continuación, pulsa 'Escuchar'. El Soporte para controles\nWii puede ser un poco extraño, así que puede que tengas que\nprobar un par de veces antes de obtener una conexión.\n\nEl Bluetooth puede procesar hasta 7 dispositivos conectados,\naunque tu kilometraje puede variar.\n\nBombSquad es compatible con los Controles Wii originales,\nNunchuks, y el Control Clásico.\nEl nuevo Control Wii Plus también funciona\npero sin accesorios.", + "macInstructionsText": "Asegúrate de que tu Wii esté apagado y el Bluetooth esté activado en\ntu Mac, a continuación, pulsa 'Escuchar'. El Soporte para controles\nWii puede ser un poco extraño, así que puede que tengas que\nprobar un par de veces antes de obtener una conexión.\n\nEl Bluetooth puede procesar hasta 7 dispositivos conectados,\naunque tu kilometraje puede variar.\n\nBombSquad es compatible con los Controles Wii originales,\nNunchuks y el Control Clásico.\nEl nuevo Control Wii Plus también funciona\npero sin accesorios.", "macInstructionsTextScale": 0.7, "thanksText": "Gracias al equipo DarwiinRemote\nPor hacer esto posible.", "thanksTextScale": 0.8, "titleText": "Configuración Wii" }, "winsPlayerText": "¡${NAME} Gana!", - "winsTeamText": "¡${NAME} Gana!!", + "winsTeamText": "¡${NAME} Gana!", "winsText": "¡${NAME} Gana!", "workspaceSyncErrorText": "Error al sincronizar ${WORKSPACE}. Mira el registro para más detalles.", "workspaceSyncReuseText": "No se puede sincronizar ${WORKSPACE}. Reusando la versión sincronizada anterior.", - "worldScoresUnavailableText": "Puntuaciones globales no disponibles.", - "worldsBestScoresText": "Mejores puntuaciones Mundiales", - "worldsBestTimesText": "Mejores tiempos Mundiales", + "worldScoresUnavailableText": "Puntuaciones mundiales no disponibles.", + "worldsBestScoresText": "Mejores Puntuaciones Mundiales", + "worldsBestTimesText": "Mejores Tiempos Mundiales", "xbox360ControllersWindow": { - "getDriverText": "Obtener Driver", + "getDriverText": "Obtener Controlador", "macInstructions2Text": "Para usar controles inalámbricos, necesitarás el receptor que\nviene con el 'Control de Xbox 360 para Windows'.\nUn receptor te permite conectar hasta cuatro controles.\n\nImportante: Receptores de tercera mano no funcionarán con este controlador;\nasegúrate de que tu receptor tenga el logo de 'Microsoft', no 'XBOX 360'.\nMicrosoft ya no vende receptores por separado, por lo que necesitarás\nel que venía con el control, o si no tendrás que buscar uno por internet.\n\nSi encuentras que esto fue útil, por favor considera donar\nal desarrollador del controlador en su sitio de internet.", "macInstructions2TextScale": 0.76, "macInstructionsText": "Para usar controles de Xbox 360, necesitarás instalar\nel controlador para Mac disponible en el siguiente enlace.\nFunciona con controles con cable e inalámbricos.", "macInstructionsTextScale": 0.8, "ouyaInstructionsText": "Para usar controles con cable de Xbox 360 con BombSquad, simplemente\nconéctalos al puerto USB de tu dispositivo. Puedes usar un conector USB\npara conectar múltiples controles.\n\nPara usar controles inalámbricos, necesitarás un receptor inalámbrico,\ndisponible como parte del paquete “Xbox 360 wireless Controller for\nWindows”, o vendido por separado. Cada receptor se conecta a un puerto\nUSB y permite que conectes hasta cuatro controles inalámbricos.", "ouyaInstructionsTextScale": 0.8, - "titleText": "Controles de Xbox 360 con ${APP_NAME}:" + "titleText": "Usando Controles de Xbox 360 con ${APP_NAME}:" }, - "yesAllowText": "¡Sí, permítelo!", - "yourBestScoresText": "Tus Mejores Puntuaciones", + "yesAllowText": "¡Sí, Permitir!", + "yourBestScoresText": "Tus Mejores Puntajes", "yourBestTimesText": "Tus Mejores Tiempos" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/spanishlatinamerica.json b/dist/ba_data/data/languages/spanishlatinamerica.json new file mode 100644 index 00000000..e162342e --- /dev/null +++ b/dist/ba_data/data/languages/spanishlatinamerica.json @@ -0,0 +1,1980 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Los nombres de las cuentas no pueden tener emojis o otros caracteres especiales", + "accountsText": "Cuentas", + "achievementProgressText": "Logros: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progreso de la Campaña [Difícil]: ${PROGRESS}", + "changeOncePerSeason": "Solo puedes cambiar esto una vez por temporada.", + "changeOncePerSeasonError": "Debes esperar hasta la siguiente temporada para cambiar esto de nuevo (en ${NUM} día/s)", + "createAnAccountText": "Crear una Cuenta", + "customName": "Nombre Personalizado", + "deleteAccountText": "Eliminar Cuenta", + "googlePlayGamesAccountSwitchText": "Si quieres usar una cuenta de Google diferente,\nusa la app Google Play Juegos para cambiarla.", + "linkAccountsEnterCodeText": "Introducir Código", + "linkAccountsGenerateCodeText": "Generar Código", + "linkAccountsInfoText": "(comparta el progreso a través de diferentes plataformas)", + "linkAccountsInstructionsNewText": "Para vincular dos cuentas, genera un código en la primera \ne introduzca ese código en la segunda. Los datos de \nla segunda cuenta serán compartidos entre ambos.\n(Los datos de la primera cuenta se perderán).\n\nPuedes vincular hasta ${COUNT} cuentas.\n\nIMPORTANTE: Solo vincula cuentas tuyas; \nSi vinculas cuentas de tus amigos no serán \ncapaces de jugar en línea al mismo tiempo.", + "linkAccountsText": "Vincular Cuentas", + "linkedAccountsText": "Cuentas Vinculadas:", + "manageAccountText": "Administrar Cuenta", + "nameChangeConfirm": "¿Quieres cambiar El nombre de tu cuenta A ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso en el modo cooperativo y \ntus puntuaciones locales (a excepción de tus boletos).\nEsto no puede deshacerse. ¿Estás seguro?", + "resetProgressConfirmText": "Esto reiniciará tu progreso en el modo cooperativo, \nlogros y puntuaciones locales (pero, no tus tickets).\nLos cambios no se pueden deshacer.\n¿Estás seguro?", + "resetProgressText": "Reiniciar Progreso", + "setAccountName": "Establecer Nombre de Cuenta", + "setAccountNameDesc": "Selecciona el nombre a mostrar para tu cuenta. \nPuedes usar el nombre de tu cuenta asociada\no crear un nombre único personalizado.", + "signInInfoText": "Inicia sesión para obtener boletos, competir en línea\ny compartir tu progreso a través de tus dispositivos.", + "signInText": "Iniciar Sesión", + "signInWithAnEmailAddressText": "Iniciar sesión con correo electronico", + "signInWithDeviceInfoText": "(una cuenta automática disponible únicamente en este dispositivo)", + "signInWithDeviceText": "Iniciar sesión con cuenta del dispositivo", + "signInWithText": "Iniciar sesion con ${SERVICE}", + "signInWithV2InfoText": "(una cuenta que funciona en todas las plataformas)", + "signInWithV2Text": "Iniciar sesión con una cuenta de ${APP_NAME}", + "signOutText": "Cerrar Sesión", + "signingInText": "Iniciando sesión...", + "signingOutText": "Cerrando sesión...", + "ticketsText": "Boletos: ${COUNT}", + "titleText": "Cuenta", + "unlinkAccountsInstructionsText": "Selecciona una cuenta para desvincular", + "unlinkAccountsText": "Desvincular Cuentas", + "unlinkLegacyV1AccountsText": "Desvincular Cuentas (V1) Heredadas", + "v2LinkInstructionsText": "Usa este enlace para crear una cuenta o para iniciar sesión.", + "viaAccount": "(cuenta vía ${NAME})", + "youAreSignedInAsText": "Has iniciado sesión como:" + }, + "achievementChallengesText": "Desafios de los Logros", + "achievementText": "Logro", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mata a 3 chicos malos con TNT", + "descriptionComplete": "Mató a 3 chicos malos con TNT", + "descriptionFull": "Mata a 3 chicos malos con TNT en ${LEVEL}", + "descriptionFullComplete": "Mató a 3 chicos malos con TNT en ${LEVEL}", + "name": "La Dinamita Hace Boom" + }, + "Boxer": { + "description": "Gana sin usar bombas", + "descriptionComplete": "Ganó sin usar bombas", + "descriptionFull": "Completa ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completó ${LEVEL} sin usar bombas", + "name": "Boxeador" + }, + "Dual Wielding": { + "descriptionFull": "Conecta 2 controles (de hardware o aplicación)", + "descriptionFullComplete": "Conectó 2 controles (de hardware o aplicación)", + "name": "Doble Empuñadura" + }, + "Flawless Victory": { + "description": "Gana sin ser lastimado", + "descriptionComplete": "Ganó sin ser lastimado", + "descriptionFull": "Gana ${LEVEL} sin ser lastimado", + "descriptionFullComplete": "Ganó ${LEVEL} sin ser golpeado", + "name": "Victoria Impecable" + }, + "Free Loader": { + "descriptionFull": "Empieza un juego de Todos-Contra-Todos con 2 o más jugadores", + "descriptionFullComplete": "Empezó un juego de Todos-Contra-Todos con 2 o más jugadores", + "name": "Cargador Libre" + }, + "Gold Miner": { + "description": "Mata a 6 chicos malos con minas terrestres", + "descriptionComplete": "Mató a 6 chicos malos con minas terrestres", + "descriptionFull": "Mata a 6 chicos malos con minas terrestres en ${LEVEL}", + "descriptionFullComplete": "Mató a 6 chicos malos con minas terrestres en ${LEVEL}", + "name": "Minero de Oro" + }, + "Got the Moves": { + "description": "Gana sin usar golpes ni bombas", + "descriptionComplete": "Ganó sin usar golpes ni bombas", + "descriptionFull": "Gana ${LEVEL} sin golpes ni bombas", + "descriptionFullComplete": "Ganó ${LEVEL} sin golpes ni bombas", + "name": "Tengo los Movimientos" + }, + "In Control": { + "descriptionFull": "Conecta un control (de hardware o aplicación)", + "descriptionFullComplete": "Conectó un control. (de hardware o aplicación)", + "name": "En Control" + }, + "Last Stand God": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Dios de la guerra En ${LEVEL}" + }, + "Last Stand Master": { + "description": "Anota 250 puntos", + "descriptionComplete": "Anotó 250 puntos", + "descriptionFull": "Anota 250 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 250 puntos en ${LEVEL}", + "name": "Maestro de ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotó 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Mine Games": { + "description": "Mata a 3 chicos malos con minas terrestres", + "descriptionComplete": "Mató a 3 chicos malos con minas terrestres", + "descriptionFull": "Mata a 3 chicos malos con minas terrestres en ${LEVEL}", + "descriptionFullComplete": "Mató a 3 chicos con minas terrestres en ${LEVEL}", + "name": "Juegos de Minas" + }, + "Off You Go Then": { + "description": "Arroja a 3 chicos malos fuera del mapa", + "descriptionComplete": "Arrojó a 3 chicos malos fuera del mapa", + "descriptionFull": "Arroja a 3 chicos malos fuera del mapa en ${LEVEL}", + "descriptionFullComplete": "Arrojó a 3 chicos malos fuera del mapa en ${LEVEL}", + "name": "Te Vas Abajo Entonces" + }, + "Onslaught God": { + "description": "Anota 5000 puntos", + "descriptionComplete": "Anotó 5000 puntos", + "descriptionFull": "Anota 5000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 5000 puntos en ${LEVEL}", + "name": "Dios de La ${LEVEL}" + }, + "Onslaught Master": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotó 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Maestro de La ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Derroto todas las oleadas.", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Mago de La ${LEVEL}" + }, + "Precision Bombing": { + "description": "Gana sin potenciadores", + "descriptionComplete": "Ganó sin potenciadores", + "descriptionFull": "Gana ${LEVEL} sin potenciadores", + "descriptionFullComplete": "Ganó ${LEVEL} sin potenciadores", + "name": "Bombardeo con Precisión" + }, + "Pro Boxer": { + "description": "Gana sin usar bombas", + "descriptionComplete": "Ganó sin usar bombas", + "descriptionFull": "Completa ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completó ${LEVEL} sin usar bombas", + "name": "Boxeador Profesional" + }, + "Pro Football Shutout": { + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo en ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganó el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas de ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas de ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Completa todas las oleadas", + "descriptionComplete": "Completó todas las oleadas", + "descriptionFull": "Completa todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo en ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganó el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Runaround God": { + "description": "Anota 2000 puntos", + "descriptionComplete": "Anotó 2000 puntos", + "descriptionFull": "Anota 2000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 2000 puntos en ${LEVEL}", + "name": "Dios de La ${LEVEL}" + }, + "Runaround Master": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotó 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Maestro de La ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Mago de La ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Comparte exitosamente el juego con un amigo", + "descriptionFullComplete": "Compartió exitosamente el juego con un amigo", + "name": "Compartir es querer." + }, + "Stayin' Alive": { + "description": "Gana sin morir", + "descriptionComplete": "Ganó sin morir", + "descriptionFull": "Gana ${LEVEL} sin morir", + "descriptionFullComplete": "Ganó ${LEVEL} sin morir", + "name": "Sobreviviendo" + }, + "Super Mega Punch": { + "description": "Inflige 100% de daño con un solo golpe", + "descriptionComplete": "Infligió 100% de daño con un solo golpe", + "descriptionFull": "Inflige 100% de daño con un golpe en ${LEVEL}", + "descriptionFullComplete": "Infligió 100% de daño con un golpe en ${LEVEL}", + "name": "Súper Mega Golpe" + }, + "Super Punch": { + "description": "Inflige 50% de daño con un golpe", + "descriptionComplete": "Infligió 50% de daño con un golpe", + "descriptionFull": "Inflige 50% de daño con un golpe en ${LEVEL}", + "descriptionFullComplete": "Infligió 50% de daño con un golpe en ${LEVEL}", + "name": "Súper Golpe" + }, + "TNT Terror": { + "description": "Mata a 6 chicos malos con TNT", + "descriptionComplete": "Mató a 6 chicos malos con TNT", + "descriptionFull": "Mata a 6 chicos malos con TNT en ${LEVEL}", + "descriptionFullComplete": "Mató a 6 chicos malos con TNT en ${LEVEL}", + "name": "Pirómano" + }, + "Team Player": { + "descriptionFull": "Empieza un juego de Equipos con 4 o más jugadores", + "descriptionFullComplete": "Empezó un juego de Equipos con 4 o más jugadores", + "name": "Jugador de Equipo" + }, + "The Great Wall": { + "description": "Detén a cada uno de los chicos malos", + "descriptionComplete": "Detuvo a cada uno de los chicos malos", + "descriptionFull": "Detén a cada uno de los chicos malos en ${LEVEL}", + "descriptionFullComplete": "Detuvo a cada uno de los chicos malos en ${LEVEL}", + "name": "La Gran Muralla" + }, + "The Wall": { + "description": "Detén a cada uno de los chicos malos", + "descriptionComplete": "Detuvo a cada uno de los chicos malos", + "descriptionFull": "Detén a cada uno de los chicos malos en ${LEVEL}", + "descriptionFullComplete": "Detuvo a cada uno de los chicos malos en ${LEVEL}", + "name": "La Muralla" + }, + "Uber Football Shutout": { + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo en ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganó el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Completa todas las oleadas", + "descriptionComplete": "Completó todas las oleadas", + "descriptionFull": "Completa todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + } + }, + "achievementsRemainingText": "Logros Restantes:", + "achievementsText": "Logros", + "achievementsUnavailableForOldSeasonsText": "Disculpe, los logros específicos no están disponibles para temporadas anteriores.", + "activatedText": "${THING} activado.", + "addGameWindow": { + "getMoreGamesText": "Obtener Más Juegos...", + "titleText": "Agregar Juego" + }, + "addToFavoritesText": "Agregar a Favoritos", + "addedToFavoritesText": "'${NAME}' añadido a Favoritos.", + "allText": "Todo", + "allowText": "Permitir", + "alreadySignedInText": "Tu cuenta está registrada en otro dispositivo;\npor favor cambia de cuentas o cierra el juego en tu \notro dispositivo e inténtalo de nuevo.", + "apiVersionErrorText": "No se puede cargar el módulo ${NAME}; este apunta a la versión-api ${VERSION_USED}; necesitamos ${VERSION_REQUIRED}.", + "applyText": "Aplicar", + "areYouSureText": "¿Estás seguro/a?", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" se activa solo cuando los audífonos estan conectados)", + "headRelativeVRAudioText": "Audio RV Relativo a la Cabeza", + "musicVolumeText": "Volumen de la Música", + "soundVolumeText": "Volumen del Sonido", + "soundtrackButtonText": "Bandas Sonoras", + "soundtrackDescriptionText": "(usa tu propia música para reproducir durante los juegos)", + "titleText": "Audio" + }, + "autoText": "Auto", + "backText": "Atrás", + "banThisPlayerText": "Banear a Este Jugador", + "bestOfFinalText": "Final Mejor-de-${COUNT}", + "bestOfSeriesText": "Mejor de ${COUNT} series:", + "bestRankText": "Tu mejor rango es #${RANK}", + "bestRatingText": "Tu mejor clasificación es ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Potenciar", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} se configura en la propia aplicación.", + "buttonText": "botón", + "canWeDebugText": "¿Te gustaría que ${APP_NAME} reporte errores, fallos internos\ne información básica de uso al desarrollador de forma automática?\n\nDicha informacíon no incluirá datos personales y ayudará a\nmantener el juego funcionando sin contratiempos ni problemas.", + "cancelText": "Cancelar", + "cantConfigureDeviceText": "Lo sentimos, ${DEVICE} no es configurable.", + "challengeEndedText": "Este desafío ha terminado.", + "chatMuteText": "Silenciar Chat", + "chatMutedText": "Chat Silenciado", + "chatUnMuteText": "Desilenciar Chat", + "chests": { + "prizeOddsText": "Posibles Premios", + "reduceWaitText": "Reducir Espera", + "slotDescriptionText": "Esta ranura puede contener un cofre.\n\nGana cofres al jugar niveles del modo campaña,\nposicionándote en torneos y completando\nlogros.", + "slotText": "${NUM} Ranura de Cofre", + "slotsFullWarningText": "ADVERTENCIA: Tus espacios de cofres están llenos.\nCualquier cofre ganado en esta partida, será perdido.", + "unlocksInText": "Se desbloquea en:" + }, + "choosingPlayerText": "", + "claimText": "Reclamar", + "codesExplainText": "Los códigos son proporcionados por el desarrollador para\ndiagnosticar y corregir problemas de la cuenta.", + "completeThisLevelToProceedText": "¡Debes completar\neste nivel para avanzar!", + "completionBonusText": "Bono por Completar", + "configControllersWindow": { + "configureControllersText": "Configurar Controles", + "configureKeyboard2Text": "Configurar Teclado J2", + "configureKeyboardText": "Configurar Teclado", + "configureMobileText": "Dispositivos Móviles como Controles", + "configureTouchText": "Configurar Pantalla Táctil", + "ps3Text": "Controles de PS3", + "titleText": "Controles", + "wiimotesText": "Wiimotes", + "xbox360Text": "Controles de Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: el soporte de los controles varía según el dispositivo y la versión de Android.", + "pressAnyButtonText": "Pulsa cualquier botón en el control\n que desees configurar...", + "titleText": "Configurar Controles" + }, + "configGamepadWindow": { + "advancedText": "Avanzado", + "advancedTitleText": "Configuración Avanzada del Control", + "analogStickDeadZoneDescriptionText": "(súbelo si tu personaje 'derrapa' cuando sueltas la palanca)", + "analogStickDeadZoneText": "Zona Muerta de La Palanca Analógica", + "appliesToAllText": "(aplica a todos los controles de este tipo)", + "autoRecalibrateDescriptionText": "(habilita esta opción si tu personaje no se mueve a toda velocidad)", + "autoRecalibrateText": "Auto-Recalibrar Palanca Analógica", + "axisText": "eje", + "clearText": "vaciar", + "dpadText": "Flechas del Mando", + "extraStartButtonText": "Botón Extra de Inicio", + "ifNothingHappensTryAnalogText": "Si no pasa nada, intenta asignar la palanca analógica en cambio.", + "ifNothingHappensTryDpadText": "Si no pasa nada, intenta asignar el d-pad en cambio.", + "ignoreCompletelyDescriptionText": "(evita que este control este afectando el juego y/o menús)", + "ignoreCompletelyText": "Ignorar Completamente", + "ignoredButton1Text": "Botón 1 Ignorado", + "ignoredButton2Text": "Botón 2 Ignorado", + "ignoredButton3Text": "Botón 3 Ignorado", + "ignoredButton4Text": "Botón 4 Ignorado", + "ignoredButtonDescriptionText": "(usa esto para prevenir que los botones de 'inicio' o 'sincronización' afecten la Interfaz Visual)", + "pressAnyAnalogTriggerText": "Presiona cualquier gatillo analógico...", + "pressAnyButtonOrDpadText": "Presiona cualquier botón o dpad...", + "pressAnyButtonText": "Presiona cualquier botón...", + "pressLeftRightText": "Presiona izquierda o derecha...", + "pressUpDownText": "Presiona arriba o abajo...", + "runButton1Text": "Botón para Correr 1", + "runButton2Text": "Botón para Correr 2", + "runTrigger1Text": "Gatillo para Correr 1", + "runTrigger2Text": "Gatillo para Correr 2", + "runTriggerDescriptionText": "(los gatillos analógicos te dejan correr a velocidades distintas)", + "secondHalfText": "Utiliza esta opción para configurar\nla segunda mitad de un control 2 en 1\nque se muestre como un solo control.", + "secondaryEnableText": "Habilitar", + "secondaryText": "Control Secundario", + "startButtonActivatesDefaultDescriptionText": "(desactívalo si tu botón de inicio es más bien un botón de 'menú')", + "startButtonActivatesDefaultText": "El Botón de Inicio Activa la Función por Defecto", + "titleText": "Configurar Control", + "twoInOneSetupText": "Configuración de Controles 2 en 1", + "uiOnlyDescriptionText": "(evitar que este control se una a un juego)", + "uiOnlyText": "Limitar a Uso en Menú", + "unassignedButtonsRunText": "Todos los Botones sin Asignar Corren", + "unsetText": "", + "vrReorientButtonText": "Boton de Reorientación de RV" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteText": "Nota: la mayoría de teclados sólo pueden registrar algunas\npulsaciones a la vez, así que tener un segundo teclado puede\nfuncionar mejor que un teclado compartido por los 2 jugadores.\nTen en cuenta que todavía necesitas asignar teclas únicas a los\ndos jugadores incluso en ese caso." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Tamaño de Control de Acciones", + "actionsText": "Acciones", + "buttonsText": "botones", + "dragControlsText": "", + "joystickText": "palanca", + "movementControlScaleText": "Tamaño de Escala de Movimiento", + "movementText": "Movimiento", + "resetText": "Reiniciar", + "swipeControlsHiddenText": "Ocultar Iconos Deslizantes", + "swipeInfoText": "Controles del estilo 'Deslizante' toman un poco de practica, pero\nhacen que sea más fácil jugar sin mirar los controles.", + "swipeText": "deslizar", + "titleText": "Configurar Pantalla Táctil" + }, + "configureDeviceInSystemSettingsText": "${DEVICE} se puede configurar en la aplicación Configuración del Sistema.", + "configureItNowText": "Configurar ahora?", + "configureText": "Configurar", + "connectMobileDevicesWindow": { + "amazonText": "Tienda de Amazon (Appstore)", + "appStoreText": "App Store", + "bestResultsText": "Para mejores resultados necesitas una red inalámbrica rápida. Puedes\nreducir el retraso wifi apagando otros dispositivos inalámbricos,\njugando cerca de tu router inalámbrico y conectando el\njuego anfitrión directamente a la red a través del cable Ethernet.", + "explanationText": "Para utilizar tus dispositivos móviles como controles, \ninstala la app \"${REMOTE_APP_NAME}\" en ellos. Todos tus dispositivos \npueden conectarse a un juego de ${APP_NAME} a través de una red Wi-fi, ¡es gratis!.", + "forAndroidText": "para Android:", + "forIOSText": "para iOS:", + "getItForText": "Consigue ${REMOTE_APP_NAME} para iOS en la App Store\no para Android en la Tienda de Google Play o Appstore de Amazon", + "googlePlayText": "Google Play", + "titleText": "Utilizando Dispositivos como Controles:" + }, + "continuePurchaseText": "¿Continuar por ${PRICE}?", + "continueText": "Continuar", + "controlsText": "Controles", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Esto no aplica a las clasificaciones de todo-el-tiempo.", + "activenessInfoText": "Este multiplicador aumenta en los días que juegas\ny disminuye cuando no juegas.", + "activityText": "Actividad", + "campaignText": "Campaña", + "challengesInfoText": "Gana premios por completar los mini-juegos.\n\nLos premios y la dificultad de los niveles incrementa\ncada vez que se completa y\ndecrece cuando uno expira o no se cumple.", + "challengesText": "Desafíos", + "currentBestText": "Mejor Actualmente", + "customText": "Personalizado", + "entryFeeText": "Entrada", + "forfeitConfirmText": "¿Renunciar a este desafío?", + "forfeitNotAllowedYetText": "Todavía no puedes abandonar este desafío.", + "forfeitText": "Abandonar", + "multipliersText": "Multiplicadores", + "nextChallengeText": "Siguiente Desafío", + "nextPlayText": "Siguiente Juego", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Juega Ahora", + "pointsText": "Puntos", + "powerRankingFinishedSeasonUnrankedText": "(temporada terminada sin clasificar)", + "powerRankingNotInTopText": "(fuera del top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Clasificación del Jugador", + "prizesText": "Premios", + "proMultInfoText": "Los jugadores con la mejora de ${PRO}\nreciben una bonificación del ${PERCENT}% de puntos.", + "seeMoreText": "Más...", + "skipWaitText": "Omitir la Espera", + "timeRemainingText": "Tiempo Restante", + "toRankedText": "Para Clasificar", + "totalText": "total", + "tournamentInfoText": "Compite por puntajes altos con\notros jugadores en tu liga.\n\nLos premios los obtienen los jugadores\ncon mejor puntaje al acabarse el torneo.", + "welcome1Text": "Bienvenido a ${LEAGUE}. Puedes mejorar tu\nposición en la liga ganando estrellas, completando\nlogros y ganando trofeos en desafíos.", + "welcome2Text": "También puedes ganar boletos desde varias actividades similares.\nLos boletos pueden ser usados para desbloquear nuevos personajes,\nmapas y minijuegos, entrar a torneos y más.", + "yourPowerRankingText": "Tu Clasificación Actual:" + }, + "copyConfirmText": "Copiado en el portapapeles.", + "copyOfText": "Copia de ${NAME}", + "copyText": "Copiar", + "createEditPlayerText": "", + "createText": "Crear", + "creditsWindow": { + "additionalAudioArtIdeasText": "Audio Adicional, Arte Inicial, e Ideas por ${NAME}", + "additionalMusicFromText": "Música adicional de ${NAME}", + "allMyFamilyText": "Mis amigos y mi familia que ayudaron con las pruebas", + "codingGraphicsAudioText": "Código, Gráficos y Audio por ${NAME}", + "languageTranslationsText": "Traducciones:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Música de dominio público vía ${NAME}", + "softwareBasedOnText": "Este software está basado parcialmente en el trabajo de ${NAME}", + "songCreditText": "${TITLE} Interpretada por ${PERFORMER}\nCompuesta por ${COMPOSER}, Arreglos por ${ARRANGER}, Publicada por ${PUBLISHER},\nCortesía de ${SOURCE}", + "soundAndMusicText": "Sonido & Música:", + "soundsText": "Sonidos (${SOURCE}):", + "specialThanksText": "Agradecimientos Especiales:", + "thanksEspeciallyToText": "Gracias especialmente a ${NAME}", + "titleText": "Créditos de ${APP_NAME}", + "whoeverInventedCoffeeText": "A quien inventó el café" + }, + "currentStandingText": "Tu puesto actual es #${RANK}", + "customizeText": "Personalizar...", + "deathsTallyText": "${COUNT} muertes", + "deathsText": "Muertes", + "debugText": "depurar", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: Es recomendable poner Ajustes->Gráficos->Texturas en 'Alto' al probar esto.", + "runCPUBenchmarkText": "Ejecutar Punto de Referencia del CPU", + "runGPUBenchmarkText": "Ejecutar Punto de Referencia del GPU", + "runMediaReloadBenchmarkText": "Ejecutar Punto de Referencia del Media-Reload", + "runStressTestText": "Ejecutar prueba de resistencia", + "stressTestPlayerCountText": "Conteo de Jugadores", + "stressTestPlaylistDescriptionText": "Lista de juegos de Prueba de Estrés", + "stressTestPlaylistNameText": "Nombre de la Lista de juegos", + "stressTestPlaylistTypeText": "Tipo de Lista de juegos", + "stressTestRoundDurationText": "Duración de Ronda", + "stressTestTitleText": "Prueba de Estrés", + "titleText": "Pruebas de Estrés y Rendimiento", + "totalReloadTimeText": "Tiempo total de recarga: ${TIME} (ver registro para detalles)" + }, + "defaultGameListNameText": "Lista de juegos ${PLAYMODE} Por Defecto", + "defaultNewGameListNameText": "Mi Lista de juegos ${PLAYMODE}", + "deleteText": "Borrar", + "demoText": "Demo", + "denyText": "Denegar", + "deprecatedText": "Obsoleto", + "descriptionText": "Descripción", + "desktopResText": "Resolución de Escritorio", + "deviceAccountUpgradeText": "Advertencia:\nIniciaste sesión con una cuenta de dispositivo (${NAME}).\nLas cuentas de dispositivo serán removidas en una futura actualización.\nActualiza a una Cuenta V2 si quieres conservar tu progreso.", + "difficultyEasyText": "Fácil", + "difficultyHardOnlyText": "Solo en Modo Difícil", + "difficultyHardText": "Difícil", + "difficultyHardUnlockOnlyText": "Este nivel solo puede ser desbloqueado en modo difícil.\n¡¿¡¿¡Piensas tener lo que se necesita!?!?!", + "directBrowserToURLText": "Por favor abre la siguiente URL en tu navegador:", + "disableRemoteAppConnectionsText": "Deshabilitar Conexiones Remotas de la Aplicación", + "disableXInputDescriptionText": "Permite más de 4 controles pero puede que no funcione bien.", + "disableXInputText": "Deshabilitar XInput", + "disabledText": "Deshabilitado", + "discardText": "Descartar", + "discordFriendsText": "¿Quieres buscar gente nueva con quien jugar?\n¡Únete a nuestro Discord y encuentra nuevos amigos!", + "discordJoinText": "Únete al Discord", + "doneText": "Hecho", + "drawText": "Empate", + "duplicateText": "Duplicar", + "editGameListWindow": { + "addGameText": "Añadir\nJuego", + "cantOverwriteDefaultText": "¡No es posible modificar la lista de juegos por defecto!", + "cantSaveAlreadyExistsText": "¡Ya existe una lista de juegos con ese nombre!", + "cantSaveEmptyListText": "¡No puedes guardar una lista de juegos vacía!", + "editGameText": "Editar\nJuego", + "listNameText": "Nombre de La Lista de Juegos", + "nameText": "Nombre", + "removeGameText": "Eliminar\nJuego", + "saveText": "Guardar Lista", + "titleText": "Editor de Lista de Juegos" + }, + "editProfileWindow": { + "accountProfileInfoText": "Este perfil especial tiene un nombre\ny un icono basado en tu cuenta.\n\n${ICONS}\n\nCrea perfiles personalizados si quieres usar\ndiferentes nombres o iconos personalizados.", + "accountProfileText": "(perfil de cuenta)", + "availableText": "El nombre \"${NAME}\" está disponible.", + "characterText": "personaje", + "checkingAvailabilityText": "Revisando la disponibilidad para \"${NAME}\"...", + "colorText": "color", + "getMoreCharactersText": "Obtener Más Personajes...", + "getMoreIconsText": "Obtener Más Iconos...", + "globalProfileInfoText": "Los perfiles de jugador globales tienen un nombre único\na nivel mundial. También tienen iconos personalizados.", + "globalProfileText": "(perfil global)", + "highlightText": "Destacado", + "iconText": "icono", + "localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía de que los nombres sean únicos. \nCrea un perfil global\npara reservar un nombre único y tener un icono personalizado.", + "localProfileText": "(perfil local)", + "nameDescriptionText": "Nombre del Jugador", + "nameText": "Nombre", + "profileAlreadyExistsText": "Ya existe un perfil con ese nombre.", + "randomText": "aleatorio", + "titleEditText": "Editar Perfil", + "titleNewText": "Nuevo Perfil", + "unavailableText": "\"${NAME}\" no está disponible; intenta otro nombre.", + "upgradeProfileInfoText": "Esto reservará tu nombre de jugador a nivel mundial\ny podrás asignarle un icono personalizado.", + "upgradeToGlobalProfileText": "Actualizar a Perfil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "No puedes borrar la banda sonora predeterminada.", + "cantEditDefaultText": "No puedes editar la banda sonora predeterminada. Duplicala o crea una nueva.", + "cantOverwriteDefaultText": "No puedes sobreescribir la banda sonora predeterminada", + "cantSaveAlreadyExistsText": "¡Ya existe una banda sonora con ese nombre!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Banda Sonora Predeterminada", + "deleteConfirmText": "Borrar Banda Sonora:\n\n'${NAME}'?", + "deleteText": "Borrar\nBanda Sonora", + "duplicateText": "Duplicar\nBanda Sonora", + "editSoundtrackText": "Editor de Banda Sonora", + "editText": "Editar\nBanda Sonora", + "fetchingITunesText": "buscando playlists en la App de Música...", + "musicVolumeZeroWarning": "Advertencia: el volumen de la música está en 0", + "nameText": "Nombre", + "newSoundtrackNameText": "Mi Banda Sonora ${COUNT}", + "newSoundtrackText": "Nueva Banda Sonora:", + "newText": "Nueva\nBanda Sonora", + "selectAPlaylistText": "Selecciona Una Playlist", + "selectASourceText": "Fuente de La Música", + "testText": "prueba", + "titleText": "Bandas Sonoras", + "useDefaultGameMusicText": "Música del Juego Por Defecto", + "useITunesPlaylistText": "Playlist de la App de Música", + "useMusicFileText": "Archivo de Música (mp3, etc).", + "useMusicFolderText": "Carpeta de Archivos de Audio" + }, + "editText": "Editar", + "enabledText": "Habilitado", + "endText": "Fin", + "enjoyText": "¡Diviértete!", + "epicDescriptionFilterText": "${DESCRIPTION} En cámara lenta épica.", + "epicNameFilterText": "${NAME} - Modo épico", + "errorAccessDeniedText": "acceso denegado", + "errorDeviceTimeIncorrectText": "La hora de tu dispositivo está incorrecta por ${HOURS} hora(s).\nEsto podría causar algunos problemas.\nPor favor verifica la hora y zona horaria en ajustes.", + "errorOutOfDiskSpaceText": "espacio insuficiente en el disco", + "errorSecureConnectionFailText": "No se puede establecer una conexión segura en la nube; la red podría estar fallando.", + "errorText": "Error", + "errorUnknownText": "error desconocido", + "exitGameText": "¿Salir de ${APP_NAME}?", + "expiredAgoText": "Expiró hace ${T}", + "expiresInText": "Expira en ${T}", + "exportSuccessText": "'${NAME}' exportado.", + "externalStorageText": "Almacenamiento Externo", + "failText": "Fallaste", + "fatalErrorText": "Oh oh; algo está mal por aquí.\nPor favor intenta reinstalar la app o\ncontacta a ${EMAIL} para recibir ayuda.", + "fileSelectorWindow": { + "titleFileFolderText": "Elige un Archivo o Carpeta", + "titleFileText": "Elige un Archivo", + "titleFolderText": "Elige una Carpeta", + "useThisFolderButtonText": "Usar Esta Carpeta" + }, + "filterText": "Filtro", + "finalScoreText": "Puntaje Final", + "finalScoresText": "Puntajes Finales", + "finalTimeText": "Tiempo Final", + "finishingInstallText": "Terminando la instalación; espera un momento...", + "fireTVRemoteWarningText": "* Para una mejor experiencia, \nutiliza controles o instala la\napp '${REMOTE_APP_NAME}' en tus\ndispositivos móviles y tabletas.", + "firstToFinalText": "Primero de ${COUNT} Finales", + "firstToSeriesText": "Primero de ${COUNT} Series", + "fiveKillText": "¡¡¡COMBO QUÍNTUPLE!!!", + "flawlessWaveText": "¡Oleada Perfecta!", + "fourKillText": "¡¡¡COMBO CUÁDRUPLE!!!", + "friendScoresUnavailableText": "Puntajes no disponibles.", + "gameLeadersText": "Líderes del Juego ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "No puedes borrar la lista de juegos predeterminada.", + "cantEditDefaultText": "¡No puedes editar la lista de juegos predeterminada! Duplicala o crea una nueva.", + "cantShareDefaultText": "No puedes compartir la lista de juegos predeterminada.", + "deleteConfirmText": "¿Borrar \"${LIST}\"?", + "deleteText": "Borrar\nLista de Juegos", + "duplicateText": "Duplicar\nLista de Juegos", + "editText": "Editar\nLista de Juegos", + "newText": "Nueva\nLista de Juegos", + "pointsToWinText": "Puntos Para Ganar", + "seriesLengthText": "Duración de la Serie", + "showTutorialText": "Ver Tutorial", + "shuffleGameOrderText": "Orden de Juego Aleatorio", + "titleText": "Personalizar Listas de Juegos de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Agregar Juego" + }, + "gamesToText": "${WINCOUNT} juegos a ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Recuerda: cualquier dispositivo en la fiesta puede\ntener más de un jugador si tienen controles suficientes.", + "aboutDescriptionText": "Usa estas pestañas para armar una partida.\n\nLas partidas te permiten jugar y competir con\ntus amigos a través de diferentes dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu partida.\n(con un control, presiona ${BUTTON} mientras estés en el menú)", + "aboutText": "Acerca De", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} te envió ${COUNT} boletos en ${APP_NAME}", + "appInviteSendACodeText": "Envíales Un Código", + "appInviteTitleText": "Invitación de La App ${APP_NAME}", + "bluetoothAndroidSupportText": "(funciona con cualquier dispositivo Android con Bluetooth)", + "bluetoothDescriptionText": "Alojar/unirse a una partida vía Bluetooth:", + "bluetoothHostText": "Alojar vía Bluetooth", + "bluetoothJoinText": "Unirse vía Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "revisando...", + "copyCodeConfirmText": "Código copiado al portapapeles.", + "copyCodeText": "Copiar Código", + "dedicatedServerInfoText": "Para mejores resultados, crea un servidor dedicado. Visita bombsquadgame.com/server para aprender cómo hacerlo.", + "descriptionShortText": "Usa la pestaña de Reunir para crear una fiesta.", + "disconnectClientsText": "Esto desconectará a ${COUNT} jugador(es) de\ntu partida. ¿Estás seguro?", + "earnTicketsForRecommendingAmountText": "Tus amigos recibirán ${COUNT} boletos si prueban el juego\n(y recibirás ${YOU_COUNT} boletos por cada amigo que pruebe el juego).", + "earnTicketsForRecommendingText": "Comparte el juego\na cambio de boletos gratis...", + "emailItText": "Envíar Correo", + "favoritesSaveText": "Guardar Como Favorito", + "favoritesText": "Favoritos", + "freeCloudServerAvailableMinutesText": "El siguiente servidor estará disponible en ${MINUTES} minuto(s).", + "freeCloudServerAvailableNowText": "¡Servidor en la nube gratuito disponible!", + "freeCloudServerNotAvailableText": "No hay servidores en la nube gratuitos disponibles.", + "friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos de ${APP_NAME} de ${NAME}", + "friendPromoCodeAwardText": "Recibirás ${COUNT} boletos cada vez que lo uses.", + "friendPromoCodeExpireText": "El código expirará en ${EXPIRE_HOURS} hora(s) y solo funciona para jugadores nuevos.", + "friendPromoCodeInstructionsText": "Para usarlo, abre ${APP_NAME} y ve a \"Ajustes->Avanzado->Enviar Información\"\nVisita bombsquadgame.com para enlaces de descarga de todas las plataformas disponibles.", + "friendPromoCodeRedeemLongText": "Se puede canjear por ${COUNT} boletos gratis hasta por ${MAX_USES} personas.", + "friendPromoCodeRedeemShortText": "Puede ser canjeado por ${COUNT} boletos en el juego.", + "friendPromoCodeWhereToEnterText": "(en \"Ajustes->Avanzado->Enviar Información\")", + "getFriendInviteCodeText": "Obtener Código de Invitación de Amigo", + "googlePlayDescriptionText": "Invitar jugadores de Google Play a tu partida:", + "googlePlayInviteText": "Invitar", + "googlePlayReInviteText": "Hay ${COUNT} jugador(es) de Google Play en tu fiesta\nque se desconectarán si creas una nueva invitación.\nInclúyelos en la nueva invitación para tenerlos de vuelta.", + "googlePlaySeeInvitesText": "Ver Invitaciones", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Versión Android / Google Play)", + "hostPublicPartyDescriptionText": "Alojar una Partida Pública", + "hostingUnavailableText": "Alojamiento No Disponible", + "inDevelopmentWarningText": "Nota:\n\nJugar en red es una función todavía en desarrollo.\nPor ahora, es altamente recomendado que todos\nlos jugadores estén en la misma red Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "¿Tus amigos no tienen el juego? Invítalos a\nprobarlo y recibirán ${COUNT} boletos gratis.", + "inviteFriendsText": "Invitar Amigos", + "joinPublicPartyDescriptionText": "Unirse a una Partida Pública", + "localNetworkDescriptionText": "Unirse a una Partida Cercana (LAN, Bluetooth, etc.)", + "localNetworkText": "Red Local", + "makePartyPrivateText": "Hacer Mi Partida Privada", + "makePartyPublicText": "Hacer Mi Partida Pública", + "manualAddressText": "Dirección", + "manualConnectText": "Conectar", + "manualDescriptionText": "Unirse a una partida por dirección:", + "manualJoinSectionText": "Unirse Por Dirección", + "manualJoinableFromInternetText": "¿Se pueden unir desde internet?:", + "manualJoinableNoWithAsteriskText": "NO*", + "manualJoinableYesText": "SÍ", + "manualRouterForwardingText": "*para arreglarlo, configura tu router para que redireccione el puerto UDP ${PORT} a tu dirección local", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Tu dirección desde internet:", + "manualYourLocalAddressText": "Tu dirección local:", + "nearbyText": "Cerca", + "noConnectionText": "", + "noPartiesAddedText": "Sin Fiestas Añadidas", + "otherVersionsText": "(otras versiones)", + "partyCodeText": "Código de La Partida", + "partyInviteAcceptText": "Aceptar", + "partyInviteDeclineText": "Denegar", + "partyInviteIgnoreText": "Ignorar", + "partyInviteText": "${NAME} te ha invitado\na unirse a su partida!", + "partyNameText": "Nombre de La Partida", + "partyServerRunningText": "Tu servidor se esta ejecutando.", + "partySizeText": "tamaño de partida", + "partyStatusCheckingText": "comprobando estado...", + "partyStatusJoinableText": "ahora se pueden unir a tu partida desde internet", + "partyStatusNoConnectionText": "incapaz de conectarse al servidor", + "partyStatusNotJoinableText": "no se pueden unir a tu partida desde internet", + "partyStatusNotPublicText": "tu partida no es pública", + "pingText": "ping", + "portText": "Puerto", + "privatePartyCloudDescriptionText": "Las partidas privadas se ejecutan en la nube; no requieren configuración del router.", + "privatePartyHostText": "Alojar una Partida Privada", + "privatePartyJoinText": "Unirse a una Partida Privada", + "privateText": "Privado", + "publicHostRouterConfigText": "Esto puede requerir configurar el reenvío de puertos en tu router. Para una opción más fácil, aloja una partida privada.", + "publicText": "Público", + "requestingAPromoCodeText": "Pidiendo un código...", + "sendDirectInvitesText": "Enviar Directamente La Invitación", + "shareThisCodeWithFriendsText": "Comparte este código con tus amigos:", + "showMyAddressText": "Mostrar Mi Dirección", + "startHostingPaidText": "Alojar Ahora Por ${COST}", + "startHostingText": "Alojar", + "startStopHostingMinutesText": "Puede iniciar y detener el alojamiento de forma gratuita durante los próximos ${MINUTES} minuto(s).", + "stopHostingText": "Dejar de Alojar", + "titleText": "Reunir", + "wifiDirectDescriptionBottomText": "Si todo los dispositivos disponen de 'Wi-fi Directo', deberían poder utilizarlo para\nencontrar y conectarse entre ellos. Cuando todos estén conectados, puedes formar \npartidas, usando la pestaña 'Red Local', como si estuvieran en la misma red Wi-fi.\n\nPara mejores resultados, el alojador del Wi-fi Directo también debe ser el alojador de la partida en ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Directo puede ser utilizado para conectar dispositivos Android sin\ntener que utilizar una red Wi-Fi. Esto funciona mejor en Android 4.2 hacia adelante.\n\nPara utilizarlo, abre los ajustes de Wi-Fi y busca 'Wi-Fi Directo' en el menú.", + "wifiDirectOpenWiFiSettingsText": "Abrir Ajustes de Wi-Fi", + "wifiDirectText": "Wi-Fi Directo", + "worksBetweenAllPlatformsText": "(funciona en todas las plataformas)", + "youHaveBeenSentAPromoCodeText": "Has enviado un código promocional de ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "¡GRATIS!", + "freeTicketsText": "Boletos Gratis", + "inProgressText": "Ya hay una transacción en progreso; por favor inténtalo mas tarde.", + "purchasesRestoredText": "Compras restauradas.", + "receivedTicketsText": "¡Recibiste ${COUNT} boletos!", + "restorePurchasesText": "Restaurar Compras", + "ticketPack1Text": "Paquete de Boletos Pequeño", + "ticketPack2Text": "Paquete de Boletos Mediano", + "ticketPack3Text": "Paquete de Boletos Grande", + "ticketPack4Text": "Paquete de Boletos Jumbo", + "ticketPack5Text": "Paquete de Boletos Mamut", + "ticketPack6Text": "Paquete de Boletos Supremo", + "ticketsFromASponsorText": "Ver un anuncio\na cambio de ${COUNT} boletos", + "ticketsText": "${COUNT} Boletos", + "titleText": "Conseguir Boletos", + "unavailableLinkAccountText": "Disculpe, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.", + "unavailableTemporarilyText": "No disponible por el momento; por favor inténtalo más tarde.", + "unavailableText": "Disculpe, esto no está disponible.", + "versionTooOldText": "Lo sentimos, esta versión del juego es muy antigua; por favor actualízala a una nueva versión.", + "youHaveShortText": "tienes ${COUNT}", + "youHaveText": "tienes ${COUNT} boletos" + }, + "goldPass": { + "desc1InfTokensText": "Fichas infinitas.", + "desc2NoAdsText": "Sin anuncios.", + "desc3ForeverText": "Para siempre.", + "goldPassText": "Pase de Oro" + }, + "googlePlayPurchasesNotAvailableText": "Las compras de Google Play no están disponibles.\nEs posible que debas actualizar la aplicación de tu tienda.", + "googlePlayServicesNotAvailableText": "Los Servicios de Google Play no están disponibles.\nAlgunas funciones de la aplicación pueden estar deshabilitadas.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Siempre", + "fullScreenCmdText": "Pantalla completa (Cmd-F)", + "fullScreenCtrlText": "Pantalla completa (Ctrl-F)", + "fullScreenText": "Pantalla completa", + "gammaText": "Gama", + "highText": "Alto", + "higherText": "Altísimo", + "lowText": "Bajo", + "maxFPSText": "FPS Máximos", + "mediumText": "Medio", + "neverText": "Nunca", + "resolutionText": "Resolución", + "showFPSText": "Mostrar FPS", + "texturesText": "Texturas", + "titleText": "Gráficos", + "tvBorderText": "Borde del TV", + "verticalSyncText": "Sincronización Vertical", + "visualsText": "Visuales" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nMás fuerte que los golpes, pero puede\nresultar en autolesiones graves.\nPara mejores resultados, tírala hacia tus\noponentes antes de que explote.", + "canHelpText": "${APP_NAME} te puede ayudar.", + "controllersInfoText": "Puedes jugar ${APP_NAME} con tus amigos en una red o todos pueden\njugar en el mismo dispositivo si se tienen varios controles.\n${APP_NAME} soporta una gran variedad de ellos; incluso puedes utilizar\ntus dispositivos móviles como controles instalando la app '${REMOTE_APP_NAME}'.\nVe a \"Ajustes->Controles\" para más información.", + "controllersInfoTextRemoteOnly": "Tu puedes jugar ${APP_NAME} con tus amigos en la red o pueden\njugar todos en el mismo dispositivo usando los teléfonos\ncomo controles con la aplicación '${REMOTE_APP_NAME}'.", + "controllersText": "Controles", + "controlsSubtitleText": "Tu amistoso personaje de ${APP_NAME} tiene algunas acciones básicas:", + "controlsText": "Controles", + "devicesInfoText": "La versión de RV de ${APP_NAME} se puede jugar en la red con la versión \nregular, así que saca tus celulares, tablets y computadoras extras y que \nempieze el juego. Es muy útil conectar un dispositivo con la versión\nregular a uno con la versión VR para que todos los que estén fuera\npuedan ver la acción.", + "devicesText": "Dispositivos", + "friendsGoodText": "Cuantos más, mejor. ${APP_NAME} es más divertido con muchos \namigos y soporta hasta 8 a la vez, lo que nos lleva a:", + "friendsText": "Amigos", + "jumpInfoText": "- Saltar -\nSalta para cruzar pequeños espacios, \npara tirar cosas más lejos y \npara expresar sentimientos de alegría.", + "orPunchingSomethingText": "O golpear algo, tirarlo por un precipicio y explotarlo en plena caída con una bomba pegajosa.", + "pickUpInfoText": "- Recoger -\nAgarra banderas, enemigos o cualquier\notra cosa no pegada al suelo.\nPresiona de nuevo para lanzar.", + "powerupBombDescriptionText": "Te permite sacar tres bombas\nrapidamente en lugar de solo una.", + "powerupBombNameText": "Bombas Triples", + "powerupCurseDescriptionText": "Probablemente quieras evitar estos.\n ...¿o talvez no?", + "powerupCurseNameText": "Maldición", + "powerupHealthDescriptionText": "Te restaura la salud completamente.\nNunca lo habrías adivinado.", + "powerupHealthNameText": "Botiquín", + "powerupIceBombsDescriptionText": "Más débiles que las bombas normales\npero dejan a tus enemigos congelados\ny particularmente frágiles.", + "powerupIceBombsNameText": "Bombas de Hielo", + "powerupImpactBombsDescriptionText": "Levemente más débiles que las bombas regulares, pero explotan al impacto.", + "powerupImpactBombsNameText": "Insta-Bombas", + "powerupLandMinesDescriptionText": "Estas vienen en grupos de 3;\nSon buenas para defensa territorial\no para detener enemigos veloces.", + "powerupLandMinesNameText": "Minas Terrestres", + "powerupPunchDescriptionText": "Hacen que tus golpes sean más duros,\nmás rápidos, mejores y más fuertes.", + "powerupPunchNameText": "Guantes de Boxeo", + "powerupShieldDescriptionText": "Absorbe un poco de daño\npara que asi no tengas que hacerlo tu.", + "powerupShieldNameText": "Escudo-de-Energía", + "powerupStickyBombsDescriptionText": "Se adhieren a todo lo que toquen.\nProducen hilaridad.", + "powerupStickyBombsNameText": "Bombas Pegajosas", + "powerupsSubtitleText": "Obviamente, ningún juego estaría completo sin potenciadores:", + "powerupsText": "Potenciadores", + "punchInfoText": "- Golpear -\nLos golpes hacen más daño cuanto\nmás rápido se muevan tus puños, así que\ncorre, salta y gira como un loco.", + "runInfoText": "- Correr -\nMantén CUALQUIER botón para correr. Los gatillos o botones traseros funcionan bien si los tienes.\nCorrer te lleva a lugares más rápido pero es más difícil girar, así que ten cuidado con los barrancos.", + "someDaysText": "Hay días en los que sientes ganas de golpear algo. O volar algo.", + "titleText": "Ayuda de ${APP_NAME}", + "toGetTheMostText": "Para sacar el máximo partido a este juego, necesitas:", + "welcomeText": "¡Bienvenido a ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} está navegando los menús como un pro -", + "importPlaylistCodeInstructionsText": "Usa el siguiente código para importar esta lista de juegos en otra parte:", + "importPlaylistSuccessText": "Lista de Juegos '${NAME}' importada ${TYPE}", + "importText": "Importar", + "importingText": "Importando...", + "inGameClippedNameText": "en el juego será\n\"${NAME}\"", + "inboxText": "Bandeja de Entrada", + "installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación.\nPuede que te hayas quedado sin espacio en tu dispositivo.\nLibera un poco de tu espacio e intenta de nuevo.", + "internal": { + "arrowsToExitListText": "pulsa ${LEFT} o ${RIGHT} para salir de la lista", + "buttonText": "botón", + "cantKickHostError": "No puedes expulsar al anfitrión.", + "chatBlockedText": "${NAME} está bloqueado del chat por ${TIME} segundos.", + "connectedToGameText": "Unido a '${NAME}'", + "connectedToPartyText": "¡Unido a la partida de ${NAME}!", + "connectingToPartyText": "Conectando...", + "connectionFailedHostAlreadyInPartyText": "Conexión fallida; el anfitrión está en otra partida.", + "connectionFailedPartyFullText": "Conexión fallida; la partida está llena.", + "connectionFailedText": "Conexión fallida.", + "connectionFailedVersionMismatchText": "Conexión fallida; el anfitrión corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "connectionRejectedText": "Conexión rechazada.", + "controllerConnectedText": "${CONTROLLER} conectado.", + "controllerDetectedText": "1 control detectado.", + "controllerDisconnectedText": "${CONTROLLER} desconectado.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Intenta conectarlo de nuevo.", + "controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menús.", + "controllerReconnectedText": "${CONTROLLER} reconectado.", + "controllersConnectedText": "${COUNT} controles conectados.", + "controllersDetectedText": "${COUNT} controles detectados.", + "controllersDisconnectedText": "${COUNT} controles desconectados.", + "corruptFileText": "Archivo(s) corrupto(s) detectado(s). Por favor intenta reinstalando o contácta a ${EMAIL}", + "errorPlayingMusicText": "Error reproduciendo música: ${MUSIC}", + "errorResettingAchievementsText": "Incapaz de reiniciar los logros; por favor inténtalo de nuevo más tarde.", + "hasMenuControlText": "${NAME} tiene el control del menú.", + "incompatibleNewerVersionHostText": "El anfitrión está ejecutando una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.", + "incompatibleVersionHostText": "El anfitrión está ejecutando una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "incompatibleVersionPlayerText": "${NAME} está ejecutando una versión diferente del juego.\nAsegúrate de que ambos estén actualizados y vuelva a intentarlo.", + "invalidAddressErrorText": "Error: dirección inválida.", + "invalidNameErrorText": "Error: nombre inválido.", + "invalidPortErrorText": "Error: puerto inválido.", + "invitationSentText": "Invitación enviada.", + "invitationsSentText": "${COUNT} invitaciones enviadas.", + "joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta.\nVe a 'Jugar' para iniciar un juego.", + "keyboardText": "Teclado", + "kickIdlePlayersKickedText": "Expulsando a ${NAME} por estar inactivo.", + "kickIdlePlayersWarning1Text": "${NAME} será expulsado en ${COUNT} segundos si sigue inactivo.", + "kickIdlePlayersWarning2Text": "(puedes apagar esto en Ajustes -> Avanzado)", + "leftGameText": "Abandonó '${NAME}'.", + "leftPartyText": "Abandonó la partida de ${NAME}.", + "noMusicFilesInFolderText": "La carpeta no contiene archivos de audio.", + "playerJoinedPartyText": "¡${NAME} se unió a la partida!", + "playerLeftPartyText": "${NAME} abandonó la partida.", + "rejectingInviteAlreadyInPartyText": "Rechazando invitación (ya estás en una partida).", + "serverRestartingText": "El servidor se está reiniciando. Por favor vuelva a unirse en un momento...", + "serverShuttingDownText": "El servidor está fuera de servicio...", + "signInErrorText": "Error iniciando sesión.", + "signInNoConnectionText": "Imposible iniciar sesión. (¿no hay conexión a internet?)", + "telnetAccessDeniedText": "ERROR: El usuario no concedió acceso telnet.", + "timeOutText": "(tiempo fuera en ${TIME} segundo/s)", + "touchScreenJoinWarningText": "Te uniste con la pantalla táctil.\nSi este fue un error, presiona 'Menú->Abandonar Juego' con ella.", + "touchScreenText": "Pantalla Táctil", + "unableToCompleteTryAgainText": "Incapaz de completar esto ahora mismo.\nPor favor, inténtelo de nuevo.", + "unableToResolveHostText": "Error: incapaz de encontrar el anfitrión.", + "unavailableNoConnectionText": "No disponible por el momento (¿no tienes conexión a internet?)", + "vrOrientationResetCardboardText": "Usa esto para reiniciar la orientación de RV.\nPara jugar el juego necesitarás un control externo.", + "vrOrientationResetText": "Orientación de RV reiniciada.", + "willTimeOutText": "(caducará si está inactivo)" + }, + "inventoryText": "Inventario", + "jumpBoldText": "SALTAR", + "jumpText": "Saltar", + "keepText": "Mantener", + "keepTheseSettingsText": "¿Mantener estos ajustes?", + "keyboardChangeInstructionsText": "Presiona dos veces el espacio para cambiar los teclados.", + "keyboardNoOthersAvailableText": "No hay más teclados disponibles.", + "keyboardSwitchText": "Cambiando teclado a \"${NAME}\".", + "kickOccurredText": "${NAME} ha sido expulsado.", + "kickQuestionText": "¿Expulsar a ${NAME}?", + "kickText": "Expulsar", + "kickVoteCantKickAdminsText": "Los administradores no pueden ser expulsados.", + "kickVoteCantKickSelfText": "No puedes expulsarte a ti mismo.", + "kickVoteFailedNotEnoughVotersText": "No hay suficientes jugadores para votar.", + "kickVoteFailedText": "Votación de expulsión fallida.", + "kickVoteStartedText": "Se ha iniciado una votación de expulsión para '${NAME}'.", + "kickVoteText": "Votar para Expulsar", + "kickVotingDisabledText": "El voto para expulsar esta desactivado.", + "kickWithChatText": "Escribe ${YES} en el chat para \"Si\" y ${NO} para \"No\".", + "killsTallyText": "${COUNT} asesinatos", + "killsText": "Asesinatos", + "kioskWindow": { + "easyText": "Fácil", + "epicModeText": "Modo Lento", + "fullMenuText": "Menú Completo", + "hardText": "Difícil", + "mediumText": "Medio", + "singlePlayerExamplesText": "Ejemplos de 1 Jugador / Modo Cooperativo", + "versusExamplesText": "Ejemplos de Versus" + }, + "languageSetText": "El idioma ahora es \"${LANGUAGE}\".", + "lapNumberText": "Vuelta ${CURRENT}/${TOTAL}", + "lastGamesText": "(últimos ${COUNT} juegos)", + "leaderboardsText": "Clasificaciones", + "league": { + "allTimeText": "Todo El Tiempo", + "currentSeasonText": "Temporada Actual (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Rango de Liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "La temporada terminó hace ${NUMBER} día(s).", + "seasonEndsDaysText": "La temporada termina en ${NUMBER} día(s).", + "seasonEndsHoursText": "La temporada termina en ${NUMBER} hora(s).", + "seasonEndsMinutesText": "La temporada termina en ${NUMBER} minuto(s).", + "seasonText": "Temporada ${NUMBER}", + "tournamentLeagueText": "Debes alcanzar la liga ${NAME} para entrar a este torneo.", + "trophyCountsResetText": "El conteo de trofeos se reiniciará la próxima temporada.", + "upToDateBonusDescriptionText": "Los jugadores con una version reciente \ndel juego obtienen un bonus del ${PERCENT}% aquí.", + "upToDateBonusText": "Bono Actualizado" + }, + "learnMoreText": "Aprender Más", + "levelBestScoresText": "Mejores puntajes en ${LEVEL}", + "levelBestTimesText": "Mejores tiempos en ${LEVEL}", + "levelIsLockedText": "${LEVEL} está bloqueado.", + "levelMustBeCompletedFirstText": "${LEVEL} debe completarse primero.", + "levelText": "Nivel ${NUMBER}", + "levelUnlockedText": "¡Nivel Desbloqueado!", + "livesBonusText": "Bono de Vidas", + "loadingText": "cargando", + "loadingTryAgainText": "Cargando; vuelve a intentarlo en un momento...", + "macControllerSubsystemBothText": "Ambos (no recomendado)", + "macControllerSubsystemClassicText": "Clásico", + "macControllerSubsystemDescriptionText": "(intenta cambiar esto si tus controles no están funcionando)", + "macControllerSubsystemMFiNoteText": "Control hecho para iOS/Mac detectado;\nTal vez quieras activar esto en Ajustes -> Controles", + "macControllerSubsystemMFiText": "Creado para iOS/Mac", + "macControllerSubsystemTitleText": "Soporte del Control", + "mainMenu": { + "creditsText": "Créditos", + "demoMenuText": "Menú Demo", + "endGameText": "Terminar Juego", + "endTestText": "Terminar Prueba", + "exitGameText": "Salir del Juego", + "exitToMenuText": "¿Salir al menú?", + "howToPlayText": "Cómo Jugar", + "justPlayerText": "(Solo ${NAME})", + "leaveGameText": "Abandonar Juego", + "leavePartyConfirmText": "¿Realmente deseas abandonar la partida?", + "leavePartyText": "Abandonar Partida", + "quitText": "Salir", + "resumeText": "Reanudar", + "settingsText": "Ajustes" + }, + "makeItSoText": "Que así sea", + "mapSelectGetMoreMapsText": "Obtener Más Mapas...", + "mapSelectText": "Seleccionar...", + "mapSelectTitleText": "Mapas para ${GAME}", + "mapText": "Mapa", + "maxConnectionsText": "Máximo de Conexiones", + "maxPartySizeText": "Capacidad Máxima de La Partida", + "maxPlayersText": "Máximo de Jugadores", + "merchText": "¡Mercancía!", + "modeArcadeText": "Modo Arcade", + "modeClassicText": "Modo Clásico", + "modeDemoText": "Modo Demo", + "moreSoonText": "Más próximamente...", + "mostDestroyedPlayerText": "Jugador Más Destruido", + "mostValuablePlayerText": "Jugador Más Valioso", + "mostViolatedPlayerText": "Jugador Más Violado", + "mostViolentPlayerText": "Jugador Más Violento", + "moveText": "Mover", + "multiKillText": "¡¡¡COMBO DE ${COUNT}!!!", + "multiPlayerCountText": "${COUNT} jugadores", + "mustInviteFriendsText": "Nota: debes invitar a tus amigos en\nel panel \"${GATHER}\" o conectar\ncontroles para jugar multijugador.", + "nameBetrayedText": "${NAME} traicionó a ${VICTIM}.", + "nameDiedText": "${NAME} ha muerto.", + "nameKilledText": "${NAME} mató a ${VICTIM}.", + "nameNotEmptyText": "¡El nombre no puede quedar vacío!", + "nameScoresText": "¡${NAME} Anotó!", + "nameSuicideKidFriendlyText": "${NAME} murió accidentalmente.", + "nameSuicideText": "${NAME} cometió suicidio.", + "nameText": "Nombre", + "nativeText": "Nativo", + "newExclaimText": "¡Nuevo!", + "newPersonalBestText": "¡Nuevo récord personal!", + "newTestBuildAvailableText": "¡Una nueva build de prueba está disponible! (${VERSION} build ${BUILD}).\nObténla en ${ADDRESS}", + "newText": "Nuevo", + "newVersionAvailableText": "¡Una nueva version de ${APP_NAME} está disponible! (${VERSION})", + "nextAchievementsText": "Siguientes Logros:", + "nextLevelText": "Siguiente Nivel", + "noAchievementsRemainingText": "- ninguno", + "noContinuesText": "(sin re-intentos)", + "noExternalStorageErrorText": "No se encontró almacenamiento externo en este dispositivo", + "noGameCircleText": "Error: no registrado en GameCircle", + "noMessagesText": "Sin mensajes.", + "noPluginsInstalledText": "Sin Complementos Instalados", + "noScoresYetText": "Sin puntajes aún.", + "noServersFoundText": "No se encontraron servidores.", + "noThanksText": "No Gracias", + "noTournamentsInTestBuildText": "ADVERTENCIA: Los puntajes de los torneos en esta versión de prueba serán ignorados.", + "noValidMapsErrorText": "Mapas válidos no encontrados para este tipo de juego.", + "notEnoughPlayersRemainingText": "No hay jugadores suficientes restantes; sal e inicia un nuevo juego.", + "notEnoughPlayersText": "¡Necesitas por lo menos ${COUNT} jugadores para comenzar!", + "notEnoughTicketsText": "¡No tienes suficientes tickets!", + "notNowText": "Ahora No", + "notSignedInErrorText": "Debes iniciar sesión para hacer esto.", + "notSignedInGooglePlayErrorText": "Debes iniciar sesión con Google Play para hacer esto.", + "notSignedInText": "no registrado", + "notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Iniciar sesión con ${SERVICE}' si quieres usarla.", + "nothingIsSelectedErrorText": "¡No hay nada seleccionado!", + "numberText": "#${NUMBER}", + "offText": "Apagar", + "okText": "Aceptar", + "onText": "Encender", + "oneMomentText": "Un Momento...", + "onslaughtRespawnText": "${PLAYER} reaparecerá en la oleada ${WAVE}", + "openMeText": "Ábreme!", + "openNowText": "Abrir Ahora", + "openText": "Abrir", + "orText": "${A} o ${B}", + "otherText": "Otros...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "¡Su propia bandera debe estar\nen su base para anotar!", + "partyWindow": { + "chatMessageText": "Mensaje del Chat", + "emptyText": "Tu partida está vacía", + "hostText": "(anfitrión)", + "sendText": "Enviar", + "titleText": "Tu Partida" + }, + "pausedByHostText": "(pausado por el anfitrión)", + "perfectWaveText": "¡Oleada Perfecta!", + "pickUpText": "Recoger", + "playModes": { + "coopText": "Cooperativo", + "freeForAllText": "Todos contra Todos", + "multiTeamText": "Múlti-Equipo", + "singlePlayerCoopText": "Un Jugador / Equipos", + "teamsText": "Equipos" + }, + "playText": "Jugar", + "playWindow": { + "oneToFourPlayersText": "1-4 jugadores", + "titleText": "Jugar", + "twoToEightPlayersText": "2-8 jugadores" + }, + "playerCountAbbreviatedText": "${COUNT}j", + "playerDelayedJoinText": "${PLAYER} entrará al comienzo de la siguiente ronda.", + "playerInfoText": "Información del Jugador", + "playerLeftText": "${PLAYER} abandonó el juego.", + "playerLimitReachedText": "Límite de ${COUNT} jugadores alcanzado; no se permiten más.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "No puedes borrar el perfil de tu cuenta.", + "deleteButtonText": "Borrar\nPerfil", + "deleteConfirmText": "¿Borrar '${PROFILE}'?", + "editButtonText": "Editar\nPerfil", + "explanationText": "(nombres de jugadores personalizados y apariencias para esta cuenta)", + "newButtonText": "Nuevo\nPerfil", + "titleText": "Perfiles del Jugador" + }, + "playerText": "Jugador", + "playlistNoValidGamesErrorText": "Esta lista de juegos contiene juegos desbloqueables no válidos.", + "playlistNotFoundText": "playlist no encontrada", + "playlistText": "Lista de Juegos", + "playlistsText": "Listas de juegos", + "pleaseRateText": "Si te gusta ${APP_NAME}, por favor tomate un momento\npara calificar o escribir una reseña. Esto proporciona\ninformación útil y ayuda al soporte del futuro desarrollo del juego.\n\n¡gracias!\n-eric", + "pleaseWaitText": "Por favor, espera...", + "pluginClassLoadErrorText": "Error cargando el complemento '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Error iniciando complemento '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Ajustes de Complementos", + "pluginsAutoEnableNewText": "Activar automáticamente los nuevos complementos", + "pluginsDetectedText": "Complemento(s) detectado(s). Reinicia el juego o ve a ajustes para configurarlo.", + "pluginsDisableAllText": "Deshabilitar Todos Los Complementos", + "pluginsEnableAllText": "Habilitar Todos Los Complementos", + "pluginsRemovedText": "${NUM} complemento(s) ya no está(n).", + "pluginsText": "Complementos", + "practiceText": "Práctica", + "pressAnyButtonPlayAgainText": "Presiona cualquier botón para jugar de nuevo...", + "pressAnyButtonText": "Presiona cualquier botón para continuar...", + "pressAnyButtonToJoinText": "presiona cualquier botón para unirte al juego...", + "pressAnyKeyButtonPlayAgainText": "Presiona cualquier tecla/botón para jugar de nuevo...", + "pressAnyKeyButtonText": "Presiona cualquier botón/tecla para continuar...", + "pressAnyKeyText": "Presiona cualquier tecla...", + "pressJumpToFlyText": "** Presiona saltar repetidamente para volar **", + "pressPunchToJoinText": "presiona GOLPEAR para unirte...", + "pressToOverrideCharacterText": "presiona ${BUTTONS} para cambiar de personaje", + "pressToSelectProfileText": "presiona ${BUTTONS} para seleccionar un perfil", + "pressToSelectTeamText": "presiona ${BUTTONS} para seleccionar un equipo", + "promoCodeWindow": { + "codeText": "Código", + "enterText": "Ingresar" + }, + "promoSubmitErrorText": "Error al enviar código; comprueba tu conexión a Internet", + "ps3ControllersWindow": { + "macInstructionsText": "Apaga tu PS3, asegúrate que el Bluetooth esté activado en\ntu Mac, a continuación, conecta el control a tu Mac a través \nde un cable USB para sincronizarlo. A partir de entonces, se \npuede utilizar el botón de inicio del control para conectarlo con\ntu Mac ya sea por cable (USB) o el modo inalámbrico (Bluetooth).\n\nEn algunas Macs es posible que te pida una contraseña al momento de sincronizar.\nSi esto ocurre, consulta el siguiente tutorial o busca en Google para obtener ayuda.\n\n\n\n\nLos controles de PS3 conectados inalámbricamente deberían de aparecer en la lista de\ndispositivos en Preferencias del Sistema->Bluetooth. Puede que tengas que eliminarlos\nde esa lista cuando quieras utilizarlos de nuevo con tu PS3.\n\nAsimismo, asegúrate de desconectarlos del Bluetooth cuando no los estés\nusando o las baterías se queden sin energía.\n\nEl Bluetooth puede soportat hasta 7 dispositivos,\naunque tu kilometraje puede variar.", + "ouyaInstructionsText": "Para usar un control de PS3 con tu OUYA, tienes que conectarlo una sola vez con\nun cable USB para sincronizarlo. Al hacer esto se pueden desconectar tus otros \ncontroles, por lo que debes reiniciar tu OUYA y desconectar el cable USB.\n\nA partir de entonces deberías ser capaz de usar el botón INICIO para conectarte de\nforma inalámbrica. Cuando hayas terminado de jugar, mantén pulsado el botón INICIO\ndurante 10 segundos para apagar el control, de lo contrario puede permanecer encendido\ny gastar las baterías.", + "pairingTutorialText": "sincronizando video tutorial", + "titleText": "Para usar Controles de PS3 con ${APP_NAME}:" + }, + "punchBoldText": "GOLPEAR", + "punchText": "Golpear", + "purchaseForText": "Comprar por ${PRICE}", + "purchaseGameText": "Comprar Juego", + "purchaseNeverAvailableText": "Lo siento, las compras no están disponibles en esta build.\nIntenta iniciar sesión en otra plataforma y realizar compras desde ahí.", + "purchaseNotAvailableText": "Esta compra no está disponible.", + "purchasingText": "Comprando...", + "quitGameText": "¿Salir de ${APP_NAME}?", + "quittingIn5SecondsText": "Saliendo en 5 segundos...", + "randomPlayerNamesText": "Pablo, Cristiano, Fulanito, Macondo, Margarita, Martín, Martina, Fabian, Felipe, Franco, Fernando, Pancho, Pepito, David, Diego, Tomás, Andres, Federico, Juan, Joaquín, Huevo Duro, Chico Pobre, Chico Rico", + "randomText": "Generar", + "rankText": "Rango", + "ratingText": "Valoración", + "reachWave2Text": "Llega hasta la segunda horda\npara clasificar.", + "readyText": "listo", + "recentText": "Reciente", + "remoteAppInfoShortText": "${APP_NAME} es más divertido cuando se juega con la familia y amigos.\nConecta uno o más controles de hardware o instala la app\n${REMOTE_APP_NAME} en los teléfonos o tabletas para usarlos\ncomo controles.", + "remote_app": { + "app_name": "Control Remoto BombSquad", + "app_name_short": "BSRemoto", + "button_position": "Posición de Los Botones", + "button_size": "Tamaño de Los Botones", + "cant_resolve_host": "No se encuentra el anfitrión.", + "capturing": "Captando...", + "connected": "Conectado.", + "description": "Usa tu teléfono o tableta como control para BombSquad.\nHasta 8 dispositivos pueden conectarse a la vez para un épico caos de multijugador local en un solo TV o tableta.", + "disconnected": "Desconectado por el servidor.", + "dpad_fixed": "fijo", + "dpad_floating": "flotante", + "dpad_position": "Posición del D-Pad", + "dpad_size": "Tamaño del D-Pad", + "dpad_type": "Tipo de D-Pad", + "enter_an_address": "Ingresa una Dirección", + "game_full": "El juego está lleno o no acepta conexiones.", + "game_shut_down": "El juego se ha cerrado.", + "hardware_buttons": "Botones del Hardware", + "join_by_address": "Unirse por Dirección...", + "lag": "Lag: ${SECONDS} segundo/s", + "reset": "Restablecer a predeterminado", + "run1": "Ejecutar 1", + "run2": "Ejecutar 2", + "searching": "Buscando partidas de BombSquad...", + "searching_caption": "Toca el nombre de la partida para unirte.\nTen en cuenta que debes estar en la misma conexión Wi-Fi de la partida.", + "start": "Empezar", + "version_mismatch": "Las versiones no coinciden.\nAsegurate que BombSquad y BombSquad Remote\nestán actualizados e intenta de nuevo." + }, + "removeInGameAdsText": "Desbloquea \"${PRO}\" en la tienda para quitar la publicidad del juego.", + "removeInGameAdsTokenPurchaseText": "OFERTA DE TIEMPO LIMITADO: Compra CUALQUIER paquete de fichas para quitar los anuncios del juego.", + "renameText": "Renombrar", + "replayEndText": "Terminar Repetición", + "replayNameDefaultText": "Repetición Último Juego", + "replayReadErrorText": "Error leyendo archivo de repetición.", + "replayRenameWarningText": "Renombra \"${REPLAY}\" después de un juego si quieres quedarte con el; o sino será reemplazado.", + "replayVersionErrorText": "Lo sentimos, esta repetición fue hecha en una\nversión diferente del juego y no se puede usar.", + "replayWatchText": "Ver Repetición", + "replayWriteErrorText": "Error creando archivo de repetición.", + "replaysText": "Repeticiones", + "reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje inapropiado u otro mal comportamiento.\nPor favor, describelo aquí abajo:", + "reportThisPlayerCheatingText": "Trampas", + "reportThisPlayerLanguageText": "Lenguaje Inapropiado", + "reportThisPlayerReasonText": "¿Qué te gustaría reportar?", + "reportThisPlayerText": "Reportar Este Jugador", + "requestingText": "Solicitando...", + "restartText": "Reiniciar", + "retryText": "Reintentar", + "revertText": "Deshacer", + "runText": "Correr", + "saveText": "Guardar", + "scanScriptsErrorText": "Error(es) escaneando script(s); Vea el registro para más detalles.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} y ${NUM} otro(s) módulo(s) se deberán actualizar para el api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} se deberá actualizar para el api ${API}", + "scoreChallengesText": "Desafíos de Puntuación", + "scoreListUnavailableText": "La lista de puntajes no está disponible.", + "scoreText": "Puntaje", + "scoreUnits": { + "millisecondsText": "Milisegundos", + "pointsText": "Puntos", + "secondsText": "Segundos" + }, + "scoreWasText": "(era ${COUNT})", + "selectText": "Elegir", + "sendInfoDescriptionText": "Envía información del estado de la cuenta y de la aplicación al desarrollador.\nPor favor incluya su nombre o el motivo del envío.", + "seriesWinLine1PlayerText": "GANA LA", + "seriesWinLine1TeamText": "GANA LA", + "seriesWinLine1Text": "GANA LA", + "seriesWinLine2Text": "SERIE!", + "settingsWindow": { + "accountText": "Cuenta", + "advancedText": "Avanzado", + "audioText": "Audio", + "controllersText": "Controles", + "graphicsText": "Gráficos", + "playerProfilesMovedText": "Nota: Los Perfiles de Jugadores se han movido a la ventana de Cuenta en el menú principal.", + "titleText": "Ajustes" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(un teclado en pantalla simple y amigable con controles para editar textos)", + "alwaysUseInternalKeyboardText": "Siempre usar el teclado interno", + "benchmarksText": "Rendimiento y Pruebas de Estrés", + "devToolsText": "Herramientas de Desarrollador", + "disableCameraGyroscopeMotionText": "Deshabilitar el movimiento del giroscopio de la cámara", + "disableCameraShakeText": "Deshabilitar el temblor de la cámara", + "disableThisNotice": "(puedes deshabilitar este aviso en ajustes avanzados)", + "enterPromoCodeText": "Ingresar Código", + "forTestingText": "Nota: estos datos son solo para pruebas y se reiniciarán cuando salga de la app.", + "helpTranslateText": "Las traducciones de ${APP_NAME} son un esfuerzo\napoyado por la comunidad. Si deseas aportar o corregir una\ntraducción, utiliza el siguiente enlace. ¡Gracias de antemano!", + "insecureConnectionsDescriptionText": "no es recomendado, pero quizás permita el multijugador\ndesde paises o conexiones restringidas.", + "insecureConnectionsText": "Usar conexiones inseguras", + "kickIdlePlayersText": "Expulsar a jugadores inactivos", + "kidFriendlyModeText": "Modo Niños (violencia reducida, etc).", + "languageText": "Idioma", + "moddingGuideText": "Guía de Modificación", + "moddingToolsText": "Herramientas de Modificación", + "mustRestartText": "Tienes que reiniciar el juego para que tome efecto.", + "netTestingText": "Prueba de Red", + "resetText": "Reiniciar", + "sendInfoText": "Enviar Información", + "showBombTrajectoriesText": "Mostrar Trayectorias de Las Bombas", + "showDemosWhenIdleText": "Mostrar demostraciones cuando estés inactivo", + "showDeprecatedLoginTypesText": "Mostrar tipos de inicio de sesión obsoletos", + "showDevConsoleButtonText": "Mostrar botón de consola de desarrollador", + "showInGamePingText": "Mostrar ping en el juego", + "showPlayerNamesText": "Mostrar Nombres de Los Jugadores", + "showUserModsText": "Mostrar Carpeta de Mods", + "titleText": "Avanzado", + "translationEditorButtonText": "Editor de Traducción de ${APP_NAME}", + "translationFetchErrorText": "estado de traducción no disponible", + "translationFetchingStatusText": "viendo estado de traducción...", + "translationInformMe": "Informarme cuando mi idioma necesite actualizaciones", + "translationNoUpdateNeededText": "El idioma actual está actualizado; ¡wuju!", + "translationUpdateNeededText": "** ¡¡El idioma actual necesita actualizarse!! **", + "vrTestingText": "Prueba RV" + }, + "shareText": "Compartir", + "sharingText": "Compartiendo...", + "showText": "Mostrar", + "signInForPromoCodeText": "Debes iniciar sesión con tu cuenta para que el código funcione.", + "singleGamePlaylistNameText": "Solo ${GAME}", + "singlePlayerCountText": "1 jugador", + "sizeLargeText": "Grande", + "sizeMediumText": "Mediano", + "sizeSmallText": "Pequeño", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Selección de Personajes", + "Chosen One": "El Elegido", + "Epic": "Juegos en Modo Épico", + "Epic Race": "Carrera Épica", + "FlagCatcher": "Captura la Bandera", + "Flying": "Pensamientos Felices", + "Football": "Fútbol", + "ForwardMarch": "Asalto", + "GrandRomp": "Conquista", + "Hockey": "Hockey", + "Keep Away": "Aléjate", + "Marching": "Evasiva", + "Menu": "Menú Principal", + "Onslaught": "Matanza", + "Race": "Carrera", + "Scary": "Rey de la Colina", + "Scores": "Pantalla de Puntuación", + "Survival": "Eliminación", + "ToTheDeath": "Combate Mortal", + "Victory": "Pantalla de Puntuación Final" + }, + "spaceKeyText": "espacio", + "statsText": "Estadísticas", + "stopRemindingMeText": "Deja de recordarmelo", + "storagePermissionAccessText": "Esto requiere acceso de almacenamiento", + "store": { + "alreadyOwnText": "¡Ya tienes ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Quita los anuncios y las pantallas molestas\n• Desbloquea más ajustes del juego\n• También incluye:", + "buyText": "Comprar", + "charactersText": "Personajes", + "comingSoonText": "Próximamente...", + "extrasText": "Extras", + "holidaySpecialText": "¡Especial de Temporada!", + "howToSwitchCharactersText": "(ve a \"${SETTINGS} -> ${PLAYER_PROFILES}\" para asignar y personalizar los personajes)", + "howToUseIconsText": "(crea perfiles globales de jugador (en la ventana de cuenta) para usarlos)", + "howToUseMapsText": "(usa estos mapas en tus listas de juegos por equipos y todos contra todos)", + "iconsText": "Iconos", + "loadErrorText": "No se pudo cargar la página.\nRevisa tu conexión a internet.", + "loadingText": "cargando", + "mapsText": "Mapas", + "miniGamesText": "MiniJuegos", + "oneTimeOnlyText": "(solo una vez)", + "purchaseAlreadyInProgressText": "Una compra de este artículo se encuentra en progreso.", + "purchaseConfirmText": "¿Comprar ${ITEM}?", + "purchaseNotValidError": "Compra inválida.\nContacte a ${EMAIL} si esto es un error.", + "purchaseText": "Comprar", + "saleBundleText": "¡Paquete en Oferta!", + "saleExclaimText": "¡Oferta!", + "salePercentText": "(${PERCENT}% menos)", + "saleText": "OFERTA", + "searchText": "Buscar", + "teamsFreeForAllGamesText": "Juegos de Equipos / Todos contra Todos", + "totalWorthText": "*** ¡${TOTAL_WORTH} de valor! ***", + "upgradeQuestionText": "¿Mejorar?", + "winterSpecialText": "Especial de Invierno", + "youOwnThisText": "- ya posees esto -" + }, + "storeDescriptionText": "¡Juego de locura de a 8 Jugadores!\n\n¡Revienta a tus amigos (o a la computadora) en un torneo de mini-juegos explosivos como Captura la Bandera, Hockey-Bomba y Combate Mortal Épico en cámara lenta!\n\nControles sencillos y un amplio soporte de controles hacen que sea fácil que 8 personas entren en la acción; ¡incluso puedes usar tus dispositivos móviles como controles a través de la aplicación gratuita de 'Control Remoto BombSquad'!\n\n¡Fuera Bombas!\n\nEcha un vistazo en: www.froemling.net/bombsquad para más información.", + "storeDescriptions": { + "blowUpYourFriendsText": "Revienta a tus amigos.", + "competeInMiniGamesText": "Compite en minijuegos de carreras, vuelo y mucho más.", + "customize2Text": "Personaliza personajes, minijuegos e incluso la banda sonora.", + "customizeText": "Personaliza tus personajes y crea tus propias listas de minijuegos.", + "sportsMoreFunText": "Los deportes son más divertidos con explosivos.", + "teamUpAgainstComputerText": "Forma un equipo contra la computadora." + }, + "storeText": "Tienda", + "submitText": "Enviar", + "submittingPromoCodeText": "Enviando Código...", + "successText": "¡Éxito!", + "supportEmailText": "Si estás teniendo algún problema con la\napp, por favor, manda un email a ${EMAIL}.", + "teamNamesColorText": "Nombres de Equipos/Colores...", + "telnetAccessGrantedText": "Esta versión de prueba ya no está activa; busca una versión nueva.", + "telnetAccessText": "Acceso a Telnet detectado; ¿permitir?", + "testBuildErrorText": "Esta versión de prueba ya no es activa; busca una versión más nueva.", + "testBuildText": "Compilación de Prueba", + "testBuildValidateErrorText": "Incapaz de validar esta compilación de prueba. (¿no tienes conexión a internet?)", + "testBuildValidatedText": "Compilación de Prueba Validada; ¡Disfruta!", + "thankYouText": "¡Gracias por tu ayuda! ¡¡Disfruta el juego!!", + "threeKillText": "¡¡COMBO TRIPLE!!", + "ticketsDescriptionText": "Los tickets pueden ser usados para desbloquear\npersonajes, mapas, minijuegos y más en la tienda.\n\nLos tickets pueden ser encontrados en los cofres\nganados a través de la campaña, torneos y logros.", + "timeBonusText": "Bono de Tiempo", + "timeElapsedText": "Tiempo Transcurrido", + "timeExpiredText": "Tiempo Expirado", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Consejo", + "titleText": "BombSquad", + "titleVRText": "BombSquad RV", + "tokens": { + "getTokensText": "Obtén Fichas", + "notEnoughTokensText": "¡Fichas insuficientes!", + "numTokensText": "${COUNT} Fichas", + "openNowDescriptionText": "Tienes suficiente fichas para \nabrir esto ahora - no tienes\nque esperar.", + "shinyNewCurrencyText": "La brillante nueva moneda de BombSquad.", + "tokenPack1Text": "Paquete de Fichas Pequeña", + "tokenPack2Text": "Paquete de Fichas Mediana", + "tokenPack3Text": "Paquete de Fichas Grande", + "tokenPack4Text": "Paquete de Fichas Jumbo", + "tokensDescriptionText": "Los tokens son usados para acelerar el desbloqueo de\ncofres entre otras funciones del juego y la cuenta.\n\nPuedes ganar fichas en el juego o comprarlas\nen paquetes. O comprar el Pase de Oro para tokens \ninfinitos y nunca más escuchar de ellos de nuevo.", + "youHaveGoldPassText": "Tienes un Pase de Oro.\nTodas las compras de fichas son gratis.\nDisfruta!" + }, + "topFriendsText": "Mejores Amigos", + "tournamentCheckingStateText": "Buscando estado del campeonato; espere por favor...", + "tournamentEndedText": "Este torneo ha acabado. Uno nuevo comenzará pronto.", + "tournamentEntryText": "Entrada Al Torneo", + "tournamentFinalStandingsText": "Clasificación Final", + "tournamentResultsRecentText": "Resultados de Torneos Recientes", + "tournamentStandingsText": "Puestos del Torneo", + "tournamentText": "Torneo", + "tournamentTimeExpiredText": "Tiempo del Torneo Expirado", + "tournamentsDisabledWorkspaceText": "Los torneos están deshabilitados cuando los espacios de trabajo están activos.\nPara volver a habilitar los torneos, deshabilite su espacio de trabajo y reinicie el juego.", + "tournamentsText": "Torneos", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Huesos", + "Butch": "Butch", + "Easter Bunny": "Conejo de Pascua", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Suertudo", + "Mel": "Mel", + "Middle-Man": "Hombre Intermedio", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Papá Noel", + "Snake Shadow": "Serpiente Sombría", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "Entrenamiento de ${GAME}", + "Infinite ${GAME}": "${GAME} Infinito", + "Infinite Onslaught": "Matanza Infinita", + "Infinite Runaround": "Evasiva Infinita", + "Onslaught Training": "Entrenamiento de Matanza", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Fútbol Pro", + "Pro Onslaught": "Matanza Pro", + "Pro Runaround": "Evasiva Pro", + "Rookie ${GAME}": "${GAME} Novato", + "Rookie Football": "Fútbol Novato", + "Rookie Onslaught": "Matanza Novato", + "The Last Stand": "La Batalla Final", + "Uber ${GAME}": "${GAME} Ultra", + "Uber Football": "Fútbol Ultra", + "Uber Onslaught": "Matanza Ultra", + "Uber Runaround": "Evasiva Ultra" + }, + "displayItemNames": { + "${C} Tickets": "${C} Boletos", + "${C} Tokens": "${C} Ficha(s)", + "Chest": "Cofre", + "L1 Chest": "Cofre N1", + "L2 Chest": "Cofre N2", + "L3 Chest": "Cofre N3", + "L4 Chest": "Cofre N4", + "L5 Chest": "Cofre N5", + "L6 Chest": "Cofre N6", + "Unknown Chest": "Cofre Desconocido" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sé el elegido durante el tiempo designado para ganar.\nMata al elegido para convertirte en él.", + "Bomb as many targets as you can.": "Bombardea tantos blancos como puedas.", + "Carry the flag for ${ARG1} seconds.": "Carga la bandera por ${ARG1} segundos.", + "Carry the flag for a set length of time.": "Carga la bandera por un determinado tiempo.", + "Crush ${ARG1} of your enemies.": "Elimina ${ARG1} de tus enemigos.", + "Defeat all enemies.": "Acaba con todo lo que se mueva.", + "Dodge the falling bombs.": "Esquiva las bombas.", + "Final glorious epic slow motion battle to the death.": "Gloriosa batalla final en épica cámara lenta hasta la muerte.", + "Gather eggs!": "¡Recolecta huevos!", + "Get the flag to the enemy end zone.": "Lleva la bandera enemiga a tu zona.", + "How fast can you defeat the ninjas?": "¿Cuán rápido puedes derrotar a los ninjas?", + "Kill a set number of enemies to win.": "Mata a un número determinado de enemigos para ganar.", + "Last one standing wins.": "El último en pie gana.", + "Last remaining alive wins.": "El último en quedar vivo gana.", + "Last team standing wins.": "El último equipo en pie gana.", + "Prevent enemies from reaching the exit.": "Evita que los enemigos lleguen a la salida.", + "Reach the enemy flag to score.": "Toca la bandera enemiga para anotar.", + "Return the enemy flag to score.": "Devuelve la bandera enemiga para anotar.", + "Run ${ARG1} laps.": "Corre ${ARG1} vueltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corre ${ARG1} vueltas. Todo tu equipo debe cruzar la meta.", + "Run 1 lap.": "Corre 1 vuelta.", + "Run 1 lap. Your entire team has to finish.": "Corre 1 vuelta. Todo tu equipo debe cruzar la meta.", + "Run real fast!": "¡Corre muy rápido!", + "Score ${ARG1} goals.": "Anota ${ARG1} goles.", + "Score ${ARG1} touchdowns.": "Anota ${ARG1} touchdowns.", + "Score a goal.": "Anota un gol.", + "Score a touchdown.": "Anota un touchdown.", + "Score some goals.": "Anota unos goles.", + "Secure all ${ARG1} flags.": "Asegura las ${ARG1} banderas.", + "Secure all flags on the map to win.": "Asegura todas las banderas en el mapa para ganar.", + "Secure the flag for ${ARG1} seconds.": "Asegura la bandera por ${ARG1} segundos.", + "Secure the flag for a set length of time.": "Asegura la bandera por un tiempo determinado.", + "Steal the enemy flag ${ARG1} times.": "Roba la bandera enemiga ${ARG1} veces.", + "Steal the enemy flag.": "Roba la bandera enemiga.", + "There can be only one.": "Solo puede haber uno.", + "Touch the enemy flag ${ARG1} times.": "Toca la bandera enemiga ${ARG1} veces.", + "Touch the enemy flag.": "Toca la bandera enemiga.", + "carry the flag for ${ARG1} seconds": "carga la bandera por ${ARG1} segundos.", + "kill ${ARG1} enemies": "mata a ${ARG1} enemigos", + "last one standing wins": "el último en pie gana", + "last team standing wins": "el último equipo en pie gana", + "return ${ARG1} flags": "devuelve ${ARG1} banderas", + "return 1 flag": "devuelve 1 bandera", + "run ${ARG1} laps": "corre ${ARG1} vueltas", + "run 1 lap": "corre 1 vuelta", + "score ${ARG1} goals": "anota ${ARG1} goles", + "score ${ARG1} touchdowns": "anota ${ARG1} touchdowns", + "score a goal": "anota un gol", + "score a touchdown": "anota un touchdown", + "secure all ${ARG1} flags": "asegura las ${ARG1} banderas", + "secure the flag for ${ARG1} seconds": "asegura la bandera por ${ARG1} segundos", + "touch ${ARG1} flags": "toca ${ARG1} banderas", + "touch 1 flag": "toca 1 bandera" + }, + "gameNames": { + "Assault": "Asalto", + "Capture the Flag": "Captura la Bandera", + "Chosen One": "El Elegido", + "Conquest": "Conquista", + "Death Match": "Combate Mortal", + "Easter Egg Hunt": "Búsqueda de Huevos de Pascua", + "Elimination": "Eliminación", + "Football": "Fútbol", + "Hockey": "Hockey", + "Keep Away": "Aléjate", + "King of the Hill": "Rey de la Colina", + "Meteor Shower": "Lluvia de Meteoritos", + "Ninja Fight": "Pelea Ninja", + "Onslaught": "Matanza", + "Race": "Carrera", + "Runaround": "Evasiva", + "Target Practice": "Blanco de Práctica", + "The Last Stand": "La Batalla Final" + }, + "inputDeviceNames": { + "Keyboard": "Teclado", + "Keyboard P2": "Teclado P2" + }, + "languages": { + "Arabic": "Árabe", + "Belarussian": "Bielorruso", + "Chinese": "Chino - Simplificado ", + "ChineseSimplified": "Chino Simplificado", + "ChineseTraditional": "Chino Tradicional (Zhōngwén)", + "Croatian": "Croata", + "Czech": "Checo", + "Danish": "Danés", + "Dutch": "Holandés", + "English": "Inglés", + "Esperanto": "Esperanto", + "Filipino": "Filipino", + "Finnish": "Finlandés", + "French": "Francés", + "German": "Alemán", + "Gibberish": "Algarabía", + "Greek": "Griego", + "Hindi": "Hindi", + "Hungarian": "Húngaro", + "Indonesian": "Indonesio", + "Italian": "Italiano", + "Japanese": "Japonés", + "Korean": "Coreano", + "Malay": "Malayo", + "Persian": "Persa", + "PirateSpeak": "Habla Pirata", + "Polish": "Polaco", + "Portuguese": "Portugués", + "PortugueseBrazil": "Portugués - Brazil", + "PortuguesePortugal": "Portugués - Portugal", + "Romanian": "Rumano", + "Russian": "Ruso", + "Serbian": "Serbio", + "Slovak": "Eslovaco", + "Spanish": "Español", + "SpanishLatinAmerica": "Español - Latinoamerica", + "SpanishSpain": "Español - España", + "Swedish": "Sueco", + "Tamil": "Tamil", + "Thai": "Tailandés", + "Turkish": "Turco", + "Ukrainian": "Ucraniano", + "Venetian": "Veneciano", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronce", + "Diamond": "Diamante", + "Gold": "Oro", + "Silver": "Plata" + }, + "mapsNames": { + "Big G": "Gran G", + "Bridgit": "Puentecito", + "Courtyard": "Patio Real", + "Crag Castle": "Castillo del Risco", + "Doom Shroom": "Hongo de La Muerte", + "Football Stadium": "Estadio de Fútbol", + "Happy Thoughts": "Pensamientos Felices", + "Hockey Stadium": "Estadio de Hockey", + "Lake Frigid": "Lago Frígido", + "Monkey Face": "Cara de Mono", + "Rampage": "Medio Tubo", + "Roundabout": "Rotonda", + "Step Right Up": "Paso Al Frente", + "The Pad": "La Plataforma", + "Tip Top": "Punta Superior", + "Tower D": "Torre D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Solo Épico", + "Just Sports": "Solo Deportes" + }, + "scoreNames": { + "Flags": "Banderas", + "Goals": "Goles", + "Score": "Puntaje", + "Survived": "Sobrevivió", + "Time": "Tiempo", + "Time Held": "Tiempo Mantenido" + }, + "serverResponses": { + "A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta.", + "A reward has already been given for that address.": "Ya se le ha dado una recompensa a esa dirección.", + "Account linking successful!": "¡Vinculación de cuenta exitosa!", + "Account unlinking successful!": "¡Desvinculación de cuenta exitosa!", + "Accounts are already linked.": "Las cuentas ya están vinculadas.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No se pudo verificar la vista del anuncio. \nPor favor asegúrese de estar ejecutando una versión oficial y actualizada del juego.", + "An error has occurred; (${ERROR})": "Un error ha ocurrido; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Un error ha ocurrido; por favor contacte al soporte. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Un error ha ocurrido; por favor contacta a support@froemling.net.", + "An error has occurred; please try again later.": "Un error ha ocurrido; por favor intentalo más tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres vincular estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!", + "BombSquad Pro unlocked!": "¡BombSquad Pro desbloqueado!", + "Can't link 2 accounts of this type.": "No se pueden vincular 2 cuentas de este tipo.", + "Can't link 2 diamond league accounts.": "No se pueden vincular 2 cuentas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo vincular; sobrepasaría el máximo de cuentas vinculadas de ${COUNT}.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trampa detectada; puntajes y premios suspendidos por ${COUNT} días.", + "Could not establish a secure connection.": "No se pudo establecer una conexión segura.", + "Daily maximum reached.": "Máximo diario conseguido.", + "Daily sign-in reward": "Recompensa por iniciar sesión diariamente", + "Entering tournament...": "Entrando al torneo...", + "Invalid code.": "Código inválido.", + "Invalid payment; purchase canceled.": "Pago inválido; compra cancelada.", + "Invalid promo code.": "Código promocional inválido.", + "Invalid purchase.": "Compra inválida.", + "Invalid tournament entry; score will be ignored.": "Entrada de torneo inválida; el puntaje será ignorado.", + "Item unlocked!": "¡Artículo desbloqueado!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACIÓN DENEGADA. ${ACCOUNT} contiene\ndatos significativos que podrían PERDERSE EN SU TOTALIDAD.\nPuedes vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Vincular ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?", + "Longer streaks lead to better rewards.": "Rachas mayores significan Mejores recompensas.", + "Max number of playlists reached.": "Número máximo de listas de juegos alcanzado.", + "Max number of profiles reached.": "Número máximo de perfiles alcanzado.", + "Maximum friend code rewards reached.": "Máximo de premios por códigos de amigos alcanzado.", + "Message is too long.": "El mensaje es muy largo.", + "New tournament result!": "¡Nuevo resultado del torneo!", + "No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor inténtelo de nuevo más tarde.", + "No slots available. Free a slot and try again.": "No hay ranuras libres. Libere una e intentélo de nuevo.", + "Profile \"${NAME}\" upgraded successfully.": "El perfil \"${NAME}\" se ha mejorado satisfactoriamente.", + "Profile could not be upgraded.": "El perfil no pudo ser mejorado.", + "Purchase successful!": "¡Compra exitosa!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} boletos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} boletos.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funcionalidad del servidor ya no es compatible en esta versión del juego;\nActualiza a una versión más reciente.", + "Sorry, there are no uses remaining on this code.": "Disculpe, pero no quedan usos disponibles de este código.", + "Sorry, this code has already been used.": "Disculpe, este código ya ha sido usado.", + "Sorry, this code has expired.": "Disculpe, este código ha expirado.", + "Sorry, this code only works for new accounts.": "Disculpe, este código solo funciona para cuentas nuevas.", + "Sorry, this has expired.": "Disculpe, esto ya ha expirado.", + "Still searching for nearby servers; please try again soon.": "Todavía buscando por servidores cercanos; inténtelo de nuevo más tarde.", + "Streak: ${NUM} days": "Racha de: ${NUM} días", + "Temporarily unavailable; please try again later.": "Temporalmente indisponible; por favor inténtalo más tarde.", + "The tournament ended before you finished.": "El torneo terminó antes de que terminaras.", + "This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desvinculada por ${NUM} día(s).", + "This code cannot be used on the account that created it.": "Este código no puede ser usado en la misma cuenta que ha sido creado.", + "This is currently unavailable; please try again later.": "Esto no está disponible actualmente; por favor inténtelo más tarde.", + "This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más reciente.", + "Tournaments disabled due to rooted device.": "Los torneos han sido deshabilitados debido a que tú dispositivo esta rooteado.", + "Tournaments require ${VERSION} or newer": "Los torneos requieren la versión ${VERSION} o más nueva", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desvincular ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán.\n(excepto los logros en algunos casos)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: Se han emitido reclamaciones de hackeos contra tu cuenta.\nLas cuentas que se encuentren hackeando serán baneadas. Por favor juega limpio.", + "Wait reduced!": "Espera reducida!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Advertencia: Esta versión del juego está limitada a los datos de cuenta antiguos; es posible que falten datos o que estén desactualizados.\nPor favor actualiza a una versión más reciente del juego para ver los datos más recientes de tu cuenta.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres vincular tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!", + "You already own this!": "¡Ya posees esto!", + "You can join in ${COUNT} seconds.": "Puedes unirte en ${COUNT} segundo(s).", + "You don't have enough tickets for this!": "¡No tienes suficientes boletos para esto!", + "You don't own that.": "No posees eso.", + "You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} boletos!", + "You got ${COUNT} tokens!": "¡Obtuviste ${COUNT} ficha(s)!", + "You got a ${ITEM}!": "¡Conseguiste un ${ITEM}!", + "You got a chest!": "¡Obtuviste un cofre!", + "You got an achievement reward!": "¡Obtuviste una recompensa por tu logro!", + "You have been promoted to a new league; congratulations!": "Has sido ascendido a una nueva liga; ¡felicitaciones!", + "You lost a chest! (All your chest slots were full)": "¡Perdiste un cofre! (Todas tus ranuras de cofres estaban llenas).", + "You must update the app to view this.": "Debes actualizar la aplicación para ver esto.", + "You must update to a newer version of the app to do this.": "Debes actualizar la aplicación a una versión más reciente para hacer esto.", + "You must update to the newest version of the game to do this.": "Necesitas actualizar a la versión más reciente del juego para hacer esto.", + "You must wait a few seconds before entering a new code.": "Debes esperar unos segundos antes de ingresar un código nuevo.", + "You placed #${RANK} in a tournament!": "Quedaste en el puesto #${RANK} en un torneo!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Quedaste en la posición #${RANK} en el campeonato. ¡Gracias por jugar!", + "Your account was rejected. Are you signed in?": "Tu cuenta fue rechazada. ¿Estás registrado?", + "Your ad views are not registering. Ad options will be limited for a while.": "Tus vistas de anuncios no se están registrando. Las opciones de anuncios serán limitadas por un tiempo.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo.", + "Your friend code was used by ${ACCOUNT}": "Tu código de amigo fue usado por ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuto", + "1 Second": "1 Segundo", + "10 Minutes": "10 Minutos", + "2 Minutes": "2 Minutos", + "2 Seconds": "2 Segundos", + "20 Minutes": "20 Minutos", + "4 Seconds": "4 Segundos", + "5 Minutes": "5 Minutos", + "8 Seconds": "8 Segundos", + "Allow Negative Scores": "Permitir Puntajes Negativos", + "Balance Total Lives": "Repartir Vidas Totales", + "Bomb Spawning": "Aparecer Bombas", + "Chosen One Gets Gloves": "El Elegido Consigue Guantes de Boxeo", + "Chosen One Gets Shield": "El Elegido Consigue Electro-Escudo", + "Chosen One Time": "Tiempo del Elegido", + "Enable Impact Bombs": "Habilitar Insta-Bombas", + "Enable Triple Bombs": "Habilitar Bombas Triples", + "Entire Team Must Finish": "Todo el Equipo Debe Terminar", + "Epic Mode": "Modo Épico", + "Flag Idle Return Time": "Tiempo de Retorno de Bandera Inactiva", + "Flag Touch Return Time": "Retorno de Bandera con Toque", + "Hold Time": "Retención", + "Kills to Win Per Player": "Asesinatos para Ganar Por Jugador", + "Laps": "Vueltas", + "Lives Per Player": "Vidas Por Jugador", + "Long": "Largo", + "Longer": "Más Largo", + "Mine Spawning": "Aparecer Minas", + "No Mines": "Sin Minas", + "None": "Ninguno", + "Normal": "Normal", + "Pro Mode": "Modo Pro", + "Respawn Times": "Tiempo de Reaparición", + "Score to Win": "Puntos para Ganar", + "Short": "Corto", + "Shorter": "Más Corto", + "Solo Mode": "Modo Solitario", + "Target Count": "Número de Objetivos", + "Time Limit": "Límite de Tiempo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} ha sido descalificado porque ${PLAYER} se ha ido", + "Killing ${NAME} for skipping part of the track!": "¡${NAME} Murió por saltarse un pedazo de la pista!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / spam de botones te noqueará." + }, + "teamNames": { + "Bad Guys": "Chicos Malos", + "Blue": "Azul", + "Good Guys": "Chicos Buenos", + "Red": "Rojo" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un corre-salta-gira-golpea perfecto puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.", + "Always remember to floss.": "Siempre acuérdate de cepillar tus dientes.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea perfiles para \ntu y tus amigos \ncon \ntus nombres preferidos y\napariencias en vez de usar unos aleatorios.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Las cajas de maldición te convierten en una bomba de tiempo.\nLa única cura es agarrar rápidamente un botiquín.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de sus apariencias, las habilidades de todos los personajes\nson idénticas, así que escoge el que más te guste a ti.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No eres invencible con ese electro-escudo; todavía puedes caerte de un acantilado.", + "Don't run all the time. Really. You will fall off cliffs.": "No corras todo el tiempo. En serio. Te vas a caer.", + "Don't spin for too long; you'll become dizzy and fall.": "No gires por un largo tiempo; puedes marearte y caer.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Mantén cualquier botón para correr. (Los gatillos son para eso si los tienes)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén presionado cualquier botón para correr. Llegarás a lugares más rápido\npero no girarás muy bien, así que cuidado con los acantilados.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de Hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te recoge, dale un golpe y te soltará.\nTambién funciona en la vida real.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si no tienes suficientes controles, instala la aplicación '${REMOTE_APP_NAME}'\nen tus dispositivos móviles para usarlos como controles.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Si te adhieres a una bomba pegajosa, salta y da muchas vueltas. Es posible que sacudas\nla bomba pegada o sin nada más tus últimos momentos serán entretenidos.", + "If you kill an enemy in one hit you get double points for it.": "Si matas a un enemigo de un solo golpe obtendrás puntos dobles.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si tomaste una maldición, tu única esperanza es\nencontrar un botiquín en tus últimos segundos.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Si te quedas quieto, estás frito. Corre y esquiva para sobrevivir...", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si tienes muchos jugadores yendo y viniendo, activa 'expulsar jugadores inactivos'\nen ajustes en caso de que alguien se olvide de abandonar el juego.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o la \"Resolución\" en Ajustes->Gráficos", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si la imagen va lenta, intenta reducir la resolución\no los visuales en los ajustes gráficos del juego.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Captura la Bandera, la bandera tuya debe estar en tu base para que anotes.\nSi el otro equipo está a punto de anotar, robar su bandera evitará que anoten.", + "In hockey, you'll maintain more speed if you turn gradually.": "En hockey, mantendrás tu impulso si giras gradualmente.", + "It's easier to win with a friend or two helping.": "Es más fácil ganar con un amigo o dos ayudando.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Salta antes de tirar una bomba para que alcance lugares altos.", + "Land-mines are a good way to stop speedy enemies.": "Las minas terrestres son una buena manera para detener enemigos veloces.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muchas cosas se pueden recoger y lanzar, incluyendo a otros jugadores.\nArroja a tus enemigos por los precipicios. Te sentirás mejor.", + "No, you can't get up on the ledge. You have to throw bombs.": "No, no puedes subir a la cornisa. Tienes que lanzar bombas.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Los jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes conectar o quitar controles en cualquier momento.", + "Practice using your momentum to throw bombs more accurately.": "Practica usando tu impulso para tirar bombas con más precisión.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Los golpes hacen más daño cuanto más rápido se mueven tus puños,\nasí que intenta correr, saltar y girar como un loco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba para 'latiguearla' y lanzarla lejos.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimina un gran cantidad de enemigos\nal detonar una bomba cerca de una caja TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La cabeza es la zona más vulnerable, una bomba pegajosa\na la cabeza usualmente significa game-over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nivel no tiene fin, pero un alto puntaje aquí\nte hará ganar el respeto eterno por todo el mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "La fuerza de tiro se basa en la dirección que estás sosteniendo.\nPara arrojar algo justo delante de ti, no sostengas ninguna dirección.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "¿Cansado de la pista de audio? ¡Reemplázala con tu música!\nVe a Ajustes->Audio->Banda Sonora", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Intenta 'Cocinar' bombas por un segundo o dos antes de tirarlas.", + "Try tricking enemies into killing eachother or running off cliffs.": "Engaña a tus enemigos para que se eliminen entre sí o para que corran a los acantilados.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Usa el botón de 'recoger' para agarrar la bandera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Azota de un lado a otro para conseguir más distancia en tus tiros.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Puedes 'dirigir' tus golpes girando a la izquierda o derecha. Esto\nes útil para tirar a los enemigos al vacío o para anotar en el hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Puedes saber si una bomba va a explotar basado en el \ncolor de las chispas de su mecha: amarillo...naranja...rojo...¡BOOM!", + "You can throw bombs higher if you jump just before throwing.": "Puedes tirar bombas más alto si saltas justo antes de tirarlas.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Te haces daño si golpeas tu cabeza contra cosas, \nasí que trata de no golpear tu cabeza contra cosas.", + "Your punches do much more damage if you are running or spinning.": "Tus golpes hacen mucho más daño si estás corriendo o girando." + } + }, + "trophiesRequiredText": "Esto requiere al menos ${NUMBER} trofeos.", + "trophiesText": "Trofeos", + "trophiesThisSeasonText": "Trofeos Esta Temporada", + "tutorial": { + "cpuBenchmarkText": "Corriendo tutorial en velocidad ridícula (pruebas de velocidad de CPU)", + "phrase01Text": "¡Hey, hola!", + "phrase02Text": "¡Bienvenido a ${APP_NAME}!", + "phrase03Text": "Te dare algunos consejos para controlar tu personaje:", + "phrase04Text": "Muchas cosas en ${APP_NAME} se basan mayoritariamente en FÍSICAS.", + "phrase05Text": "Por ejemplo, cuando golpeas...", + "phrase06Text": "..el daño se basa en la velocidad de tus puños.", + "phrase07Text": "¿Ves? No nos estábamos moviendo, así que eso apenas lastimó a ${NAME}.", + "phrase08Text": "Ahora vamos a saltar y girar para conseguir más velocidad.", + "phrase09Text": "Ah, mucho mejor.", + "phrase10Text": "Correr también ayuda.", + "phrase11Text": "Mantén pulsado CUALQUIER botón para correr.", + "phrase12Text": "Para golpes extra-asombrosos, intenta correr Y girar.", + "phrase13Text": "Ups; lo siento por eso ${NAME}.", + "phrase14Text": "Puedes recoger y lanzar cosas como banderas.. o ${NAME}.", + "phrase15Text": "Por último, hay bombas.", + "phrase16Text": "Lanzar bombas requiere práctica.", + "phrase17Text": "¡Auch! Ese no fue un buen tiro.", + "phrase18Text": "Moverte ayuda a lanzarlas más lejos.", + "phrase19Text": "Saltar ayuda a lanzarlas más alto.", + "phrase20Text": "\"Latiguea\" tus bombas para hacer lanzamientos aún más lejanos.", + "phrase21Text": "Hacer que exploten donde tú quieres puede ser complicado.", + "phrase22Text": "Rayos.", + "phrase23Text": "Intentemos \"cocinar\" la mecha por un segundo o dos.", + "phrase24Text": "¡Hurra! Así es como se hace.", + "phrase25Text": "Bueno, eso es todo.", + "phrase26Text": "¡Ahora ve por ellos, campeón!", + "phrase27Text": "Recuerda tu entrenamiento, ¡y VOLVERÁS con vida!", + "phrase28Text": "...o a lo mejor...", + "phrase29Text": "¡Buena Suerte!", + "randomName1Text": "Federico", + "randomName2Text": "Enrique", + "randomName3Text": "Guillermo", + "randomName4Text": "Carlos", + "randomName5Text": "Felipe", + "skipConfirmText": "¿Realmente quieres omitir el tutorial? Toca o presiona para confirmar.", + "skipVoteCountText": "${COUNT}/${TOTAL} votos para saltarse el tutorial", + "skippingText": "saltando el tutorial...", + "toSkipPressAnythingText": "(pulsa cualquier botón para omitir el tutorial)" + }, + "twoKillText": "¡COMBO DOBLE!", + "uiScaleText": "Escala de Interfaz de Usuario", + "unavailableText": "no disponible", + "unclaimedPrizesText": "Tienes premios sin reclamar!", + "unconfiguredControllerDetectedText": "Control desconfigurado detectado:", + "unlockThisInTheStoreText": "Esto debe ser desbloqueado en la tienda.", + "unlockThisProfilesText": "Para crear más de ${NUM} cuentas, necesitas:", + "unlockThisText": "Para desbloquear esto, necesitas:", + "unsupportedControllerText": "Lo sentimos, el control \"${NAME}\" no es compatible.", + "unsupportedHardwareText": "Disculpe, este dispositivo no soporta esta compilación del juego.", + "upFirstText": "A continuación:", + "upNextText": "A continuación en el juego ${COUNT}:", + "updatingAccountText": "Actualizando tu cuenta...", + "upgradeText": "Mejorar", + "upgradeToPlayText": "Desbloquea \"${PRO}\" en la tienda para jugar esto.", + "useDefaultText": "Usar Por Defecto", + "userSystemScriptsCreateText": "Crear Scripts del Sistema del Usuario", + "userSystemScriptsDeleteText": "Eliminar Scripts del Sistema del Usuario", + "usesExternalControllerText": "Este juego usa un control externo como entrada.", + "usingItunesText": "Usando Aplicación de Música para la banda sonora...", + "v2AccountLinkingInfoText": "Para vincular cuentas V2, usa el botón \"Administrar Cuenta\".", + "v2AccountRequiredText": "Esto requiere una cuenta V2. Actualice su cuenta e inténtelo de nuevo.", + "validatingTestBuildText": "Validando Compilación de Prueba...", + "viaText": "a través de", + "victoryText": "¡Victoria!", + "voteDelayText": "No puedes iniciar otra votación por ${NUMBER} segundo(s)", + "voteInProgressText": "Ya hay una votación en progreso.", + "votedAlreadyText": "Ya votaste", + "votesNeededText": "${NUMBER} voto(s) necesario(s)", + "vsText": "vs.", + "waitingForHostText": "(esperando a que ${HOST} continúe)", + "waitingForPlayersText": "esperando jugadores para unirse...", + "waitingInLineText": "Esperando en línea (la partida está llena)...", + "watchAVideoText": "Ver un Vídeo", + "watchAnAdText": "Ver un Anuncio", + "watchWindow": { + "deleteConfirmText": "¿Borrar \"${REPLAY}\"?", + "deleteReplayButtonText": "Borrar\nRepetición", + "myReplaysText": "Mis Repeticiones", + "noReplaySelectedErrorText": "Ninguna Repetición Seleccionada", + "playbackSpeedText": "Velocidad de Reproducción: ${SPEED}", + "renameReplayButtonText": "Renombrar\nRepetición", + "renameReplayText": "Renombrar \"${REPLAY}\" a:", + "renameText": "Renombrar", + "replayDeleteErrorText": "Error borrando la repetición.", + "replayNameText": "Nombre de la Repetición", + "replayRenameErrorAlreadyExistsText": "Una repetición con ese nombre ya existe.", + "replayRenameErrorInvalidName": "No se puede renombrar la repetición; nombre inválido.", + "replayRenameErrorText": "Error renombrando repetición.", + "sharedReplaysText": "Compartir repeticiones", + "titleText": "Ver", + "watchReplayButtonText": "Ver\nRepetición" + }, + "waveText": "Oleada", + "wellSureText": "¡Pues Claro!", + "whatIsThisText": "¿Qué es esto?", + "winsPlayerText": "¡${NAME} Gana!", + "winsTeamText": "¡${NAME} Gana!", + "winsText": "¡Ganó ${NAME}!", + "workspaceSyncErrorText": "Error al sincronizar ${WORKSPACE}. Mira el registro para más detalles.", + "workspaceSyncReuseText": "No se puede sincronizar ${WORKSPACE}. Reusando la versión previamente sincronizada.", + "worldScoresUnavailableText": "Puntuaciones mundiales no disponibles.", + "worldsBestScoresText": "Mejores Puntuaciones Mundiales", + "worldsBestTimesText": "Mejores Tiempos Mundiales", + "yesAllowText": "¡Sí, Permitir!", + "yourBestScoresText": "Tus Mejores Puntajes", + "yourBestTimesText": "Tus Mejores Tiempos", + "yourPrizeText": "Tu premio:" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/spanishspain.json b/dist/ba_data/data/languages/spanishspain.json new file mode 100644 index 00000000..e162342e --- /dev/null +++ b/dist/ba_data/data/languages/spanishspain.json @@ -0,0 +1,1980 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Los nombres de las cuentas no pueden tener emojis o otros caracteres especiales", + "accountsText": "Cuentas", + "achievementProgressText": "Logros: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progreso de la Campaña [Difícil]: ${PROGRESS}", + "changeOncePerSeason": "Solo puedes cambiar esto una vez por temporada.", + "changeOncePerSeasonError": "Debes esperar hasta la siguiente temporada para cambiar esto de nuevo (en ${NUM} día/s)", + "createAnAccountText": "Crear una Cuenta", + "customName": "Nombre Personalizado", + "deleteAccountText": "Eliminar Cuenta", + "googlePlayGamesAccountSwitchText": "Si quieres usar una cuenta de Google diferente,\nusa la app Google Play Juegos para cambiarla.", + "linkAccountsEnterCodeText": "Introducir Código", + "linkAccountsGenerateCodeText": "Generar Código", + "linkAccountsInfoText": "(comparta el progreso a través de diferentes plataformas)", + "linkAccountsInstructionsNewText": "Para vincular dos cuentas, genera un código en la primera \ne introduzca ese código en la segunda. Los datos de \nla segunda cuenta serán compartidos entre ambos.\n(Los datos de la primera cuenta se perderán).\n\nPuedes vincular hasta ${COUNT} cuentas.\n\nIMPORTANTE: Solo vincula cuentas tuyas; \nSi vinculas cuentas de tus amigos no serán \ncapaces de jugar en línea al mismo tiempo.", + "linkAccountsText": "Vincular Cuentas", + "linkedAccountsText": "Cuentas Vinculadas:", + "manageAccountText": "Administrar Cuenta", + "nameChangeConfirm": "¿Quieres cambiar El nombre de tu cuenta A ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso en el modo cooperativo y \ntus puntuaciones locales (a excepción de tus boletos).\nEsto no puede deshacerse. ¿Estás seguro?", + "resetProgressConfirmText": "Esto reiniciará tu progreso en el modo cooperativo, \nlogros y puntuaciones locales (pero, no tus tickets).\nLos cambios no se pueden deshacer.\n¿Estás seguro?", + "resetProgressText": "Reiniciar Progreso", + "setAccountName": "Establecer Nombre de Cuenta", + "setAccountNameDesc": "Selecciona el nombre a mostrar para tu cuenta. \nPuedes usar el nombre de tu cuenta asociada\no crear un nombre único personalizado.", + "signInInfoText": "Inicia sesión para obtener boletos, competir en línea\ny compartir tu progreso a través de tus dispositivos.", + "signInText": "Iniciar Sesión", + "signInWithAnEmailAddressText": "Iniciar sesión con correo electronico", + "signInWithDeviceInfoText": "(una cuenta automática disponible únicamente en este dispositivo)", + "signInWithDeviceText": "Iniciar sesión con cuenta del dispositivo", + "signInWithText": "Iniciar sesion con ${SERVICE}", + "signInWithV2InfoText": "(una cuenta que funciona en todas las plataformas)", + "signInWithV2Text": "Iniciar sesión con una cuenta de ${APP_NAME}", + "signOutText": "Cerrar Sesión", + "signingInText": "Iniciando sesión...", + "signingOutText": "Cerrando sesión...", + "ticketsText": "Boletos: ${COUNT}", + "titleText": "Cuenta", + "unlinkAccountsInstructionsText": "Selecciona una cuenta para desvincular", + "unlinkAccountsText": "Desvincular Cuentas", + "unlinkLegacyV1AccountsText": "Desvincular Cuentas (V1) Heredadas", + "v2LinkInstructionsText": "Usa este enlace para crear una cuenta o para iniciar sesión.", + "viaAccount": "(cuenta vía ${NAME})", + "youAreSignedInAsText": "Has iniciado sesión como:" + }, + "achievementChallengesText": "Desafios de los Logros", + "achievementText": "Logro", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mata a 3 chicos malos con TNT", + "descriptionComplete": "Mató a 3 chicos malos con TNT", + "descriptionFull": "Mata a 3 chicos malos con TNT en ${LEVEL}", + "descriptionFullComplete": "Mató a 3 chicos malos con TNT en ${LEVEL}", + "name": "La Dinamita Hace Boom" + }, + "Boxer": { + "description": "Gana sin usar bombas", + "descriptionComplete": "Ganó sin usar bombas", + "descriptionFull": "Completa ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completó ${LEVEL} sin usar bombas", + "name": "Boxeador" + }, + "Dual Wielding": { + "descriptionFull": "Conecta 2 controles (de hardware o aplicación)", + "descriptionFullComplete": "Conectó 2 controles (de hardware o aplicación)", + "name": "Doble Empuñadura" + }, + "Flawless Victory": { + "description": "Gana sin ser lastimado", + "descriptionComplete": "Ganó sin ser lastimado", + "descriptionFull": "Gana ${LEVEL} sin ser lastimado", + "descriptionFullComplete": "Ganó ${LEVEL} sin ser golpeado", + "name": "Victoria Impecable" + }, + "Free Loader": { + "descriptionFull": "Empieza un juego de Todos-Contra-Todos con 2 o más jugadores", + "descriptionFullComplete": "Empezó un juego de Todos-Contra-Todos con 2 o más jugadores", + "name": "Cargador Libre" + }, + "Gold Miner": { + "description": "Mata a 6 chicos malos con minas terrestres", + "descriptionComplete": "Mató a 6 chicos malos con minas terrestres", + "descriptionFull": "Mata a 6 chicos malos con minas terrestres en ${LEVEL}", + "descriptionFullComplete": "Mató a 6 chicos malos con minas terrestres en ${LEVEL}", + "name": "Minero de Oro" + }, + "Got the Moves": { + "description": "Gana sin usar golpes ni bombas", + "descriptionComplete": "Ganó sin usar golpes ni bombas", + "descriptionFull": "Gana ${LEVEL} sin golpes ni bombas", + "descriptionFullComplete": "Ganó ${LEVEL} sin golpes ni bombas", + "name": "Tengo los Movimientos" + }, + "In Control": { + "descriptionFull": "Conecta un control (de hardware o aplicación)", + "descriptionFullComplete": "Conectó un control. (de hardware o aplicación)", + "name": "En Control" + }, + "Last Stand God": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Dios de la guerra En ${LEVEL}" + }, + "Last Stand Master": { + "description": "Anota 250 puntos", + "descriptionComplete": "Anotó 250 puntos", + "descriptionFull": "Anota 250 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 250 puntos en ${LEVEL}", + "name": "Maestro de ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotó 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Mine Games": { + "description": "Mata a 3 chicos malos con minas terrestres", + "descriptionComplete": "Mató a 3 chicos malos con minas terrestres", + "descriptionFull": "Mata a 3 chicos malos con minas terrestres en ${LEVEL}", + "descriptionFullComplete": "Mató a 3 chicos con minas terrestres en ${LEVEL}", + "name": "Juegos de Minas" + }, + "Off You Go Then": { + "description": "Arroja a 3 chicos malos fuera del mapa", + "descriptionComplete": "Arrojó a 3 chicos malos fuera del mapa", + "descriptionFull": "Arroja a 3 chicos malos fuera del mapa en ${LEVEL}", + "descriptionFullComplete": "Arrojó a 3 chicos malos fuera del mapa en ${LEVEL}", + "name": "Te Vas Abajo Entonces" + }, + "Onslaught God": { + "description": "Anota 5000 puntos", + "descriptionComplete": "Anotó 5000 puntos", + "descriptionFull": "Anota 5000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 5000 puntos en ${LEVEL}", + "name": "Dios de La ${LEVEL}" + }, + "Onslaught Master": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotó 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Maestro de La ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Derroto todas las oleadas.", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Mago de La ${LEVEL}" + }, + "Precision Bombing": { + "description": "Gana sin potenciadores", + "descriptionComplete": "Ganó sin potenciadores", + "descriptionFull": "Gana ${LEVEL} sin potenciadores", + "descriptionFullComplete": "Ganó ${LEVEL} sin potenciadores", + "name": "Bombardeo con Precisión" + }, + "Pro Boxer": { + "description": "Gana sin usar bombas", + "descriptionComplete": "Ganó sin usar bombas", + "descriptionFull": "Completa ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completó ${LEVEL} sin usar bombas", + "name": "Boxeador Profesional" + }, + "Pro Football Shutout": { + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo en ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganó el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas de ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas de ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Completa todas las oleadas", + "descriptionComplete": "Completó todas las oleadas", + "descriptionFull": "Completa todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo en ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganó el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Runaround God": { + "description": "Anota 2000 puntos", + "descriptionComplete": "Anotó 2000 puntos", + "descriptionFull": "Anota 2000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 2000 puntos en ${LEVEL}", + "name": "Dios de La ${LEVEL}" + }, + "Runaround Master": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotó 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 500 puntos en ${LEVEL}", + "name": "Maestro de La ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotó 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotó 1000 puntos en ${LEVEL}", + "name": "Mago de La ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Comparte exitosamente el juego con un amigo", + "descriptionFullComplete": "Compartió exitosamente el juego con un amigo", + "name": "Compartir es querer." + }, + "Stayin' Alive": { + "description": "Gana sin morir", + "descriptionComplete": "Ganó sin morir", + "descriptionFull": "Gana ${LEVEL} sin morir", + "descriptionFullComplete": "Ganó ${LEVEL} sin morir", + "name": "Sobreviviendo" + }, + "Super Mega Punch": { + "description": "Inflige 100% de daño con un solo golpe", + "descriptionComplete": "Infligió 100% de daño con un solo golpe", + "descriptionFull": "Inflige 100% de daño con un golpe en ${LEVEL}", + "descriptionFullComplete": "Infligió 100% de daño con un golpe en ${LEVEL}", + "name": "Súper Mega Golpe" + }, + "Super Punch": { + "description": "Inflige 50% de daño con un golpe", + "descriptionComplete": "Infligió 50% de daño con un golpe", + "descriptionFull": "Inflige 50% de daño con un golpe en ${LEVEL}", + "descriptionFullComplete": "Infligió 50% de daño con un golpe en ${LEVEL}", + "name": "Súper Golpe" + }, + "TNT Terror": { + "description": "Mata a 6 chicos malos con TNT", + "descriptionComplete": "Mató a 6 chicos malos con TNT", + "descriptionFull": "Mata a 6 chicos malos con TNT en ${LEVEL}", + "descriptionFullComplete": "Mató a 6 chicos malos con TNT en ${LEVEL}", + "name": "Pirómano" + }, + "Team Player": { + "descriptionFull": "Empieza un juego de Equipos con 4 o más jugadores", + "descriptionFullComplete": "Empezó un juego de Equipos con 4 o más jugadores", + "name": "Jugador de Equipo" + }, + "The Great Wall": { + "description": "Detén a cada uno de los chicos malos", + "descriptionComplete": "Detuvo a cada uno de los chicos malos", + "descriptionFull": "Detén a cada uno de los chicos malos en ${LEVEL}", + "descriptionFullComplete": "Detuvo a cada uno de los chicos malos en ${LEVEL}", + "name": "La Gran Muralla" + }, + "The Wall": { + "description": "Detén a cada uno de los chicos malos", + "descriptionComplete": "Detuvo a cada uno de los chicos malos", + "descriptionFull": "Detén a cada uno de los chicos malos en ${LEVEL}", + "descriptionFullComplete": "Detuvo a cada uno de los chicos malos en ${LEVEL}", + "name": "La Muralla" + }, + "Uber Football Shutout": { + "description": "Gana sin dejar que los chicos malos anoten", + "descriptionComplete": "Ganó sin dejar que los chicos malos anotaran", + "descriptionFull": "Gana ${LEVEL} sin dejar que los chicos malos anoten", + "descriptionFullComplete": "Ganó ${LEVEL} sin dejar que los chicos malos anotaran", + "name": "Blanqueo en ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganó el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganó el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Vence todas las oleadas", + "descriptionComplete": "Venció todas las oleadas", + "descriptionFull": "Vence todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Completa todas las oleadas", + "descriptionComplete": "Completó todas las oleadas", + "descriptionFull": "Completa todas las oleadas en ${LEVEL}", + "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + } + }, + "achievementsRemainingText": "Logros Restantes:", + "achievementsText": "Logros", + "achievementsUnavailableForOldSeasonsText": "Disculpe, los logros específicos no están disponibles para temporadas anteriores.", + "activatedText": "${THING} activado.", + "addGameWindow": { + "getMoreGamesText": "Obtener Más Juegos...", + "titleText": "Agregar Juego" + }, + "addToFavoritesText": "Agregar a Favoritos", + "addedToFavoritesText": "'${NAME}' añadido a Favoritos.", + "allText": "Todo", + "allowText": "Permitir", + "alreadySignedInText": "Tu cuenta está registrada en otro dispositivo;\npor favor cambia de cuentas o cierra el juego en tu \notro dispositivo e inténtalo de nuevo.", + "apiVersionErrorText": "No se puede cargar el módulo ${NAME}; este apunta a la versión-api ${VERSION_USED}; necesitamos ${VERSION_REQUIRED}.", + "applyText": "Aplicar", + "areYouSureText": "¿Estás seguro/a?", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" se activa solo cuando los audífonos estan conectados)", + "headRelativeVRAudioText": "Audio RV Relativo a la Cabeza", + "musicVolumeText": "Volumen de la Música", + "soundVolumeText": "Volumen del Sonido", + "soundtrackButtonText": "Bandas Sonoras", + "soundtrackDescriptionText": "(usa tu propia música para reproducir durante los juegos)", + "titleText": "Audio" + }, + "autoText": "Auto", + "backText": "Atrás", + "banThisPlayerText": "Banear a Este Jugador", + "bestOfFinalText": "Final Mejor-de-${COUNT}", + "bestOfSeriesText": "Mejor de ${COUNT} series:", + "bestRankText": "Tu mejor rango es #${RANK}", + "bestRatingText": "Tu mejor clasificación es ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Potenciar", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} se configura en la propia aplicación.", + "buttonText": "botón", + "canWeDebugText": "¿Te gustaría que ${APP_NAME} reporte errores, fallos internos\ne información básica de uso al desarrollador de forma automática?\n\nDicha informacíon no incluirá datos personales y ayudará a\nmantener el juego funcionando sin contratiempos ni problemas.", + "cancelText": "Cancelar", + "cantConfigureDeviceText": "Lo sentimos, ${DEVICE} no es configurable.", + "challengeEndedText": "Este desafío ha terminado.", + "chatMuteText": "Silenciar Chat", + "chatMutedText": "Chat Silenciado", + "chatUnMuteText": "Desilenciar Chat", + "chests": { + "prizeOddsText": "Posibles Premios", + "reduceWaitText": "Reducir Espera", + "slotDescriptionText": "Esta ranura puede contener un cofre.\n\nGana cofres al jugar niveles del modo campaña,\nposicionándote en torneos y completando\nlogros.", + "slotText": "${NUM} Ranura de Cofre", + "slotsFullWarningText": "ADVERTENCIA: Tus espacios de cofres están llenos.\nCualquier cofre ganado en esta partida, será perdido.", + "unlocksInText": "Se desbloquea en:" + }, + "choosingPlayerText": "", + "claimText": "Reclamar", + "codesExplainText": "Los códigos son proporcionados por el desarrollador para\ndiagnosticar y corregir problemas de la cuenta.", + "completeThisLevelToProceedText": "¡Debes completar\neste nivel para avanzar!", + "completionBonusText": "Bono por Completar", + "configControllersWindow": { + "configureControllersText": "Configurar Controles", + "configureKeyboard2Text": "Configurar Teclado J2", + "configureKeyboardText": "Configurar Teclado", + "configureMobileText": "Dispositivos Móviles como Controles", + "configureTouchText": "Configurar Pantalla Táctil", + "ps3Text": "Controles de PS3", + "titleText": "Controles", + "wiimotesText": "Wiimotes", + "xbox360Text": "Controles de Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: el soporte de los controles varía según el dispositivo y la versión de Android.", + "pressAnyButtonText": "Pulsa cualquier botón en el control\n que desees configurar...", + "titleText": "Configurar Controles" + }, + "configGamepadWindow": { + "advancedText": "Avanzado", + "advancedTitleText": "Configuración Avanzada del Control", + "analogStickDeadZoneDescriptionText": "(súbelo si tu personaje 'derrapa' cuando sueltas la palanca)", + "analogStickDeadZoneText": "Zona Muerta de La Palanca Analógica", + "appliesToAllText": "(aplica a todos los controles de este tipo)", + "autoRecalibrateDescriptionText": "(habilita esta opción si tu personaje no se mueve a toda velocidad)", + "autoRecalibrateText": "Auto-Recalibrar Palanca Analógica", + "axisText": "eje", + "clearText": "vaciar", + "dpadText": "Flechas del Mando", + "extraStartButtonText": "Botón Extra de Inicio", + "ifNothingHappensTryAnalogText": "Si no pasa nada, intenta asignar la palanca analógica en cambio.", + "ifNothingHappensTryDpadText": "Si no pasa nada, intenta asignar el d-pad en cambio.", + "ignoreCompletelyDescriptionText": "(evita que este control este afectando el juego y/o menús)", + "ignoreCompletelyText": "Ignorar Completamente", + "ignoredButton1Text": "Botón 1 Ignorado", + "ignoredButton2Text": "Botón 2 Ignorado", + "ignoredButton3Text": "Botón 3 Ignorado", + "ignoredButton4Text": "Botón 4 Ignorado", + "ignoredButtonDescriptionText": "(usa esto para prevenir que los botones de 'inicio' o 'sincronización' afecten la Interfaz Visual)", + "pressAnyAnalogTriggerText": "Presiona cualquier gatillo analógico...", + "pressAnyButtonOrDpadText": "Presiona cualquier botón o dpad...", + "pressAnyButtonText": "Presiona cualquier botón...", + "pressLeftRightText": "Presiona izquierda o derecha...", + "pressUpDownText": "Presiona arriba o abajo...", + "runButton1Text": "Botón para Correr 1", + "runButton2Text": "Botón para Correr 2", + "runTrigger1Text": "Gatillo para Correr 1", + "runTrigger2Text": "Gatillo para Correr 2", + "runTriggerDescriptionText": "(los gatillos analógicos te dejan correr a velocidades distintas)", + "secondHalfText": "Utiliza esta opción para configurar\nla segunda mitad de un control 2 en 1\nque se muestre como un solo control.", + "secondaryEnableText": "Habilitar", + "secondaryText": "Control Secundario", + "startButtonActivatesDefaultDescriptionText": "(desactívalo si tu botón de inicio es más bien un botón de 'menú')", + "startButtonActivatesDefaultText": "El Botón de Inicio Activa la Función por Defecto", + "titleText": "Configurar Control", + "twoInOneSetupText": "Configuración de Controles 2 en 1", + "uiOnlyDescriptionText": "(evitar que este control se una a un juego)", + "uiOnlyText": "Limitar a Uso en Menú", + "unassignedButtonsRunText": "Todos los Botones sin Asignar Corren", + "unsetText": "", + "vrReorientButtonText": "Boton de Reorientación de RV" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteText": "Nota: la mayoría de teclados sólo pueden registrar algunas\npulsaciones a la vez, así que tener un segundo teclado puede\nfuncionar mejor que un teclado compartido por los 2 jugadores.\nTen en cuenta que todavía necesitas asignar teclas únicas a los\ndos jugadores incluso en ese caso." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Tamaño de Control de Acciones", + "actionsText": "Acciones", + "buttonsText": "botones", + "dragControlsText": "", + "joystickText": "palanca", + "movementControlScaleText": "Tamaño de Escala de Movimiento", + "movementText": "Movimiento", + "resetText": "Reiniciar", + "swipeControlsHiddenText": "Ocultar Iconos Deslizantes", + "swipeInfoText": "Controles del estilo 'Deslizante' toman un poco de practica, pero\nhacen que sea más fácil jugar sin mirar los controles.", + "swipeText": "deslizar", + "titleText": "Configurar Pantalla Táctil" + }, + "configureDeviceInSystemSettingsText": "${DEVICE} se puede configurar en la aplicación Configuración del Sistema.", + "configureItNowText": "Configurar ahora?", + "configureText": "Configurar", + "connectMobileDevicesWindow": { + "amazonText": "Tienda de Amazon (Appstore)", + "appStoreText": "App Store", + "bestResultsText": "Para mejores resultados necesitas una red inalámbrica rápida. Puedes\nreducir el retraso wifi apagando otros dispositivos inalámbricos,\njugando cerca de tu router inalámbrico y conectando el\njuego anfitrión directamente a la red a través del cable Ethernet.", + "explanationText": "Para utilizar tus dispositivos móviles como controles, \ninstala la app \"${REMOTE_APP_NAME}\" en ellos. Todos tus dispositivos \npueden conectarse a un juego de ${APP_NAME} a través de una red Wi-fi, ¡es gratis!.", + "forAndroidText": "para Android:", + "forIOSText": "para iOS:", + "getItForText": "Consigue ${REMOTE_APP_NAME} para iOS en la App Store\no para Android en la Tienda de Google Play o Appstore de Amazon", + "googlePlayText": "Google Play", + "titleText": "Utilizando Dispositivos como Controles:" + }, + "continuePurchaseText": "¿Continuar por ${PRICE}?", + "continueText": "Continuar", + "controlsText": "Controles", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Esto no aplica a las clasificaciones de todo-el-tiempo.", + "activenessInfoText": "Este multiplicador aumenta en los días que juegas\ny disminuye cuando no juegas.", + "activityText": "Actividad", + "campaignText": "Campaña", + "challengesInfoText": "Gana premios por completar los mini-juegos.\n\nLos premios y la dificultad de los niveles incrementa\ncada vez que se completa y\ndecrece cuando uno expira o no se cumple.", + "challengesText": "Desafíos", + "currentBestText": "Mejor Actualmente", + "customText": "Personalizado", + "entryFeeText": "Entrada", + "forfeitConfirmText": "¿Renunciar a este desafío?", + "forfeitNotAllowedYetText": "Todavía no puedes abandonar este desafío.", + "forfeitText": "Abandonar", + "multipliersText": "Multiplicadores", + "nextChallengeText": "Siguiente Desafío", + "nextPlayText": "Siguiente Juego", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Juega Ahora", + "pointsText": "Puntos", + "powerRankingFinishedSeasonUnrankedText": "(temporada terminada sin clasificar)", + "powerRankingNotInTopText": "(fuera del top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Clasificación del Jugador", + "prizesText": "Premios", + "proMultInfoText": "Los jugadores con la mejora de ${PRO}\nreciben una bonificación del ${PERCENT}% de puntos.", + "seeMoreText": "Más...", + "skipWaitText": "Omitir la Espera", + "timeRemainingText": "Tiempo Restante", + "toRankedText": "Para Clasificar", + "totalText": "total", + "tournamentInfoText": "Compite por puntajes altos con\notros jugadores en tu liga.\n\nLos premios los obtienen los jugadores\ncon mejor puntaje al acabarse el torneo.", + "welcome1Text": "Bienvenido a ${LEAGUE}. Puedes mejorar tu\nposición en la liga ganando estrellas, completando\nlogros y ganando trofeos en desafíos.", + "welcome2Text": "También puedes ganar boletos desde varias actividades similares.\nLos boletos pueden ser usados para desbloquear nuevos personajes,\nmapas y minijuegos, entrar a torneos y más.", + "yourPowerRankingText": "Tu Clasificación Actual:" + }, + "copyConfirmText": "Copiado en el portapapeles.", + "copyOfText": "Copia de ${NAME}", + "copyText": "Copiar", + "createEditPlayerText": "", + "createText": "Crear", + "creditsWindow": { + "additionalAudioArtIdeasText": "Audio Adicional, Arte Inicial, e Ideas por ${NAME}", + "additionalMusicFromText": "Música adicional de ${NAME}", + "allMyFamilyText": "Mis amigos y mi familia que ayudaron con las pruebas", + "codingGraphicsAudioText": "Código, Gráficos y Audio por ${NAME}", + "languageTranslationsText": "Traducciones:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Música de dominio público vía ${NAME}", + "softwareBasedOnText": "Este software está basado parcialmente en el trabajo de ${NAME}", + "songCreditText": "${TITLE} Interpretada por ${PERFORMER}\nCompuesta por ${COMPOSER}, Arreglos por ${ARRANGER}, Publicada por ${PUBLISHER},\nCortesía de ${SOURCE}", + "soundAndMusicText": "Sonido & Música:", + "soundsText": "Sonidos (${SOURCE}):", + "specialThanksText": "Agradecimientos Especiales:", + "thanksEspeciallyToText": "Gracias especialmente a ${NAME}", + "titleText": "Créditos de ${APP_NAME}", + "whoeverInventedCoffeeText": "A quien inventó el café" + }, + "currentStandingText": "Tu puesto actual es #${RANK}", + "customizeText": "Personalizar...", + "deathsTallyText": "${COUNT} muertes", + "deathsText": "Muertes", + "debugText": "depurar", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: Es recomendable poner Ajustes->Gráficos->Texturas en 'Alto' al probar esto.", + "runCPUBenchmarkText": "Ejecutar Punto de Referencia del CPU", + "runGPUBenchmarkText": "Ejecutar Punto de Referencia del GPU", + "runMediaReloadBenchmarkText": "Ejecutar Punto de Referencia del Media-Reload", + "runStressTestText": "Ejecutar prueba de resistencia", + "stressTestPlayerCountText": "Conteo de Jugadores", + "stressTestPlaylistDescriptionText": "Lista de juegos de Prueba de Estrés", + "stressTestPlaylistNameText": "Nombre de la Lista de juegos", + "stressTestPlaylistTypeText": "Tipo de Lista de juegos", + "stressTestRoundDurationText": "Duración de Ronda", + "stressTestTitleText": "Prueba de Estrés", + "titleText": "Pruebas de Estrés y Rendimiento", + "totalReloadTimeText": "Tiempo total de recarga: ${TIME} (ver registro para detalles)" + }, + "defaultGameListNameText": "Lista de juegos ${PLAYMODE} Por Defecto", + "defaultNewGameListNameText": "Mi Lista de juegos ${PLAYMODE}", + "deleteText": "Borrar", + "demoText": "Demo", + "denyText": "Denegar", + "deprecatedText": "Obsoleto", + "descriptionText": "Descripción", + "desktopResText": "Resolución de Escritorio", + "deviceAccountUpgradeText": "Advertencia:\nIniciaste sesión con una cuenta de dispositivo (${NAME}).\nLas cuentas de dispositivo serán removidas en una futura actualización.\nActualiza a una Cuenta V2 si quieres conservar tu progreso.", + "difficultyEasyText": "Fácil", + "difficultyHardOnlyText": "Solo en Modo Difícil", + "difficultyHardText": "Difícil", + "difficultyHardUnlockOnlyText": "Este nivel solo puede ser desbloqueado en modo difícil.\n¡¿¡¿¡Piensas tener lo que se necesita!?!?!", + "directBrowserToURLText": "Por favor abre la siguiente URL en tu navegador:", + "disableRemoteAppConnectionsText": "Deshabilitar Conexiones Remotas de la Aplicación", + "disableXInputDescriptionText": "Permite más de 4 controles pero puede que no funcione bien.", + "disableXInputText": "Deshabilitar XInput", + "disabledText": "Deshabilitado", + "discardText": "Descartar", + "discordFriendsText": "¿Quieres buscar gente nueva con quien jugar?\n¡Únete a nuestro Discord y encuentra nuevos amigos!", + "discordJoinText": "Únete al Discord", + "doneText": "Hecho", + "drawText": "Empate", + "duplicateText": "Duplicar", + "editGameListWindow": { + "addGameText": "Añadir\nJuego", + "cantOverwriteDefaultText": "¡No es posible modificar la lista de juegos por defecto!", + "cantSaveAlreadyExistsText": "¡Ya existe una lista de juegos con ese nombre!", + "cantSaveEmptyListText": "¡No puedes guardar una lista de juegos vacía!", + "editGameText": "Editar\nJuego", + "listNameText": "Nombre de La Lista de Juegos", + "nameText": "Nombre", + "removeGameText": "Eliminar\nJuego", + "saveText": "Guardar Lista", + "titleText": "Editor de Lista de Juegos" + }, + "editProfileWindow": { + "accountProfileInfoText": "Este perfil especial tiene un nombre\ny un icono basado en tu cuenta.\n\n${ICONS}\n\nCrea perfiles personalizados si quieres usar\ndiferentes nombres o iconos personalizados.", + "accountProfileText": "(perfil de cuenta)", + "availableText": "El nombre \"${NAME}\" está disponible.", + "characterText": "personaje", + "checkingAvailabilityText": "Revisando la disponibilidad para \"${NAME}\"...", + "colorText": "color", + "getMoreCharactersText": "Obtener Más Personajes...", + "getMoreIconsText": "Obtener Más Iconos...", + "globalProfileInfoText": "Los perfiles de jugador globales tienen un nombre único\na nivel mundial. También tienen iconos personalizados.", + "globalProfileText": "(perfil global)", + "highlightText": "Destacado", + "iconText": "icono", + "localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía de que los nombres sean únicos. \nCrea un perfil global\npara reservar un nombre único y tener un icono personalizado.", + "localProfileText": "(perfil local)", + "nameDescriptionText": "Nombre del Jugador", + "nameText": "Nombre", + "profileAlreadyExistsText": "Ya existe un perfil con ese nombre.", + "randomText": "aleatorio", + "titleEditText": "Editar Perfil", + "titleNewText": "Nuevo Perfil", + "unavailableText": "\"${NAME}\" no está disponible; intenta otro nombre.", + "upgradeProfileInfoText": "Esto reservará tu nombre de jugador a nivel mundial\ny podrás asignarle un icono personalizado.", + "upgradeToGlobalProfileText": "Actualizar a Perfil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "No puedes borrar la banda sonora predeterminada.", + "cantEditDefaultText": "No puedes editar la banda sonora predeterminada. Duplicala o crea una nueva.", + "cantOverwriteDefaultText": "No puedes sobreescribir la banda sonora predeterminada", + "cantSaveAlreadyExistsText": "¡Ya existe una banda sonora con ese nombre!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Banda Sonora Predeterminada", + "deleteConfirmText": "Borrar Banda Sonora:\n\n'${NAME}'?", + "deleteText": "Borrar\nBanda Sonora", + "duplicateText": "Duplicar\nBanda Sonora", + "editSoundtrackText": "Editor de Banda Sonora", + "editText": "Editar\nBanda Sonora", + "fetchingITunesText": "buscando playlists en la App de Música...", + "musicVolumeZeroWarning": "Advertencia: el volumen de la música está en 0", + "nameText": "Nombre", + "newSoundtrackNameText": "Mi Banda Sonora ${COUNT}", + "newSoundtrackText": "Nueva Banda Sonora:", + "newText": "Nueva\nBanda Sonora", + "selectAPlaylistText": "Selecciona Una Playlist", + "selectASourceText": "Fuente de La Música", + "testText": "prueba", + "titleText": "Bandas Sonoras", + "useDefaultGameMusicText": "Música del Juego Por Defecto", + "useITunesPlaylistText": "Playlist de la App de Música", + "useMusicFileText": "Archivo de Música (mp3, etc).", + "useMusicFolderText": "Carpeta de Archivos de Audio" + }, + "editText": "Editar", + "enabledText": "Habilitado", + "endText": "Fin", + "enjoyText": "¡Diviértete!", + "epicDescriptionFilterText": "${DESCRIPTION} En cámara lenta épica.", + "epicNameFilterText": "${NAME} - Modo épico", + "errorAccessDeniedText": "acceso denegado", + "errorDeviceTimeIncorrectText": "La hora de tu dispositivo está incorrecta por ${HOURS} hora(s).\nEsto podría causar algunos problemas.\nPor favor verifica la hora y zona horaria en ajustes.", + "errorOutOfDiskSpaceText": "espacio insuficiente en el disco", + "errorSecureConnectionFailText": "No se puede establecer una conexión segura en la nube; la red podría estar fallando.", + "errorText": "Error", + "errorUnknownText": "error desconocido", + "exitGameText": "¿Salir de ${APP_NAME}?", + "expiredAgoText": "Expiró hace ${T}", + "expiresInText": "Expira en ${T}", + "exportSuccessText": "'${NAME}' exportado.", + "externalStorageText": "Almacenamiento Externo", + "failText": "Fallaste", + "fatalErrorText": "Oh oh; algo está mal por aquí.\nPor favor intenta reinstalar la app o\ncontacta a ${EMAIL} para recibir ayuda.", + "fileSelectorWindow": { + "titleFileFolderText": "Elige un Archivo o Carpeta", + "titleFileText": "Elige un Archivo", + "titleFolderText": "Elige una Carpeta", + "useThisFolderButtonText": "Usar Esta Carpeta" + }, + "filterText": "Filtro", + "finalScoreText": "Puntaje Final", + "finalScoresText": "Puntajes Finales", + "finalTimeText": "Tiempo Final", + "finishingInstallText": "Terminando la instalación; espera un momento...", + "fireTVRemoteWarningText": "* Para una mejor experiencia, \nutiliza controles o instala la\napp '${REMOTE_APP_NAME}' en tus\ndispositivos móviles y tabletas.", + "firstToFinalText": "Primero de ${COUNT} Finales", + "firstToSeriesText": "Primero de ${COUNT} Series", + "fiveKillText": "¡¡¡COMBO QUÍNTUPLE!!!", + "flawlessWaveText": "¡Oleada Perfecta!", + "fourKillText": "¡¡¡COMBO CUÁDRUPLE!!!", + "friendScoresUnavailableText": "Puntajes no disponibles.", + "gameLeadersText": "Líderes del Juego ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "No puedes borrar la lista de juegos predeterminada.", + "cantEditDefaultText": "¡No puedes editar la lista de juegos predeterminada! Duplicala o crea una nueva.", + "cantShareDefaultText": "No puedes compartir la lista de juegos predeterminada.", + "deleteConfirmText": "¿Borrar \"${LIST}\"?", + "deleteText": "Borrar\nLista de Juegos", + "duplicateText": "Duplicar\nLista de Juegos", + "editText": "Editar\nLista de Juegos", + "newText": "Nueva\nLista de Juegos", + "pointsToWinText": "Puntos Para Ganar", + "seriesLengthText": "Duración de la Serie", + "showTutorialText": "Ver Tutorial", + "shuffleGameOrderText": "Orden de Juego Aleatorio", + "titleText": "Personalizar Listas de Juegos de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Agregar Juego" + }, + "gamesToText": "${WINCOUNT} juegos a ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Recuerda: cualquier dispositivo en la fiesta puede\ntener más de un jugador si tienen controles suficientes.", + "aboutDescriptionText": "Usa estas pestañas para armar una partida.\n\nLas partidas te permiten jugar y competir con\ntus amigos a través de diferentes dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu partida.\n(con un control, presiona ${BUTTON} mientras estés en el menú)", + "aboutText": "Acerca De", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} te envió ${COUNT} boletos en ${APP_NAME}", + "appInviteSendACodeText": "Envíales Un Código", + "appInviteTitleText": "Invitación de La App ${APP_NAME}", + "bluetoothAndroidSupportText": "(funciona con cualquier dispositivo Android con Bluetooth)", + "bluetoothDescriptionText": "Alojar/unirse a una partida vía Bluetooth:", + "bluetoothHostText": "Alojar vía Bluetooth", + "bluetoothJoinText": "Unirse vía Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "revisando...", + "copyCodeConfirmText": "Código copiado al portapapeles.", + "copyCodeText": "Copiar Código", + "dedicatedServerInfoText": "Para mejores resultados, crea un servidor dedicado. Visita bombsquadgame.com/server para aprender cómo hacerlo.", + "descriptionShortText": "Usa la pestaña de Reunir para crear una fiesta.", + "disconnectClientsText": "Esto desconectará a ${COUNT} jugador(es) de\ntu partida. ¿Estás seguro?", + "earnTicketsForRecommendingAmountText": "Tus amigos recibirán ${COUNT} boletos si prueban el juego\n(y recibirás ${YOU_COUNT} boletos por cada amigo que pruebe el juego).", + "earnTicketsForRecommendingText": "Comparte el juego\na cambio de boletos gratis...", + "emailItText": "Envíar Correo", + "favoritesSaveText": "Guardar Como Favorito", + "favoritesText": "Favoritos", + "freeCloudServerAvailableMinutesText": "El siguiente servidor estará disponible en ${MINUTES} minuto(s).", + "freeCloudServerAvailableNowText": "¡Servidor en la nube gratuito disponible!", + "freeCloudServerNotAvailableText": "No hay servidores en la nube gratuitos disponibles.", + "friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos de ${APP_NAME} de ${NAME}", + "friendPromoCodeAwardText": "Recibirás ${COUNT} boletos cada vez que lo uses.", + "friendPromoCodeExpireText": "El código expirará en ${EXPIRE_HOURS} hora(s) y solo funciona para jugadores nuevos.", + "friendPromoCodeInstructionsText": "Para usarlo, abre ${APP_NAME} y ve a \"Ajustes->Avanzado->Enviar Información\"\nVisita bombsquadgame.com para enlaces de descarga de todas las plataformas disponibles.", + "friendPromoCodeRedeemLongText": "Se puede canjear por ${COUNT} boletos gratis hasta por ${MAX_USES} personas.", + "friendPromoCodeRedeemShortText": "Puede ser canjeado por ${COUNT} boletos en el juego.", + "friendPromoCodeWhereToEnterText": "(en \"Ajustes->Avanzado->Enviar Información\")", + "getFriendInviteCodeText": "Obtener Código de Invitación de Amigo", + "googlePlayDescriptionText": "Invitar jugadores de Google Play a tu partida:", + "googlePlayInviteText": "Invitar", + "googlePlayReInviteText": "Hay ${COUNT} jugador(es) de Google Play en tu fiesta\nque se desconectarán si creas una nueva invitación.\nInclúyelos en la nueva invitación para tenerlos de vuelta.", + "googlePlaySeeInvitesText": "Ver Invitaciones", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Versión Android / Google Play)", + "hostPublicPartyDescriptionText": "Alojar una Partida Pública", + "hostingUnavailableText": "Alojamiento No Disponible", + "inDevelopmentWarningText": "Nota:\n\nJugar en red es una función todavía en desarrollo.\nPor ahora, es altamente recomendado que todos\nlos jugadores estén en la misma red Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "¿Tus amigos no tienen el juego? Invítalos a\nprobarlo y recibirán ${COUNT} boletos gratis.", + "inviteFriendsText": "Invitar Amigos", + "joinPublicPartyDescriptionText": "Unirse a una Partida Pública", + "localNetworkDescriptionText": "Unirse a una Partida Cercana (LAN, Bluetooth, etc.)", + "localNetworkText": "Red Local", + "makePartyPrivateText": "Hacer Mi Partida Privada", + "makePartyPublicText": "Hacer Mi Partida Pública", + "manualAddressText": "Dirección", + "manualConnectText": "Conectar", + "manualDescriptionText": "Unirse a una partida por dirección:", + "manualJoinSectionText": "Unirse Por Dirección", + "manualJoinableFromInternetText": "¿Se pueden unir desde internet?:", + "manualJoinableNoWithAsteriskText": "NO*", + "manualJoinableYesText": "SÍ", + "manualRouterForwardingText": "*para arreglarlo, configura tu router para que redireccione el puerto UDP ${PORT} a tu dirección local", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Tu dirección desde internet:", + "manualYourLocalAddressText": "Tu dirección local:", + "nearbyText": "Cerca", + "noConnectionText": "", + "noPartiesAddedText": "Sin Fiestas Añadidas", + "otherVersionsText": "(otras versiones)", + "partyCodeText": "Código de La Partida", + "partyInviteAcceptText": "Aceptar", + "partyInviteDeclineText": "Denegar", + "partyInviteIgnoreText": "Ignorar", + "partyInviteText": "${NAME} te ha invitado\na unirse a su partida!", + "partyNameText": "Nombre de La Partida", + "partyServerRunningText": "Tu servidor se esta ejecutando.", + "partySizeText": "tamaño de partida", + "partyStatusCheckingText": "comprobando estado...", + "partyStatusJoinableText": "ahora se pueden unir a tu partida desde internet", + "partyStatusNoConnectionText": "incapaz de conectarse al servidor", + "partyStatusNotJoinableText": "no se pueden unir a tu partida desde internet", + "partyStatusNotPublicText": "tu partida no es pública", + "pingText": "ping", + "portText": "Puerto", + "privatePartyCloudDescriptionText": "Las partidas privadas se ejecutan en la nube; no requieren configuración del router.", + "privatePartyHostText": "Alojar una Partida Privada", + "privatePartyJoinText": "Unirse a una Partida Privada", + "privateText": "Privado", + "publicHostRouterConfigText": "Esto puede requerir configurar el reenvío de puertos en tu router. Para una opción más fácil, aloja una partida privada.", + "publicText": "Público", + "requestingAPromoCodeText": "Pidiendo un código...", + "sendDirectInvitesText": "Enviar Directamente La Invitación", + "shareThisCodeWithFriendsText": "Comparte este código con tus amigos:", + "showMyAddressText": "Mostrar Mi Dirección", + "startHostingPaidText": "Alojar Ahora Por ${COST}", + "startHostingText": "Alojar", + "startStopHostingMinutesText": "Puede iniciar y detener el alojamiento de forma gratuita durante los próximos ${MINUTES} minuto(s).", + "stopHostingText": "Dejar de Alojar", + "titleText": "Reunir", + "wifiDirectDescriptionBottomText": "Si todo los dispositivos disponen de 'Wi-fi Directo', deberían poder utilizarlo para\nencontrar y conectarse entre ellos. Cuando todos estén conectados, puedes formar \npartidas, usando la pestaña 'Red Local', como si estuvieran en la misma red Wi-fi.\n\nPara mejores resultados, el alojador del Wi-fi Directo también debe ser el alojador de la partida en ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Directo puede ser utilizado para conectar dispositivos Android sin\ntener que utilizar una red Wi-Fi. Esto funciona mejor en Android 4.2 hacia adelante.\n\nPara utilizarlo, abre los ajustes de Wi-Fi y busca 'Wi-Fi Directo' en el menú.", + "wifiDirectOpenWiFiSettingsText": "Abrir Ajustes de Wi-Fi", + "wifiDirectText": "Wi-Fi Directo", + "worksBetweenAllPlatformsText": "(funciona en todas las plataformas)", + "youHaveBeenSentAPromoCodeText": "Has enviado un código promocional de ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "¡GRATIS!", + "freeTicketsText": "Boletos Gratis", + "inProgressText": "Ya hay una transacción en progreso; por favor inténtalo mas tarde.", + "purchasesRestoredText": "Compras restauradas.", + "receivedTicketsText": "¡Recibiste ${COUNT} boletos!", + "restorePurchasesText": "Restaurar Compras", + "ticketPack1Text": "Paquete de Boletos Pequeño", + "ticketPack2Text": "Paquete de Boletos Mediano", + "ticketPack3Text": "Paquete de Boletos Grande", + "ticketPack4Text": "Paquete de Boletos Jumbo", + "ticketPack5Text": "Paquete de Boletos Mamut", + "ticketPack6Text": "Paquete de Boletos Supremo", + "ticketsFromASponsorText": "Ver un anuncio\na cambio de ${COUNT} boletos", + "ticketsText": "${COUNT} Boletos", + "titleText": "Conseguir Boletos", + "unavailableLinkAccountText": "Disculpe, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.", + "unavailableTemporarilyText": "No disponible por el momento; por favor inténtalo más tarde.", + "unavailableText": "Disculpe, esto no está disponible.", + "versionTooOldText": "Lo sentimos, esta versión del juego es muy antigua; por favor actualízala a una nueva versión.", + "youHaveShortText": "tienes ${COUNT}", + "youHaveText": "tienes ${COUNT} boletos" + }, + "goldPass": { + "desc1InfTokensText": "Fichas infinitas.", + "desc2NoAdsText": "Sin anuncios.", + "desc3ForeverText": "Para siempre.", + "goldPassText": "Pase de Oro" + }, + "googlePlayPurchasesNotAvailableText": "Las compras de Google Play no están disponibles.\nEs posible que debas actualizar la aplicación de tu tienda.", + "googlePlayServicesNotAvailableText": "Los Servicios de Google Play no están disponibles.\nAlgunas funciones de la aplicación pueden estar deshabilitadas.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Siempre", + "fullScreenCmdText": "Pantalla completa (Cmd-F)", + "fullScreenCtrlText": "Pantalla completa (Ctrl-F)", + "fullScreenText": "Pantalla completa", + "gammaText": "Gama", + "highText": "Alto", + "higherText": "Altísimo", + "lowText": "Bajo", + "maxFPSText": "FPS Máximos", + "mediumText": "Medio", + "neverText": "Nunca", + "resolutionText": "Resolución", + "showFPSText": "Mostrar FPS", + "texturesText": "Texturas", + "titleText": "Gráficos", + "tvBorderText": "Borde del TV", + "verticalSyncText": "Sincronización Vertical", + "visualsText": "Visuales" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nMás fuerte que los golpes, pero puede\nresultar en autolesiones graves.\nPara mejores resultados, tírala hacia tus\noponentes antes de que explote.", + "canHelpText": "${APP_NAME} te puede ayudar.", + "controllersInfoText": "Puedes jugar ${APP_NAME} con tus amigos en una red o todos pueden\njugar en el mismo dispositivo si se tienen varios controles.\n${APP_NAME} soporta una gran variedad de ellos; incluso puedes utilizar\ntus dispositivos móviles como controles instalando la app '${REMOTE_APP_NAME}'.\nVe a \"Ajustes->Controles\" para más información.", + "controllersInfoTextRemoteOnly": "Tu puedes jugar ${APP_NAME} con tus amigos en la red o pueden\njugar todos en el mismo dispositivo usando los teléfonos\ncomo controles con la aplicación '${REMOTE_APP_NAME}'.", + "controllersText": "Controles", + "controlsSubtitleText": "Tu amistoso personaje de ${APP_NAME} tiene algunas acciones básicas:", + "controlsText": "Controles", + "devicesInfoText": "La versión de RV de ${APP_NAME} se puede jugar en la red con la versión \nregular, así que saca tus celulares, tablets y computadoras extras y que \nempieze el juego. Es muy útil conectar un dispositivo con la versión\nregular a uno con la versión VR para que todos los que estén fuera\npuedan ver la acción.", + "devicesText": "Dispositivos", + "friendsGoodText": "Cuantos más, mejor. ${APP_NAME} es más divertido con muchos \namigos y soporta hasta 8 a la vez, lo que nos lleva a:", + "friendsText": "Amigos", + "jumpInfoText": "- Saltar -\nSalta para cruzar pequeños espacios, \npara tirar cosas más lejos y \npara expresar sentimientos de alegría.", + "orPunchingSomethingText": "O golpear algo, tirarlo por un precipicio y explotarlo en plena caída con una bomba pegajosa.", + "pickUpInfoText": "- Recoger -\nAgarra banderas, enemigos o cualquier\notra cosa no pegada al suelo.\nPresiona de nuevo para lanzar.", + "powerupBombDescriptionText": "Te permite sacar tres bombas\nrapidamente en lugar de solo una.", + "powerupBombNameText": "Bombas Triples", + "powerupCurseDescriptionText": "Probablemente quieras evitar estos.\n ...¿o talvez no?", + "powerupCurseNameText": "Maldición", + "powerupHealthDescriptionText": "Te restaura la salud completamente.\nNunca lo habrías adivinado.", + "powerupHealthNameText": "Botiquín", + "powerupIceBombsDescriptionText": "Más débiles que las bombas normales\npero dejan a tus enemigos congelados\ny particularmente frágiles.", + "powerupIceBombsNameText": "Bombas de Hielo", + "powerupImpactBombsDescriptionText": "Levemente más débiles que las bombas regulares, pero explotan al impacto.", + "powerupImpactBombsNameText": "Insta-Bombas", + "powerupLandMinesDescriptionText": "Estas vienen en grupos de 3;\nSon buenas para defensa territorial\no para detener enemigos veloces.", + "powerupLandMinesNameText": "Minas Terrestres", + "powerupPunchDescriptionText": "Hacen que tus golpes sean más duros,\nmás rápidos, mejores y más fuertes.", + "powerupPunchNameText": "Guantes de Boxeo", + "powerupShieldDescriptionText": "Absorbe un poco de daño\npara que asi no tengas que hacerlo tu.", + "powerupShieldNameText": "Escudo-de-Energía", + "powerupStickyBombsDescriptionText": "Se adhieren a todo lo que toquen.\nProducen hilaridad.", + "powerupStickyBombsNameText": "Bombas Pegajosas", + "powerupsSubtitleText": "Obviamente, ningún juego estaría completo sin potenciadores:", + "powerupsText": "Potenciadores", + "punchInfoText": "- Golpear -\nLos golpes hacen más daño cuanto\nmás rápido se muevan tus puños, así que\ncorre, salta y gira como un loco.", + "runInfoText": "- Correr -\nMantén CUALQUIER botón para correr. Los gatillos o botones traseros funcionan bien si los tienes.\nCorrer te lleva a lugares más rápido pero es más difícil girar, así que ten cuidado con los barrancos.", + "someDaysText": "Hay días en los que sientes ganas de golpear algo. O volar algo.", + "titleText": "Ayuda de ${APP_NAME}", + "toGetTheMostText": "Para sacar el máximo partido a este juego, necesitas:", + "welcomeText": "¡Bienvenido a ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} está navegando los menús como un pro -", + "importPlaylistCodeInstructionsText": "Usa el siguiente código para importar esta lista de juegos en otra parte:", + "importPlaylistSuccessText": "Lista de Juegos '${NAME}' importada ${TYPE}", + "importText": "Importar", + "importingText": "Importando...", + "inGameClippedNameText": "en el juego será\n\"${NAME}\"", + "inboxText": "Bandeja de Entrada", + "installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación.\nPuede que te hayas quedado sin espacio en tu dispositivo.\nLibera un poco de tu espacio e intenta de nuevo.", + "internal": { + "arrowsToExitListText": "pulsa ${LEFT} o ${RIGHT} para salir de la lista", + "buttonText": "botón", + "cantKickHostError": "No puedes expulsar al anfitrión.", + "chatBlockedText": "${NAME} está bloqueado del chat por ${TIME} segundos.", + "connectedToGameText": "Unido a '${NAME}'", + "connectedToPartyText": "¡Unido a la partida de ${NAME}!", + "connectingToPartyText": "Conectando...", + "connectionFailedHostAlreadyInPartyText": "Conexión fallida; el anfitrión está en otra partida.", + "connectionFailedPartyFullText": "Conexión fallida; la partida está llena.", + "connectionFailedText": "Conexión fallida.", + "connectionFailedVersionMismatchText": "Conexión fallida; el anfitrión corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "connectionRejectedText": "Conexión rechazada.", + "controllerConnectedText": "${CONTROLLER} conectado.", + "controllerDetectedText": "1 control detectado.", + "controllerDisconnectedText": "${CONTROLLER} desconectado.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Intenta conectarlo de nuevo.", + "controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menús.", + "controllerReconnectedText": "${CONTROLLER} reconectado.", + "controllersConnectedText": "${COUNT} controles conectados.", + "controllersDetectedText": "${COUNT} controles detectados.", + "controllersDisconnectedText": "${COUNT} controles desconectados.", + "corruptFileText": "Archivo(s) corrupto(s) detectado(s). Por favor intenta reinstalando o contácta a ${EMAIL}", + "errorPlayingMusicText": "Error reproduciendo música: ${MUSIC}", + "errorResettingAchievementsText": "Incapaz de reiniciar los logros; por favor inténtalo de nuevo más tarde.", + "hasMenuControlText": "${NAME} tiene el control del menú.", + "incompatibleNewerVersionHostText": "El anfitrión está ejecutando una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.", + "incompatibleVersionHostText": "El anfitrión está ejecutando una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "incompatibleVersionPlayerText": "${NAME} está ejecutando una versión diferente del juego.\nAsegúrate de que ambos estén actualizados y vuelva a intentarlo.", + "invalidAddressErrorText": "Error: dirección inválida.", + "invalidNameErrorText": "Error: nombre inválido.", + "invalidPortErrorText": "Error: puerto inválido.", + "invitationSentText": "Invitación enviada.", + "invitationsSentText": "${COUNT} invitaciones enviadas.", + "joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta.\nVe a 'Jugar' para iniciar un juego.", + "keyboardText": "Teclado", + "kickIdlePlayersKickedText": "Expulsando a ${NAME} por estar inactivo.", + "kickIdlePlayersWarning1Text": "${NAME} será expulsado en ${COUNT} segundos si sigue inactivo.", + "kickIdlePlayersWarning2Text": "(puedes apagar esto en Ajustes -> Avanzado)", + "leftGameText": "Abandonó '${NAME}'.", + "leftPartyText": "Abandonó la partida de ${NAME}.", + "noMusicFilesInFolderText": "La carpeta no contiene archivos de audio.", + "playerJoinedPartyText": "¡${NAME} se unió a la partida!", + "playerLeftPartyText": "${NAME} abandonó la partida.", + "rejectingInviteAlreadyInPartyText": "Rechazando invitación (ya estás en una partida).", + "serverRestartingText": "El servidor se está reiniciando. Por favor vuelva a unirse en un momento...", + "serverShuttingDownText": "El servidor está fuera de servicio...", + "signInErrorText": "Error iniciando sesión.", + "signInNoConnectionText": "Imposible iniciar sesión. (¿no hay conexión a internet?)", + "telnetAccessDeniedText": "ERROR: El usuario no concedió acceso telnet.", + "timeOutText": "(tiempo fuera en ${TIME} segundo/s)", + "touchScreenJoinWarningText": "Te uniste con la pantalla táctil.\nSi este fue un error, presiona 'Menú->Abandonar Juego' con ella.", + "touchScreenText": "Pantalla Táctil", + "unableToCompleteTryAgainText": "Incapaz de completar esto ahora mismo.\nPor favor, inténtelo de nuevo.", + "unableToResolveHostText": "Error: incapaz de encontrar el anfitrión.", + "unavailableNoConnectionText": "No disponible por el momento (¿no tienes conexión a internet?)", + "vrOrientationResetCardboardText": "Usa esto para reiniciar la orientación de RV.\nPara jugar el juego necesitarás un control externo.", + "vrOrientationResetText": "Orientación de RV reiniciada.", + "willTimeOutText": "(caducará si está inactivo)" + }, + "inventoryText": "Inventario", + "jumpBoldText": "SALTAR", + "jumpText": "Saltar", + "keepText": "Mantener", + "keepTheseSettingsText": "¿Mantener estos ajustes?", + "keyboardChangeInstructionsText": "Presiona dos veces el espacio para cambiar los teclados.", + "keyboardNoOthersAvailableText": "No hay más teclados disponibles.", + "keyboardSwitchText": "Cambiando teclado a \"${NAME}\".", + "kickOccurredText": "${NAME} ha sido expulsado.", + "kickQuestionText": "¿Expulsar a ${NAME}?", + "kickText": "Expulsar", + "kickVoteCantKickAdminsText": "Los administradores no pueden ser expulsados.", + "kickVoteCantKickSelfText": "No puedes expulsarte a ti mismo.", + "kickVoteFailedNotEnoughVotersText": "No hay suficientes jugadores para votar.", + "kickVoteFailedText": "Votación de expulsión fallida.", + "kickVoteStartedText": "Se ha iniciado una votación de expulsión para '${NAME}'.", + "kickVoteText": "Votar para Expulsar", + "kickVotingDisabledText": "El voto para expulsar esta desactivado.", + "kickWithChatText": "Escribe ${YES} en el chat para \"Si\" y ${NO} para \"No\".", + "killsTallyText": "${COUNT} asesinatos", + "killsText": "Asesinatos", + "kioskWindow": { + "easyText": "Fácil", + "epicModeText": "Modo Lento", + "fullMenuText": "Menú Completo", + "hardText": "Difícil", + "mediumText": "Medio", + "singlePlayerExamplesText": "Ejemplos de 1 Jugador / Modo Cooperativo", + "versusExamplesText": "Ejemplos de Versus" + }, + "languageSetText": "El idioma ahora es \"${LANGUAGE}\".", + "lapNumberText": "Vuelta ${CURRENT}/${TOTAL}", + "lastGamesText": "(últimos ${COUNT} juegos)", + "leaderboardsText": "Clasificaciones", + "league": { + "allTimeText": "Todo El Tiempo", + "currentSeasonText": "Temporada Actual (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Rango de Liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "La temporada terminó hace ${NUMBER} día(s).", + "seasonEndsDaysText": "La temporada termina en ${NUMBER} día(s).", + "seasonEndsHoursText": "La temporada termina en ${NUMBER} hora(s).", + "seasonEndsMinutesText": "La temporada termina en ${NUMBER} minuto(s).", + "seasonText": "Temporada ${NUMBER}", + "tournamentLeagueText": "Debes alcanzar la liga ${NAME} para entrar a este torneo.", + "trophyCountsResetText": "El conteo de trofeos se reiniciará la próxima temporada.", + "upToDateBonusDescriptionText": "Los jugadores con una version reciente \ndel juego obtienen un bonus del ${PERCENT}% aquí.", + "upToDateBonusText": "Bono Actualizado" + }, + "learnMoreText": "Aprender Más", + "levelBestScoresText": "Mejores puntajes en ${LEVEL}", + "levelBestTimesText": "Mejores tiempos en ${LEVEL}", + "levelIsLockedText": "${LEVEL} está bloqueado.", + "levelMustBeCompletedFirstText": "${LEVEL} debe completarse primero.", + "levelText": "Nivel ${NUMBER}", + "levelUnlockedText": "¡Nivel Desbloqueado!", + "livesBonusText": "Bono de Vidas", + "loadingText": "cargando", + "loadingTryAgainText": "Cargando; vuelve a intentarlo en un momento...", + "macControllerSubsystemBothText": "Ambos (no recomendado)", + "macControllerSubsystemClassicText": "Clásico", + "macControllerSubsystemDescriptionText": "(intenta cambiar esto si tus controles no están funcionando)", + "macControllerSubsystemMFiNoteText": "Control hecho para iOS/Mac detectado;\nTal vez quieras activar esto en Ajustes -> Controles", + "macControllerSubsystemMFiText": "Creado para iOS/Mac", + "macControllerSubsystemTitleText": "Soporte del Control", + "mainMenu": { + "creditsText": "Créditos", + "demoMenuText": "Menú Demo", + "endGameText": "Terminar Juego", + "endTestText": "Terminar Prueba", + "exitGameText": "Salir del Juego", + "exitToMenuText": "¿Salir al menú?", + "howToPlayText": "Cómo Jugar", + "justPlayerText": "(Solo ${NAME})", + "leaveGameText": "Abandonar Juego", + "leavePartyConfirmText": "¿Realmente deseas abandonar la partida?", + "leavePartyText": "Abandonar Partida", + "quitText": "Salir", + "resumeText": "Reanudar", + "settingsText": "Ajustes" + }, + "makeItSoText": "Que así sea", + "mapSelectGetMoreMapsText": "Obtener Más Mapas...", + "mapSelectText": "Seleccionar...", + "mapSelectTitleText": "Mapas para ${GAME}", + "mapText": "Mapa", + "maxConnectionsText": "Máximo de Conexiones", + "maxPartySizeText": "Capacidad Máxima de La Partida", + "maxPlayersText": "Máximo de Jugadores", + "merchText": "¡Mercancía!", + "modeArcadeText": "Modo Arcade", + "modeClassicText": "Modo Clásico", + "modeDemoText": "Modo Demo", + "moreSoonText": "Más próximamente...", + "mostDestroyedPlayerText": "Jugador Más Destruido", + "mostValuablePlayerText": "Jugador Más Valioso", + "mostViolatedPlayerText": "Jugador Más Violado", + "mostViolentPlayerText": "Jugador Más Violento", + "moveText": "Mover", + "multiKillText": "¡¡¡COMBO DE ${COUNT}!!!", + "multiPlayerCountText": "${COUNT} jugadores", + "mustInviteFriendsText": "Nota: debes invitar a tus amigos en\nel panel \"${GATHER}\" o conectar\ncontroles para jugar multijugador.", + "nameBetrayedText": "${NAME} traicionó a ${VICTIM}.", + "nameDiedText": "${NAME} ha muerto.", + "nameKilledText": "${NAME} mató a ${VICTIM}.", + "nameNotEmptyText": "¡El nombre no puede quedar vacío!", + "nameScoresText": "¡${NAME} Anotó!", + "nameSuicideKidFriendlyText": "${NAME} murió accidentalmente.", + "nameSuicideText": "${NAME} cometió suicidio.", + "nameText": "Nombre", + "nativeText": "Nativo", + "newExclaimText": "¡Nuevo!", + "newPersonalBestText": "¡Nuevo récord personal!", + "newTestBuildAvailableText": "¡Una nueva build de prueba está disponible! (${VERSION} build ${BUILD}).\nObténla en ${ADDRESS}", + "newText": "Nuevo", + "newVersionAvailableText": "¡Una nueva version de ${APP_NAME} está disponible! (${VERSION})", + "nextAchievementsText": "Siguientes Logros:", + "nextLevelText": "Siguiente Nivel", + "noAchievementsRemainingText": "- ninguno", + "noContinuesText": "(sin re-intentos)", + "noExternalStorageErrorText": "No se encontró almacenamiento externo en este dispositivo", + "noGameCircleText": "Error: no registrado en GameCircle", + "noMessagesText": "Sin mensajes.", + "noPluginsInstalledText": "Sin Complementos Instalados", + "noScoresYetText": "Sin puntajes aún.", + "noServersFoundText": "No se encontraron servidores.", + "noThanksText": "No Gracias", + "noTournamentsInTestBuildText": "ADVERTENCIA: Los puntajes de los torneos en esta versión de prueba serán ignorados.", + "noValidMapsErrorText": "Mapas válidos no encontrados para este tipo de juego.", + "notEnoughPlayersRemainingText": "No hay jugadores suficientes restantes; sal e inicia un nuevo juego.", + "notEnoughPlayersText": "¡Necesitas por lo menos ${COUNT} jugadores para comenzar!", + "notEnoughTicketsText": "¡No tienes suficientes tickets!", + "notNowText": "Ahora No", + "notSignedInErrorText": "Debes iniciar sesión para hacer esto.", + "notSignedInGooglePlayErrorText": "Debes iniciar sesión con Google Play para hacer esto.", + "notSignedInText": "no registrado", + "notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Iniciar sesión con ${SERVICE}' si quieres usarla.", + "nothingIsSelectedErrorText": "¡No hay nada seleccionado!", + "numberText": "#${NUMBER}", + "offText": "Apagar", + "okText": "Aceptar", + "onText": "Encender", + "oneMomentText": "Un Momento...", + "onslaughtRespawnText": "${PLAYER} reaparecerá en la oleada ${WAVE}", + "openMeText": "Ábreme!", + "openNowText": "Abrir Ahora", + "openText": "Abrir", + "orText": "${A} o ${B}", + "otherText": "Otros...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "¡Su propia bandera debe estar\nen su base para anotar!", + "partyWindow": { + "chatMessageText": "Mensaje del Chat", + "emptyText": "Tu partida está vacía", + "hostText": "(anfitrión)", + "sendText": "Enviar", + "titleText": "Tu Partida" + }, + "pausedByHostText": "(pausado por el anfitrión)", + "perfectWaveText": "¡Oleada Perfecta!", + "pickUpText": "Recoger", + "playModes": { + "coopText": "Cooperativo", + "freeForAllText": "Todos contra Todos", + "multiTeamText": "Múlti-Equipo", + "singlePlayerCoopText": "Un Jugador / Equipos", + "teamsText": "Equipos" + }, + "playText": "Jugar", + "playWindow": { + "oneToFourPlayersText": "1-4 jugadores", + "titleText": "Jugar", + "twoToEightPlayersText": "2-8 jugadores" + }, + "playerCountAbbreviatedText": "${COUNT}j", + "playerDelayedJoinText": "${PLAYER} entrará al comienzo de la siguiente ronda.", + "playerInfoText": "Información del Jugador", + "playerLeftText": "${PLAYER} abandonó el juego.", + "playerLimitReachedText": "Límite de ${COUNT} jugadores alcanzado; no se permiten más.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "No puedes borrar el perfil de tu cuenta.", + "deleteButtonText": "Borrar\nPerfil", + "deleteConfirmText": "¿Borrar '${PROFILE}'?", + "editButtonText": "Editar\nPerfil", + "explanationText": "(nombres de jugadores personalizados y apariencias para esta cuenta)", + "newButtonText": "Nuevo\nPerfil", + "titleText": "Perfiles del Jugador" + }, + "playerText": "Jugador", + "playlistNoValidGamesErrorText": "Esta lista de juegos contiene juegos desbloqueables no válidos.", + "playlistNotFoundText": "playlist no encontrada", + "playlistText": "Lista de Juegos", + "playlistsText": "Listas de juegos", + "pleaseRateText": "Si te gusta ${APP_NAME}, por favor tomate un momento\npara calificar o escribir una reseña. Esto proporciona\ninformación útil y ayuda al soporte del futuro desarrollo del juego.\n\n¡gracias!\n-eric", + "pleaseWaitText": "Por favor, espera...", + "pluginClassLoadErrorText": "Error cargando el complemento '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Error iniciando complemento '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Ajustes de Complementos", + "pluginsAutoEnableNewText": "Activar automáticamente los nuevos complementos", + "pluginsDetectedText": "Complemento(s) detectado(s). Reinicia el juego o ve a ajustes para configurarlo.", + "pluginsDisableAllText": "Deshabilitar Todos Los Complementos", + "pluginsEnableAllText": "Habilitar Todos Los Complementos", + "pluginsRemovedText": "${NUM} complemento(s) ya no está(n).", + "pluginsText": "Complementos", + "practiceText": "Práctica", + "pressAnyButtonPlayAgainText": "Presiona cualquier botón para jugar de nuevo...", + "pressAnyButtonText": "Presiona cualquier botón para continuar...", + "pressAnyButtonToJoinText": "presiona cualquier botón para unirte al juego...", + "pressAnyKeyButtonPlayAgainText": "Presiona cualquier tecla/botón para jugar de nuevo...", + "pressAnyKeyButtonText": "Presiona cualquier botón/tecla para continuar...", + "pressAnyKeyText": "Presiona cualquier tecla...", + "pressJumpToFlyText": "** Presiona saltar repetidamente para volar **", + "pressPunchToJoinText": "presiona GOLPEAR para unirte...", + "pressToOverrideCharacterText": "presiona ${BUTTONS} para cambiar de personaje", + "pressToSelectProfileText": "presiona ${BUTTONS} para seleccionar un perfil", + "pressToSelectTeamText": "presiona ${BUTTONS} para seleccionar un equipo", + "promoCodeWindow": { + "codeText": "Código", + "enterText": "Ingresar" + }, + "promoSubmitErrorText": "Error al enviar código; comprueba tu conexión a Internet", + "ps3ControllersWindow": { + "macInstructionsText": "Apaga tu PS3, asegúrate que el Bluetooth esté activado en\ntu Mac, a continuación, conecta el control a tu Mac a través \nde un cable USB para sincronizarlo. A partir de entonces, se \npuede utilizar el botón de inicio del control para conectarlo con\ntu Mac ya sea por cable (USB) o el modo inalámbrico (Bluetooth).\n\nEn algunas Macs es posible que te pida una contraseña al momento de sincronizar.\nSi esto ocurre, consulta el siguiente tutorial o busca en Google para obtener ayuda.\n\n\n\n\nLos controles de PS3 conectados inalámbricamente deberían de aparecer en la lista de\ndispositivos en Preferencias del Sistema->Bluetooth. Puede que tengas que eliminarlos\nde esa lista cuando quieras utilizarlos de nuevo con tu PS3.\n\nAsimismo, asegúrate de desconectarlos del Bluetooth cuando no los estés\nusando o las baterías se queden sin energía.\n\nEl Bluetooth puede soportat hasta 7 dispositivos,\naunque tu kilometraje puede variar.", + "ouyaInstructionsText": "Para usar un control de PS3 con tu OUYA, tienes que conectarlo una sola vez con\nun cable USB para sincronizarlo. Al hacer esto se pueden desconectar tus otros \ncontroles, por lo que debes reiniciar tu OUYA y desconectar el cable USB.\n\nA partir de entonces deberías ser capaz de usar el botón INICIO para conectarte de\nforma inalámbrica. Cuando hayas terminado de jugar, mantén pulsado el botón INICIO\ndurante 10 segundos para apagar el control, de lo contrario puede permanecer encendido\ny gastar las baterías.", + "pairingTutorialText": "sincronizando video tutorial", + "titleText": "Para usar Controles de PS3 con ${APP_NAME}:" + }, + "punchBoldText": "GOLPEAR", + "punchText": "Golpear", + "purchaseForText": "Comprar por ${PRICE}", + "purchaseGameText": "Comprar Juego", + "purchaseNeverAvailableText": "Lo siento, las compras no están disponibles en esta build.\nIntenta iniciar sesión en otra plataforma y realizar compras desde ahí.", + "purchaseNotAvailableText": "Esta compra no está disponible.", + "purchasingText": "Comprando...", + "quitGameText": "¿Salir de ${APP_NAME}?", + "quittingIn5SecondsText": "Saliendo en 5 segundos...", + "randomPlayerNamesText": "Pablo, Cristiano, Fulanito, Macondo, Margarita, Martín, Martina, Fabian, Felipe, Franco, Fernando, Pancho, Pepito, David, Diego, Tomás, Andres, Federico, Juan, Joaquín, Huevo Duro, Chico Pobre, Chico Rico", + "randomText": "Generar", + "rankText": "Rango", + "ratingText": "Valoración", + "reachWave2Text": "Llega hasta la segunda horda\npara clasificar.", + "readyText": "listo", + "recentText": "Reciente", + "remoteAppInfoShortText": "${APP_NAME} es más divertido cuando se juega con la familia y amigos.\nConecta uno o más controles de hardware o instala la app\n${REMOTE_APP_NAME} en los teléfonos o tabletas para usarlos\ncomo controles.", + "remote_app": { + "app_name": "Control Remoto BombSquad", + "app_name_short": "BSRemoto", + "button_position": "Posición de Los Botones", + "button_size": "Tamaño de Los Botones", + "cant_resolve_host": "No se encuentra el anfitrión.", + "capturing": "Captando...", + "connected": "Conectado.", + "description": "Usa tu teléfono o tableta como control para BombSquad.\nHasta 8 dispositivos pueden conectarse a la vez para un épico caos de multijugador local en un solo TV o tableta.", + "disconnected": "Desconectado por el servidor.", + "dpad_fixed": "fijo", + "dpad_floating": "flotante", + "dpad_position": "Posición del D-Pad", + "dpad_size": "Tamaño del D-Pad", + "dpad_type": "Tipo de D-Pad", + "enter_an_address": "Ingresa una Dirección", + "game_full": "El juego está lleno o no acepta conexiones.", + "game_shut_down": "El juego se ha cerrado.", + "hardware_buttons": "Botones del Hardware", + "join_by_address": "Unirse por Dirección...", + "lag": "Lag: ${SECONDS} segundo/s", + "reset": "Restablecer a predeterminado", + "run1": "Ejecutar 1", + "run2": "Ejecutar 2", + "searching": "Buscando partidas de BombSquad...", + "searching_caption": "Toca el nombre de la partida para unirte.\nTen en cuenta que debes estar en la misma conexión Wi-Fi de la partida.", + "start": "Empezar", + "version_mismatch": "Las versiones no coinciden.\nAsegurate que BombSquad y BombSquad Remote\nestán actualizados e intenta de nuevo." + }, + "removeInGameAdsText": "Desbloquea \"${PRO}\" en la tienda para quitar la publicidad del juego.", + "removeInGameAdsTokenPurchaseText": "OFERTA DE TIEMPO LIMITADO: Compra CUALQUIER paquete de fichas para quitar los anuncios del juego.", + "renameText": "Renombrar", + "replayEndText": "Terminar Repetición", + "replayNameDefaultText": "Repetición Último Juego", + "replayReadErrorText": "Error leyendo archivo de repetición.", + "replayRenameWarningText": "Renombra \"${REPLAY}\" después de un juego si quieres quedarte con el; o sino será reemplazado.", + "replayVersionErrorText": "Lo sentimos, esta repetición fue hecha en una\nversión diferente del juego y no se puede usar.", + "replayWatchText": "Ver Repetición", + "replayWriteErrorText": "Error creando archivo de repetición.", + "replaysText": "Repeticiones", + "reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje inapropiado u otro mal comportamiento.\nPor favor, describelo aquí abajo:", + "reportThisPlayerCheatingText": "Trampas", + "reportThisPlayerLanguageText": "Lenguaje Inapropiado", + "reportThisPlayerReasonText": "¿Qué te gustaría reportar?", + "reportThisPlayerText": "Reportar Este Jugador", + "requestingText": "Solicitando...", + "restartText": "Reiniciar", + "retryText": "Reintentar", + "revertText": "Deshacer", + "runText": "Correr", + "saveText": "Guardar", + "scanScriptsErrorText": "Error(es) escaneando script(s); Vea el registro para más detalles.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} y ${NUM} otro(s) módulo(s) se deberán actualizar para el api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} se deberá actualizar para el api ${API}", + "scoreChallengesText": "Desafíos de Puntuación", + "scoreListUnavailableText": "La lista de puntajes no está disponible.", + "scoreText": "Puntaje", + "scoreUnits": { + "millisecondsText": "Milisegundos", + "pointsText": "Puntos", + "secondsText": "Segundos" + }, + "scoreWasText": "(era ${COUNT})", + "selectText": "Elegir", + "sendInfoDescriptionText": "Envía información del estado de la cuenta y de la aplicación al desarrollador.\nPor favor incluya su nombre o el motivo del envío.", + "seriesWinLine1PlayerText": "GANA LA", + "seriesWinLine1TeamText": "GANA LA", + "seriesWinLine1Text": "GANA LA", + "seriesWinLine2Text": "SERIE!", + "settingsWindow": { + "accountText": "Cuenta", + "advancedText": "Avanzado", + "audioText": "Audio", + "controllersText": "Controles", + "graphicsText": "Gráficos", + "playerProfilesMovedText": "Nota: Los Perfiles de Jugadores se han movido a la ventana de Cuenta en el menú principal.", + "titleText": "Ajustes" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(un teclado en pantalla simple y amigable con controles para editar textos)", + "alwaysUseInternalKeyboardText": "Siempre usar el teclado interno", + "benchmarksText": "Rendimiento y Pruebas de Estrés", + "devToolsText": "Herramientas de Desarrollador", + "disableCameraGyroscopeMotionText": "Deshabilitar el movimiento del giroscopio de la cámara", + "disableCameraShakeText": "Deshabilitar el temblor de la cámara", + "disableThisNotice": "(puedes deshabilitar este aviso en ajustes avanzados)", + "enterPromoCodeText": "Ingresar Código", + "forTestingText": "Nota: estos datos son solo para pruebas y se reiniciarán cuando salga de la app.", + "helpTranslateText": "Las traducciones de ${APP_NAME} son un esfuerzo\napoyado por la comunidad. Si deseas aportar o corregir una\ntraducción, utiliza el siguiente enlace. ¡Gracias de antemano!", + "insecureConnectionsDescriptionText": "no es recomendado, pero quizás permita el multijugador\ndesde paises o conexiones restringidas.", + "insecureConnectionsText": "Usar conexiones inseguras", + "kickIdlePlayersText": "Expulsar a jugadores inactivos", + "kidFriendlyModeText": "Modo Niños (violencia reducida, etc).", + "languageText": "Idioma", + "moddingGuideText": "Guía de Modificación", + "moddingToolsText": "Herramientas de Modificación", + "mustRestartText": "Tienes que reiniciar el juego para que tome efecto.", + "netTestingText": "Prueba de Red", + "resetText": "Reiniciar", + "sendInfoText": "Enviar Información", + "showBombTrajectoriesText": "Mostrar Trayectorias de Las Bombas", + "showDemosWhenIdleText": "Mostrar demostraciones cuando estés inactivo", + "showDeprecatedLoginTypesText": "Mostrar tipos de inicio de sesión obsoletos", + "showDevConsoleButtonText": "Mostrar botón de consola de desarrollador", + "showInGamePingText": "Mostrar ping en el juego", + "showPlayerNamesText": "Mostrar Nombres de Los Jugadores", + "showUserModsText": "Mostrar Carpeta de Mods", + "titleText": "Avanzado", + "translationEditorButtonText": "Editor de Traducción de ${APP_NAME}", + "translationFetchErrorText": "estado de traducción no disponible", + "translationFetchingStatusText": "viendo estado de traducción...", + "translationInformMe": "Informarme cuando mi idioma necesite actualizaciones", + "translationNoUpdateNeededText": "El idioma actual está actualizado; ¡wuju!", + "translationUpdateNeededText": "** ¡¡El idioma actual necesita actualizarse!! **", + "vrTestingText": "Prueba RV" + }, + "shareText": "Compartir", + "sharingText": "Compartiendo...", + "showText": "Mostrar", + "signInForPromoCodeText": "Debes iniciar sesión con tu cuenta para que el código funcione.", + "singleGamePlaylistNameText": "Solo ${GAME}", + "singlePlayerCountText": "1 jugador", + "sizeLargeText": "Grande", + "sizeMediumText": "Mediano", + "sizeSmallText": "Pequeño", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Selección de Personajes", + "Chosen One": "El Elegido", + "Epic": "Juegos en Modo Épico", + "Epic Race": "Carrera Épica", + "FlagCatcher": "Captura la Bandera", + "Flying": "Pensamientos Felices", + "Football": "Fútbol", + "ForwardMarch": "Asalto", + "GrandRomp": "Conquista", + "Hockey": "Hockey", + "Keep Away": "Aléjate", + "Marching": "Evasiva", + "Menu": "Menú Principal", + "Onslaught": "Matanza", + "Race": "Carrera", + "Scary": "Rey de la Colina", + "Scores": "Pantalla de Puntuación", + "Survival": "Eliminación", + "ToTheDeath": "Combate Mortal", + "Victory": "Pantalla de Puntuación Final" + }, + "spaceKeyText": "espacio", + "statsText": "Estadísticas", + "stopRemindingMeText": "Deja de recordarmelo", + "storagePermissionAccessText": "Esto requiere acceso de almacenamiento", + "store": { + "alreadyOwnText": "¡Ya tienes ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Quita los anuncios y las pantallas molestas\n• Desbloquea más ajustes del juego\n• También incluye:", + "buyText": "Comprar", + "charactersText": "Personajes", + "comingSoonText": "Próximamente...", + "extrasText": "Extras", + "holidaySpecialText": "¡Especial de Temporada!", + "howToSwitchCharactersText": "(ve a \"${SETTINGS} -> ${PLAYER_PROFILES}\" para asignar y personalizar los personajes)", + "howToUseIconsText": "(crea perfiles globales de jugador (en la ventana de cuenta) para usarlos)", + "howToUseMapsText": "(usa estos mapas en tus listas de juegos por equipos y todos contra todos)", + "iconsText": "Iconos", + "loadErrorText": "No se pudo cargar la página.\nRevisa tu conexión a internet.", + "loadingText": "cargando", + "mapsText": "Mapas", + "miniGamesText": "MiniJuegos", + "oneTimeOnlyText": "(solo una vez)", + "purchaseAlreadyInProgressText": "Una compra de este artículo se encuentra en progreso.", + "purchaseConfirmText": "¿Comprar ${ITEM}?", + "purchaseNotValidError": "Compra inválida.\nContacte a ${EMAIL} si esto es un error.", + "purchaseText": "Comprar", + "saleBundleText": "¡Paquete en Oferta!", + "saleExclaimText": "¡Oferta!", + "salePercentText": "(${PERCENT}% menos)", + "saleText": "OFERTA", + "searchText": "Buscar", + "teamsFreeForAllGamesText": "Juegos de Equipos / Todos contra Todos", + "totalWorthText": "*** ¡${TOTAL_WORTH} de valor! ***", + "upgradeQuestionText": "¿Mejorar?", + "winterSpecialText": "Especial de Invierno", + "youOwnThisText": "- ya posees esto -" + }, + "storeDescriptionText": "¡Juego de locura de a 8 Jugadores!\n\n¡Revienta a tus amigos (o a la computadora) en un torneo de mini-juegos explosivos como Captura la Bandera, Hockey-Bomba y Combate Mortal Épico en cámara lenta!\n\nControles sencillos y un amplio soporte de controles hacen que sea fácil que 8 personas entren en la acción; ¡incluso puedes usar tus dispositivos móviles como controles a través de la aplicación gratuita de 'Control Remoto BombSquad'!\n\n¡Fuera Bombas!\n\nEcha un vistazo en: www.froemling.net/bombsquad para más información.", + "storeDescriptions": { + "blowUpYourFriendsText": "Revienta a tus amigos.", + "competeInMiniGamesText": "Compite en minijuegos de carreras, vuelo y mucho más.", + "customize2Text": "Personaliza personajes, minijuegos e incluso la banda sonora.", + "customizeText": "Personaliza tus personajes y crea tus propias listas de minijuegos.", + "sportsMoreFunText": "Los deportes son más divertidos con explosivos.", + "teamUpAgainstComputerText": "Forma un equipo contra la computadora." + }, + "storeText": "Tienda", + "submitText": "Enviar", + "submittingPromoCodeText": "Enviando Código...", + "successText": "¡Éxito!", + "supportEmailText": "Si estás teniendo algún problema con la\napp, por favor, manda un email a ${EMAIL}.", + "teamNamesColorText": "Nombres de Equipos/Colores...", + "telnetAccessGrantedText": "Esta versión de prueba ya no está activa; busca una versión nueva.", + "telnetAccessText": "Acceso a Telnet detectado; ¿permitir?", + "testBuildErrorText": "Esta versión de prueba ya no es activa; busca una versión más nueva.", + "testBuildText": "Compilación de Prueba", + "testBuildValidateErrorText": "Incapaz de validar esta compilación de prueba. (¿no tienes conexión a internet?)", + "testBuildValidatedText": "Compilación de Prueba Validada; ¡Disfruta!", + "thankYouText": "¡Gracias por tu ayuda! ¡¡Disfruta el juego!!", + "threeKillText": "¡¡COMBO TRIPLE!!", + "ticketsDescriptionText": "Los tickets pueden ser usados para desbloquear\npersonajes, mapas, minijuegos y más en la tienda.\n\nLos tickets pueden ser encontrados en los cofres\nganados a través de la campaña, torneos y logros.", + "timeBonusText": "Bono de Tiempo", + "timeElapsedText": "Tiempo Transcurrido", + "timeExpiredText": "Tiempo Expirado", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Consejo", + "titleText": "BombSquad", + "titleVRText": "BombSquad RV", + "tokens": { + "getTokensText": "Obtén Fichas", + "notEnoughTokensText": "¡Fichas insuficientes!", + "numTokensText": "${COUNT} Fichas", + "openNowDescriptionText": "Tienes suficiente fichas para \nabrir esto ahora - no tienes\nque esperar.", + "shinyNewCurrencyText": "La brillante nueva moneda de BombSquad.", + "tokenPack1Text": "Paquete de Fichas Pequeña", + "tokenPack2Text": "Paquete de Fichas Mediana", + "tokenPack3Text": "Paquete de Fichas Grande", + "tokenPack4Text": "Paquete de Fichas Jumbo", + "tokensDescriptionText": "Los tokens son usados para acelerar el desbloqueo de\ncofres entre otras funciones del juego y la cuenta.\n\nPuedes ganar fichas en el juego o comprarlas\nen paquetes. O comprar el Pase de Oro para tokens \ninfinitos y nunca más escuchar de ellos de nuevo.", + "youHaveGoldPassText": "Tienes un Pase de Oro.\nTodas las compras de fichas son gratis.\nDisfruta!" + }, + "topFriendsText": "Mejores Amigos", + "tournamentCheckingStateText": "Buscando estado del campeonato; espere por favor...", + "tournamentEndedText": "Este torneo ha acabado. Uno nuevo comenzará pronto.", + "tournamentEntryText": "Entrada Al Torneo", + "tournamentFinalStandingsText": "Clasificación Final", + "tournamentResultsRecentText": "Resultados de Torneos Recientes", + "tournamentStandingsText": "Puestos del Torneo", + "tournamentText": "Torneo", + "tournamentTimeExpiredText": "Tiempo del Torneo Expirado", + "tournamentsDisabledWorkspaceText": "Los torneos están deshabilitados cuando los espacios de trabajo están activos.\nPara volver a habilitar los torneos, deshabilite su espacio de trabajo y reinicie el juego.", + "tournamentsText": "Torneos", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Huesos", + "Butch": "Butch", + "Easter Bunny": "Conejo de Pascua", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Suertudo", + "Mel": "Mel", + "Middle-Man": "Hombre Intermedio", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Papá Noel", + "Snake Shadow": "Serpiente Sombría", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "Entrenamiento de ${GAME}", + "Infinite ${GAME}": "${GAME} Infinito", + "Infinite Onslaught": "Matanza Infinita", + "Infinite Runaround": "Evasiva Infinita", + "Onslaught Training": "Entrenamiento de Matanza", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Fútbol Pro", + "Pro Onslaught": "Matanza Pro", + "Pro Runaround": "Evasiva Pro", + "Rookie ${GAME}": "${GAME} Novato", + "Rookie Football": "Fútbol Novato", + "Rookie Onslaught": "Matanza Novato", + "The Last Stand": "La Batalla Final", + "Uber ${GAME}": "${GAME} Ultra", + "Uber Football": "Fútbol Ultra", + "Uber Onslaught": "Matanza Ultra", + "Uber Runaround": "Evasiva Ultra" + }, + "displayItemNames": { + "${C} Tickets": "${C} Boletos", + "${C} Tokens": "${C} Ficha(s)", + "Chest": "Cofre", + "L1 Chest": "Cofre N1", + "L2 Chest": "Cofre N2", + "L3 Chest": "Cofre N3", + "L4 Chest": "Cofre N4", + "L5 Chest": "Cofre N5", + "L6 Chest": "Cofre N6", + "Unknown Chest": "Cofre Desconocido" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sé el elegido durante el tiempo designado para ganar.\nMata al elegido para convertirte en él.", + "Bomb as many targets as you can.": "Bombardea tantos blancos como puedas.", + "Carry the flag for ${ARG1} seconds.": "Carga la bandera por ${ARG1} segundos.", + "Carry the flag for a set length of time.": "Carga la bandera por un determinado tiempo.", + "Crush ${ARG1} of your enemies.": "Elimina ${ARG1} de tus enemigos.", + "Defeat all enemies.": "Acaba con todo lo que se mueva.", + "Dodge the falling bombs.": "Esquiva las bombas.", + "Final glorious epic slow motion battle to the death.": "Gloriosa batalla final en épica cámara lenta hasta la muerte.", + "Gather eggs!": "¡Recolecta huevos!", + "Get the flag to the enemy end zone.": "Lleva la bandera enemiga a tu zona.", + "How fast can you defeat the ninjas?": "¿Cuán rápido puedes derrotar a los ninjas?", + "Kill a set number of enemies to win.": "Mata a un número determinado de enemigos para ganar.", + "Last one standing wins.": "El último en pie gana.", + "Last remaining alive wins.": "El último en quedar vivo gana.", + "Last team standing wins.": "El último equipo en pie gana.", + "Prevent enemies from reaching the exit.": "Evita que los enemigos lleguen a la salida.", + "Reach the enemy flag to score.": "Toca la bandera enemiga para anotar.", + "Return the enemy flag to score.": "Devuelve la bandera enemiga para anotar.", + "Run ${ARG1} laps.": "Corre ${ARG1} vueltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corre ${ARG1} vueltas. Todo tu equipo debe cruzar la meta.", + "Run 1 lap.": "Corre 1 vuelta.", + "Run 1 lap. Your entire team has to finish.": "Corre 1 vuelta. Todo tu equipo debe cruzar la meta.", + "Run real fast!": "¡Corre muy rápido!", + "Score ${ARG1} goals.": "Anota ${ARG1} goles.", + "Score ${ARG1} touchdowns.": "Anota ${ARG1} touchdowns.", + "Score a goal.": "Anota un gol.", + "Score a touchdown.": "Anota un touchdown.", + "Score some goals.": "Anota unos goles.", + "Secure all ${ARG1} flags.": "Asegura las ${ARG1} banderas.", + "Secure all flags on the map to win.": "Asegura todas las banderas en el mapa para ganar.", + "Secure the flag for ${ARG1} seconds.": "Asegura la bandera por ${ARG1} segundos.", + "Secure the flag for a set length of time.": "Asegura la bandera por un tiempo determinado.", + "Steal the enemy flag ${ARG1} times.": "Roba la bandera enemiga ${ARG1} veces.", + "Steal the enemy flag.": "Roba la bandera enemiga.", + "There can be only one.": "Solo puede haber uno.", + "Touch the enemy flag ${ARG1} times.": "Toca la bandera enemiga ${ARG1} veces.", + "Touch the enemy flag.": "Toca la bandera enemiga.", + "carry the flag for ${ARG1} seconds": "carga la bandera por ${ARG1} segundos.", + "kill ${ARG1} enemies": "mata a ${ARG1} enemigos", + "last one standing wins": "el último en pie gana", + "last team standing wins": "el último equipo en pie gana", + "return ${ARG1} flags": "devuelve ${ARG1} banderas", + "return 1 flag": "devuelve 1 bandera", + "run ${ARG1} laps": "corre ${ARG1} vueltas", + "run 1 lap": "corre 1 vuelta", + "score ${ARG1} goals": "anota ${ARG1} goles", + "score ${ARG1} touchdowns": "anota ${ARG1} touchdowns", + "score a goal": "anota un gol", + "score a touchdown": "anota un touchdown", + "secure all ${ARG1} flags": "asegura las ${ARG1} banderas", + "secure the flag for ${ARG1} seconds": "asegura la bandera por ${ARG1} segundos", + "touch ${ARG1} flags": "toca ${ARG1} banderas", + "touch 1 flag": "toca 1 bandera" + }, + "gameNames": { + "Assault": "Asalto", + "Capture the Flag": "Captura la Bandera", + "Chosen One": "El Elegido", + "Conquest": "Conquista", + "Death Match": "Combate Mortal", + "Easter Egg Hunt": "Búsqueda de Huevos de Pascua", + "Elimination": "Eliminación", + "Football": "Fútbol", + "Hockey": "Hockey", + "Keep Away": "Aléjate", + "King of the Hill": "Rey de la Colina", + "Meteor Shower": "Lluvia de Meteoritos", + "Ninja Fight": "Pelea Ninja", + "Onslaught": "Matanza", + "Race": "Carrera", + "Runaround": "Evasiva", + "Target Practice": "Blanco de Práctica", + "The Last Stand": "La Batalla Final" + }, + "inputDeviceNames": { + "Keyboard": "Teclado", + "Keyboard P2": "Teclado P2" + }, + "languages": { + "Arabic": "Árabe", + "Belarussian": "Bielorruso", + "Chinese": "Chino - Simplificado ", + "ChineseSimplified": "Chino Simplificado", + "ChineseTraditional": "Chino Tradicional (Zhōngwén)", + "Croatian": "Croata", + "Czech": "Checo", + "Danish": "Danés", + "Dutch": "Holandés", + "English": "Inglés", + "Esperanto": "Esperanto", + "Filipino": "Filipino", + "Finnish": "Finlandés", + "French": "Francés", + "German": "Alemán", + "Gibberish": "Algarabía", + "Greek": "Griego", + "Hindi": "Hindi", + "Hungarian": "Húngaro", + "Indonesian": "Indonesio", + "Italian": "Italiano", + "Japanese": "Japonés", + "Korean": "Coreano", + "Malay": "Malayo", + "Persian": "Persa", + "PirateSpeak": "Habla Pirata", + "Polish": "Polaco", + "Portuguese": "Portugués", + "PortugueseBrazil": "Portugués - Brazil", + "PortuguesePortugal": "Portugués - Portugal", + "Romanian": "Rumano", + "Russian": "Ruso", + "Serbian": "Serbio", + "Slovak": "Eslovaco", + "Spanish": "Español", + "SpanishLatinAmerica": "Español - Latinoamerica", + "SpanishSpain": "Español - España", + "Swedish": "Sueco", + "Tamil": "Tamil", + "Thai": "Tailandés", + "Turkish": "Turco", + "Ukrainian": "Ucraniano", + "Venetian": "Veneciano", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronce", + "Diamond": "Diamante", + "Gold": "Oro", + "Silver": "Plata" + }, + "mapsNames": { + "Big G": "Gran G", + "Bridgit": "Puentecito", + "Courtyard": "Patio Real", + "Crag Castle": "Castillo del Risco", + "Doom Shroom": "Hongo de La Muerte", + "Football Stadium": "Estadio de Fútbol", + "Happy Thoughts": "Pensamientos Felices", + "Hockey Stadium": "Estadio de Hockey", + "Lake Frigid": "Lago Frígido", + "Monkey Face": "Cara de Mono", + "Rampage": "Medio Tubo", + "Roundabout": "Rotonda", + "Step Right Up": "Paso Al Frente", + "The Pad": "La Plataforma", + "Tip Top": "Punta Superior", + "Tower D": "Torre D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Solo Épico", + "Just Sports": "Solo Deportes" + }, + "scoreNames": { + "Flags": "Banderas", + "Goals": "Goles", + "Score": "Puntaje", + "Survived": "Sobrevivió", + "Time": "Tiempo", + "Time Held": "Tiempo Mantenido" + }, + "serverResponses": { + "A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta.", + "A reward has already been given for that address.": "Ya se le ha dado una recompensa a esa dirección.", + "Account linking successful!": "¡Vinculación de cuenta exitosa!", + "Account unlinking successful!": "¡Desvinculación de cuenta exitosa!", + "Accounts are already linked.": "Las cuentas ya están vinculadas.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No se pudo verificar la vista del anuncio. \nPor favor asegúrese de estar ejecutando una versión oficial y actualizada del juego.", + "An error has occurred; (${ERROR})": "Un error ha ocurrido; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Un error ha ocurrido; por favor contacte al soporte. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Un error ha ocurrido; por favor contacta a support@froemling.net.", + "An error has occurred; please try again later.": "Un error ha ocurrido; por favor intentalo más tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres vincular estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!", + "BombSquad Pro unlocked!": "¡BombSquad Pro desbloqueado!", + "Can't link 2 accounts of this type.": "No se pueden vincular 2 cuentas de este tipo.", + "Can't link 2 diamond league accounts.": "No se pueden vincular 2 cuentas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo vincular; sobrepasaría el máximo de cuentas vinculadas de ${COUNT}.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trampa detectada; puntajes y premios suspendidos por ${COUNT} días.", + "Could not establish a secure connection.": "No se pudo establecer una conexión segura.", + "Daily maximum reached.": "Máximo diario conseguido.", + "Daily sign-in reward": "Recompensa por iniciar sesión diariamente", + "Entering tournament...": "Entrando al torneo...", + "Invalid code.": "Código inválido.", + "Invalid payment; purchase canceled.": "Pago inválido; compra cancelada.", + "Invalid promo code.": "Código promocional inválido.", + "Invalid purchase.": "Compra inválida.", + "Invalid tournament entry; score will be ignored.": "Entrada de torneo inválida; el puntaje será ignorado.", + "Item unlocked!": "¡Artículo desbloqueado!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACIÓN DENEGADA. ${ACCOUNT} contiene\ndatos significativos que podrían PERDERSE EN SU TOTALIDAD.\nPuedes vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Vincular ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?", + "Longer streaks lead to better rewards.": "Rachas mayores significan Mejores recompensas.", + "Max number of playlists reached.": "Número máximo de listas de juegos alcanzado.", + "Max number of profiles reached.": "Número máximo de perfiles alcanzado.", + "Maximum friend code rewards reached.": "Máximo de premios por códigos de amigos alcanzado.", + "Message is too long.": "El mensaje es muy largo.", + "New tournament result!": "¡Nuevo resultado del torneo!", + "No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor inténtelo de nuevo más tarde.", + "No slots available. Free a slot and try again.": "No hay ranuras libres. Libere una e intentélo de nuevo.", + "Profile \"${NAME}\" upgraded successfully.": "El perfil \"${NAME}\" se ha mejorado satisfactoriamente.", + "Profile could not be upgraded.": "El perfil no pudo ser mejorado.", + "Purchase successful!": "¡Compra exitosa!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} boletos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} boletos.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funcionalidad del servidor ya no es compatible en esta versión del juego;\nActualiza a una versión más reciente.", + "Sorry, there are no uses remaining on this code.": "Disculpe, pero no quedan usos disponibles de este código.", + "Sorry, this code has already been used.": "Disculpe, este código ya ha sido usado.", + "Sorry, this code has expired.": "Disculpe, este código ha expirado.", + "Sorry, this code only works for new accounts.": "Disculpe, este código solo funciona para cuentas nuevas.", + "Sorry, this has expired.": "Disculpe, esto ya ha expirado.", + "Still searching for nearby servers; please try again soon.": "Todavía buscando por servidores cercanos; inténtelo de nuevo más tarde.", + "Streak: ${NUM} days": "Racha de: ${NUM} días", + "Temporarily unavailable; please try again later.": "Temporalmente indisponible; por favor inténtalo más tarde.", + "The tournament ended before you finished.": "El torneo terminó antes de que terminaras.", + "This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desvinculada por ${NUM} día(s).", + "This code cannot be used on the account that created it.": "Este código no puede ser usado en la misma cuenta que ha sido creado.", + "This is currently unavailable; please try again later.": "Esto no está disponible actualmente; por favor inténtelo más tarde.", + "This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más reciente.", + "Tournaments disabled due to rooted device.": "Los torneos han sido deshabilitados debido a que tú dispositivo esta rooteado.", + "Tournaments require ${VERSION} or newer": "Los torneos requieren la versión ${VERSION} o más nueva", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desvincular ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán.\n(excepto los logros en algunos casos)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: Se han emitido reclamaciones de hackeos contra tu cuenta.\nLas cuentas que se encuentren hackeando serán baneadas. Por favor juega limpio.", + "Wait reduced!": "Espera reducida!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Advertencia: Esta versión del juego está limitada a los datos de cuenta antiguos; es posible que falten datos o que estén desactualizados.\nPor favor actualiza a una versión más reciente del juego para ver los datos más recientes de tu cuenta.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres vincular tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!", + "You already own this!": "¡Ya posees esto!", + "You can join in ${COUNT} seconds.": "Puedes unirte en ${COUNT} segundo(s).", + "You don't have enough tickets for this!": "¡No tienes suficientes boletos para esto!", + "You don't own that.": "No posees eso.", + "You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} boletos!", + "You got ${COUNT} tokens!": "¡Obtuviste ${COUNT} ficha(s)!", + "You got a ${ITEM}!": "¡Conseguiste un ${ITEM}!", + "You got a chest!": "¡Obtuviste un cofre!", + "You got an achievement reward!": "¡Obtuviste una recompensa por tu logro!", + "You have been promoted to a new league; congratulations!": "Has sido ascendido a una nueva liga; ¡felicitaciones!", + "You lost a chest! (All your chest slots were full)": "¡Perdiste un cofre! (Todas tus ranuras de cofres estaban llenas).", + "You must update the app to view this.": "Debes actualizar la aplicación para ver esto.", + "You must update to a newer version of the app to do this.": "Debes actualizar la aplicación a una versión más reciente para hacer esto.", + "You must update to the newest version of the game to do this.": "Necesitas actualizar a la versión más reciente del juego para hacer esto.", + "You must wait a few seconds before entering a new code.": "Debes esperar unos segundos antes de ingresar un código nuevo.", + "You placed #${RANK} in a tournament!": "Quedaste en el puesto #${RANK} en un torneo!", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Quedaste en la posición #${RANK} en el campeonato. ¡Gracias por jugar!", + "Your account was rejected. Are you signed in?": "Tu cuenta fue rechazada. ¿Estás registrado?", + "Your ad views are not registering. Ad options will be limited for a while.": "Tus vistas de anuncios no se están registrando. Las opciones de anuncios serán limitadas por un tiempo.", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo.", + "Your friend code was used by ${ACCOUNT}": "Tu código de amigo fue usado por ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuto", + "1 Second": "1 Segundo", + "10 Minutes": "10 Minutos", + "2 Minutes": "2 Minutos", + "2 Seconds": "2 Segundos", + "20 Minutes": "20 Minutos", + "4 Seconds": "4 Segundos", + "5 Minutes": "5 Minutos", + "8 Seconds": "8 Segundos", + "Allow Negative Scores": "Permitir Puntajes Negativos", + "Balance Total Lives": "Repartir Vidas Totales", + "Bomb Spawning": "Aparecer Bombas", + "Chosen One Gets Gloves": "El Elegido Consigue Guantes de Boxeo", + "Chosen One Gets Shield": "El Elegido Consigue Electro-Escudo", + "Chosen One Time": "Tiempo del Elegido", + "Enable Impact Bombs": "Habilitar Insta-Bombas", + "Enable Triple Bombs": "Habilitar Bombas Triples", + "Entire Team Must Finish": "Todo el Equipo Debe Terminar", + "Epic Mode": "Modo Épico", + "Flag Idle Return Time": "Tiempo de Retorno de Bandera Inactiva", + "Flag Touch Return Time": "Retorno de Bandera con Toque", + "Hold Time": "Retención", + "Kills to Win Per Player": "Asesinatos para Ganar Por Jugador", + "Laps": "Vueltas", + "Lives Per Player": "Vidas Por Jugador", + "Long": "Largo", + "Longer": "Más Largo", + "Mine Spawning": "Aparecer Minas", + "No Mines": "Sin Minas", + "None": "Ninguno", + "Normal": "Normal", + "Pro Mode": "Modo Pro", + "Respawn Times": "Tiempo de Reaparición", + "Score to Win": "Puntos para Ganar", + "Short": "Corto", + "Shorter": "Más Corto", + "Solo Mode": "Modo Solitario", + "Target Count": "Número de Objetivos", + "Time Limit": "Límite de Tiempo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} ha sido descalificado porque ${PLAYER} se ha ido", + "Killing ${NAME} for skipping part of the track!": "¡${NAME} Murió por saltarse un pedazo de la pista!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / spam de botones te noqueará." + }, + "teamNames": { + "Bad Guys": "Chicos Malos", + "Blue": "Azul", + "Good Guys": "Chicos Buenos", + "Red": "Rojo" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un corre-salta-gira-golpea perfecto puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.", + "Always remember to floss.": "Siempre acuérdate de cepillar tus dientes.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea perfiles para \ntu y tus amigos \ncon \ntus nombres preferidos y\napariencias en vez de usar unos aleatorios.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Las cajas de maldición te convierten en una bomba de tiempo.\nLa única cura es agarrar rápidamente un botiquín.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de sus apariencias, las habilidades de todos los personajes\nson idénticas, así que escoge el que más te guste a ti.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No eres invencible con ese electro-escudo; todavía puedes caerte de un acantilado.", + "Don't run all the time. Really. You will fall off cliffs.": "No corras todo el tiempo. En serio. Te vas a caer.", + "Don't spin for too long; you'll become dizzy and fall.": "No gires por un largo tiempo; puedes marearte y caer.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Mantén cualquier botón para correr. (Los gatillos son para eso si los tienes)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén presionado cualquier botón para correr. Llegarás a lugares más rápido\npero no girarás muy bien, así que cuidado con los acantilados.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de Hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te recoge, dale un golpe y te soltará.\nTambién funciona en la vida real.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si no tienes suficientes controles, instala la aplicación '${REMOTE_APP_NAME}'\nen tus dispositivos móviles para usarlos como controles.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Si te adhieres a una bomba pegajosa, salta y da muchas vueltas. Es posible que sacudas\nla bomba pegada o sin nada más tus últimos momentos serán entretenidos.", + "If you kill an enemy in one hit you get double points for it.": "Si matas a un enemigo de un solo golpe obtendrás puntos dobles.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si tomaste una maldición, tu única esperanza es\nencontrar un botiquín en tus últimos segundos.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Si te quedas quieto, estás frito. Corre y esquiva para sobrevivir...", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si tienes muchos jugadores yendo y viniendo, activa 'expulsar jugadores inactivos'\nen ajustes en caso de que alguien se olvide de abandonar el juego.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o la \"Resolución\" en Ajustes->Gráficos", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si la imagen va lenta, intenta reducir la resolución\no los visuales en los ajustes gráficos del juego.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Captura la Bandera, la bandera tuya debe estar en tu base para que anotes.\nSi el otro equipo está a punto de anotar, robar su bandera evitará que anoten.", + "In hockey, you'll maintain more speed if you turn gradually.": "En hockey, mantendrás tu impulso si giras gradualmente.", + "It's easier to win with a friend or two helping.": "Es más fácil ganar con un amigo o dos ayudando.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Salta antes de tirar una bomba para que alcance lugares altos.", + "Land-mines are a good way to stop speedy enemies.": "Las minas terrestres son una buena manera para detener enemigos veloces.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muchas cosas se pueden recoger y lanzar, incluyendo a otros jugadores.\nArroja a tus enemigos por los precipicios. Te sentirás mejor.", + "No, you can't get up on the ledge. You have to throw bombs.": "No, no puedes subir a la cornisa. Tienes que lanzar bombas.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Los jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes conectar o quitar controles en cualquier momento.", + "Practice using your momentum to throw bombs more accurately.": "Practica usando tu impulso para tirar bombas con más precisión.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Los golpes hacen más daño cuanto más rápido se mueven tus puños,\nasí que intenta correr, saltar y girar como un loco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba para 'latiguearla' y lanzarla lejos.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimina un gran cantidad de enemigos\nal detonar una bomba cerca de una caja TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La cabeza es la zona más vulnerable, una bomba pegajosa\na la cabeza usualmente significa game-over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nivel no tiene fin, pero un alto puntaje aquí\nte hará ganar el respeto eterno por todo el mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "La fuerza de tiro se basa en la dirección que estás sosteniendo.\nPara arrojar algo justo delante de ti, no sostengas ninguna dirección.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "¿Cansado de la pista de audio? ¡Reemplázala con tu música!\nVe a Ajustes->Audio->Banda Sonora", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Intenta 'Cocinar' bombas por un segundo o dos antes de tirarlas.", + "Try tricking enemies into killing eachother or running off cliffs.": "Engaña a tus enemigos para que se eliminen entre sí o para que corran a los acantilados.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Usa el botón de 'recoger' para agarrar la bandera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Azota de un lado a otro para conseguir más distancia en tus tiros.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Puedes 'dirigir' tus golpes girando a la izquierda o derecha. Esto\nes útil para tirar a los enemigos al vacío o para anotar en el hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Puedes saber si una bomba va a explotar basado en el \ncolor de las chispas de su mecha: amarillo...naranja...rojo...¡BOOM!", + "You can throw bombs higher if you jump just before throwing.": "Puedes tirar bombas más alto si saltas justo antes de tirarlas.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Te haces daño si golpeas tu cabeza contra cosas, \nasí que trata de no golpear tu cabeza contra cosas.", + "Your punches do much more damage if you are running or spinning.": "Tus golpes hacen mucho más daño si estás corriendo o girando." + } + }, + "trophiesRequiredText": "Esto requiere al menos ${NUMBER} trofeos.", + "trophiesText": "Trofeos", + "trophiesThisSeasonText": "Trofeos Esta Temporada", + "tutorial": { + "cpuBenchmarkText": "Corriendo tutorial en velocidad ridícula (pruebas de velocidad de CPU)", + "phrase01Text": "¡Hey, hola!", + "phrase02Text": "¡Bienvenido a ${APP_NAME}!", + "phrase03Text": "Te dare algunos consejos para controlar tu personaje:", + "phrase04Text": "Muchas cosas en ${APP_NAME} se basan mayoritariamente en FÍSICAS.", + "phrase05Text": "Por ejemplo, cuando golpeas...", + "phrase06Text": "..el daño se basa en la velocidad de tus puños.", + "phrase07Text": "¿Ves? No nos estábamos moviendo, así que eso apenas lastimó a ${NAME}.", + "phrase08Text": "Ahora vamos a saltar y girar para conseguir más velocidad.", + "phrase09Text": "Ah, mucho mejor.", + "phrase10Text": "Correr también ayuda.", + "phrase11Text": "Mantén pulsado CUALQUIER botón para correr.", + "phrase12Text": "Para golpes extra-asombrosos, intenta correr Y girar.", + "phrase13Text": "Ups; lo siento por eso ${NAME}.", + "phrase14Text": "Puedes recoger y lanzar cosas como banderas.. o ${NAME}.", + "phrase15Text": "Por último, hay bombas.", + "phrase16Text": "Lanzar bombas requiere práctica.", + "phrase17Text": "¡Auch! Ese no fue un buen tiro.", + "phrase18Text": "Moverte ayuda a lanzarlas más lejos.", + "phrase19Text": "Saltar ayuda a lanzarlas más alto.", + "phrase20Text": "\"Latiguea\" tus bombas para hacer lanzamientos aún más lejanos.", + "phrase21Text": "Hacer que exploten donde tú quieres puede ser complicado.", + "phrase22Text": "Rayos.", + "phrase23Text": "Intentemos \"cocinar\" la mecha por un segundo o dos.", + "phrase24Text": "¡Hurra! Así es como se hace.", + "phrase25Text": "Bueno, eso es todo.", + "phrase26Text": "¡Ahora ve por ellos, campeón!", + "phrase27Text": "Recuerda tu entrenamiento, ¡y VOLVERÁS con vida!", + "phrase28Text": "...o a lo mejor...", + "phrase29Text": "¡Buena Suerte!", + "randomName1Text": "Federico", + "randomName2Text": "Enrique", + "randomName3Text": "Guillermo", + "randomName4Text": "Carlos", + "randomName5Text": "Felipe", + "skipConfirmText": "¿Realmente quieres omitir el tutorial? Toca o presiona para confirmar.", + "skipVoteCountText": "${COUNT}/${TOTAL} votos para saltarse el tutorial", + "skippingText": "saltando el tutorial...", + "toSkipPressAnythingText": "(pulsa cualquier botón para omitir el tutorial)" + }, + "twoKillText": "¡COMBO DOBLE!", + "uiScaleText": "Escala de Interfaz de Usuario", + "unavailableText": "no disponible", + "unclaimedPrizesText": "Tienes premios sin reclamar!", + "unconfiguredControllerDetectedText": "Control desconfigurado detectado:", + "unlockThisInTheStoreText": "Esto debe ser desbloqueado en la tienda.", + "unlockThisProfilesText": "Para crear más de ${NUM} cuentas, necesitas:", + "unlockThisText": "Para desbloquear esto, necesitas:", + "unsupportedControllerText": "Lo sentimos, el control \"${NAME}\" no es compatible.", + "unsupportedHardwareText": "Disculpe, este dispositivo no soporta esta compilación del juego.", + "upFirstText": "A continuación:", + "upNextText": "A continuación en el juego ${COUNT}:", + "updatingAccountText": "Actualizando tu cuenta...", + "upgradeText": "Mejorar", + "upgradeToPlayText": "Desbloquea \"${PRO}\" en la tienda para jugar esto.", + "useDefaultText": "Usar Por Defecto", + "userSystemScriptsCreateText": "Crear Scripts del Sistema del Usuario", + "userSystemScriptsDeleteText": "Eliminar Scripts del Sistema del Usuario", + "usesExternalControllerText": "Este juego usa un control externo como entrada.", + "usingItunesText": "Usando Aplicación de Música para la banda sonora...", + "v2AccountLinkingInfoText": "Para vincular cuentas V2, usa el botón \"Administrar Cuenta\".", + "v2AccountRequiredText": "Esto requiere una cuenta V2. Actualice su cuenta e inténtelo de nuevo.", + "validatingTestBuildText": "Validando Compilación de Prueba...", + "viaText": "a través de", + "victoryText": "¡Victoria!", + "voteDelayText": "No puedes iniciar otra votación por ${NUMBER} segundo(s)", + "voteInProgressText": "Ya hay una votación en progreso.", + "votedAlreadyText": "Ya votaste", + "votesNeededText": "${NUMBER} voto(s) necesario(s)", + "vsText": "vs.", + "waitingForHostText": "(esperando a que ${HOST} continúe)", + "waitingForPlayersText": "esperando jugadores para unirse...", + "waitingInLineText": "Esperando en línea (la partida está llena)...", + "watchAVideoText": "Ver un Vídeo", + "watchAnAdText": "Ver un Anuncio", + "watchWindow": { + "deleteConfirmText": "¿Borrar \"${REPLAY}\"?", + "deleteReplayButtonText": "Borrar\nRepetición", + "myReplaysText": "Mis Repeticiones", + "noReplaySelectedErrorText": "Ninguna Repetición Seleccionada", + "playbackSpeedText": "Velocidad de Reproducción: ${SPEED}", + "renameReplayButtonText": "Renombrar\nRepetición", + "renameReplayText": "Renombrar \"${REPLAY}\" a:", + "renameText": "Renombrar", + "replayDeleteErrorText": "Error borrando la repetición.", + "replayNameText": "Nombre de la Repetición", + "replayRenameErrorAlreadyExistsText": "Una repetición con ese nombre ya existe.", + "replayRenameErrorInvalidName": "No se puede renombrar la repetición; nombre inválido.", + "replayRenameErrorText": "Error renombrando repetición.", + "sharedReplaysText": "Compartir repeticiones", + "titleText": "Ver", + "watchReplayButtonText": "Ver\nRepetición" + }, + "waveText": "Oleada", + "wellSureText": "¡Pues Claro!", + "whatIsThisText": "¿Qué es esto?", + "winsPlayerText": "¡${NAME} Gana!", + "winsTeamText": "¡${NAME} Gana!", + "winsText": "¡Ganó ${NAME}!", + "workspaceSyncErrorText": "Error al sincronizar ${WORKSPACE}. Mira el registro para más detalles.", + "workspaceSyncReuseText": "No se puede sincronizar ${WORKSPACE}. Reusando la versión previamente sincronizada.", + "worldScoresUnavailableText": "Puntuaciones mundiales no disponibles.", + "worldsBestScoresText": "Mejores Puntuaciones Mundiales", + "worldsBestTimesText": "Mejores Tiempos Mundiales", + "yesAllowText": "¡Sí, Permitir!", + "yourBestScoresText": "Tus Mejores Puntajes", + "yourBestTimesText": "Tus Mejores Tiempos", + "yourPrizeText": "Tu premio:" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/swedish.json b/dist/ba_data/data/languages/swedish.json index 6590ae52..2bcaff46 100644 --- a/dist/ba_data/data/languages/swedish.json +++ b/dist/ba_data/data/languages/swedish.json @@ -8,6 +8,7 @@ "changeOncePerSeason": "Du kan enbart ändra detta en gång per säsong.", "changeOncePerSeasonError": "Du måste vänta tills nästa säsong för att ändra detta igen (${NUM} days)", "customName": "Anpassat Namn", + "deleteAccountText": "Ta bort konto", "googlePlayGamesAccountSwitchText": "Om du vill använda ett annat Google-konto,\nanvänd appen Google Play Spel för att byta.", "linkAccountsEnterCodeText": "Skriv in kod", "linkAccountsGenerateCodeText": "Generera kod", @@ -26,14 +27,16 @@ "setAccountNameDesc": "Välj ett namn att visa för ditt konto.\nDu kan använda användarnamnet från något av dina länkade konton eller skapa ett unikt namn.", "signInInfoText": "Logga in för att samla värdekuponger, tävla \non-line och dela framsteg över olika enheter.", "signInText": "Logga In", + "signInWithAnEmailAddressText": "Logga in med en e-postadress", "signInWithDeviceInfoText": "(endast ett automatiskt konto finns på denna enhet)", "signInWithDeviceText": "Logga in med ett enhetskonto", "signInWithGameCircleText": "Logga in med Spel Cirkel", "signInWithGooglePlayText": "Logga in med Google Play", - "signInWithTestAccountInfoText": "(allmän konto typ; använd enhets konton för att fortsätta)", + "signInWithTestAccountInfoText": "(allmän konto typ; använd enhets konton för att fortsätta) ", "signInWithTestAccountText": "Logga in med ett testkonto", + "signInWithText": "Logga in med ${SERVICE}", "signInWithV2InfoText": "(ett konto som fungerar på alla plattformar)", - "signInWithV2Text": "Logga in med ett BombSquad-konto", + "signInWithV2Text": "Logga in med ett ${APP_NAME} konto", "signOutText": "Logga Ut", "signingInText": "Loggar in...", "signingOutText": "Loggar ut...", @@ -44,6 +47,7 @@ "titleText": "Konto", "unlinkAccountsInstructionsText": "Välj ett konto att avlänka", "unlinkAccountsText": "Avlänka Konton", + "unlinkLegacyV1AccountsText": "Ta bort länken till äldre konton (V1)", "v2LinkInstructionsText": "Använd den här länken för att skapa ett konto eller logga in.", "viaAccount": "(via konto ${NAME})", "youAreLoggedInAsText": "Du är inloggad som:", @@ -333,13 +337,19 @@ "achievementsRemainingText": "Prestationer som återstår:", "achievementsText": "Prestationer", "achievementsUnavailableForOldSeasonsText": "Tyvärr, prestation detaljerna är inte tillgängliga för gamla säsonger.", + "activatedText": "${THING} aktiverad", "addGameWindow": { "getMoreGamesText": "Hämta Fler Spel...", "titleText": "Lägg till Spel" }, + "addToFavoritesText": "Lägg till i favoriter", + "addedToFavoritesText": "Lade till '${NAME}' i Favoriter.", + "allText": "Alla", "allowText": "Tillåt", "alreadySignedInText": "Ditt konto är redan inloggat på en annan enhet;\nvar god byt konto eller stäng spelet på dina\nandra enheter och försök igen.", "apiVersionErrorText": "Kan inte öppna ${NAME}; den änvänder api-version ${VERSION_USED}; det krävs dock ${VERSION_REQUIRED}.", + "applyText": "Använda", + "areYouSureText": "Är du säker?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Auto\" aktiverar endast detta när hörlurar är inkopplade)", "headRelativeVRAudioText": "Huvud-Relativt VR Audio", @@ -364,7 +374,7 @@ "boostText": "Höj", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} är konfigurerad i appen själv.", "buttonText": "Knapp", - "canWeDebugText": "Vill du att BombSquad automatiskt ska skicka bug, - och crashrapporter och grundläggande användarinfo till utvecklaren?\n\nDenna data innehåller ingen personlig information och\nhjälper till med att låta spelet flyta jämnt och felfritt.", + "canWeDebugText": "Vill du att ${APP_NAME} ska rapportera automatiskt\nbuggar, krascher och grundläggande användningsinformation till utvecklaren?\n\nDessa uppgifter innehåller ingen personlig information och hjälper till\nSe till att spelet fungerar smidigt och utan buggar.", "cancelText": "Avbryt", "cantConfigureDeviceText": "Tyvärr, ${DEVICE} är inte konfigurerbar", "challengeEndedText": "Denna utmaning är avslutad.", @@ -372,6 +382,7 @@ "chatMutedText": "Chatt dämpad", "chatUnMuteText": "Avsluta chatt", "choosingPlayerText": "", + "codesExplainText": "Koderna tillhandahålls av utvecklaren till:\nDiagnostisera och felsök ditt konto.", "completeThisLevelToProceedText": "Du måste klara\ndenna nivå för att fortsätta!", "completionBonusText": "Slutbonus", "configControllersWindow": { @@ -455,6 +466,7 @@ "titleText": "Konfigurera touchscreen", "touchControlsScaleText": "Touchkontroll skalning" }, + "configureDeviceInSystemSettingsText": "${DEVICE} kan konfigureras i appen Systeminställningar.", "configureItNowText": "Konfigurera nu?", "configureText": "Konfigurera", "connectMobileDevicesWindow": { @@ -510,6 +522,7 @@ "welcome2Text": "Du kan också tjäna biljetter från många av samma verksamhet .\nBiljetter kan användas för att låsa upp nya karaktärer, kartor och\nmini -spel , att delta i turneringar och mycket mer .", "yourPowerRankingText": "Din Spelar Rankning" }, + "copyConfirmText": "Kopieras till Urklipp.", "copyOfText": "${NAME} Kopia", "copyText": "Kopiera", "createAPlayerProfileText": "Skapa en spelarprofil?", @@ -562,7 +575,10 @@ "deleteText": "Radera", "demoText": "Demo", "denyText": "Neka", + "deprecatedText": "Deprecated", + "descriptionText": "Beskrivning", "desktopResText": "Skrivbordsupplösning", + "deviceAccountUpgradeText": "Varning:\nDu är inloggad med ett enhetskonto (${NAME}).\nEnhetskonton kommer att tas bort i en framtida uppdatering.\nUppgradera till ett V2-konto om du vill behålla dina framsteg.", "difficultyEasyText": "Lätt", "difficultyHardOnlyText": "Endast Svårt Läge", "difficultyHardText": "Svår", @@ -571,6 +587,9 @@ "disableRemoteAppConnectionsText": "Inaktivera Fjärrapps-Anslutningar", "disableXInputDescriptionText": "Tillåter mer än 4 kontroller men kanske inte funkar så bra.", "disableXInputText": "Inaktivera XInput", + "disabledText": "Handikappad", + "discordFriendsText": "Vill du leta efter nya människor att spela med?\nGå med i vår Discord och hitta nya vänner!", + "discordJoinText": "Gå med i Discord", "doneText": "Klar", "drawText": "Oavgjort", "duplicateText": "Fördubbla", @@ -605,6 +624,7 @@ "localProfileText": "(lokal profil)", "nameDescriptionText": "Spelarnamn", "nameText": "Namn", + "profileAlreadyExistsText": "Det finns redan en profil med det namnet.", "randomText": "slumpvis", "titleEditText": "Redigera Profil", "titleNewText": "Ny Profil", @@ -642,12 +662,15 @@ "useMusicFolderText": "Mappnamn för Musikfiler" }, "editText": "Redigera", + "enabledText": "Aktiverad", "endText": "slut", "enjoyText": "Ha det så roligt!", "epicDescriptionFilterText": "${DESCRIPTION} i episk slow moition.", "epicNameFilterText": "Episk ${NAME}", "errorAccessDeniedText": "åtkomst nekad", + "errorDeviceTimeIncorrectText": "Din enhets tid är felaktig med ${HOURS} timmar.\nDetta kommer sannolikt att orsaka problem.\nKontrollera dina tids- och tidszonsinställningar.", "errorOutOfDiskSpaceText": "slut på diskutrymme", + "errorSecureConnectionFailText": "Det går inte att upprätta en säker molnanslutning; nätverksfunktionen kan misslyckas.", "errorText": "Fel", "errorUnknownText": "okänt fel", "exitGameText": "Avsluta ${APP_NAME}?", @@ -687,6 +710,8 @@ "editText": "Redigera\nSpellista", "gameListText": "Spellista", "newText": "Ny\nSpellista", + "pointsToWinText": "Poäng för att vinna", + "seriesLengthText": "Serie Längd", "showTutorialText": "Visa Handledning", "shuffleGameOrderText": "Blanda spel-ordning", "titleText": "Redigera ${TYPE} Spellistor" @@ -1126,6 +1151,7 @@ "purchasingText": "Köper...", "quitGameText": "Avsluta BombSquad?", "quittingIn5SecondsText": "Avslutar om 5 sekunder...", + "randomPlayerNamesText": "Oliver, Carl, Tomten, Ikea, Vikingar", "randomText": "Slumpad", "rankText": "Rang", "ratingText": "Rating", @@ -1205,7 +1231,7 @@ }, "showText": "Visa", "signInForPromoCodeText": "Du måste logga in på ett konto för att promotion koder ska aktiveras.", - "signInWithGameCenterText": "För att använda ett Game Center konto, \nlogga in via Game Center appen.", + "signInWithGameCenterText": "För att använda ett Game Center konto, \nlogga in via Game Center appen. ", "singleGamePlaylistNameText": "Endast ${GAME}", "singlePlayerCountText": "1 spelare", "soloNameFilterText": "Solo ${NAME}", diff --git a/dist/ba_data/data/languages/tamil.json b/dist/ba_data/data/languages/tamil.json index 1ca6ed33..c48dbd1a 100644 --- a/dist/ba_data/data/languages/tamil.json +++ b/dist/ba_data/data/languages/tamil.json @@ -6,7 +6,9 @@ "campaignProgressText": "பிரச்சார முன்னேற்றம் [கடினமானது] : ${PROGRESS}", "changeOncePerSeason": "ஒரு பருவத்திற்கு ஒரு முறை மட்டுமே இதை மாற்ற முடியும்.", "changeOncePerSeasonError": "இதை மீண்டும் மாற்ற அடுத்த சீசன் வரை நீங்கள் காத்திருக்க வேண்டும் (${NUM} நாட்கள்)", + "createAnAccountText": "புதிய கணக்கை உருவாக்கவும்", "customName": "தனிப்பயன் பெயர்", + "deleteAccountText": "கணக்கை நீக்கவும்", "googlePlayGamesAccountSwitchText": "நீங்கள் வேறு Google கணக்கைப் பயன்படுத்த விரும்பினால்,\nமாறுவதற்கு Google Play கேம்ஸ் பயன்பாட்டைப் பயன்படுத்தவும்.", "linkAccountsEnterCodeText": "குறியீட்டை உள்ளிடவும்", "linkAccountsGenerateCodeText": "குறியீட்டை உருவாக்கவும்", @@ -23,14 +25,16 @@ "setAccountNameDesc": "உங்கள் கணக்குக்கு காட்ட வேண்டிய பெயரை தேர்வு செய்யவும். \nஉங்கள் இணைக்கப்பட்ட கணக்குகளிலிருந்து ஒரு பெயரை தேர்வு செய்யலாம் \nஅல்லது புதிய பெயரை உருவாக்கலாம்.", "signInInfoText": "சீட்டுகள் சேர்க்க, இணையத்தில் போட்டியிட,\nமுன்னேற்றங்களை பகிர, புகுபதிவு செய்யவும்.", "signInText": "புகுபதிகை", + "signInWithAnEmailAddressText": "மின்னஞ்சல் முகவரியுடன் உள்நுழை", "signInWithDeviceInfoText": "(இந்த சாதனத்திலிருந்து ஒரு தானியங்கி கணக்கு மட்டுமே கிடைக்கும்)", "signInWithDeviceText": "சாதனக் கணக்கில் உள்நுழைக", "signInWithGameCircleText": "Game Circle மூலம் உள்நுழைக", "signInWithGooglePlayText": "Google Play உடன் உள்நுழைக", "signInWithTestAccountInfoText": "(மரபு கணக்கு வகை; முன்னோக்கி செல்லும் சாதனக் கணக்குகளைப் பயன்படுத்தவும்)", "signInWithTestAccountText": "சோதனைக் கணக்கில் உள்நுழைக", + "signInWithText": "${SERVICE} -உடன் உள்நுழை", "signInWithV2InfoText": "(அனைத்து தளங்களிலும் செயல்படும் கணக்கு)", - "signInWithV2Text": "BombSquad கணக்கில் உள்நுழையவும்", + "signInWithV2Text": "${APP_NAME} கணக்கில் உள்நுழையவும்", "signOutText": "வெளியேறு", "signingInText": "புகுபதிகை நடைபெறுகிறது...", "signingOutText": "விடுபதிகை நடைபெறுகிறது...", @@ -332,9 +336,14 @@ "getMoreGamesText": "மேலும் விளையாட்டுகளைப் பெறுங்கள்...", "titleText": "விளையாட்டைச் சேர்" }, + "addToFavoritesText": "பிடித்தவையில் சேர்", + "addedToFavoritesText": "பிடித்தவற்றில் '${NAME}' சேர்க்கப்பட்டது", + "allText": "அனைத்து", "allowText": "அனுமதி", "alreadySignedInText": "உங்கள் கணக்கு மற்றொரு சாதனத்திலிருந்து உள்நுழைந்துள்ளது;\nதயவுசெய்து கணக்குகளை மாற்றவும் அல்லது விளையாட்டை மூடவும்\nபிற சாதனங்கள் மற்றும் மீண்டும் முயற்சிக்கவும்.", "apiVersionErrorText": "${NAME} தொகுதியை ஏற்ற முடியவில்லை; இது api-version ${VERSION_USED} ஐ குறிவைக்கிறது; எங்களுக்கு ${VERSION_REQUIRED} தேவைப்படுகிறது.", + "applyText": "இடு", + "areYouSureText": "நீ சொல்வது உறுதியா?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(ஹெட்ஃபோன்கள் செருகப்படும்போது மட்டுமே \"ஆட்டோ\" இதை இயக்குகிறது)", "headRelativeVRAudioText": "தலை-உறவினர் VR ஆடியோ", @@ -357,14 +366,24 @@ "boostText": "ஊக்குவிக்கவும்", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} பயன்பாட்டில் உள்ளமைக்கப்பட்டுள்ளது.", "buttonText": "பொத்தானை", - "canWeDebugText": "BombSquad தானாகப் புகாரளிக்க விரும்புகிறீர்களா?\nடெவலப்பருக்கு பிழைகள், செயலிழப்புகள் மற்றும் அடிப்படை பயன்பாட்டு தகவல்?\n\nஇந்தத் தரவில் தனிப்பட்ட தகவல் இல்லை மற்றும் உதவுகிறது\nவிளையாட்டை சீராக மற்றும் பிழையில்லாமல் வைத்துக்கொள்ளுங்கள்.", + "canWeDebugText": "${APP_NAME} தானாகப் புகாரளிக்க விரும்புகிறீர்களா?\nடெவலப்பருக்கு பிழைகள், செயலிழப்புகள் மற்றும் அடிப்படை பயன்பாட்டு தகவல்?\n\nஇந்தத் தரவில் தனிப்பட்ட தகவல் இல்லை மற்றும் உதவுகிறது\nவிளையாட்டை சீராக மற்றும் பிழையில்லாமல் வைத்துக்கொள்ளுங்கள்.", "cancelText": "ரத்து", "cantConfigureDeviceText": "மன்னிக்கவும்,${DEVICE} கட்டமைக்கப்படவில்லை.", "challengeEndedText": "இந்த சவால் முடிந்தது.", "chatMuteText": "அரட்டை முடக்கு", "chatMutedText": "அரட்டை முடக்கப்பட்டது", "chatUnMuteText": "அரட்டையை இயக்கு", + "chests": { + "prizeOddsText": "பரிசு முரண்பாடுகள்", + "reduceWaitText": "காத்திருப்பைக் குறைக்கவும்", + "slotDescriptionText": "இந்த ஸ்லாட் ஒரு மார்பை வைத்திருக்க முடியும்.\n\nபிரச்சார நிலைகளில் விளையாடுவதன் மூலம் மார்புகளை சம்பாதிக்கவும்,\nபோட்டிகளில் இடம்பெறுதல், மற்றும் நிறைவு செய்தல்\nசாதனைகள்.", + "slotText": "மார்பு துளை ${NUM}", + "slotsFullWarningText": "எச்சரிக்கை: உங்கள் பெட்டிகள் நிரம்பியுள்ளன.\nஇந்த விளையாட்டில் பெறும் புதிய பெட்டிகள் கிடைக்காது.", + "unlocksInText": "திறப்பதற்கு இன்னும் இருக்க நேரம்" + }, "choosingPlayerText": "<பிளேயரைத் தேர்ந்தெடுப்பது>", + "claimText": "உரிமைகோரல்", + "codesExplainText": "கணக்குச் சிக்கல்களைக் கண்டறிந்து சரிசெய்ய\nடெவலப்பர்களால் குறியீடுகள் வழங்கப்படுகின்றன.", "completeThisLevelToProceedText": "தொடர நீங்கள்\n இந்த நிலையை முடிக்க வேண்டும்!", "completionBonusText": "நிறைவு போனஸ்", "configControllersWindow": { @@ -445,6 +464,7 @@ "swipeText": "ஸ்வைப்", "titleText": "தொடுதிரையை உள்ளமைக்கவும்" }, + "configureDeviceInSystemSettingsText": "${DEVICE} ஐ சிஸ்டம் அமைப்புகள் பயன்பாட்டில் உள்ளமைக்க முடியும்.", "configureItNowText": "இப்போது அதை உள்ளமைக்கவா?", "configureText": "உள்ளமை", "connectMobileDevicesWindow": { @@ -548,6 +568,7 @@ "demoText": "டெமோ", "denyText": "மறுக்க", "deprecatedText": "நிராகரிக்கப்பட்டது", + "descriptionText": "விளக்கம்", "desktopResText": "டெஸ்க்டாப் ரெஸ்", "deviceAccountUpgradeText": "எச்சரிக்கை:\nசாதனக் கணக்கில் (${NAME}) உள்நுழைந்துள்ளீர்கள்.\nஎதிர்கால புதுப்பிப்பில் சாதன கணக்குகள் அகற்றப்படும்.\nஉங்கள் முன்னேற்றத்தைத் தொடர விரும்பினால், V2 கணக்கிற்கு மேம்படுத்தவும்.", "difficultyEasyText": "சுலபம்", @@ -558,6 +579,10 @@ "disableRemoteAppConnectionsText": "ரிமோட்-ஆப் இணைப்புகளை முடக்கு", "disableXInputDescriptionText": "4 க்கும் மேற்பட்ட கட்டுப்பாட்டாளர்களை அனுமதிக்கிறது ஆனால் வேலை செய்யாமல் போகலாம்.", "disableXInputText": "XInput ஐ முடக்கு", + "disabledText": "முடக்கப்பட்ட எழுத்து", + "discardText": "புறக்கணிடு", + "discordFriendsText": "விளையாட புதிய நபர்களைத் தேட வேண்டுமா?\nஎங்கள் டிஸ்கார்டில் சேர்ந்து புதிய நண்பர்களைக் கண்டறியவும்!", + "discordJoinText": "டிஸ்கார்டில் சேரவும்", "doneText": "முடிந்தது", "drawText": "டிரா", "duplicateText": "நகல்எடுத்தல்", @@ -590,6 +615,7 @@ "localProfileText": "(உள்ளூர் சுயவிவரம்)", "nameDescriptionText": "வீரரின் பெயர்", "nameText": "பெயர்", + "profileAlreadyExistsText": "அந்தப் பெயரில் ஒரு சுயவிவரம் ஏற்கனவே உள்ளது.", "randomText": "சீரற்ற", "titleEditText": "சுயவிவரத்தைத் திருத்து", "titleNewText": "புதிய சுயவிவரம்", @@ -625,6 +651,7 @@ "useMusicFolderText": "இசை கோப்புகளின் கோப்புறை" }, "editText": "மாற்று", + "enabledText": "செயல்படுத்த", "endText": "முற்று", "enjoyText": "மகிழ்!", "epicDescriptionFilterText": "${DESCRIPTION} காவிய மெதுவான இயக்கத்தில்.", @@ -670,6 +697,8 @@ "duplicateText": "நகல்எடு்\nபிளேலிஸ்ட்", "editText": "தொகு\nபிளேலிஸ்ட்", "newText": "புதிய\nபிளேலிஸ்ட்", + "pointsToWinText": "வெற்றிக்கான புள்ளிகள்", + "seriesLengthText": "தொடர் நீளம்", "showTutorialText": "டுடோரியலைக் காட்டு", "shuffleGameOrderText": "விளையாட்டு ஆர்டரை கலக்கவும்", "titleText": "${TYPE} பிளேலிஸ்ட்களைத் தனிப்பயனாக்கவும்" @@ -707,10 +736,10 @@ "friendHasSentPromoCodeText": "${NAME} இலிருந்து ${COUNT} ${APP_NAME} டிக்கெட்டுகள்", "friendPromoCodeAwardText": "ஒவ்வொரு முறையும் நீங்கள் பயன்படுத்தும்போது ${COUNT} டிக்கெட்டுகளைப் பெறுவீர்கள்.", "friendPromoCodeExpireText": "குறியீடு ${EXPIRE_HOURS} மணிநேரத்தில் காலாவதியாகும் மற்றும் புதிய பிளேயர்களுக்கு மட்டுமே வேலை செய்யும்.", - "friendPromoCodeInstructionsText": "இதைப் பயன்படுத்த, ${APP_NAME} ஐத் திறந்து \"அமைப்புகள்-> மேம்பட்ட-> குறியீட்டை உள்ளிடவும்\" என்பதற்குச் செல்லவும்.\nஆதரிக்கப்படும் அனைத்து தளங்களுக்கும் பதிவிறக்க இணைப்புகளுக்கு bombsquadgame.com ஐப் பார்க்கவும்.", + "friendPromoCodeInstructionsText": "இதைப் பயன்படுத்த, ${APP_NAME} ஐத் திறந்து \"அமைப்புகள்->மேம்பட்ட->தகவல் அனுப்பு\" என்பதற்குச் செல்லவும்.\nஆதரிக்கப்படும் அனைத்து தளங்களுக்கும் பதிவிறக்க இணைப்புகளுக்கு bombsquadgame.com ஐப் பார்க்கவும்.", "friendPromoCodeRedeemLongText": "இதை ${MAX_USES} பேர் வரை ${COUNT} இலவச டிக்கெட்டுகளுக்கு மீட்டெடுக்கலாம்.", "friendPromoCodeRedeemShortText": "விளையாட்டில் ${COUNT} டிக்கெட்டுகளுக்கு அதை மீட்டெடுக்கலாம்.", - "friendPromoCodeWhereToEnterText": "(\"அமைப்புகள்-> மேம்பட்ட-> குறியீட்டை உள்ளிடவும்\")", + "friendPromoCodeWhereToEnterText": "(\"அமைப்புகள்->மேம்பட்ட->தகவல் அனுப்பு\")", "getFriendInviteCodeText": "நண்பர் அழைப்புக் குறியீட்டைப் பெறுங்கள்", "googlePlayDescriptionText": "உங்கள் விருந்துக்கு Google Play பிளேயர்களை அழைக்கவும்:", "googlePlayInviteText": "அழை", @@ -742,6 +771,7 @@ "manualYourLocalAddressText": "உங்கள் உள்ளூர் முகவரி:", "nearbyText": "அருகில்", "noConnectionText": "<இணைப்பு இல்லை>", + "noPartiesAddedText": "கூட்டங்கள் சேர்க்கப்படவில்லை", "otherVersionsText": "(பிற பதிப்புகள்)", "partyCodeText": "பார்ட்டி குறியீடு", "partyInviteAcceptText": "ஏற்றுக்கொள்", @@ -805,6 +835,12 @@ "youHaveShortText": "உங்களிடம் ${COUNT} உள்ளது", "youHaveText": "உங்களிடம் ${COUNT} டிக்கெட்டுகள் உள்ளன" }, + "goldPass": { + "desc1InfTokensText": "எல்லையற்ற டோக்கன்கள்.", + "desc2NoAdsText": "விளம்பரங்கள் இல்லை.", + "desc3ForeverText": "எப்போதும்.", + "goldPassText": "தங்க நுழைவு அட்டை" + }, "googleMultiplayerDiscontinuedText": "மன்னிக்கவும், கூகுளின் மல்டிபிளேயர் சேவை இனி கிடைக்காது.\nநான் முடிந்தவரை விரைவாக மாற்றுவதற்கு வேலை செய்கிறேன்.\nஅதுவரை, வேறு இணைப்பு முறையை முயற்சிக்கவும்.\n-எரிக்", "googlePlayPurchasesNotAvailableText": "Google Play வாங்குதல்கள் கிடைக்கவில்லை.\nஉங்கள் ஸ்டோர் பயன்பாட்டைப் புதுப்பிக்க வேண்டியிருக்கலாம்.", "googlePlayServicesNotAvailableText": "Google Play சேவைகள் கிடைக்கவில்லை.\nசில ஆப்ஸ் செயல்பாடுகள் முடக்கப்பட்டிருக்கலாம்.", @@ -813,10 +849,12 @@ "alwaysText": "எப்போதும்", "fullScreenCmdText": "முழுத்திரை (Cmd-F)", "fullScreenCtrlText": "முழுத்திரை (Ctrl-F)", + "fullScreenText": "முழு திரை", "gammaText": "காமா", "highText": "உயர்", "higherText": "அதிக", "lowText": "குறைந்த", + "maxFPSText": "அதிக FPS", "mediumText": "நடுத்தர", "neverText": "ஒருபோதும்", "resolutionText": "பகுத்தல்", @@ -986,6 +1024,7 @@ "tournamentLeagueText": "இந்த போட்டியில் நுழைய நீங்கள் ${NAME} லீக்கை அடைய வேண்டும்.", "trophyCountsResetText": "அடுத்த சீசனில் கோப்பைகளின் எண்ணிக்கை மீட்டமைக்கப்படும்." }, + "learnMoreText": "மேலும் அறிக", "levelBestScoresText": "${LEVEL} இல் சிறந்த மதிப்பெண்கள்", "levelBestTimesText": "${LEVEL} இல் சிறந்த நேரங்கள்", "levelIsLockedText": "${LEVEL} லாக் செய்யப்பட்டது.", @@ -1045,6 +1084,7 @@ "nameSuicideText": "${NAME} தற்கொலை செய்து கொண்டார்.", "nameText": "பெயர்", "nativeText": "பூர்வீகம்", + "newExclaimText": "புதியது!", "newPersonalBestText": "புதிய தனிப்பட்ட சிறந்த!", "newTestBuildAvailableText": "ஒரு புதிய சோதனை உருவாக்கம் கிடைக்கிறது! (${VERSION} உருவாக்க ${BUILD}).\n${ADDRESS} இல் பெறுங்கள்.", "newText": "புதிய", @@ -1055,7 +1095,9 @@ "noContinuesText": "(தொடரும் இல்லை)", "noExternalStorageErrorText": "இந்தச் சாதனத்தில் வெளிப்புறச் சேமிப்பு இல்லை", "noGameCircleText": "பிழை: GameCircle இல் உள்நுழையவில்லை", + "noPluginsInstalledText": "செருகுநிரல்கள் எதுவும் நிறுவப்படவில்லை", "noScoresYetText": "இன்னும் மதிப்பெண்கள் இல்லை.", + "noServersFoundText": "சேவையகங்கள் எதுவும் இல்லை.", "noThanksText": "இல்லை, நன்றி!", "noTournamentsInTestBuildText": "எச்சரிக்கை: இந்த சோதனை உருவாக்கத்தில் இருந்து போட்டியின் மதிப்பெண்கள் புறக்கணிக்கப்படும்.", "noValidMapsErrorText": "இந்த விளையாட்டு வகைக்கு சரியான வரைபடங்கள் இல்லை.", @@ -1124,7 +1166,11 @@ "pleaseWaitText": "தயவுசெய்து காத்திருங்கள்...", "pluginClassLoadErrorText": "செருகுநிரல் வகுப்பை ஏற்றுவதில் பிழை '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "'${PLUGIN}' செருகுநிரலைத் தொடங்குவதில் பிழை: ${ERROR}", + "pluginSettingsText": "செருகுநிரல் அமைப்புகள்", + "pluginsAutoEnableNewText": "புதிய செருகுநிரல்களை தானாக இயக்கவும்", "pluginsDetectedText": "புதிய செருகுநிரல்(கள்) கண்டறியப்பட்டது. அவற்றைச் செயல்படுத்த மீண்டும் தொடங்கவும் அல்லது அமைப்புகளில் உள்ளமைக்கவும்.", + "pluginsDisableAllText": "அனைத்து செருகுநிரல்களையும் முடக்கு", + "pluginsEnableAllText": "அனைத்து செருகுநிரல்களையும் இயக்கு", "pluginsRemovedText": "${NUM} செருகுநிரல்(கள்) இனி காணப்படவில்லை.", "pluginsText": "செருகுநிரல்கள்", "practiceText": "பயிற்சி", @@ -1156,6 +1202,8 @@ "punchText": "குத்து", "purchaseForText": "${PRICE} க்கு வாங்கு", "purchaseGameText": "வாங்கு விளையாட்டு", + "purchaseNeverAvailableText": "மன்னிக்கவும், இந்த உருவாக்கத்தில் வாங்குதல்கள் இல்லை.\nவேறொரு தளத்தில் உங்கள் கணக்கில் உள்நுழைந்து, அங்கிருந்து வாங்கவும்.", + "purchaseNotAvailableText": "இந்த கொள்முதல் கிடைக்கவில்லை.", "purchasingText": "வாங்குகிறது...", "quitGameText": "${APP_NAME} ஐ விட்டு வெளியேறவா?", "quittingIn5SecondsText": "5 வினாடிகளில் வெளியேறும்...", @@ -1217,7 +1265,9 @@ "revertText": "பின்செல்", "runText": "ஓடு", "saveText": "சேமி", - "scanScriptsErrorText": "ஸ்கிரிப்ட்களை ஸ்கேன் செய்வதில் பிழை (கள்); விவரங்களுக்கு பதிவைப் பார்க்கவும்.", + "scanScriptsErrorText": "ஸ்கிரிப்ட்களை ஸ்கேன் செய்வதில் பிழை(கள்). விவரங்களுக்கு பதிவைப் பார்க்கவும்.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} மற்றும் ${NUM} பிற மாடுல்(கள்) APIக்காக புதுப்பிக்க படவேண்டும் ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} Api காக புதுப்பிக்க படவேண்டும் ${API}.", "scoreChallengesText": "ஸ்கோர் சவால்கள்", "scoreListUnavailableText": "மதிப்பெண் பட்டியல் கிடைக்கவில்லை.", "scoreText": "மதிப்பெண் பெரு", @@ -1228,6 +1278,7 @@ }, "scoreWasText": "(${COUNT} இருந்தது)", "selectText": "தேர்ந்தெடு", + "sendInfoDescriptionText": "டெவெலப்பருக்கு கணக்கு மற்றும் பயன்பாட்டு நிலைத் தகவலை அனுப்புகிறது.\nஉங்கள் பெயர் அல்லது அனுப்புவதற்கான காரணத்தைச் சேர்க்கவும்.", "seriesWinLine1PlayerText": "வெற்றி", "seriesWinLine1TeamText": "வெற்றி", "seriesWinLine1Text": "வெற்றி", @@ -1245,6 +1296,7 @@ "alwaysUseInternalKeyboardDescriptionText": "(உரை திருத்துவதற்கான ஒரு எளிய, கட்டுப்படுத்தி-நட்பு திரையில் விசைப்பலகை)", "alwaysUseInternalKeyboardText": "எப்போதும் உள் விசைப்பலகையைப் பயன்படுத்தவும்", "benchmarksText": "அளவுகோல்கள் மற்றும் மன அழுத்த சோதனைகள்", + "devToolsText": "டெவலப்பர் கருவிகள்", "disableCameraGyroscopeMotionText": "கேமரா கைரோஸ்கோப் இயக்கத்தை முடக்கவும்", "disableCameraShakeText": "கேமரா குலுக்கை முடக்கு", "disableThisNotice": "(மேம்பட்ட அமைப்புகளில் இந்த அறிவிப்பை முடக்கலாம்)", @@ -1257,10 +1309,16 @@ "kidFriendlyModeText": "குழந்தை நட்பு முறை (குறைந்த வன்முறை போன்றவை)", "languageText": "மொழி", "moddingGuideText": "மோடிங் வழிகாட்டி", + "moddingToolsText": "மாற்றியமைக்கும் கருவிகள்", "mustRestartText": "இது நடைமுறைக்கு வர நீங்கள் விளையாட்டை மறுதொடக்கம் செய்ய வேண்டும்.", "netTestingText": "நெட்வொர்க் சோதனை", "resetText": "மீட்டு", + "sendInfoText": "தகவல் அனுப்பு", "showBombTrajectoriesText": "வெடிகுண்டு பாதைகளைக் காட்டு", + "showDemosWhenIdleText": "செயலற்ற நிலையில் டெமோக்களைக் காட்டு", + "showDeprecatedLoginTypesText": "நிராகரிக்கப்பட்ட உள்நுழைவு வகைகளைக் காட்டு", + "showDevConsoleButtonText": "உருவாக்குபவர் பணியகத்தை காட்டு", + "showInGamePingText": "பிணைய தாமதத்தைக் காட்டு", "showPlayerNamesText": "பிளேயர் பெயர்களைக் காட்டு", "showUserModsText": "மோட்ஸ் கோப்புறையைக் காட்டு", "titleText": "மேம்பட்ட அமைப்புகள்", @@ -1268,8 +1326,8 @@ "translationFetchErrorText": "மொழிபெயர்ப்பு நிலை கிடைக்கவில்லை", "translationFetchingStatusText": "மொழிபெயர்ப்பு நிலையை சரிபார்க்கிறது...", "translationInformMe": "எனது மொழிக்கு புதுப்பிப்புகள் தேவைப்படும்போது எனக்குத் தெரியப்படுத்துங்கள்", - "translationNoUpdateNeededText": "தற்போதைய மொழி புதுப்பித்த நிலையில் உள்ளது; வூஹூ!", - "translationUpdateNeededText": "** தற்போதைய மொழிக்கு புதுப்பிப்புகள் தேவை !! **", + "translationNoUpdateNeededText": "தற்போதைய மொழி புதுப்பித்த நிலையில் உள்ளது; அடிதூள்!", + "translationUpdateNeededText": "** தற்போதைய மொழிக்கு புதுப்பிப்புகள் தேவை!! **", "vrTestingText": "VR சோதனை" }, "shareText": "பகிர்", @@ -1279,6 +1337,9 @@ "signInWithGameCenterText": "Game Center கணக்கைப் பயன்படுத்த,\nGame Center ஆப் மூலம் உள்நுழையவும்.", "singleGamePlaylistNameText": "வெறும் ${GAME}", "singlePlayerCountText": "1 வீரர்", + "sizeLargeText": "பெரியது", + "sizeMediumText": "நடுத்தரம்", + "sizeSmallText": "சிறியது", "soloNameFilterText": "தனி ${NAME}", "soundtrackTypeNames": { "CharSelect": "குணம் தேர்ந்தெடுத்தல்", @@ -1351,6 +1412,8 @@ "storeText": "ஸ்டோர்", "submitText": "சமர்ப்பிக்கவும்", "submittingPromoCodeText": "குறியீட்டைச் சமர்ப்பிக்கிறது...", + "successText": "வெற்றி!", + "supportEmailText": "நீங்கள் ஏதேனும் சிக்கல்களை எதிர்கொண்டால் பயன்பாடு,\nதயவுசெய்து ${EMAIL} க்கு மின்னஞ்சல் செய்யவும்.", "teamNamesColorText": "அணியின் பெயர்கள்/நிறங்கள்...", "telnetAccessGrantedText": "டெல்நெட் அணுகல் இயக்கப்பட்டது.", "telnetAccessText": "டெல்நெட் அணுகல் கண்டறியப்பட்டது; அனுமதிக்கவா?", @@ -1370,6 +1433,17 @@ "tipText": "உதவிக்குறிப்பு", "titleText": "பாம்ஸ்குவாட்", "titleVRText": "பாம்ஸ்குவாட் VR", + "tokens": { + "getTokensText": "டோக்கன்களைப் பெறுங்கள்", + "notEnoughTokensText": "போதுமான டோக்கன்கள் இல்லை!", + "numTokensText": "${COUNT} டோக்கன்கள்", + "shinyNewCurrencyText": "BombSquad இன் பளபளப்பான புதிய நாணயம்.", + "tokenPack1Text": "சிறிய டோக்கன் பேக்", + "tokenPack2Text": "நடுத்தர டோக்கன் பேக்", + "tokenPack3Text": "பெரிய டோக்கன் பேக்", + "tokenPack4Text": "மிகப்பெரிய டோக்கன் பேக்", + "youHaveGoldPassText": "உங்களிடம் தங்க நுழைவு அட்டை உள்ளது.\nஅனைத்து டோக்கன் வாங்குதல்களும் இலவசம்.\nமகிழுங்கள்!" + }, "topFriendsText": "சிறந்த நண்பர்கள்", "tournamentCheckingStateText": "போட்டி நிலையை சரிபார்க்கிறது; தயவுசெய்து காத்திருங்கள்...", "tournamentEndedText": "இந்த போட்டி முடிந்தது. புதியது விரைவில் தொடங்கும்.", @@ -1534,12 +1608,12 @@ "Malay": "மலாய்", "Persian": "பர்ஷியன்", "Polish": "பலிஷ்", - "Portuguese": "போர்சுகிஸ்", + "Portuguese": "போர்சுகிஸ் ", "Romanian": "ரோமானியன்", "Russian": "ரஷ்யன்", "Serbian": "சர்பியன்", "Slovak": "ஸ்லோவக்", - "Spanish": "ஸ்பானிஷ்", + "Spanish": "ஸ்பானிஷ் ", "Swedish": "ஸ்வீடிஷ்", "Tamil": "தமிழ்", "Thai": "தாய்", @@ -1645,7 +1719,10 @@ "You don't own that.": "உங்களுக்கு அது சொந்தமில்லை.", "You got ${COUNT} tickets!": "நீங்கள் ${COUNT} டிக்கெட்டுகளைப் பெற்றுள்ளீர்கள்!", "You got a ${ITEM}!": "உங்களுக்கு ${ITEM} கிடைத்துள்ளது!", + "You got an achievement reward!": "நீங்கள் ஒரு சாதனை பரிசு பெற்றுள்ளீர்கள்!", "You have been promoted to a new league; congratulations!": "நீங்கள் ஒரு புதிய லீக்கில் பதவி உயர்வு பெற்றுள்ளீர்கள்; வாழ்த்துக்கள்!", + "You lost a chest! (All your chest slots were full)": "நீங்கள் ஒரு பெட்டியை இழந்துவிட்டீர்கள்! (உங்கள் அனைத்து பெட்டி இடங்களும் நிரம்பியிருந்தன)", + "You must update the app to view this.": "நீங்கள் இதைப் பார்ப்பதற்கு செயலியை புதுப்பிக்க வேண்டும்.", "You must update to a newer version of the app to do this.": "இதைச் செய்ய நீங்கள் பயன்பாட்டின் புதிய பதிப்பைப் புதுப்பிக்க வேண்டும்.", "You must update to the newest version of the game to do this.": "இதைச் செய்ய நீங்கள் விளையாட்டின் புதிய பதிப்பைப் புதுப்பிக்க வேண்டும்.", "You must wait a few seconds before entering a new code.": "புதிய குறியீட்டை உள்ளிடுவதற்கு சில வினாடிகள் காத்திருக்க வேண்டும்.", @@ -1799,11 +1876,13 @@ "toSkipPressAnythingText": "(பயிற்சியைத் தவிர்க்க எதையும் தட்டவும் அல்லது அழுத்தவும்)" }, "twoKillText": "இரட்டை கொலை!", + "uiScaleText": "பயனர் இடைமுக அளவு", "unavailableText": "கிடைக்கவில்லை", "unconfiguredControllerDetectedText": "கட்டமைக்கப்படாத கட்டுப்படுத்தி கண்டறியப்பட்டது:", "unlockThisInTheStoreText": "இதை ஸ்டோரில் திறக்க வேண்டும்.", "unlockThisProfilesText": "${NUM} க்கும் அதிகமான சுயவிவரங்களை உருவாக்க, உங்களுக்கு இது தேவை:", "unlockThisText": "இதைத் திறக்க, உங்களுக்குத் தேவை:", + "unsupportedControllerText": "மன்னிக்கவும், கட்டுப்படுத்தி \"${NAME}\" ஆதரிக்கப்படவில்லை.", "unsupportedHardwareText": "மன்னிக்கவும், இந்த வன்பொருள் விளையாட்டின் உருவாக்கத்தால் ஆதரிக்கப்படவில்லை.", "upFirstText": "முதலில் மேலே:", "upNextText": "${COUNT} விளையாட்டில் அடுத்தது:", @@ -1811,10 +1890,14 @@ "upgradeText": "மேம்படுத்தல்", "upgradeToPlayText": "இதை விளையாட கேம் ஸ்டோரில் \"${PRO}\" ஐத் திறக்கவும்.", "useDefaultText": "இயல்புநிலையைப் பயன்படுத்தவும்", + "userSystemScriptsCreateText": "பயனர் கணினி ஸ்கிரிப்ட்களை உருவாக்கவும்", + "userSystemScriptsDeleteText": "பயனர் கணினி ஸ்கிரிப்ட்களை நீக்கவும்", "usesExternalControllerText": "இந்த விளையாட்டு உள்ளீட்டிற்கு வெளிப்புற கட்டுப்படுத்தியைப் பயன்படுத்துகிறது.", "usingItunesText": "ஒலிப்பதிவுக்காக மியூசிக் ஆப் பயன்படுத்துகிறது...", "v2AccountLinkingInfoText": "V2 கணக்குகளை இணைக்க, 'கணக்கை நிர்வகி' பட்டனைப் பயன்படுத்தவும்.", + "v2AccountRequiredText": "இதற்கு V2 கணக்கு தேவை. உங்கள் கணக்கை மேம்படுத்தி மீண்டும் முயற்சிக்கவும்.", "validatingTestBuildText": "சோதனை கட்டத்தை சரிபார்க்கிறது...", + "viaText": "வழியாக", "victoryText": "வெற்றி!", "voteDelayText": "நீங்கள் மற்றொரு வாக்கை ${NUMBER} வினாடிகளுக்குத் தொடங்க முடியாது", "voteInProgressText": "வாக்கெடுப்பு ஏற்கனவே நடந்து கொண்டிருக்கிறது.", @@ -1871,7 +1954,7 @@ "worldsBestScoresText": "உலகின் சிறந்த மதிப்பெண்கள்", "worldsBestTimesText": "உலகின் சிறந்த நேரங்கள்", "xbox360ControllersWindow": { - "getDriverText": "Driver ஐ பெரு", + "getDriverText": "Driver ஐ பெரு ", "macInstructions2Text": "கட்டுப்படுத்திகளை கம்பியில்லாமல் பயன்படுத்த, உங்களுக்கு ரிசீவரும் தேவை\nவிண்டோஸிற்கான எக்ஸ்பாக்ஸ் 360 வயர்லெஸ் கன்ட்ரோலருடன் வருகிறது.\nஒரு ரிசீவர் உங்களை 4 கட்டுப்படுத்திகளை இணைக்க அனுமதிக்கிறது.\n\nமுக்கியமானது: 3 வது தரப்பு பெறுநர்கள் இந்த டிரைவருடன் வேலை செய்ய மாட்டார்கள்;\nஉங்கள் ரிசீவர் அதில் 'மைக்ரோசாப்ட்' என்று கூறுவதை உறுதி செய்து கொள்ளுங்கள், 'எக்ஸ்பாக்ஸ் 360' அல்ல.\nமைக்ரோசாப்ட் இனி தனித்தனியாக விற்காது, எனவே நீங்கள் பெற வேண்டும்\nகட்டுப்பாட்டாளருடன் தொகுக்கப்பட்ட ஒன்று அல்லது வேறு ஈபேயைத் தேடுங்கள்.\n\nஇது உங்களுக்கு பயனுள்ளதாக இருந்தால், தயவுசெய்து ஒரு நன்கொடையைக் கருத்தில் கொள்ளவும்\nஅவரது தளத்தில் டிரைவர் டெவலப்பர்.", "macInstructionsText": "எக்ஸ்பாக்ஸ் 360 கட்டுப்படுத்திகளைப் பயன்படுத்த, நீங்கள் நிறுவ வேண்டும்\nமேக் டிரைவர் கீழே உள்ள இணைப்பில் கிடைக்கிறது.\nஇது கம்பி மற்றும் வயர்லெஸ் கட்டுப்படுத்திகளுடன் வேலை செய்கிறது.", "ouyaInstructionsText": "BombSquad உடன் கம்பி எக்ஸ்பாக்ஸ் 360 கட்டுப்படுத்திகளைப் பயன்படுத்த, வெறுமனே\nஅவற்றை உங்கள் சாதனத்தின் USB போர்ட்டில் செருகவும். நீங்கள் ஒரு USB ஹப் பயன்படுத்தலாம்\nபல கட்டுப்படுத்திகளை இணைக்க.\n\nவயர்லெஸ் கன்ட்ரோலர்களைப் பயன்படுத்த உங்களுக்கு வயர்லெஸ் ரிசீவர் தேவை,\n\"விண்டோஸிற்கான எக்ஸ்பாக்ஸ் 360 வயர்லெஸ் கன்ட்ரோலர்\" இன் ஒரு பகுதியாக கிடைக்கிறது\nதொகுப்பு அல்லது தனித்தனியாக விற்கப்படுகிறது. ஒவ்வொரு ரிசீவரும் USB போர்ட்டில் செருகப்படுகிறது மற்றும்\n4 வயர்லெஸ் கட்டுப்படுத்திகளை இணைக்க உங்களை அனுமதிக்கிறது.", @@ -1879,5 +1962,6 @@ }, "yesAllowText": "ஆம், அனுமதி!", "yourBestScoresText": "உங்கள் சிறந்த மதிப்பெண்கள்", - "yourBestTimesText": "உங்கள் சிறந்த நேரங்கள்" + "yourBestTimesText": "உங்கள் சிறந்த நேரங்கள்", + "yourPrizeText": "உங்கள் பரிசு:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/thai.json b/dist/ba_data/data/languages/thai.json index 6f006320..9a39c80a 100644 --- a/dist/ba_data/data/languages/thai.json +++ b/dist/ba_data/data/languages/thai.json @@ -1,44 +1,49 @@ { "accountSettingsWindow": { "accountNameRules": "ชื่อบัญชีต้องไม่มีอิโมจิหรือตัวอักษรพิเศษอื่นๆ", - "accountsText": "บัญชี", + "accountsText": "บัญชีผู้ใช้", "achievementProgressText": "ผ่านความสำเร็จ: ${COUNT} จาก ${TOTAL}", "campaignProgressText": "ความคืบหน้าในภารกิจ [ยาก]: ${PROGRESS}", "changeOncePerSeason": "คุณสามารถเปลี่ยนได้เพียงครั้งเดียวต่อฤดูกาล", - "changeOncePerSeasonError": "คุณต้องรอจนกว่าฤดูกาลหน้าจะเปลี่ยนอีก (${NUM} days)", + "changeOncePerSeasonError": "คุณต้องรอจนกว่าฤดูกาลหน้าจะเปลี่ยนอีก (${NUM} วัน)", + "createAnAccountText": "สร้างบัญชี", "customName": "ชื่อที่กำหนดเอง", + "deleteAccountText": "ลบบัญชีผู้ใช้", "googlePlayGamesAccountSwitchText": "หากคุณต้องการใช้บัญชี Google อื่น\nใช้แอป Google Play Games เพื่อเปลี่ยน", "linkAccountsEnterCodeText": "ใส่รหัส", "linkAccountsGenerateCodeText": "สร้างรหัส", "linkAccountsInfoText": "(ใช้ความคืบหน้าร่วมกันกับแพลตฟอร์มอื่นๆ)", - "linkAccountsInstructionsNewText": "หากต้องการเชื่อมโยงสองบัญชีให้สร้างรหัสในบัญชีแรกและป้อนรหัสนั้นในวินาที ข้อมูลจากบัญชีที่สองจะถูกแชร์ระหว่างทั้งสอง(ข้อมูลจากบัญชีแรกจะหายไป): ${COUNT} ** .", + "linkAccountsInstructionsNewText": "หากต้องการเชื่อมโยงสองบัญชี ให้สร้างรหัสในบัญชีแรก\nและป้อนรหัสนั้นในบัญชีที่สอง ข้อมูลจาก\nบัญชีที่สองจะถูกแชร์ระหว่างทั้งสอง\n(ข้อมูลจากบัญชีแรกจะหายไป)\n\nคุณสามารถเชื่อมโยงได้ถึง ${COUNT} บัญชี\n\nข้อสำคัญ: เชื่อมโยงบัญชีที่คุณเป็นเจ้าของเท่านั้น\nหากคุณเชื่อมโยงกับบัญชีของเพื่อน คุณจะไม่ทำ\nสามารถเล่นออนไลน์ได้ในเวลาเดียวกัน", "linkAccountsInstructionsText": "เพื่อที่จะผูกทั้งสองบัญชีเข้าด้วยกัน จะต้องสร้างรหัสรหัสหนึ่ง\nแล้วจะต้องใส่รหัสในบัญที่คุณต้องการจะเชื่อมโยงเข้าด้วยกัน\nความคืบหน้าและสิ่งของในคลังของทั้งสองบัญชีจะถูกรวมกัน\nคุณสามารถเชื่อมโยงได้ทั้งหมด ${COUNT} บัญชี\n\nระวัง! หลังจากผูกบัญชีแล้วจะไม่สามารถยกเลิกได้!", "linkAccountsText": "ผูกบัญชี", - "linkedAccountsText": "บัญชีที่เชื่อมโยงแล้ว", + "linkedAccountsText": "บัญชีที่เชื่อมโยงแล้ว:", "manageAccountText": "จัดการบัญชี", "nameChangeConfirm": "คุณต้องการเปลี่ยนชื่อบัญชีของคุณเป็น ${NAME} หรือไม่", "resetProgressConfirmNoAchievementsText": "การทำสิ่งนี้จะรีเซ็ตความคืบหน้าต่างๆ ในโหมด co-op\nและคะแนนดีที่สุดในอุปกรณ์นี้ (แต่จะไม่รีเซ็ตตั๋วของคุณ) \nการทำสิ่งนี้ไม่สามารถยกเลิกได้! คุณแน่ใจหรือไม่?", "resetProgressConfirmText": "การทำสิ่งนี้จะรีเซ็ตความคืบหน้าในโหมด co-op,\nความสำเร็จและคะแนนดีที่สุดในอุปกรณ์นี้\n(แต่จะไม่รีเซ็ตตั๋วของคุณ) การทำสิ่งนี้จะ\nไม่สามารถยกเลิกได้! คุณแน่ใจหรือไม่?", "resetProgressText": "รีเซ็ตความคืบหน้า", "setAccountName": "ตั้งชื่อบัญชี", - "setAccountNameDesc": "เลือกชื่อที่จะแสดงสำหรับบัญชีของคุณคุณสามารถใช้ชื่อจากหนึ่งในการเชื่อมโยงของคุณบัญชีหรือสร้างชื่อที่กำหนดเองที่ไม่ซ้ำกัน:{Thanakorn}", + "setAccountNameDesc": "เลือกชื่อที่จะแสดงสำหรับบัญชีของคุณ\nคุณสามารถใช้ชื่อจากหนึ่งในบัญชีที่เชื่อมโยงของคุณ\nหรือสร้างชื่อที่กำหนดเองที่ไม่ซ้ำใคร", "signInInfoText": "เข้าสู่ระบบเพื่อเก็บตั๋วในการเล่นแบบออนไลน์,\nและแบ่งปันความคืบหน้าของคุณกับอุปกรณ์อื่นๆ", - "signInText": "ลงชื่อเข้าใช้", + "signInText": "เข้าสู่ระบบ", + "signInWithAnEmailAddressText": "เข้าสู่ระบบด้วยที่อยู่อีเมล", "signInWithDeviceInfoText": "(บัญชีอัตโนมัติที่ใช้ได้เฉพาะในอุปกรณ์นี้)", - "signInWithDeviceText": "เข้าสู่ระบบจากอุปกรณ์นี้", + "signInWithDeviceText": "เข้าสู่ระบบด้วยอุปกรณ์นี้", "signInWithGameCircleText": "เข้าสู่ระบบด้วยบัญชี Game Circle", "signInWithGooglePlayText": "ลงชื่อเข้าใช้ด้วยบัญชี Google Play", "signInWithTestAccountInfoText": "(บัญชีทดลอง;เลือกตัวเลือกนี้เพื่อไปต่อ)", "signInWithTestAccountText": "ลงชื่อเข้าใช้เพื่อทดลอง", + "signInWithText": "เข้าสู่ระบบด้วย ${SERVICE}", "signInWithV2InfoText": "(บัญชีที่ใช้งานได้กับทุกแพลตฟอร์ม)", - "signInWithV2Text": "ลงชื่อเข้าใช้ด้วยบัญชี BombSquad", + "signInWithV2Text": "เข้าสู่ระบบด้วยบัญชี ${APP_NAME}", "signOutText": "ออกจากระบบ", - "signingInText": "กำลังลงชื่อเข้าใช้...", + "signingInText": "กำลังเข้าสู่ระบบ...", "signingOutText": "กำลังออกจากระบบ...", - "ticketsText": "ตั๋ว: ${COUNT}", + "ticketsText": "ตั๋ว: ${COUNT} ใบ", "titleText": "บัญชี", "unlinkAccountsInstructionsText": "เลือกบัญชีที่จะยกเลิกการเชื่อมโยง", "unlinkAccountsText": "ยกเลิกการเชื่อมโยงบัญชี", + "unlinkLegacyV1AccountsText": "ยกเลิกการเชื่อมโยงบัญชีแบบเก่า (V1)", "v2LinkInstructionsText": "ใช้ลิงก์นี้เพื่อสร้างบัญชีหรือลงชื่อเข้าใช้", "viaAccount": "ผ่านบัญชี ${NAME}", "youAreSignedInAsText": "คุณลงชื่อเข้าใช้ในบัญชี:" @@ -49,8 +54,8 @@ "Boom Goes the Dynamite": { "description": "ฆ่าศัตรู 3 คนด้วย TNT", "descriptionComplete": "ฆ่าศัตรู 3 คนด้วย TNT แล้ว", - "descriptionFull": "ฆ่าศัตรู ${LEVEL} 3 คนด้วย TNT", - "descriptionFullComplete": "ฆ่าศัตรู 3 คน ด้วย TNT ใน ${LEVEL}", + "descriptionFull": "ฆ่าศัตรู 3 คนด้วย TNT ใน ${LEVEL}", + "descriptionFullComplete": "ฆ่าศัตรู 3 คน ด้วย TNT ใน ${LEVEL} แล้ว", "name": "ระเบิดดังสนั่นหวั่นไหวจากไดนาไมต์" }, "Boxer": { @@ -89,7 +94,7 @@ "descriptionComplete": "ชนะโดยไม่ต้องใช้หมัดหรือระเบิดแล้ว", "descriptionFull": "ชนะ ${LEVEL} โดยไม่ต้องใช้หมัดหรือระเบิด", "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ต้องใช้หมัดหรือระเบิดแล้ว", - "name": "เร่งรีบ" + "name": "พริ้วไหวดั่งสายลม" }, "In Control": { "descriptionFull": "เชื่อมต่อกับคอนโทรลเลอร์", @@ -115,7 +120,7 @@ "descriptionComplete": "ทำคะแนน 500 คะแนนแล้ว", "descriptionFull": "ทำคะแนน 500 คะแนนใน ${LEVEL}", "descriptionFullComplete": "ทำคะแนน 500 คะแนนใน ${LEVEL} แล้ว", - "name": "ผู้วิเศษ ${LEVEL}" + "name": "พ่อมด ${LEVEL}" }, "Mine Games": { "description": "ฆ่าศัตรู 3 คนด้วยกับระเบิด", @@ -332,16 +337,21 @@ "getMoreGamesText": "รับเกมเพิ่มเติม", "titleText": "เพิ่มเกม" }, + "addToFavoritesText": "เพื่มในรายการโปรด", + "addedToFavoritesText": "เพื่ม '${NAME}' ในรายการโปรดแล้ว", + "allText": "ทั้งหมด", "allowText": "ยอมรับ", - "alreadySignedInText": "บัญชีของคุณลงชื่อเข้าใช้จากอุปกรณ์อื่น\nโปรดเปลี่ยนบัญชีหรือปิดเกมของคุณ\nอุปกรณ์อื่นและลองอีกครั้ง", + "alreadySignedInText": "บัญชีของคุณลงชื่อเข้าใช้จากอุปกรณ์อื่น;\nโปรดเปลี่ยนบัญชีหรือปิดเกมบนอุปกรณ์อื่น\nของคุณและลองอีกครั้ง", "apiVersionErrorText": "ไม่สามารถโหลดโมดูล ${NAME} ได้; มันอยู่ในเวอร์ชั่น api ${VERSION_USED}; แต่เราต้องการเวอร์ชั่น ${VERSION_REQUIRED}", + "applyText": "นำมาใช้ในเกม", + "areYouSureText": "คุณแน่ใจใช่มั้ย?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"อัติโนมัติ\" เปิดสิ่งนี้เฉพาะตอนที่เสียบหูฟังอยู่เท่านั้น)", "headRelativeVRAudioText": "ระดับเสียงเครื่องสวมหัว VR", "musicVolumeText": "ระดับเสียงเพลง", "soundVolumeText": "ระดับเสียงประกอบ", "soundtrackButtonText": "เพลงประกอบ", - "soundtrackDescriptionText": "(นำเพลงของคุณเองมาใช้ในการเล่นเกม)", + "soundtrackDescriptionText": "(นำเพลงของคุณเองมาใช้เล่นในเกม)", "titleText": "การตั้งค่าเสียง" }, "autoText": "อัติโนมัติ", @@ -356,14 +366,23 @@ "boostText": "บูสท์", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} กำลังค่าในตัวแอพเอง", "buttonText": "ปุ่ม", - "canWeDebugText": "คุณอยากให้ BombSquad แจ้งข้อผิดพลาด ปัญหา\nและข้อมูลการใช้งานทั่วไปกับผู้สร้างโดยอัติโนมัติหรือไม่?\n\nข้อมูลนี้จะไม่เกี่ยวข้องกับข้อมูลส่วนตัวและจะช่วยให้\nสามารถเล่นเกมได้อย่างราบรื่นและไม่มีข้อผิดพลาด", + "canWeDebugText": "คุณต้องการให้ ${APP_NAME} รายงานข้อบกพร่อง ข้อขัดข้อง และข้อมูลการใช้งานพื้นฐานไปยังผู้พัฒนาโดยอัตโนมัติหรือไม่\n\nข้อมูลนี้ไม่มีข้อมูลส่วนบุคคลและช่วยให้เกมทำงานได้อย่างราบรื่นและไม่มีข้อบกพร่อง", "cancelText": "ยกเลิก", "cantConfigureDeviceText": "ขออภัย, ${DEVICE} ไม่สามารถตั้งค่าได้", "challengeEndedText": "การท้าทายนี้ได้จบลงแล้ว", "chatMuteText": "ปิดเสียงแชท", "chatMutedText": "ปิดเสียงการแชท", "chatUnMuteText": "ยกเลิกการปิดเสียงแขท", + "chests": { + "prizeOddsText": "อัตราการได้รางวัล", + "reduceWaitText": "ลดเวลารอ", + "slotDescriptionText": "ช่องนี้ใช้สำหรับใส่หีบ\n\nรับหีบได้จากการเล่นด่านต่างๆ ในด่านแคมเปญ,\nการเข้าร่วมการแข่งขันและการทำความสำเร็จ\nให้สำเร็จ", + "slotText": "ช่องเก็บหีบที่ ${NUM}", + "slotsFullWarningText": "คำเตือน: ช่องเก็บหีบของคุณเต็มหมดแล้ว\nหีบใดๆ ที่คุณได้รับจากเกมนี้จะหายไป" + }, "choosingPlayerText": "<กำลังเลือกผู้เล่น>", + "claimText": "รับ", + "codesExplainText": "นักพัฒนาซอฟต์แวร์มอบรหัสเพื่อ\nวินิจฉัยและแก้ไขปัญหาบัญชี", "completeThisLevelToProceedText": "คุณต้องผ่านด่านนี้\nก่อนจึงจะไปต่อได้!", "completionBonusText": "รางวัลการผ่านด่าน", "configControllersWindow": { @@ -422,7 +441,7 @@ "twoInOneSetupText": "การตั้งค่าคอนโทรลเลอร์แบบ 2 ใน 1", "uiOnlyDescriptionText": "(ป้องกันคอนโทรลเลอร์ตัวนี้ไม่ให้ใช้เข้าร่วมเกม)", "uiOnlyText": "จำกัดในการใช้เมนู", - "unassignedButtonsRunText": "วิ่งปุ่มที่ไม่ได้ตั้งทั้งหมด", + "unassignedButtonsRunText": "ใช้ปุ่มที่ไม่ได้กำหนดทั้งหมดในการวิ่ง", "unsetText": "<ไม่ได้ตั้ง>", "vrReorientButtonText": "ปรับทิศทางปุ่ม VR" }, @@ -444,6 +463,7 @@ "swipeText": "การปัด", "titleText": "การตั้งค่าหน้าจอสัมผัส" }, + "configureDeviceInSystemSettingsText": "", "configureItNowText": "จะตั้งค่ามันตอนนี้หรือไม่?", "configureText": "ตั้งค่า", "connectMobileDevicesWindow": { @@ -545,7 +565,8 @@ "deleteText": "ลบ", "demoText": "ทดลอง", "denyText": "ยกเลิก", - "deprecatedText": "คัดค้าน", + "deprecatedText": "ไม่ถูกใช้งาน", + "descriptionText": "คำอธิบายเกม", "desktopResText": "เดสก์ท็อป Res", "deviceAccountUpgradeText": "คำเตือน:\nคุณลงชื่อเข้าใช้ด้วยบัญชีอุปกรณ์ (${NAME})\nบัญชีอุปกรณ์จะถูกลบออกในการอัปเดตในอนาคต\nอัปเกรดเป็นบัญชี V2 หากคุณต้องการติดตามความคืบหน้า", "difficultyEasyText": "ง่าย", @@ -556,6 +577,10 @@ "disableRemoteAppConnectionsText": "ปิดการใช้การเชื่อมต่อแอพรีโมต", "disableXInputDescriptionText": "อนุญาตให้ใช้คอนโทรลเลอร์มากกว่า 4 ตัวแต่จะทำงานได้ไม่ค่อยดีเท่าไหร่", "disableXInputText": "ปิด XInput", + "disabledText": "ปิด", + "discardText": "ทิ้ง", + "discordFriendsText": "ต้องการหาเพื่อนที่จะเล่นด้วยใช่ไหม\nเข้า Discord ของพวกเราและหาเพื่อนใหม่ๆ!", + "discordJoinText": "เข้าร่วม Discord", "doneText": "เสร็จสิ้น", "drawText": "เสมอ", "duplicateText": "ทำซ้ำ", @@ -588,6 +613,7 @@ "localProfileText": "(โปรไฟล์ส่วนตัว)", "nameDescriptionText": "ชื่อผู้เล่น", "nameText": "ชื่อ", + "profileAlreadyExistsText": "โปรไฟล์นี้ไม่สามารถใช้ชื่อนี้ได้", "randomText": "สุ่มชื่อ", "titleEditText": "แก้ไขโปรไฟล์", "titleNewText": "สร้างโปรไฟล์ใหม่", @@ -623,10 +649,11 @@ "useMusicFolderText": "โฟลเดอร์ของไฟล์เพลง" }, "editText": "แก้ไข", + "enabledText": "เปิด", "endText": "จบ", "enjoyText": "ขอให้สนุก!", "epicDescriptionFilterText": "${DESCRIPTION} ในการเคลื่อนไหวที่ช้ามากๆ", - "epicNameFilterText": "${NAME} แบบช้ามหากาฬ", + "epicNameFilterText": "มหากาพย์ ${NAME}", "errorAccessDeniedText": "การเข้าถึงถูกปฏิเสธ", "errorDeviceTimeIncorrectText": "เวลาของอุปกรณ์ไม่ถูกต้อง ${HOURS} ชั่วโมง\nมีแนวโน้มที่จะทำให้เกิดปัญหา\nโปรดตรวจสอบการตั้งค่าเวลาและเขตเวลาของคุณ", "errorOutOfDiskSpaceText": "พื้นที่ว่างในเครื่องหมด", @@ -634,6 +661,8 @@ "errorText": "ข้อผิดพลาด", "errorUnknownText": "ข้อผิดพลาดที่ไม่รู้จัก", "exitGameText": "จะออกจาก ${APP_NAME} หรือไม่?", + "expiredAgoText": "หมดอายุเมื่อ ${T} ที่แล้ว", + "expiresInText": "หมดอายุใน ${T}", "exportSuccessText": "'${NAME}' ถูกส่งออกแล้ว", "externalStorageText": "พื้นที่ว่าง", "failText": "ล้มเหลว", @@ -668,6 +697,8 @@ "duplicateText": "ทำซ้ำ\nเพลย์ลิส", "editText": "แก้ไข\nเพลย์ลิส", "newText": "สร้าง\nเพลย์ลิสใหม่", + "pointsToWinText": "คะแนนและชัยชนะ", + "seriesLengthText": "ความยาวในการโชว์", "showTutorialText": "โชว์การสอนก่อนเริ่ม", "shuffleGameOrderText": "เรียงเกมตามลำดับ", "titleText": "ปรับแต่งเพลย์ลิส ${TYPE}" @@ -693,6 +724,7 @@ "copyCodeConfirmText": "คัดลอกรหัสไปยังคลิปบอร์ดแล้ว", "copyCodeText": "คัดลอกรหัส", "dedicatedServerInfoText": "เพื่อผลลัพธ์ที่ดีที่สุดตั้งค่าเซิร์ฟเวอร์เฉพาะ ดู bombsquadgame.com/server เพื่อเรียนรู้วิธีการ", + "descriptionShortText": "ใช้หน้าต่างรวมตัวเพื่อเข้าร่วมปาร์ตี้", "disconnectClientsText": "สิ่งนี้จะตัดการเชื่อมต่อผู้เล่น ${COUNT} คน\nในงานปาร์ตี้ของคุณ คุณแน่ใจไหม?", "earnTicketsForRecommendingAmountText": "เพื่อน ๆ จะได้รับตั๋ว ${COUNT} ถ้าพวกเขาลองเล่นเกม\n(และคุณจะได้รับ ${YOU_COUNT} สำหรับแต่ละคนที่ทำ)", "earnTicketsForRecommendingText": "แชร์เกมนี้\nสำหรับตั๋วฟรี", @@ -705,10 +737,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} ตั๋วจาก ${NAME}", "friendPromoCodeAwardText": "คุณจะได้รับตั๋ว ${COUNT} ทุกครั้งที่ใช้", "friendPromoCodeExpireText": "รหัสจะหมดอายุใน ${EXPIRE_HOURS} ชั่วโมงและใช้ได้กับผู้เล่นใหม่เท่านั้น", - "friendPromoCodeInstructionsText": "หากต้องการใช้งานให้เปิด ${APP_NAME} แล้วไปที่ \"การตั้งค่า -> ขั้นสูง -> ใส่รหัส\"\nดู bombsquadgame.com สำหรับลิงก์ดาวน์โหลดสำหรับแพลตฟอร์มที่รองรับทั้งหมด", + "friendPromoCodeInstructionsText": "หากต้องการใช้ ให้เปิด ${APP_NAME} แล้วไปที่ \"การตั้งค่า->ขั้นสูง->ส่งข้อมูล\"\nไปที่ bombsquadgame.com เพื่อดูลิงก์ดาวน์โหลดสำหรับแพลตฟอร์มที่รองรับทั้งหมด", "friendPromoCodeRedeemLongText": "สามารถแลกเป็นตั๋วฟรี ${COUNT} คนสูงถึง ${MAX_USES} คน", "friendPromoCodeRedeemShortText": "สามารถแลกเป็นตั๋ว ${COUNT} ใบในเกม", - "friendPromoCodeWhereToEnterText": "(ใน \"การตั้งค่า->ขั้นสูง->ป้อนรหัส\")", + "friendPromoCodeWhereToEnterText": "(ใน \"ตั้งค่า->ขั้นสูง->ส่งข้อมูล\")", "getFriendInviteCodeText": "รับรหัสเชิญเพื่อน", "googlePlayDescriptionText": "เชิญผู้เล่น Google Play เข้าร่วมปาร์ตี้ของคุณ:", "googlePlayInviteText": "เชิญ", @@ -740,6 +772,7 @@ "manualYourLocalAddressText": "ที่อยู่ในท้องถิ่นของคุณ:", "nearbyText": "ใกล้เคียง", "noConnectionText": "<ไม่มีการเชื่อมต่อ>", + "noPartiesAddedText": "ไม่มีปาร์ตี้เพื่มอยู่", "otherVersionsText": "(เวอร์ชั่นอื่นๆ)", "partyCodeText": "รหัสปาร์ตี้", "partyInviteAcceptText": "ยอมรับ", @@ -803,6 +836,12 @@ "youHaveShortText": "คุณมี ${COUNT} ใบ", "youHaveText": "คุณมีตั๋ว ${COUNT} ใบ" }, + "goldPass": { + "desc1InfTokensText": "โทเค็นที่ไม่มีที่สิ้นสุด", + "desc2NoAdsText": "ไม่มีโฆษณา", + "desc3ForeverText": "ตลอดไป.", + "goldPassText": "บัตรทองคำ" + }, "googleMultiplayerDiscontinuedText": "ขออภัย บริการผู้เล่นหลายคนของ Google ไม่มีให้บริการอีกต่อไป\nฉันกำลังดำเนินการเปลี่ยนให้เร็วที่สุด\nในระหว่างนี้ โปรดลองวิธีการเชื่อมต่ออื่น\n-เอริค", "googlePlayPurchasesNotAvailableText": "ไม่สามารถซื้อด้วย Google Play ได้\nคุณอาจต้องอัปเดตแอปร้านค้าของคุณ", "googlePlayServicesNotAvailableText": "บริการ Google Play ไม่พร้อมใช้งาน\nฟังก์ชันบางอย่างของแอปอาจถูกปิดใช้งาน", @@ -811,10 +850,12 @@ "alwaysText": "ตลอด", "fullScreenCmdText": "เต็มหน้าจอ (Cmd-F)", "fullScreenCtrlText": "เต็มหน้าจอ (Ctrl-F)", + "fullScreenText": "แสดงเต็มจอ", "gammaText": "ส่องสว่าง", "highText": "สูง", "higherText": "สูงกว่า", "lowText": "ต่ำ", + "maxFPSText": "อัตราเฟรมสูงสุด", "mediumText": "ปานกลาง", "neverText": "ไม่เคย", "resolutionText": "ความละเอียด", @@ -875,6 +916,7 @@ "importText": "นำเข้า", "importingText": "กำลังนำเข้า...", "inGameClippedNameText": "ในเกมจะเป็น\n\"${NAME}\"", + "inboxText": "กล่องข้อความ", "installDiskSpaceErrorText": "ข้อผิดพลาด: ไม่สามารถทำการติดตั้งให้เสร็จสิ้นได้\nคุณอาจไม่มีที่ว่างบนอุปกรณ์ของคุณ\nล้างพื้นที่บางส่วนแล้วลองอีกครั้ง", "internal": { "arrowsToExitListText": "กด ${LEFT} หรือ ${RIGHT} เพื่อออกจากรายการ", @@ -929,12 +971,14 @@ "timeOutText": "(หมดเวลาใน ${TIME} วินาที)", "touchScreenJoinWarningText": "คุณได้เข้าร่วมกับหน้าจอสัมผัส\nหากนี่เป็นข้อผิดพลาด ให้แตะ 'เมนู -> ออกจากเกม' ด้วย", "touchScreenText": "หน้าจอสัมผัส", + "unableToCompleteTryAgainText": "ไม่สามารถดำเนินการได้ในขณะนี้\nโปรดลองอีกครั้ง", "unableToResolveHostText": "ข้อผิดพลาด: ไม่สามารถแก้ไขโฮสต์", "unavailableNoConnectionText": "ไม่สามารถใช้งานได้ในขณะนี้ (ไม่มีการเชื่อมต่ออินเทอร์เน็ตหรอ?)", "vrOrientationResetCardboardText": "ใช้เพื่อรีเซ็ตการวางแนว VR\nในการเล่นเกม คุณจะต้องมีคอนโทรลเลอร์ภายนอก", "vrOrientationResetText": "รีเซ็ตการวางแนว VR", "willTimeOutText": "(จะหมดเวลาถ้าว่าง)" }, + "inventoryText": "คลังเก็บของ", "jumpBoldText": "กระโดด", "jumpText": "กระโดด", "keepText": "เก็บไว้", @@ -981,8 +1025,11 @@ "seasonEndsMinutesText": "จะสิ้นสุดซีซั่นในอีก ${NUMBER} นาที", "seasonText": "ซีซั่น ${NUMBER}", "tournamentLeagueText": "คุณต้องไปถึงลีก ${NAME} เพื่อเข้าร่วมการแข่งขันนี้", - "trophyCountsResetText": "จำนวนถ้วยรางวัลจะรีเซ็ตในซีซั่นหน้า" + "trophyCountsResetText": "จำนวนถ้วยรางวัลจะรีเซ็ตในซีซั่นหน้า", + "upToDateBonusDescriptionText": "ผู้เล่นที่รันเกมนี้ด้วยเวอร์ชันล่าสุด\nจะได้รับโบนัส ${PERCENT}% ที่นี่", + "upToDateBonusText": "โบนัสอัพเดท" }, + "learnMoreText": "เรียนรู้เพิ่มเติม", "levelBestScoresText": "คะแนนที่ดีที่สุดใน ${LEVEL}", "levelBestTimesText": "เวลาที่ดีที่สุดใน ${LEVEL}", "levelIsLockedText": "${LEVEL} ถูกล็อก", @@ -1022,14 +1069,17 @@ "maxConnectionsText": "จำนวนผู้ที่เชื่อมต่อได้สูงสุด", "maxPartySizeText": "จำนวนคนในปาร์ตี้สูงสุด", "maxPlayersText": "ผู้เล่นที่เล่นได้สูงสุด", + "merchText": "สินค้า!", "modeArcadeText": "โหมดอาเขต", "modeClassicText": "โหมดคลาสสิก", "modeDemoText": "โหมดสาธิต", + "moreSoonText": "จะมีเพิ่มเติมในเร็วๆ นี้...", + "mostDestroyedPlayerText": "ผู้เล่นที่ถูกขยี้มากที่สุด", "mostValuablePlayerText": "ผู้เล่นที่ทำคะแนนมากที่สุด", "mostViolatedPlayerText": "ผู้เล่นที่ฆ่าน้อยที่สุด", "mostViolentPlayerText": "ผู้เล่นที่ฆ่ามากที่สุด", "moveText": "เคลื่อนไหว", - "multiKillText": "ฆ่า ${COUNT}!!!", + "multiKillText": "ฆ่า ${COUNT} คน!!!", "multiPlayerCountText": "ผู้เล่น ${COUNT} คน", "mustInviteFriendsText": "หมายเหตุ: คุณต้องเชิญเพื่อนใน\nแผง \"${GATHER}\" หรือไฟล์แนบ\nตัวควบคุมเพื่อเล่นหลายคน", "nameBetrayedText": "${NAME} หักหลัง ${VICTIM}", @@ -1040,7 +1090,8 @@ "nameSuicideKidFriendlyText": "${NAME} ตายจากอุบัติเหตุ", "nameSuicideText": "${NAME} ฆ่าตัวตาย", "nameText": "ชื่อ", - "nativeText": "พื้นเมือง", + "nativeText": "ดั้งเดิม", + "newExclaimText": "ใหม่!", "newPersonalBestText": "ใหม่ส่วนตัวดีที่สุด!", "newTestBuildAvailableText": "มีการสร้างการทดสอบที่ใหม่กว่า! (${VERSION} บิลด์ ${BUILD})\nรับได้ที่ ${ADDRESS}", "newText": "ใหม่", @@ -1051,17 +1102,21 @@ "noContinuesText": "(ไม่มีต่อ)", "noExternalStorageErrorText": "ไม่พบที่จัดเก็บข้อมูลภายนอกในอุปกรณ์นี้", "noGameCircleText": "ข้อผิดพลาด: ไม่ได้ลงชื่อเข้าใช้ GameCircle", + "noMessagesText": "ไม่มีข้อความ", + "noPluginsInstalledText": "ไม่มีปลั๊กอินติดตั้งอยู่", "noScoresYetText": "ไม่มีคะแนน", + "noServersFoundText": "ไม่พบเซิร์ฟเวอร์", "noThanksText": "ไม่เป็นไรขอบคุณ", "noTournamentsInTestBuildText": "คำเตือน: คะแนนการแข่งขันจากรุ่นทดสอบนี้จะถูกละเว้น", "noValidMapsErrorText": "ไม่พบแผนที่ที่ถูกต้องสำหรับเกมนี้", "notEnoughPlayersRemainingText": "ไม่มีผู้เล่นเหลือพอ กรุณาออกแล้วเริ่มเกมใหม่", "notEnoughPlayersText": "คุณต้องการผู้เล่นอย่างน้อย ${COUNT} คนจึงจะเริ่มเกมได้!", + "notEnoughTicketsText": "มีตั๋วไม่พอ!", "notNowText": "ไม่ใช่ตอนนี้", - "notSignedInErrorText": "คุณต้องลงชื่อเข้าใช้เพื่อทำสิ่งนี้", - "notSignedInGooglePlayErrorText": "คุณต้องลงชื่อเข้าใช้ Google Play เพื่อดำเนินการนี้", - "notSignedInText": "ไม่ได้ลงชื่อเข้าใช้", - "notUsingAccountText": "หมายเหตุ: ละเว้นบัญชี ${SERVICE}\nไปที่ 'บัญชี -> ลงชื่อเข้าใช้ด้วย ${SERVICE}' หากคุณต้องการ", + "notSignedInErrorText": "คุณต้องเข้าสู่ระบบเพื่อทำสิ่งนี้", + "notSignedInGooglePlayErrorText": "คุณต้องเข้าสู่ระบบ Google Play เพื่อดำเนินการต่อ", + "notSignedInText": "ไม่ได้เข้าสู่ระบบ", + "notUsingAccountText": "หมายเหตุ: ละเว้นบัญชี ${SERVICE}\nไปที่ 'บัญชี -> เข้าสู่ระบบด้วย ${SERVICE}' หากคุณต้องการ", "nothingIsSelectedErrorText": "ไม่มีอะไรถูกเลือก!", "numberText": "#${NUMBER}", "offText": "ปิด", @@ -1069,9 +1124,12 @@ "onText": "เปิด", "oneMomentText": "แป๊บนึง...", "onslaughtRespawnText": "${PLAYER} จะเกิดใหม่ในรอบที่ ${WAVE}", + "openMeText": "เปิดฉันสิ!", + "openNowText": "เปิดตอนนี้", + "openText": "เปิด", "orText": "${A} หรือ ${B}", "otherText": "อื่น...", - "outOfText": "(#${RANK} จาก ${ALL})", + "outOfText": "ที่ (#${RANK} จาก ${ALL})", "ownFlagAtYourBaseWarning": "ธงของคุณจะต้องอยู่ที่\nฐานจึงจะทำคะแนนได้!", "packageModsEnabledErrorText": "การเล่นแบบใช้เน็ตไม่มสามรถใช้งานได้ในเมื่อ \"แพ็คเกจม็อดท้องถิ่น\" กำลังเปิดอยู่ (ดูได้ใน การตั้งค่า-> ขั้นสูง)", "partyWindow": { @@ -1120,7 +1178,11 @@ "pleaseWaitText": "โปรดรอ...", "pluginClassLoadErrorText": "เกิดข้อผิดพลาดในการโหลดคลาสปลั๊กอิน '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "เกิดข้อผิดพลาดในการเริ่มต้นปลั๊กอิน '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "การตั้งค่าปลั๊กอิน", + "pluginsAutoEnableNewText": "เปิดใช้งานปลั๊กอินใหม่โดยอัตโนมัติ", "pluginsDetectedText": "ตรวจพบปลั๊กอินใหม่ รีสตาร์ทเกมเพื่อเปิดใช้งาน หรือกำหนดค่าได้ในการตั้งค่า", + "pluginsDisableAllText": "ปิดใช้งานปลั๊กอินทั้งหมด", + "pluginsEnableAllText": "เปิดใช้งานปลั๊กอินทั้งหมด", "pluginsRemovedText": "ไม่พบปลั๊กอิน ${NUM} รายการอีกต่อไป", "pluginsText": "ปลั๊กอิน", "practiceText": "ฝึกฝน", @@ -1150,6 +1212,8 @@ "punchText": "ต่อย", "purchaseForText": "ซื้อในราคา ${PRICE}", "purchaseGameText": "ซื้อเกม", + "purchaseNeverAvailableText": "ขออภัย ไม่สามารถซื้อได้ในขณะนี้\nลองลงชื่อเข้าใช้บัญชีของคุณบนอุปกรณ์อื่นแล้วซื้ออีกครั้ง", + "purchaseNotAvailableText": "ไม่สามารถซื้อได้ในขณะนี้", "purchasingText": "กำลังจัดซื้อ...", "quitGameText": "ออกจาก ${APP_NAME} ไหม?", "quittingIn5SecondsText": "ออกจากระบบใน 5 วินาที...", @@ -1191,6 +1255,7 @@ "version_mismatch": "เวอร์ชั่นตรงกัน.\nตรวจสอบให้แน่ใจว่า BombSquad และ BombSquad Remote\nเป็นเวอร์ชันล่าสุดแล้วลองอีกครั้ง" }, "removeInGameAdsText": "ปลดล็อก \"${PRO}\" ในร้านค้าเพื่อลบโฆษณาในเกม", + "removeInGameAdsTokenPurchaseText": "ข้อเสนอจำกัดเวลา: ซื้อแพ็คโทเค็นใดๆ เพื่อลบโฆษณาในเกม", "renameText": "เปลี่ยนชื่อ", "replayEndText": "สิ้นสุดการเล่นซ้ำ", "replayNameDefaultText": "รีเพลย์เกมล่าสุด", @@ -1211,7 +1276,9 @@ "revertText": "ย้อนกลับ", "runText": "วิ่ง", "saveText": "บันทึก", - "scanScriptsErrorText": "ข้อผิดพลาดในการสแกนสคริปต์; ดูบันทึกสำหรับรายละเอียด", + "scanScriptsErrorText": "เกิดข้อผิดพลาดในการสแกนสคริปต์ ดูบันทึกสำหรับรายละเอียด", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} และ ${NUM} โมดูลอื่นๆ (s) จำเป็นต้องมีการอัพเดตสำหรับ api นี้ ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} จำเป็นต้องมีการอัพเดตสำหรับ api นี้ ${API}.", "scoreChallengesText": "คะแนนความท้าทาย", "scoreListUnavailableText": "ไม่มีรายการคะแนน", "scoreText": "คะแนน", @@ -1222,10 +1289,11 @@ }, "scoreWasText": "(เดิมคือ ${COUNT})", "selectText": "เลือก", + "sendInfoDescriptionText": "ส่งข้อมูลบัญชีและสถานะแอปให้กับนักพัฒนา\nโปรดระบุชื่อหรือเหตุผลในการส่ง", "seriesWinLine1PlayerText": "ชนะ", "seriesWinLine1TeamText": "ชนะ", "seriesWinLine1Text": "ชนะ", - "seriesWinLine2Text": "ซีรีส์", + "seriesWinLine2Text": "ซีรีส์!", "settingsWindow": { "accountText": "บัญชี", "advancedText": "ขั้นสูง", @@ -1239,40 +1307,52 @@ "alwaysUseInternalKeyboardDescriptionText": "(แป้นพิมพ์บนหน้าจอที่เรียบง่ายและเป็นมิตรกับตัวควบคุมสำหรับการแก้ไขข้อความ)", "alwaysUseInternalKeyboardText": "ใช้แป้นพิมพ์ภายในเสมอ", "benchmarksText": "เกณฑ์มาตรฐานและการทดสอบความเครียด", - "disableCameraGyroscopeMotionText": "ปิดใช้งานการเคลื่อนไหวของกล้อง Gyroscope", - "disableCameraShakeText": "ปิดใช้งานการสั่นของกล้อง", + "devToolsText": "เครื่องมือสำหรับนักพัฒนา", + "disableCameraGyroscopeMotionText": "ปิดใช้งานการเคลื่อนไหวของไจโรสโคปของกล้อง", + "disableCameraShakeText": "ปิดการสั่นของกล้อง", "disableThisNotice": "(คุณสามารถปิดการใช้งานประกาศนี้ในการตั้งค่าขั้นสูง)", "enablePackageModsDescriptionText": "(การเปิดใช้งานที่ทำให้ใช้ม็อดได้หลากหลายมากขึ้นแต่จะปิดระบบการเล่นแบบใช้เน็ต)", "enablePackageModsText": "เปิดแพ็คเกจม็อดท้องถิ่น", "enterPromoCodeText": "ใส่รหัส", "forTestingText": "หมายเหตุ: ค่าเหล่านี้ใช้สำหรับการทดสอบเท่านั้นและจะสูญหายไปเมื่อออกจากแอป", - "helpTranslateText": "การแปลที่ไม่ใช่ภาษาอังกฤษของ ${APP_NAME} เป็นชุมชน\nสนับสนุนความพยายาม หากคุณต้องการมีส่วนร่วมหรือแก้ไข\nแปลตามลิงค์ด้านล่างครับ ขอบคุณล่วงหน้า!", + "helpTranslateText": "การแปลที่ไม่ใช่ภาษาอังกฤษของเกม ${APP_NAME} ได้รับการ\nสนับสนุนจากชุมชน หากคุณต้องการมีส่วนร่วมหรือแก้ไขการแปล \nโปรดคลิ๊กลิงก์ด้านล่าง ขอบคุณล่วงหน้า!", + "insecureConnectionsDescriptionText": "ไม่แนะนำแต่สามารถเล่นออนไลน์ได้\nจากประเทศหรือเครือข่ายที่ถูกจำกัด", + "insecureConnectionsText": "ใช้การเชื่อมต่อที่ไม่ปลอดภัย", "kickIdlePlayersText": "เตะผู้เล่นที่ไม่ได้ใช้งาน", "kidFriendlyModeText": "โหมดเป็นมิตรกับเด็ก (ลดความรุนแรง ฯลฯ)", "languageText": "ภาษา", "moddingGuideText": "คู่มือการม็อด", + "moddingToolsText": "การดัดแปลงเครื่องมือเกม", "mustRestartText": "คุณต้องเริ่มเกมใหม่เพื่อให้สิ่งนี้มีผล", "netTestingText": "การทดสอบเครือข่าย", "resetText": "รีเซ็ต", + "sendInfoText": "ส่งข้อมูล", "showBombTrajectoriesText": "แสดงวิถีลูกระเบิด", + "showDemosWhenIdleText": "แสดงการสาธิตเมื่อไม่ได้ใช้งาน", + "showDeprecatedLoginTypesText": "แสดงประเภทการเข้าสู่ระบบที่ไม่ใช้แล้ว", + "showDevConsoleButtonText": "แสดงปุ่มคอนโซลสำรับนักพัฒนา", + "showInGamePingText": "แสดงค่า ping ในเกม", "showPlayerNamesText": "แสดงชื่อผู้เล่น", "showUserModsText": "แสดงโฟลเดอร์ Mods", "titleText": "ขั้นสูง", - "translationEditorButtonText": "${APP_NAME} ผู้แก้ไขการแปล", + "translationEditorButtonText": "หน้าแก้ไขการแปลภาษาของ ${APP_NAME}", "translationFetchErrorText": "สถานะการแปลไม่พร้อมใช้งาน", "translationFetchingStatusText": "กำลังตรวจสอบสถานะการแปล...", "translationInformMe": "แจ้งฉันเมื่อภาษาของฉันต้องการการอัปเดต", - "translationNoUpdateNeededText": "ภาษาปัจจุบันเป็นปัจจุบัน วู้ฮู!", - "translationUpdateNeededText": "** ภาษาปัจจุบันต้องการการอัปเดต !! **", + "translationNoUpdateNeededText": "ภาษาปัจจุบันทันสมัยแล้ว", + "translationUpdateNeededText": "** ภาษาปัจจุบันต้องการการอัปเดตตอนนี้!! **", "vrTestingText": "การทดสอบ VR" }, "shareText": "แบ่งปัน", "sharingText": "การแบ่งปัน...", "showText": "แสดง", - "signInForPromoCodeText": "คุณต้องลงชื่อเข้าใช้บัญชีเพื่อให้รหัสมีผล", + "signInForPromoCodeText": "คุณต้องเข้าสู่ระบบเพื่อให้รหัสมีผล", "signInWithGameCenterText": "ในการใช้บัญชี Game Center\nลงชื่อเข้าใช้ด้วยแอพ Game Center", "singleGamePlaylistNameText": "แค่ ${GAME}", "singlePlayerCountText": "ผู้เล่น 1 คน", + "sizeLargeText": "ใหญ่", + "sizeMediumText": "ปานกลาง", + "sizeSmallText": "เล็ก", "soloNameFilterText": "เดี่ยว ${NAME}", "soundtrackTypeNames": { "CharSelect": "การเลือกตัวละคร", @@ -1345,7 +1425,9 @@ "storeText": "ร้านค้า", "submitText": "ส่ง", "submittingPromoCodeText": "กำลังส่งรหัส...", - "teamNamesColorText": "Team Names/Colors...", + "successText": "ความสำเร็จ!", + "supportEmailText": "หากคุณประสบปัญหาใดๆ กับแอป โปรดส่งอีเมลไปที่ ${EMAIL}", + "teamNamesColorText": "ชื่อทีม/สี...", "telnetAccessGrantedText": "เปิดใช้งานการเข้าถึง Telnet", "telnetAccessText": "ตรวจพบการเข้าถึง Telnet; อนุญาต?", "testBuildErrorText": "รุ่นทดสอบนี้ไม่ทำงานอีกต่อไป โปรดตรวจสอบเวอร์ชันใหม่", @@ -1354,6 +1436,7 @@ "testBuildValidatedText": "ทดสอบบิลด์ที่ตรวจสอบแล้ว; สนุก!", "thankYouText": "ขอบคุณสำหรับการสนับสนุนของคุณ! สนุกกับเกม!!", "threeKillText": "ฆ่าสามครั้ง!!", + "ticketsDescriptionText": "สามารถใช้ตั๋วเพื่อปลดล็อคตัวละคร,\nแผนที่, มินิเกมและอื่นๆ ได้ในร้านค้า\n\nสามารถพบตั๋วได้ในหีบที่ได้รับจาก\nแคมเปญ, ทัวร์นาเมนต์และความสำเร็จ", "timeBonusText": "โบนัสเวลา", "timeElapsedText": "เวลาที่ผ่านไป", "timeExpiredText": "เวลาหมด", @@ -1364,10 +1447,23 @@ "tipText": "เคล็ดลับ", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "รับโทเค็น", + "notEnoughTokensText": "โทเค็นไม่เพียงพอ!", + "numTokensText": "${COUNT} โทเค็น", + "shinyNewCurrencyText": "สกุลเงินใหม่อันแวววาวของ BombSquad", + "tokenPack1Text": "แพ็คโทเค็นขนาดเล็ก!", + "tokenPack2Text": "แพ็คโทเค็นขนาดกลาง!", + "tokenPack3Text": "แพ็คโทเค็นขนาดใหญ่", + "tokenPack4Text": "แพ็คโทเค็นจัมโบ้!!", + "tokensDescriptionText": "โทเค็นใช้เพื่อเร่งความเร็วในการปลดล็อกหีบ\nและสำหรับคุณสมบัติของเกมและบัญชีอื่นๆ\n\nคุณสามารถรับโทเค็นในเกมหรือซื้อเป็นแพ็ค \nหรือซื้อ Gold Pass เพื่อรับรางวัลไม่จำกัด\nและไม่ต้องพบเจอมันอีกต่อไป", + "youHaveGoldPassText": "คุณมี บัตรทองคำ\nการซื้อโทเค็นทั้งหมดฟรี\nสนุกได้เลย!" + }, "topFriendsText": "เพื่อนที่ดีที่สุด", "tournamentCheckingStateText": "การตรวจสอบสถานะการแข่งขัน โปรดรอ...", "tournamentEndedText": "การแข่งขันนี้สิ้นสุดลงแล้ว ใหม่จะเริ่มเร็ว ๆ นี้", "tournamentEntryText": "รายการแข่งขัน", + "tournamentFinalStandingsText": "ตารางสรุปผลคะแนน", "tournamentResultsRecentText": "ผลการแข่งขันล่าสุด", "tournamentStandingsText": "อันดับการแข่งขัน", "tournamentText": "การแข่งขัน", @@ -1423,6 +1519,18 @@ "Uber Onslaught": "Uber Onslaught", "Uber Runaround": "Uber Runaround" }, + "displayItemNames": { + "${C} Tickets": "ตั๋ว ${C} ใบ", + "${C} Tokens": "โทเคน ${C} เหรียญ", + "Chest": "หีบทั่วไป", + "L1 Chest": "หีบระดับ 1", + "L2 Chest": "หีบระดับ 2", + "L3 Chest": "หีบระดับ 3", + "L4 Chest": "หีบระดับ 4", + "L5 Chest": "หีบระดับ 5", + "L6 Chest": "หีบระดับ 6", + "Unknown Chest": "หีบที่ไม่รู้จัก" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "เป็นผู้ที่ได้รับเลือกเป็นระยะเวลาหนึ่งเพื่อชนะ\nฆ่าคนที่ถูกเลือกให้เป็น", "Bomb as many targets as you can.": "วางระเบิดเป้าหมายให้ได้มากที่สุด", @@ -1525,7 +1633,9 @@ "Italian": "ภาษาอิตาลี", "Japanese": "ภาษาญี่ปุ่น", "Korean": "ภาษาเกาหลี", + "Malay": "ภาษามาเลเซีย", "Persian": "ภาษาเปอร์เซีย", + "PirateSpeak": "โจรสลัดพูดกับคุณ", "Polish": "ภาษาโปแลนด์", "Portuguese": "ภาษาโปรตุเกส", "Romanian": "ภาษาโรมาเนีย", @@ -1556,7 +1666,7 @@ "Football Stadium": "สนามฟุตบอล", "Happy Thoughts": "ความคิดที่เป็นสุข", "Hockey Stadium": "สนามฮอกกี้", - "Lake Frigid": "ทะเลสาบฟริจิด", + "Lake Frigid": "ทะเลสาบเยือกแข็ง", "Monkey Face": "หน้าลิง", "Rampage": "อาละวาด", "Roundabout": "วงเวียน", @@ -1597,6 +1707,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "ตรวจพบการโกง; คะแนนและรางวัลถูกระงับเป็นเวลา ${COUNT} วัน", "Could not establish a secure connection.": "ไม่สามารถสร้างการเชื่อมต่อที่ปลอดภัย", "Daily maximum reached.": "ถึงสูงสุดรายวันแล้ว", + "Daily sign-in reward": "รางวัลการลงชื่อเข้าใช้รายวัน", "Entering tournament...": "เข้าสู่การแข่งขัน...", "Invalid code.": "รหัสไม่ถูกต้อง", "Invalid payment; purchase canceled.": "การชำระเงินไม่ถูกต้อง การซื้อถูกยกเลิก", @@ -1606,11 +1717,14 @@ "Item unlocked!": "ปลดล็อคไอเทมแล้ว!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "การเชื่อมโยงถูกปฏิเสธ ${ACCOUNT} ประกอบด้วย\nข้อมูลสำคัญที่จะสูญหายทั้งหมด\nคุณสามารถเชื่อมโยงในลำดับตรงกันข้ามหากคุณต้องการ\n(และสูญเสียข้อมูลของบัญชีนี้แทน)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "เชื่อมโยงบัญชี ${ACCOUNT} กับบัญชีนี้หรือไม่\nข้อมูลที่มีอยู่ทั้งหมดใน ${ACCOUNT} จะหายไป\nไม่สามารถยกเลิกได้ คุณแน่ใจไหม?", + "Longer streaks lead to better rewards.": "ยิ่งรับรางวัลต่อเนื่องนานเท่าไรก็จะยิ่งได้รับรางวัลที่ดียิ่งขึ้นเท่านั้น", "Max number of playlists reached.": "ถึงจำนวนเพลย์ลิสต์สูงสุดแล้ว", "Max number of profiles reached.": "ถึงจำนวนโปรไฟล์สูงสุดแล้ว", "Maximum friend code rewards reached.": "รางวัลรหัสเพื่อนถึงขีดจำกัดแล้ว", "Message is too long.": "ข้อความยาวเกินไป", + "New tournament result!": "ผลการแข่งขันใหม่!", "No servers are available. Please try again soon.": "ไม่มีเซิร์ฟเวอร์ที่พร้อมใช้งาน โปรดลองอีกครั้งในเร็วๆ นี้", + "No slots available. Free a slot and try again.": "ไม่มีช่องว่าง ทำให้มีช่องเก็บหีบว่างแล้วลองใหม่อีกครั้ง", "Profile \"${NAME}\" upgraded successfully.": "อัปเกรดโปรไฟล์ \"${NAME}\" สำเร็จแล้ว", "Profile could not be upgraded.": "ไม่สามารถอัพเกรดโปรไฟล์ได้", "Purchase successful!": "ซื้อสำเร็จ!", @@ -1620,7 +1734,9 @@ "Sorry, this code has already been used.": "ขออภัย รหัสนี้ถูกใช้ไปแล้ว", "Sorry, this code has expired.": "ขออภัย รหัสนี้หมดอายุแล้ว", "Sorry, this code only works for new accounts.": "ขออภัย รหัสนี้ใช้ได้กับบัญชีใหม่เท่านั้น", + "Sorry, this has expired.": "ขออภัย หมดอายุแล้ว", "Still searching for nearby servers; please try again soon.": "ยังคงค้นหาเซิร์ฟเวอร์ใกล้เคียง โปรดลองอีกครั้งในเร็วๆ นี้", + "Streak: ${NUM} days": "ต่อเนื่อง: ${NUM} วัน", "Temporarily unavailable; please try again later.": "ปิดให้บริการชั่วคราว; โปรดลองอีกครั้งในภายหลัง.", "The tournament ended before you finished.": "การแข่งขันสิ้นสุดลงก่อนที่คุณจะเสร็จสิ้น", "This account cannot be unlinked for ${NUM} days.": "บัญชีนี้ไม่สามารถยกเลิกการเชื่อมโยงได้เป็นเวลา ${NUM} วัน", @@ -1631,19 +1747,27 @@ "Tournaments require ${VERSION} or newer": "ทัวร์นาเมนต์ต้องใช้ ${VERSION} หรือใหม่กว่า", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "ยกเลิกการเชื่อมโยง ${ACCOUNT} จากบัญชีนี้หรือไม่\nข้อมูลทั้งหมดใน ${ACCOUNT} จะถูกรีเซ็ต\n(ยกเว้นความสำเร็จในบางกรณี)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "คำเตือน: มีการร้องเรียนเกี่ยวกับการแฮ็กบัญชีของคุณ\nบัญชีที่พบว่ามีการแฮ็คจะถูกแบน กรุณาเล่นอย่างยุติธรรม", + "Wait reduced!": "ลดเวลารอแล้ว!", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "คุณต้องการเชื่อมโยงบัญชีอุปกรณ์ของคุณกับบัญชีนี้หรือไม่?\n\nบัญชีอุปกรณ์ของคุณคือ ${ACCOUNT1}\nบัญชีนี้คือ ${ACCOUNT2}\n\nนี้จะช่วยให้คุณรักษาความคืบหน้าที่มีอยู่ของคุณ\nคำเตือน: สิ่งนี้ไม่สามารถยกเลิกได้!", "You already own this!": "คุณเป็นเจ้าของสิ่งนี้แล้ว!", "You can join in ${COUNT} seconds.": "คุณสามารถเข้าร่วมได้ภายในอีก ${COUNT} วินาที", "You don't have enough tickets for this!": "คุณมีตั๋วไม่เพียงพอสำหรับสิ่งนี้!", "You don't own that.": "คุณไม่ได้เป็นเจ้าของสิ่งนั้น", "You got ${COUNT} tickets!": "คุณได้รับตั๋ว ${COUNT} ใบ!", + "You got ${COUNT} tokens!": "คุณได้รับโทเคน ${COUNT} เหรียญ!", "You got a ${ITEM}!": "คุณได้รับ ${ITEM}!", + "You got a chest!": "คุณได้รับหีบ!", + "You got an achievement reward!": "คุณได้รับรางวัลความสำเร็จ!", "You have been promoted to a new league; congratulations!": "คุณได้รับการเลื่อนตำแหน่งเป็นลีกใหม่ ยินดีด้วย!", + "You lost a chest! (All your chest slots were full)": "คุณเสียหีบไป! (ช่องเก็บหีบของคุณเต็มหมดแล้ว)", + "You must update the app to view this.": "คุณต้องอัปเดตแอปเพื่อดูสิ่งนี้", "You must update to a newer version of the app to do this.": "คุณต้องอัปเดตแอปเป็นเวอร์ชันใหม่กว่าจึงจะทำได้", "You must update to the newest version of the game to do this.": "คุณต้องอัปเดตเป็นเวอร์ชันใหม่ล่าสุดของเกมจึงจะสามารถทำได้", "You must wait a few seconds before entering a new code.": "คุณต้องรอสักครู่ก่อนที่จะป้อนรหัสใหม่", + "You placed #${RANK} in a tournament!": "คุณอยู่อันดับที่ #${RANK} ในการแข่งขัน!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "คุณติดอันดับ #${RANK} ในทัวร์นาเมนต์ที่แล้ว ขอบคุณสำหรับการเล่น!", - "Your account was rejected. Are you signed in?": "บัญชีของคุณถูกปฏิเสธ คุณลงชื่อเข้าใช้หรือไม่", + "Your account was rejected. Are you signed in?": "บัญชีของคุณถูกปฏิเสธ คุณได้เข้าสู่ระบบหรือไม่?", + "Your ad views are not registering. Ad options will be limited for a while.": "การดูโฆษณาของคุณไม่ได้ถูกบันทึก ตัวเลือกโฆษณาจะถูกจำกัดชั่วคราว", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "สำเนาเกมของคุณได้รับการแก้ไขแล้ว\nโปรดยกเลิกการเปลี่ยนแปลงและลองอีกครั้ง", "Your friend code was used by ${ACCOUNT}": "รหัสเพื่อนของคุณถูกใช้โดย ${ACCOUNT}" }, @@ -1792,11 +1916,13 @@ "toSkipPressAnythingText": "(แตะหรือกดอะไรก็ได้เพื่อข้ามบทแนะนำ)" }, "twoKillText": "ดับเบิ้ลคิล!", + "uiScaleText": "สเกล UI", "unavailableText": "ไม่พร้อมใช้งาน", "unconfiguredControllerDetectedText": "ตรวจพบคอนโทรลเลอร์ที่ไม่ได้กำหนดค่า:", "unlockThisInTheStoreText": "สิ่งนี้จะต้องปลดล็อคในร้านค้า", "unlockThisProfilesText": "ในการสร้างมากกว่า ${NUM} โปรไฟล์ คุณต้อง:", "unlockThisText": "เพื่อปลดล็อกสิ่งนี้ คุณต้อง:", + "unsupportedControllerText": "ขออภัย ไม่รองรับตัวควบคุม \"${NAME}\"", "unsupportedHardwareText": "ขออภัย ฮาร์ดแวร์นี้ไม่ได้รับการสนับสนุนโดยบิวด์ของเกมนี้", "upFirstText": "ขึ้นก่อน:", "upNextText": "ต่อไปในเกม ${COUNT}:", @@ -1804,10 +1930,14 @@ "upgradeText": "อัพเกรด", "upgradeToPlayText": "ปลดล็อก \"${PRO}\" ในร้านค้าในเกมเพื่อเล่นเกมนี้", "useDefaultText": "ใช้ค่าเริ่มต้น", + "userSystemScriptsCreateText": "สร้างสคริปต์ระบบผู้ใช้", + "userSystemScriptsDeleteText": "ลบสคริปต์ระบบผู้ใช้", "usesExternalControllerText": "เกมนี้ใช้คอนโทรลเลอร์ภายนอกสำหรับการป้อนข้อมูล", "usingItunesText": "การใช้แอพ Music สำหรับซาวด์แทร็ก...", "v2AccountLinkingInfoText": "หากต้องการเชื่อมโยงบัญชี V2 ให้ใช้ปุ่ม 'จัดการบัญชี'", + "v2AccountRequiredText": "จำเป็นต้องมีบัญชี V2 อัปเกรดบัญชีของคุณแล้วลองอีกครั้ง", "validatingTestBuildText": "กำลังตรวจสอบการสร้างการทดสอบ...", + "viaText": "จาก", "victoryText": "ชัยชนะ!", "voteDelayText": "คุณไม่สามารถเริ่มโหวตได้อีกเป็นเวลา ${NUMBER} วินาที", "voteInProgressText": "กำลังดำเนินการโหวทอยู่แล้ว", @@ -1872,5 +2002,6 @@ }, "yesAllowText": "ใช่อนุญาต!", "yourBestScoresText": "คะแนนที่ดีที่สุดของคุณ", - "yourBestTimesText": "เวลาที่ดีที่สุดของคุณ" + "yourBestTimesText": "เวลาที่ดีที่สุดของคุณ", + "yourPrizeText": "รางวัลของคุณ:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/turkish.json b/dist/ba_data/data/languages/turkish.json index 3b8de283..443481ae 100644 --- a/dist/ba_data/data/languages/turkish.json +++ b/dist/ba_data/data/languages/turkish.json @@ -7,7 +7,9 @@ "campaignProgressText": "Mücadele İlerlemesi [Zor]: ${PROGRESS}", "changeOncePerSeason": "Bunu sezon başına sadece bir kere değiştirebilirsin", "changeOncePerSeasonError": "Bunu tekrar değiştirmek için bir sonraki sezona kadar beklemelisin (${NUM}gün)", + "createAnAccountText": "Hesap Oluştur", "customName": "Özel isim", + "deleteAccountText": "Hesabı Sil", "googlePlayGamesAccountSwitchText": "Eğer farklı bir google hesabı kullanmak istiyorsanız,\nGoogle Play Oyunlar uygulamasını kullabilirsiniz.", "linkAccountsEnterCodeText": "Kod Gir", "linkAccountsGenerateCodeText": "Kod Oluştur", @@ -25,14 +27,16 @@ "setAccountNameDesc": "Hesabın için gösterilecek bir isim seç. \nBağladığın hesaplardan birinin adını kullanabilir\nya da yeni bir tane oluşturabilirsin.", "signInInfoText": "Bilet toplamak Çevrimiçi olmak ve ilerlemeyi \ndiğer cihazlarla paylaşmak için Giriş yap.", "signInText": "Giriş Yap", + "signInWithAnEmailAddressText": "Bir e-posta adresiyle giriş yap", "signInWithDeviceInfoText": "Otomatik bir hesap sadece bu cihaz için kullanılabilir", "signInWithDeviceText": "Cihaz hesabı ile Giriş yap", "signInWithGameCircleText": "Game Circle ile Giriş yap", "signInWithGooglePlayText": "Google Play ile Giriş yap", "signInWithTestAccountInfoText": "(miras hesabı;bu cihaz hesaplarını ileride de kullan)", "signInWithTestAccountText": "Test hesabı ile Giriş yap", + "signInWithText": "${SERVICE} ile giriş yap.", "signInWithV2InfoText": "(bütün platformlarda çalışan bir hesap)", - "signInWithV2Text": "BombSquad hesabıyla giriş yap", + "signInWithV2Text": "${APP_NAME} hesabıyla giriş yap", "signOutText": "Çıkış Yap", "signingInText": "Giriş yapılıyor...", "signingOutText": "Çıkış yapılıyor...", @@ -334,9 +338,14 @@ "getMoreGamesText": "Daha Çok Oyun...", "titleText": "Oyun Ekle" }, + "addToFavoritesText": "Favorilere ekle", + "addedToFavoritesText": "'${NAME}' Favorilere eklendi.", + "allText": "Hepsi", "allowText": "Kabul Et", "alreadySignedInText": "Başka bir cihazda hesabına giriş yapılmış;\nlütfen hesapları değiştir ya da diğer cihazlardaki\noyunu kapat ve tekrar dene.", "apiVersionErrorText": "Modul yüklenemiyor ${NAME}; hedef api-versiyon ${VERSION_USED}; ihtiyacımız olan ${VERSION_REQUIRED}.", + "applyText": "Kaydet", + "areYouSureText": "Emin misin?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(\"Oto\" yalnızca kulaklıklar takılı iken etkinleşir)", "headRelativeVRAudioText": "Head-Relative VR Ses", @@ -359,14 +368,24 @@ "boostText": "Öne Geç", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} Uygulamayı kendisine yapılandır", "buttonText": "buton", - "canWeDebugText": "Oyun otomatik olarak hataları, çökmeleri ve basit \nkullanım istatistiklerini geliştiriciye gondersin mi?\n\nBu veri içeriği kişisel bilgilerinizi kullanmaz\noyunun daha iyi çalışmasına yardımcı olur.", + "canWeDebugText": "${APP_NAME} hataları, çökmeleri ve basit kullanım \nbilgilerini otomatik olarak geliştiriciye göndersin mi?\n\nBu veri hiçbir kişisel bilgi içermez ve oyunun daha \nakıcı ve hatasız çalısmasına yardımcı olur.", "cancelText": "İptal", "cantConfigureDeviceText": "Üzgünüz, ${DEVICE} ayarlanabilir değil.", "challengeEndedText": "Bu mücadele sona erdi.", "chatMuteText": "Konuşmayı sustur", "chatMutedText": "Sohbet Susturuldu", "chatUnMuteText": "Konuşmayı aç", + "chests": { + "prizeOddsText": "Olası Ödüller", + "reduceWaitText": "Beklemeyi Hızlandır", + "slotDescriptionText": "Bu yuvaya sandık koyulabilir.\n\nSandıklar mücadele bölümleri oynayarak, \nturnuvalara katılarak ve başarılar elde \nederek kazanılır.", + "slotText": "Sandık Yuvası ${NUM}", + "slotsFullWarningText": "UYARI: Bütün sandık yuvaları dolu.\nBu oyundan kazandığın sandıklar kaybolacak.", + "unlocksInText": "Açılacak" + }, "choosingPlayerText": "", + "claimText": "Topla", + "codesExplainText": "Kodlar geliştirici tarafından sağlanır\nhesap sorunlarını teşhis edin ve düzeltin.", "completeThisLevelToProceedText": "İlerlemek için bu \nseviyeyi tamamlamalısınız!", "completionBonusText": "Tamamlama Bonusu", "configControllersWindow": { @@ -447,6 +466,7 @@ "swipeText": "sürme", "titleText": "Dokunmatikleri Yapılandır" }, + "configureDeviceInSystemSettingsText": "${DEVICE} Sistem ayarları uygulamasında yapılandırılabilir.", "configureItNowText": "Şimdi yapılandır?", "configureText": "Yapılandır", "connectMobileDevicesWindow": { @@ -498,7 +518,7 @@ "totalText": "toplam", "tournamentInfoText": "Ligindeki diğer oyuncular arasında\nen yüksek skoru yap.\n\nÖdüller En fazla skor yapan oyuncular\narasında turnuva süresi bittiğinde verilir.", "welcome1Text": "${LEAGUE} hoş geldiniz. Lig sıralamanı turnuvalarda\nyıldız derecesi kazanarak, başarıları tamamlayarak\nve kupalar kazanarak geliştirebilirsin.", - "welcome2Text": "Ayrıca benzer aktivitelerden biletler kazanabilirsin.\nBiletler yeni karakterler, haritalar, mini-oyunlar\nve turnuvalara katılmak için kulanılabilir.", + "welcome2Text": "Ayrıca benzer aktivitelerden bilet kazanabilirsin.\nBiletler yeni karakterler, haritalar, mini-oyunlar\nve turnuvalara katılmak için kulanılabilir.", "yourPowerRankingText": "Oyuncu Sıralaman:" }, "copyConfirmText": "Panoya kopyalandı.", @@ -549,6 +569,7 @@ "demoText": "Tanıtım", "denyText": "Reddet", "deprecatedText": "Kullanımdan kaldırıldı", + "descriptionText": "Açıklama", "desktopResText": "PC Çözünürlüğü", "deviceAccountUpgradeText": "Uyarı:\n(${NAME}) isimli bir cihaz hesabıyla giriş yaptın.\nCihaz hesapları gelecek güncellemelerde kaldırılacak.\nİlerlemeni tutmak istiyorsan V2 hesabına geçiş yap.", "difficultyEasyText": "Kolay", @@ -559,6 +580,10 @@ "disableRemoteAppConnectionsText": "Remote-App Bağlantılarını Engelle", "disableXInputDescriptionText": "4 kontrolcüden fazla kullanılabilir fakat iyi çalışmayabilir.", "disableXInputText": "XInput etkisizleştir", + "disabledText": "Kullanılmıyor", + "discardText": "İptal", + "discordFriendsText": "Yeni oyuncular mı arıyorsun?\nDiscord sunucumuza katılarak yeni arkadaşlar edinebilirsin!", + "discordJoinText": "Discord sunucumuza katıl", "doneText": "Tamam", "drawText": "Beraberlik", "duplicateText": "Kopyala", @@ -591,6 +616,7 @@ "localProfileText": "(yerel profil)", "nameDescriptionText": "Oyuncu Adı", "nameText": "Ad", + "profileAlreadyExistsText": "Bu ad ile bir profil zaten var.", "randomText": "rastgele", "titleEditText": "Profil Düzenle", "titleNewText": "Yeni Profil", @@ -626,6 +652,7 @@ "useMusicFolderText": "Müzik Dosyaları Klasörü" }, "editText": "Düzenle", + "enabledText": "Onaylanmış", "endText": "Bitir", "enjoyText": "Keyfini Çıkar!", "epicDescriptionFilterText": "${DESCRIPTION} epik ağırçekim.", @@ -637,6 +664,8 @@ "errorText": "Hata", "errorUnknownText": "bilinmeyen hata", "exitGameText": "Çık ${APP_NAME}?", + "expiredAgoText": "${T} önce süresi doldu", + "expiresInText": "${T} sonra süresi dolacak", "exportSuccessText": "'${NAME}' Dışa Aktarıldı.", "externalStorageText": "Harici Depolama", "failText": "Başarısızlık", @@ -671,6 +700,8 @@ "duplicateText": "ÇalmaListesi\nKopyala", "editText": "ÇalmaListesi\nDüzenle", "newText": "ÇalmaListesi\nYarat", + "pointsToWinText": "Kazanmak İçin Gereken Puan", + "seriesLengthText": "Seri Uzunluğu", "showTutorialText": "Öğreticiyi Göster", "shuffleGameOrderText": "Oyun Sırasını Karıştır", "titleText": "Özel ${TYPE} ÇalmaListeleri" @@ -696,6 +727,7 @@ "copyCodeConfirmText": "Kod panoya kopyalandı", "copyCodeText": "Kodu kopyala", "dedicatedServerInfoText": "En iyi sonuçlar için ozel sunucu ayarlayın. Bakınız; bombsquadgame.com/server", + "descriptionShortText": "Lobi penceresini kullanarak bir parti oluştur.", "disconnectClientsText": "Bu, partindeki ${COUNT} oyuncunun bağlantısını\nkesecek. Emin misin ?", "earnTicketsForRecommendingAmountText": "Eğer arkadaşların oyunu denerler ise ${COUNT} bilet alacak\n(Sen ise bunu her yapan için ${YOU_COUNT} tane.)", "earnTicketsForRecommendingText": "Bedave bilet için\nOyunu paylaş...", @@ -708,10 +740,10 @@ "friendHasSentPromoCodeText": "${NAME} tarafından ${COUNT} ${APP_NAME} bileti", "friendPromoCodeAwardText": "Kullanıldığı her zaman ${COUNT} bilet alacaksın.", "friendPromoCodeExpireText": "Bu kodun ${EXPIRE_HOURS} saat içinde süresi dolacak ve sadece yeni oyuncularda çalışır.", - "friendPromoCodeInstructionsText": "Kullanmak için ${APP_NAME} uygulamasını açın ve \"Ayarlar->Gelişmiş->Promo Kodu\"\nna gidin. Tüm platformlar arası İndirme bağlantıları için bombsquadgame.com'a gidin.", + "friendPromoCodeInstructionsText": "Kullanmak için ${APP_NAME} uygulamasını açın ve \"Ayarlar->Gelişmiş->Kodu gir\" \ngidin. Tüm platformlar arası İndirme bağlantıları için bombsquadgame.com'a gidin.", "friendPromoCodeRedeemLongText": "Maksimum ${MAX_USES} kişi olmak üzere ${COUNT} bedava bilet alabilirsin.", "friendPromoCodeRedeemShortText": "Oyun içi ${COUNT} bilet alabilirsin", - "friendPromoCodeWhereToEnterText": "(Ayarlar>Gelişmiş>Promo kodu gir içinde)", + "friendPromoCodeWhereToEnterText": "(\"Ayarlar>Gelişmiş>Kodu gir\" içinde)", "getFriendInviteCodeText": "Arkadaş Davet Kodu Al", "googlePlayDescriptionText": "Partine Google Play oyuncularını davet et:", "googlePlayInviteText": "Davet", @@ -743,6 +775,7 @@ "manualYourLocalAddressText": "Yerel adresiniz:", "nearbyText": "Yakında", "noConnectionText": "", + "noPartiesAddedText": "Parti Eklenmedi", "otherVersionsText": "(diğer sürümler)", "partyCodeText": "Parti kodu", "partyInviteAcceptText": "Kabul Et", @@ -799,13 +832,19 @@ "ticketsFromASponsorText": "${COUNT} Bilet için\nbir reklam izle", "ticketsText": "${COUNT} Bilet", "titleText": "Bilet Al", - "unavailableLinkAccountText": "Üzgünüz, Satın almalar bu patformda kullanılamaz.\nBu geçici oldugu gibi, bu hesabını diğer platformlardaki\nhesablara bağlayabilir oradan satın alma işlemi yapbilirsin.", + "unavailableLinkAccountText": "Üzgünüz, Satın almalar bu patformda kullanılamaz.\nBu geçici oldugu gibi, bu hesabını diğer platformlardaki\nhesaplara bağlayabilir oradan satın alma işlemi yapbilirsin.", "unavailableTemporarilyText": "Bu şu anda müsait değil; lütfen daha sonra tekrar deneyin.", "unavailableText": "Üzgünüz, Bu mümkün değil.", "versionTooOldText": "Üzgünüz, Oyunun bu sürümü çok eski; lütfen yeni bir sürüme güncelleyin.", "youHaveShortText": "${COUNT} Biletin var", "youHaveText": "${COUNT} biletin var" }, + "goldPass": { + "desc1InfTokensText": "Sınırsız jeton.", + "desc2NoAdsText": "Reklamları kaldır.", + "desc3ForeverText": "Ebediyen.", + "goldPassText": "Gold Pass" + }, "googleMultiplayerDiscontinuedText": "Üzgünüz, Google'ın çok oyunculu servisi şu anda çalışmıyor.\nBir yer değişimi için olabildiğince hızlı çalışıyorum.\nO zamana kadar, lütfen başka bir bağlantı yöntemi deneyin.\n-Eric", "googlePlayPurchasesNotAvailableText": "Google Play satın alma işlemleri mevcut değildir.\nMağaza uygulamanızı güncellemeniz gerekebilir.", "googlePlayServicesNotAvailableText": "Google Play Hizmetleri kullanılamıyor.\nBazı uygulama işlevleri devre dışı bırakılabilir.", @@ -814,10 +853,12 @@ "alwaysText": "Her Zaman", "fullScreenCmdText": "Tam Ekran (Cmd-F)", "fullScreenCtrlText": "Tam Ekran (Ctrl-F)", + "fullScreenText": "Tam Ekran", "gammaText": "Gama", "highText": "Yüksek", "higherText": "Çok Yüksek", "lowText": "Düşük", + "maxFPSText": "Maksimum FPS", "mediumText": "Orta", "neverText": "Asla", "resolutionText": "Çözünürlük", @@ -878,6 +919,7 @@ "importText": "İçe Aktar", "importingText": "İçe Aktarılıyor...", "inGameClippedNameText": "Şöyle görünecek\n\"${NAME}\"", + "inboxText": "Gelen kutusu", "installDiskSpaceErrorText": "HATA: Kurulum tamamlanamıyor.\nCihazınızda boş alan kalmamış olabilir.\nBiraz alan açın ve yeniden deneyin.", "internal": { "arrowsToExitListText": "Listeden çıkmak için ${LEFT} ya da ${RIGHT} basın.", @@ -932,12 +974,14 @@ "timeOutText": "(${TIME} saniye içinde süre dolacak)", "touchScreenJoinWarningText": "DokunmatikEkran ile katıldın.\nEğer yanlışlıkla olduysa 'Menü->Oyundan Ayrıl' ile düzelt.", "touchScreenText": "DokunmatikEkran", + "unableToCompleteTryAgainText": "Şu anda bunu gerçekleştirmek mümkün değil.\nLütfen tekrar deneyin.", "unableToResolveHostText": "Hata: kurucu çözümlenemiyor.", "unavailableNoConnectionText": "Bu şu an kullanılamaz (internet bağlantısı yok?)", "vrOrientationResetCardboardText": "Bunu kullanmak için VR oryantasyonunu sıfırla.\nOyunu oynamak için harici kontrolcüye ihtiyacın olacak.", "vrOrientationResetText": "VR oryantasyonunu sıfırla.", "willTimeOutText": "(boşta durursa süre dolacak)" }, + "inventoryText": "Envanter", "jumpBoldText": "ZIPLA", "jumpText": "Zıpla", "keepText": "Koru", @@ -984,8 +1028,11 @@ "seasonEndsMinutesText": "Sezon ${NUMBER} dakika içinde sonlanacak", "seasonText": "Sezon ${NUMBER}", "tournamentLeagueText": "Bu tunuvaya katılmak için ${NAME} olmalısın.", - "trophyCountsResetText": "Kupalar bir sonraki sezon sıfırlanacak." + "trophyCountsResetText": "Kupalar bir sonraki sezon sıfırlanacak.", + "upToDateBonusDescriptionText": "En son sürümü çalıştıran oyuncular\n${PERCENT}% kadar bonus ödül alacak.", + "upToDateBonusText": "Son-Sürüm Bonusu" }, + "learnMoreText": "Fazlasını öğren", "levelBestScoresText": "${LEVEL} En-İyi Skorlar", "levelBestTimesText": "${LEVEL} En-İyi Süreler", "levelIsLockedText": "${LEVEL} kilitli.", @@ -1029,6 +1076,8 @@ "modeArcadeText": "Arcade Modu", "modeClassicText": "Klasik Mod", "modeDemoText": "Demo Modu", + "moreSoonText": "Daha fazlası yakında...", + "mostDestroyedPlayerText": "En Çok Öldürülen Oyuncu", "mostValuablePlayerText": "En Değerli Oyuncu", "mostViolatedPlayerText": "En Çok Saldırılan Oyuncu", "mostViolentPlayerText": "En Saldırgan Oyuncu", @@ -1045,6 +1094,7 @@ "nameSuicideText": "${NAME} intihar etti.", "nameText": "İsim", "nativeText": "Gerçek", + "newExclaimText": "Yeni!", "newPersonalBestText": "Yeni kişisel rekor!", "newTestBuildAvailableText": "Yeni bir test yapısı mevcut! (${VERSION} yapı ${BUILD}).\n${ADDRESS} buradan edinebilirsin", "newText": "Yeni", @@ -1055,12 +1105,16 @@ "noContinuesText": "(sürdürülemiyor)", "noExternalStorageErrorText": "Bu cihazda harici depolama bulunamadı", "noGameCircleText": "Hata: GameCircle girişi yapılamadı", + "noMessagesText": "Mesaj yok.", + "noPluginsInstalledText": "Yüklü Eklenti Yok", "noScoresYetText": "Henüz skor yok.", + "noServersFoundText": "Sunucu Bulunamadı.", "noThanksText": "Hayır Teşekkürler", "noTournamentsInTestBuildText": "DİKKAT: Bu test sürümündeki turnuva skorları dikkate alınmayacaktır.", "noValidMapsErrorText": "Bu oyun tipi için geçerli harita bulunamadı.", "notEnoughPlayersRemainingText": "Yeterince oyuncu kalmadı; çık ve yeni bir oyun başlat.", "notEnoughPlayersText": "Bu oyunu başlatmak için en az ${COUNT} oyuncuya ihtiyacın var!", + "notEnoughTicketsText": "Hiç biletin kalmadı", "notNowText": "Şimdi Değil", "notSignedInErrorText": "Bunu yapmak için giriş yapmalısın.", "notSignedInGooglePlayErrorText": "Bunu yapmak için Google Play ile giriş yapmalısın.", @@ -1073,6 +1127,9 @@ "onText": "Açık", "oneMomentText": "Bir dakika...", "onslaughtRespawnText": "${PLAYER} oyuncusu ${WAVE}. dalgada yeniden doğacak", + "openMeText": "Aç Beni", + "openNowText": "Şimdi Aç", + "openText": "Aç", "orText": "${A} veya ${B}", "otherText": "Diğer...", "outOfText": "(${ALL} için #${RANK})", @@ -1158,6 +1215,8 @@ "punchText": "yumruk", "purchaseForText": "${PRICE} için Satın Al", "purchaseGameText": "Oyun Satın Al", + "purchaseNeverAvailableText": "Üzgünüm, Satın alımlar bu sürümde mevcut değil.\nBaşka bir platformda profiline giriş yapmayı ve oradan satın alım yapmayı dene.", + "purchaseNotAvailableText": "Bu satın alım mevcut değildir.", "purchasingText": "Satın Alınıyor...", "quitGameText": "Çık ${APP_NAME}?", "quittingIn5SecondsText": "5 saniye içinde çıkılacak...", @@ -1199,6 +1258,7 @@ "version_mismatch": "Versiyon uyuşmuyor.\nBombSquad ve BombSquad Remote'nin son \nsürüm olduğundan emin ol ve tekrar dene." }, "removeInGameAdsText": "Oyun-içi reklamları kaldırmak için \"${PRO}\" kilidini mağazadan aç.", + "removeInGameAdsTokenPurchaseText": "SINIRLI SÜRELİ TEKLİF: Oyun içi reklamları kaldırmak için HERHANGİ BİR jeton paketi satın alın.", "renameText": "Yeniden Adlandır", "replayEndText": "Tekrarı Kapat", "replayNameDefaultText": "Son Oyun Tekrarı", @@ -1219,7 +1279,9 @@ "revertText": "Eski Haline Döndür", "runText": "Koş", "saveText": "Kaydet", - "scanScriptsErrorText": "Betikleri tararken hata oluştu; detaylar için logları kontrol edin.", + "scanScriptsErrorText": "Betik(ler) taranırken hata oluştu. Detaylar için logları kontrol edin.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} ve ${NUM} diğer modül(ler) api ${API} için güncellenmelidir.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} api ${API} için güncellenmelidir.", "scoreChallengesText": "Mücadele Skoru", "scoreListUnavailableText": "Skor listesi mevcut değil.", "scoreText": "Skor", @@ -1230,6 +1292,7 @@ }, "scoreWasText": "(${COUNT} idi)", "selectText": "Seç", + "sendInfoDescriptionText": "Geliştiriciye hesap ve uygulama durumu bilgilerini gönderir.\nGöndermek için lütfen ad ve gönderme sebebini de ekleyin.", "seriesWinLine1PlayerText": "SERİLERİ", "seriesWinLine1TeamText": "SERİLERİ", "seriesWinLine1Text": "SERİLERİ", @@ -1245,25 +1308,33 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(Basitçe; yazı yazmak için daha kullanışlı ekran klavyesi)", - "alwaysUseInternalKeyboardText": "Her zaman Dahili Klavye Kullan", + "alwaysUseInternalKeyboardText": "Her zaman dahili klavye kullan", "benchmarksText": "Benchmark & Stres-Testleri", - "disableCameraGyroscopeMotionText": "Kamera Jiroskop Hareketini Devre Dışı Bırak", - "disableCameraShakeText": "Kamera Titremesini Devre Dışı Bırak", + "devToolsText": "Geliştirici Ayarları", + "disableCameraGyroscopeMotionText": "Kamera jiroskop hareketini devre dışı bırak", + "disableCameraShakeText": "Kamera titremesini devre dışı bırak", "disableThisNotice": "(bu bildiriyi gelişmiş ayarlardan devre dışı bırakabilirsiniz)", "enablePackageModsDescriptionText": "(ekstra modlama özelliği ekler fakat ağ-oyununu etkisiz kılar)", "enablePackageModsText": "Yerel Paket Modlarını Etkinleştir", "enterPromoCodeText": "Kodu gir", "forTestingText": "Not: Bu değerler sadece test için ve uygulamadan çıkıldığında sıfırlanacak.", "helpTranslateText": "${APP_NAME}'ın İngilizce olmayan çevirileri topluluk yardımı ile\nyapılabilir. Katkı veya düzgün çeviri yapmak istiyorsan aşağıdaki\nbağlantıya tıkla. Şimdiden teşekkürler!", - "kickIdlePlayersText": "Boştaki Oyuncuları Çıkar", + "insecureConnectionsDescriptionText": "önerilmez, sınırlı ülke ve bağlantılarda\noynamanı sağlar", + "insecureConnectionsText": "Güvensiz bağlantılar kullan", + "kickIdlePlayersText": "Boştaki oyuncuları çıkar", "kidFriendlyModeText": "Çoçuk Modu (Azaltılmış şiddet, vb)", "languageText": "Dil", "moddingGuideText": "Modlama Rehberi", + "moddingToolsText": "Modlama Araçları", "mustRestartText": "Etkisini göstermesi için oyunu yeniden başlatmalısınız.", "netTestingText": "Ağ Testi", "resetText": "Sıfırla", + "sendInfoText": "Bilgi Gönder", "showBombTrajectoriesText": "Bomba Gidişatını Göster", - "showInGamePingText": "Oyun İçinde Gecikmeyi Göster", + "showDemosWhenIdleText": "Boşta iken demolar göster", + "showDeprecatedLoginTypesText": "Kullanımdan kaldırılmış oturum açma türlerini göster", + "showDevConsoleButtonText": "Geliştirici panelini aç", + "showInGamePingText": "Oyun içinde gecikmeyi göster", "showPlayerNamesText": "Oyuncu Adlarını Göster", "showUserModsText": "Mod Klasörünü Göster", "titleText": "Gelişmiş", @@ -1271,7 +1342,7 @@ "translationFetchErrorText": "çeviri durumu mevcut değil", "translationFetchingStatusText": "Çeviri durumu kontrol ediliyor...", "translationInformMe": "Benim dilimin güncellenmesi gerektiğinde bana haber ver", - "translationNoUpdateNeededText": "Şu anki dil güncel; wohooo!", + "translationNoUpdateNeededText": "Şu anki dil güncel; wohoo!", "translationUpdateNeededText": "** Şu anki dilin güncellenmeye ihtiyacı var!! **", "vrTestingText": "VR Testi" }, @@ -1282,6 +1353,9 @@ "signInWithGameCenterText": "Game Center hesabı kullanmak için\nGame Center uygulaması ile giriş yap.", "singleGamePlaylistNameText": "Sadece ${GAME}", "singlePlayerCountText": "1 oyuncu", + "sizeLargeText": "Büyük", + "sizeMediumText": "Orta", + "sizeSmallText": "Küçük", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Karakter Seçimi", @@ -1307,6 +1381,7 @@ }, "spaceKeyText": "boşluk", "statsText": "İstatistikler", + "stopRemindingMeText": "Bana hatırlatma", "storagePermissionAccessText": "Bu depolama erişimine ihtiyaç duyuyor", "store": { "alreadyOwnText": "${NAME} zaten sende var!", @@ -1355,6 +1430,8 @@ "storeText": "Mağaza", "submitText": "Gönder", "submittingPromoCodeText": "Kod Gönderiliyor...", + "successText": "Başarı!", + "supportEmailText": "Uygulama ile ilgili herhangi bir sorun yaşıyorsanız,\nlütfen ${EMAIL} adresine e-posta gönderin.", "teamNamesColorText": "Takım isimleri/Renkler...", "telnetAccessGrantedText": "Telnet Erişimi aktif.", "telnetAccessText": "Telnet erişimi algılandı; izin ver?", @@ -1364,6 +1441,7 @@ "testBuildValidatedText": "Test Yapısı Onaylandı; Keyfinı Çıkar!", "thankYouText": "Desteğin için teşekkürler! Oyunun tadını çıkar!!", "threeKillText": "ÜÇLÜ ÖLÜM!!", + "ticketsDescriptionText": "Biletler karakterler haritalar, mini oyunlar ve daha \nfazlasının kilidini açmak için mağazada kullanılabilir.\n\nBiletler mücadele , turnuvalar ve başarılarla \nkazanılan sandıklardan çıkabilir.", "timeBonusText": "Süre Bonusu", "timeElapsedText": "Geçen Süre", "timeExpiredText": "Süre Doldu", @@ -1374,10 +1452,24 @@ "tipText": "İpucu", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Jeton al", + "notEnoughTokensText": "Yeterli jetonun yok!", + "numTokensText": "${COUNT} Jeton", + "openNowDescriptionText": "Sandığı açmak için yeterince\njetonun var - beklemene\ngerek yok.", + "shinyNewCurrencyText": "BombSquad'ın parlak yeni para birimi.", + "tokenPack1Text": "Küçük Jeton Paketi", + "tokenPack2Text": "Orta Jeton Paketi", + "tokenPack3Text": "Büyük Jeton Paketi", + "tokenPack4Text": "Kocaman Jeton Paketi", + "tokensDescriptionText": "Jetonlar, sandık kilitlerinin açılmasını hızlandırmak ve \ndiğer oyun ve hesap özellikleri için kullanılır.\n\nOyunda jeton kazanabilir veya jeton paketleri satın \nalabilirsiniz. Veya Gold Pass'i alıp, sonsuz jetonun \nkeyfini çıkarır ve bir daha asla endişelenmezsiniz.", + "youHaveGoldPassText": "Bir Gold Pass'in var.\nTüm Jeton satın alımları ücretsiz.\nKeyfini çıkar!" + }, "topFriendsText": "En İyi Arkadaşlar", "tournamentCheckingStateText": "Turnuva durumu denetleniyor; lütfen bekleyin...", "tournamentEndedText": "Bu turnuva sonlandı. Yeni bir tanesi yakında başlayacak.", "tournamentEntryText": "Turnuva Katılımı", + "tournamentFinalStandingsText": "Son Sıralama", "tournamentResultsRecentText": "Son Turnıva Sonuçları", "tournamentStandingsText": "Turnuva Kazananları", "tournamentText": "Turnuva", @@ -1433,6 +1525,18 @@ "Uber Onslaught": "Üst Düzey Saldırı", "Uber Runaround": "Üst Düzey Dolambaç" }, + "displayItemNames": { + "${C} Tickets": "${C} Bilet", + "${C} Tokens": "${C} Jeton", + "Chest": "Sandık", + "L1 Chest": "S1 Sandık", + "L2 Chest": "S2 Sandık", + "L3 Chest": "S3 Sandık", + "L4 Chest": "S4 Sandık", + "L5 Chest": "S5 Sandık", + "L6 Chest": "S6 Sandık", + "Unknown Chest": "Bilinmeyen Sandık" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Kazanmak için uzun süre seçilmiş kişi ol.\nseçilmiş kişi olmak için seçilmiş kişiyi öldür.", "Bomb as many targets as you can.": "Yapabildiğin kadar hedefi bombala.", @@ -1537,6 +1641,7 @@ "Korean": "Korece", "Malay": "Malayca", "Persian": "Farsça", + "PirateSpeak": "Korsan Dili", "Polish": "Polonya Dili", "Portuguese": "Portekizce", "Romanian": "Romence", @@ -1608,6 +1713,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Hile algılandı; skorlar ve ödüller ${COUNT} gün için askıya alındı.", "Could not establish a secure connection.": "Güvenli bir bağlantı sağlanamadı.", "Daily maximum reached.": "Günlük sınıra ulaşıldı.", + "Daily sign-in reward": "Günlük giriş ödülü", "Entering tournament...": "Turnuvaya giriliyor...", "Invalid code.": "Geçersiz kod.", "Invalid payment; purchase canceled.": "Geçersiz ödeme; satın alma iptal edildi.", @@ -1617,11 +1723,14 @@ "Item unlocked!": "Öğe kilidi açıldı!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "EŞLEŞTİRME ENGELLENDİ ${ACCOUNT}\nhesabının önemli verilerinin tümü kayıp olacak!\nKarşı taraftan eşleştirme yapabilirsiniz\n(Ve verileriniz kayıp olmaz)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "${ACCOUNT} hesabı bu hesaba bağlansın mı?\n${ACCOUNT} hesabı üzerindeki tüm mevcut veriler kaybolacak.\nBu işlem geri alınamaz. Emin misiniz?", + "Longer streaks lead to better rewards.": "Daha uzun seriler daha iyi ödüller verir.", "Max number of playlists reached.": "Maksimum çalmaListesine ulaşıldı.", "Max number of profiles reached.": "Profiller için maksimum sayıya ulaşıldı.", "Maximum friend code rewards reached.": "Arkadaş kodu maksimuma ulaştı.", "Message is too long.": "Mesaj çok uzun.", + "New tournament result!": "Yeni turnuva sonucu!", "No servers are available. Please try again soon.": "Kullanılabilir sunucu yok. Lütfen kısa süre sonra tekrar deneyin.", + "No slots available. Free a slot and try again.": "Boş yuva mevcut değil. Bir yuva boşaltın ve tekrar deneyin.", "Profile \"${NAME}\" upgraded successfully.": "\"${NAME}\" Profili başarı ile yükseltildi.", "Profile could not be upgraded.": "Profil yükseltilemedi.", "Purchase successful!": "Satın Alma Başarılı!", @@ -1631,7 +1740,9 @@ "Sorry, this code has already been used.": "Üzgünüz, bu kod zaten kullanılmış.", "Sorry, this code has expired.": "Üzgünüz, Bu kodun süresi doldu.", "Sorry, this code only works for new accounts.": "Üzgünüz, bu kod yalnızca yeni hesaplar için çalışır.", + "Sorry, this has expired.": "Maalesef, bunun süresi dolmuş.", "Still searching for nearby servers; please try again soon.": "Hala yakındaki sunucuları arıyor; lütfen kısa süre sonra tekrar deneyin.", + "Streak: ${NUM} days": "Seri: ${NUM} gün", "Temporarily unavailable; please try again later.": "Geçici olarak kullanım dışı; lütfen daha sonra tekrar deneyiniz.", "The tournament ended before you finished.": "Sen bitiremeden turnuva sona erdi.", "This account cannot be unlinked for ${NUM} days.": "Bu hesap, ${NUM} gün boyunca kaldırılamaz.", @@ -1642,19 +1753,28 @@ "Tournaments require ${VERSION} or newer": "Turnuvalar ${VERSION} veya daha yeni bir sürümü gerektirir", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "${ACCOUNT} hesabının bağlantısını kaldırmak mı istiyorsunuz?\n${ACCOUNT} hesabı üzerindeki tüm veriler sıfırlanacak.\n(bazı durumlarda başarılar hariç)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "UYARI: Hesabınız hile kullanımı nedeniyle şikayet edilmiştir.\nHile kullanıldığı tespit edilen hesaplar yasaklanacaktır. Lütfen adil oyna.", + "Wait reduced!": "Bekleme azaldı!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Uyarı: Oyunun bu sürümü eski hesap verileriyle sınırlıdır; bazı şeyler eksik veya güncelliğini yitirmiş görünebilir.\nLütfen en son hesap verilerinizi görmek için oyunun daha yeni bir sürümüne yükseltin.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Cihaz hesabınızı bununla bağlamak istermisiniz?\n\nCihaz hesabınız: ${ACCOUNT1}\nBu hesap: ${ACCOUNT2}\n\nUlaştığın ilerlemeler saklanacak.\nUyarı: Bu işlem geri alınamaz!", "You already own this!": "Buna zaten sahipsin!", "You can join in ${COUNT} seconds.": "\"${COUNT}\" saniye içinde katılabilirsin.", "You don't have enough tickets for this!": "Bunun için yeterince biletiniz yok!", "You don't own that.": "Buna sahip değilsin.", "You got ${COUNT} tickets!": "${COUNT} Bilet kazandınız!", + "You got ${COUNT} tokens!": "${COUNT} jeton kazandın!", "You got a ${ITEM}!": "Bir ${ITEM} kazandınız!", + "You got a chest!": "Sandık kazandın!", + "You got an achievement reward!": "Başarı ödülü kazandın!", "You have been promoted to a new league; congratulations!": "Yeni bir lige terfi ettin; tebrikler!", + "You lost a chest! (All your chest slots were full)": "Bir sandık kaybettin! (Tüm sandık yuvaların doluydu)", + "You must update the app to view this.": "Bunu görmek için oyunu güncellemen gerekli.", "You must update to a newer version of the app to do this.": "Bunu yapmak için uygulamayı yeni bir sürüme güncellemelisin.", "You must update to the newest version of the game to do this.": "Bunu yapmak için oyunun en yeni sürümüne güncellemelisiniz.", "You must wait a few seconds before entering a new code.": "Yeni bir kod girmeden önce biraz beklemelisin.", + "You placed #${RANK} in a tournament!": "Bir turnuvada #${RANK} sırada yer aldın!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Son turnuvada #${RANK}. oldun. Oynadığın için teşekkürler!", "Your account was rejected. Are you signed in?": "Hesabın reddedildi. Oturum açtın mı?", + "Your ad views are not registering. Ad options will be limited for a while.": "Reklam bilgilerin kayıt altına alınamıyor. Reklam seçeneklerin bir sürelik kısıtlanacak.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Oyununun kopyası modifiye edilmiş.\nLütfen eski haline döndürüp tekrar deneyin.", "Your friend code was used by ${ACCOUNT}": "Arkadaş kodun ${ACCOUNT} tarafından kullanılmış" }, @@ -1803,11 +1923,14 @@ "toSkipPressAnythingText": "(öğreticiyi atlamak için herhangi bir tuşa bas)" }, "twoKillText": "ÇİFTE ÖLÜM!", + "uiScaleText": "UI Boyutu", "unavailableText": "mevcut değil", + "unclaimedPrizesText": "Alınmamış ödüllerin var!", "unconfiguredControllerDetectedText": "Yapılandırılmamış kontrolcü tespit edildi:", "unlockThisInTheStoreText": "Bunun mağazada kilidi açık olmalı.", "unlockThisProfilesText": "${NUM} taneden daha fazla profil yaratmak için ihtiyacın olan:", "unlockThisText": "Bu kilidi açmak için ihtiyacın olan:", + "unsupportedControllerText": "Üzgünüm, kontrolcü \"${NAME}\" desteklenmiyor.", "unsupportedHardwareText": "Üzgünüz, bu donanım oyunun bu sürümü tarafından desteklenmiyor.", "upFirstText": "İlki:", "upNextText": "Sıradaki oyun ${COUNT}:", @@ -1815,11 +1938,15 @@ "upgradeText": "Yükselt", "upgradeToPlayText": "Bunu oynamak için \"${PRO}\" kilidini oyun-içi mağazadan aç.", "useDefaultText": "Varsayılanı Kullan", + "userSystemScriptsCreateText": "Kullanıcı Sistem Kodlarını Oluştur", + "userSystemScriptsDeleteText": "Kullanıcı Sistem Kodlarını Sil", "usesExternalControllerText": "Bu oyun girdi olarak harici kontrolcü kullanıyor.", "usingItunesText": "Müzikler için iTunes kullanılıyor...", "usingItunesTurnRepeatAndShuffleOnText": "Lütfen iTunes da karıştırmanın KAPALI oldugundan ve Yinelemenin TÜM oldugundan emin olun. ", "v2AccountLinkingInfoText": "V2 hesapları bağlamak için, 'Hesabı yönet' butonuna tıklayın.", + "v2AccountRequiredText": "Bu bir V2 hesap gerektirir. Hesabını yükseltip tekrar dene.", "validatingTestBuildText": "Test Yapısı Onaylanıyor...", + "viaText": "Böyle de bilinir", "victoryText": "Galibiyet!", "voteDelayText": "${NUMBER} saniye boyunca başka oylama başlatamazsın.", "voteInProgressText": "Oylama zaten işlemde.", @@ -1863,7 +1990,7 @@ "wiimoteSetupWindow": { "copyrightText": "DarwiinRemote TelifHakkı", "listenText": "Dinle", - "macInstructionsText": "Wii nin kapalı olduğundan ve 'Dinle'ye bastığında\nMac'inde Bluetooth'un açık olduğundan emin ol.Wii\ndesteği biraz tuhaftır bu yüzden bağlanmadan önce\nbirkaç kere denemelisin.\n\nBluetooth çeşitli uzaklıklardan 7 cihaza\nkadar destek verir.\n\nBombSquad Orijinal Wiimoteleri Nunchukslari ve\nKlasik Kontrolcüleri destekler.\nYeni Wii Remote Plus'da şuanda çalışıyor\nfakat eklenmiş değil.", + "macInstructionsText": "Wii nin kapalı olduğundan ve 'Dinle'ye bastığında\nMac'inde Bluetooth'un açık olduğundan emin ol.Wii\ndesteği biraz tuhaftır bu yüzden bağlanmadan önce\nbirkaç kere denemelisin.\n\nBluetooth çeşitli uzaklıklardan 7 cihaza\nkadar destek verir.\n\nBombSquad Orijinal Wiimoteleri Nunchukslari ve\nKlasik Kontrolcüleri destekler.\nYeni Wii Remote Plus'da şuanda çalışıyor\nfakat eklenmiş değil. ", "thanksText": "DarwiinRemote takımına bunu mümkün\nkıldığı için teşekkürler.", "titleText": "Wiimote Kurulumu" }, @@ -1885,5 +2012,6 @@ }, "yesAllowText": "Evet, Kabul!", "yourBestScoresText": "En İyi Skorların", - "yourBestTimesText": "En İyi Sürelerin" + "yourBestTimesText": "En İyi Sürelerin", + "yourPrizeText": "Ödülün:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/ukrainian.json b/dist/ba_data/data/languages/ukrainian.json index 371b3dfe..33b5864e 100644 --- a/dist/ba_data/data/languages/ukrainian.json +++ b/dist/ba_data/data/languages/ukrainian.json @@ -7,7 +7,9 @@ "campaignProgressText": "Прогрес кампанії [Тяжко]: ${PROGRESS}", "changeOncePerSeason": "Ви можете змінити це лише раз в сезон.", "changeOncePerSeasonError": "Ви повинні дочекатися наступного сезону, щоб змінити це знову (${NUM} днів)", + "createAnAccountText": "Створити Акаунт", "customName": "Ім'я акаунта", + "deleteAccountText": "Видалити аккаунт", "googlePlayGamesAccountSwitchText": "Якщо ви хочете використовувати інший акаунт Google,\nперейдіть у додаток Google Play Games, щоб змінити його.", "linkAccountsEnterCodeText": "Ввести Код", "linkAccountsGenerateCodeText": "Створити Код", @@ -25,14 +27,16 @@ "setAccountNameDesc": "Виберіть ім'я для відображення свого акаунту.\nВи можете використовувати ім'я одного з ваших прив'язаних\nакаунтів або створити своє унікальне ім'я.", "signInInfoText": "Увійдіть, щоб збирати квитки, змагатися онлайн,\nі синхронізувати прогрес між пристроями.", "signInText": "Увійти", + "signInWithAnEmailAddressText": "Увійдіть за допомогою електронної адреси", "signInWithDeviceInfoText": "(для цього пристрою доступний тільки стандартний акаунт)", "signInWithDeviceText": "Увійти використовуючи акаунт пристрою", "signInWithGameCircleText": "Увійти через Game Circle", "signInWithGooglePlayText": "Увійти через Google Play", "signInWithTestAccountInfoText": "(тест-аккаунт; надалі використовуйте акаунт пристрою)", "signInWithTestAccountText": "Увійти через тестовий акаунт", + "signInWithText": "Увійти за допомогою ${SERVICE}", "signInWithV2InfoText": "(обліковий запис, який працює на всіх платформах)", - "signInWithV2Text": "Увійдіть за допомогою облікового запису BombSquad", + "signInWithV2Text": "Увійдіть за допомогою облікового запису ${APP_NAME}", "signOutText": "Вийти", "signingInText": "Вхід…", "signingOutText": "Вихід…", @@ -336,9 +340,14 @@ "getMoreGamesText": "Ще ігри...", "titleText": "Додати гру" }, + "addToFavoritesText": "Додати в обране", + "addedToFavoritesText": "Додано '${NAME}' до вибраного.", + "allText": "Все", "allowText": "Дозволити", "alreadySignedInText": "На вашому акаунті грають на іншому пристрої;\nбудь ласка зайдіть з іншого акаунта або закрийте гру на\nіншому пристрої та спробуйте знову.", "apiVersionErrorText": "Неможливо завантажити модуль ${NAME}; він призначений для API версії ${VERSION_USED}; потрібна версія ${VERSION_REQUIRED}.", + "applyText": "Застосувати", + "areYouSureText": "Ти впевнений?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(Режим \"Auto\" включайте його тільки коли підключені навушники)", "headRelativeVRAudioText": "Позиційно-залежне VR-аудіо", @@ -360,14 +369,24 @@ "boostText": "Підсилення", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} налаштовується в самому додатку.", "buttonText": "кнопка", - "canWeDebugText": "Хочете, щоб BombSquad автоматично повідомляв розробнику\nпро помилки, збої і основну інформацію про використання?\n\nЦі дані не містять ніякої особистої інформації і допомагають\nпідтримувати гру в робочому стані без збоїв і помилок.", + "canWeDebugText": "Хочете, щоб ${APP_NAME} автоматично повідомляв розробнику\nпро помилки, збої і основну інформацію про використання?\n\nЦі дані не містять ніякої особистої інформації і допомагають\nпідтримувати гру в робочому стані без збоїв і помилок.", "cancelText": "Скасувати", "cantConfigureDeviceText": "Вибачте, ${DEVICE} неможливо налаштувати.", "challengeEndedText": "Це змагання завершено.", "chatMuteText": "Приглушити чат", "chatMutedText": "Чат приглушений", "chatUnMuteText": "Включити чат", + "chests": { + "prizeOddsText": "Ймовірність Виграшу", + "reduceWaitText": "Скоротити час", + "slotDescriptionText": "У цій комірці може бути скриня.\n\nЗаробляй скрині граючи в рівні кампанії,\nпосідаючи місця в турнірах та виконуючи\nдосягнення.", + "slotText": "Комірка для Скрині ${NUM}", + "slotsFullWarningText": "ЗАСТЕРЕЖЕННЯ: Усі комірки заповнені скринями.\nСкрині, що ти заробиш цієї гри, буде втрачено.", + "unlocksInText": "Відкривається Через" + }, "choosingPlayerText": "<вибір гравця>", + "claimText": "Забрати", + "codesExplainText": "Розробник надає коди для діагностики та\nусунення проблем з обліковим записом.", "completeThisLevelToProceedText": "Щоб продовжити, потрібно\nпройти цей рівень!", "completionBonusText": "Бонус за проходження", "configControllersWindow": { @@ -448,6 +467,7 @@ "swipeText": "змахнути", "titleText": "Налаштування сенсорного екрану" }, + "configureDeviceInSystemSettingsText": "${DEVICE} можна налаштувати в налаштуваннях системи", "configureItNowText": "Налаштувати зараз?", "configureText": "Налаштувати", "connectMobileDevicesWindow": { @@ -550,6 +570,7 @@ "demoText": "Демо", "denyText": "Відхилити", "deprecatedText": "Застаріла", + "descriptionText": "Опис", "desktopResText": "Розширення екрану", "deviceAccountUpgradeText": "Увага!\nТи ввійшов за допомогою акаунта пристрою (${NAME}).\nАкаунти пристроїв будуть видалені у майбутньому оновленні.\nОновись до V2-акаунта, якщо ти хочеш зберегти свій прогрес.", "difficultyEasyText": "Легкий", @@ -560,6 +581,10 @@ "disableRemoteAppConnectionsText": "Відключення з'єднання RemoteApp", "disableXInputDescriptionText": "Підключення більше 4 контролерів, але може не працювати.", "disableXInputText": "Відключити XInput", + "disabledText": "Виключено", + "discardText": "Відкинути", + "discordFriendsText": "Хочете шукати нових людей для гри?\nПриєднуйтесь до нашого Discord і знайдіть нових друзів!", + "discordJoinText": "Приєднуйтесь до Discord", "doneText": "Готово", "drawText": "Нічия", "duplicateText": "Дублювати", @@ -592,6 +617,7 @@ "localProfileText": "(локальний профіль)", "nameDescriptionText": "Ім'я гравця", "nameText": "Ім'я", + "profileAlreadyExistsText": "Профіль з таким ім'ям вже існує.", "randomText": "випадкове", "titleEditText": "Змінити профіль", "titleNewText": "Новий профіль", @@ -627,6 +653,7 @@ "useMusicFolderText": "Тека з музикою" }, "editText": "Редагувати", + "enabledText": "Включено", "endText": "Кінець", "enjoyText": "Успіхів!", "epicDescriptionFilterText": "${DESCRIPTION} в епічному сповільненій дії.", @@ -638,6 +665,8 @@ "errorText": "Помилка", "errorUnknownText": "невідома помилка", "exitGameText": "Вийти з ${APP_NAME}?", + "expiredAgoText": "Закінчився ${T} тому", + "expiresInText": "Закінчується через ${T}", "exportSuccessText": "'${NAME}' експортовано.", "externalStorageText": "Зовнішня пам'ять", "failText": "Провал", @@ -672,6 +701,8 @@ "duplicateText": "Дублювати\nплейлист", "editText": "Змінити\nплейлист", "newText": "Новий\nплейлист", + "pointsToWinText": "Очок до виграшу", + "seriesLengthText": "Довжина серії", "showTutorialText": "Показати туторіал", "shuffleGameOrderText": "Змішати порядок ігор", "titleText": "Налаштувати плейлисти '${TYPE}'" @@ -697,6 +728,7 @@ "copyCodeConfirmText": "Код скопійовано до буферу обміну", "copyCodeText": "Скопіювати код", "dedicatedServerInfoText": "Для кращого результату створіть окремий сервер. Дивись bombsquadgame.com/server", + "descriptionShortText": "", "disconnectClientsText": "Це відключить ${COUNT} гравців\nУ вашому лобі. Ви впевнені?", "earnTicketsForRecommendingAmountText": "Друзі отримають ${COUNT} квитки, якщо вони спробують гру \n(і ви будете отримувати ${YOU_COUNT} для кожного, це зробить)", "earnTicketsForRecommendingText": "Поділися грою\nОтримай квитки ...", @@ -709,10 +741,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} квитків від ${NAME}", "friendPromoCodeAwardText": "Ви отримаєте ${COUNT} квитків за кожну активацію.", "friendPromoCodeExpireText": "Код дійсний протягом ${EXPIRE_HOURS} годин і тільки для нових гравців.", - "friendPromoCodeInstructionsText": "Для активації в ${APP_NAME} зайдіть в \"Налаштування->Додатково->Ввести код\".\nЗнайди на bombsquadgame.com версію гри для своєї платформи.", + "friendPromoCodeInstructionsText": "Щоб скористатися ним, відкрийте ${APP_NAME} і перейдіть у «Налаштування->Додатково->Надіслати інформацію».\nПосилання для завантаження для всіх підтримуваних платформ дивіться на bombsquadgame.com.", "friendPromoCodeRedeemLongText": "Кожна активація приносить ${COUNT} квитків до ${MAX_USES} гравцям.", "friendPromoCodeRedeemShortText": "Він принесе ${COUNT} квитків в грі.", - "friendPromoCodeWhereToEnterText": "(В \"Налаштування->Додатково->Ввести код\")", + "friendPromoCodeWhereToEnterText": "(у \"Налаштування->Додатково->Надіслати інформацію\")", "getFriendInviteCodeText": "Отримати промо-код", "googlePlayDescriptionText": "Запросити гравців Google Play в ваше лобі:", "googlePlayInviteText": "Запросити", @@ -744,6 +776,7 @@ "manualYourLocalAddressText": "Ваш локальний адрес:", "nearbyText": "Поблизу", "noConnectionText": "<немає з'єднання>", + "noPartiesAddedText": "Партії не додано", "otherVersionsText": "(інші версії)", "partyCodeText": "Код групи", "partyInviteAcceptText": "Прийняти", @@ -807,6 +840,12 @@ "youHaveShortText": "у вас ${COUNT}", "youHaveText": "У вас ${COUNT} квитків" }, + "goldPass": { + "desc1InfTokensText": "Нескінченні жетони.", + "desc2NoAdsText": "Без реклами.", + "desc3ForeverText": "Назавжди.", + "goldPassText": "золотий пропуск" + }, "googleMultiplayerDiscontinuedText": "Пробачте, але сервіс мультіплеєра від Google тепер не доступний.\nЯ працюю над зміною сервіса як можно скоріше.\nДо цього, будь ласка, подивіться інакші способи гри в мультіплеєр. \n-Ерік", "googlePlayPurchasesNotAvailableText": "Покупки в Google Play недоступні.\nМожливо, вам знадобиться оновити програму магазину.", "googlePlayServicesNotAvailableText": "Google Play сервіси недоступні.\nДеякі функції програми не роблять.", @@ -815,10 +854,12 @@ "alwaysText": "Завжди", "fullScreenCmdText": "Повноекранний (Cmd-F)", "fullScreenCtrlText": "Повноекранний (Ctrl-F)", + "fullScreenText": "Повний екран", "gammaText": "Гамма", "highText": "Високий", "higherText": "Вище", "lowText": "Низький", + "maxFPSText": "Максимальна частота кадрів", "mediumText": "Середній", "neverText": "Ніколи", "resolutionText": "Розширення", @@ -879,6 +920,7 @@ "importText": "Імпорт", "importingText": "Імпортую...", "inGameClippedNameText": "У грі буде\n\"${NAME}\"", + "inboxText": "Вхідні", "installDiskSpaceErrorText": "ПОМИЛКА: не вдалося завершити встановлення. \nМоже не вистачає вільного місця на вашому \nпристрої. Звільніть місце та спробуйте ще раз.", "internal": { "arrowsToExitListText": "Щоб вийти зі списку натисніть ${LEFT} або ${RIGHT}", @@ -933,12 +975,14 @@ "timeOutText": "(залишилося ${TIME} секунд)", "touchScreenJoinWarningText": "Ви приєдналися з сенсорним екраном.\nЯкщо це була помилка, натисніть 'Меню->Покинути гру'.", "touchScreenText": "Сенсорний екран", + "unableToCompleteTryAgainText": "Не в змозі завершити це зараз.\nСпробуй ще раз, будь ласка.", "unableToResolveHostText": "Помилка: неможливо досягти хоста.", "unavailableNoConnectionText": "Зараз це недоступно (немає інтернет з'єднання?)", "vrOrientationResetCardboardText": "Використовуйте це, щоб скинути орієнтацію VR.\nЩоб грати в гру вам буде потрібен зовнішній контролер.", "vrOrientationResetText": "Скидання орієнтації VR.", "willTimeOutText": "(час вийде при бездіяльності)" }, + "inventoryText": "Інтвентар", "jumpBoldText": "СТРИБОК", "jumpText": "Стрибнути", "keepText": "Залишити", @@ -985,8 +1029,11 @@ "seasonEndsMinutesText": "Сезон завершиться через ${NUMBER} хвилин.", "seasonText": "Сезон ${NUMBER}", "tournamentLeagueText": "Щоб брати участь в цьому турнірі, ви повинні досягти ліги ${NAME}.", - "trophyCountsResetText": "Трофеї будуть скинуті в наступному сезоні." + "trophyCountsResetText": "Трофеї будуть скинуті в наступному сезоні.", + "upToDateBonusDescriptionText": "Гравці, що використовують останню версію гри,\nотримають ${PERCENT}% бонус", + "upToDateBonusText": "Бонус Прогресу" }, + "learnMoreText": "Вивчайте більше", "levelBestScoresText": "Кращий рекорд на ${LEVEL}", "levelBestTimesText": "Кращий час на ${LEVEL}", "levelIsLockedText": "${LEVEL} заблокований.", @@ -1030,6 +1077,8 @@ "modeArcadeText": "Аркадний режим", "modeClassicText": "Класичний режим", "modeDemoText": "Демо режим", + "moreSoonText": "Незабаром буде більше..", + "mostDestroyedPlayerText": "Найбільш Побитий Гравець", "mostValuablePlayerText": "Найцінніший гравець", "mostViolatedPlayerText": "Самий побитий гравець", "mostViolentPlayerText": "Самий буйний гравець", @@ -1046,6 +1095,7 @@ "nameSuicideText": "${NAME} скоїв суїцид.", "nameText": "Ім'я", "nativeText": "Власний", + "newExclaimText": "Новинка!", "newPersonalBestText": "Новий особистий рекорд!", "newTestBuildAvailableText": "Доступна нова тестова версія! (${VERSION} збірка ${BUILD}).\nОновити: ${ADDRESS}", "newText": "Новий", @@ -1056,12 +1106,16 @@ "noContinuesText": "(без продовжень)", "noExternalStorageErrorText": "На цьому пристрої не знайдено зовнішньої пам'яті", "noGameCircleText": "Помилка: не ввійшли в GameCircle", + "noMessagesText": "Немає повідомлень.", + "noPluginsInstalledText": "Плагіни не встановлено", "noScoresYetText": "Рахунка поки немає.", + "noServersFoundText": "Серверів не знайдено", "noThanksText": "Ні дякую", "noTournamentsInTestBuildText": "ВАЖЛИВО: Турнірні Очки на цій тестовій версії будуть ігноровані.", "noValidMapsErrorText": "Для даного типу гри не знайдено коректних карт.", "notEnoughPlayersRemainingText": "Залишилося недостатньо гравців; вийдіть і почніть нову гру.", "notEnoughPlayersText": "Для початку цієї гри потрібно як мінімум ${COUNT} гравця!", + "notEnoughTicketsText": "Не вистачає квитків!", "notNowText": "Не зараз", "notSignedInErrorText": "Увійдіть щоб зробити це.", "notSignedInGooglePlayErrorText": "Увійдіть спочатку в Google Play, а там подивимося.", @@ -1074,6 +1128,9 @@ "onText": "Вкл", "oneMomentText": "Хвилинку...", "onslaughtRespawnText": "${PLAYER} відродиться в ${WAVE} хвилі", + "openMeText": "Відкрий Мене!", + "openNowText": "Відчинити зараз", + "openText": "Відчинити", "orText": "${A} або ${B}", "otherText": "Інші...", "outOfText": "(${RANK} з ${ALL})", @@ -1159,6 +1216,8 @@ "punchText": "Вдарити", "purchaseForText": "Купити за ${PRICE}", "purchaseGameText": "Купити гру", + "purchaseNeverAvailableText": "На жаль, покупки недоступні для цієї збірки.\nСпробуйте ввійти у свій обліковий запис на іншій платформі та робити покупки звідти.", + "purchaseNotAvailableText": "Ця покупка недоступна.", "purchasingText": "Покупка...", "quitGameText": "Вийти з ${APP_NAME}?", "quittingIn5SecondsText": "Вихід через 5 секунд...", @@ -1200,6 +1259,7 @@ "version_mismatch": "Розбіжність версій.\nПереконайтеся, що BombSquad і контролер BombSquad Remote\nоновлені до останньої версії і спробуйте ще раз." }, "removeInGameAdsText": "Розблокуйте \"${PRO}\" в магазині, щоб прибрати рекламу в грі.", + "removeInGameAdsTokenPurchaseText": "ОБМЕЖЕНА ЧАСОМ ПРОПОЗИЦІЯ: Придбай БУДЬ-ЯКИЙ набір жетонів, аби вилучити рекламу з гри.", "renameText": "Перейменувати", "replayEndText": "Завершити перегляд повтору", "replayNameDefaultText": "Повтор останньої гри", @@ -1221,6 +1281,8 @@ "runText": "Бігти", "saveText": "Зберегти", "scanScriptsErrorText": "Помилка(и) сканування скриптів; дивіться лог для деталей.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} і ${NUM} інших модулів потрібно оновити для api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} потрібно оновити для api ${API}.", "scoreChallengesText": "Медалі за очки", "scoreListUnavailableText": "Список очок недоступний.", "scoreText": "Очки", @@ -1231,6 +1293,7 @@ }, "scoreWasText": "(було ${COUNT})", "selectText": "Вибрати", + "sendInfoDescriptionText": "Надсилає інформацію про обліковий запис і стан програми розробнику. Будь ласка, вкажіть своє ім'я або причину надсилання\nِ", "seriesWinLine1PlayerText": "ПЕРЕМІГ У", "seriesWinLine1TeamText": "ПЕРЕМОГЛИ У", "seriesWinLine1Text": "ПЕРЕМІГ У", @@ -1246,24 +1309,32 @@ }, "settingsWindowAdvanced": { "alwaysUseInternalKeyboardDescriptionText": "(проста, зручна для контролера віртуальна клавіатура для введення тексту)", - "alwaysUseInternalKeyboardText": "Завжди використовувати вбудовану клавіатуру", + "alwaysUseInternalKeyboardText": "Завжди використовуйте внутрішню клавіатуру", "benchmarksText": "Тест продуктивності і навантаження", - "disableCameraGyroscopeMotionText": "Вимкнути Рух Гіроскопу Камери", - "disableCameraShakeText": "Вимкнути Тремтіння Камери", + "devToolsText": "Інструменти розробника", + "disableCameraGyroscopeMotionText": "Вимкнути рух гіроскопа камери", + "disableCameraShakeText": "Вимкнути тремтіння камери", "disableThisNotice": "(ви можете відключити це повідомлення в налаштуваннях)", "enablePackageModsDescriptionText": "(включає додаткові можливості для модінгу, але відключає мережеву гру)", "enablePackageModsText": "Включити моди локального пакета", "enterPromoCodeText": "Ввести код", "forTestingText": "Примітка: ці значення використовуються тільки для тестування і будуть втрачені, коли додаток завершить роботу.", "helpTranslateText": "Переклади гри ${APP_NAME} з англійської зроблені спільнотою. \nЯкщо ви хочете запропонувати або виправити переклад, \nПерейдіть за посиланню нижче. Заздалегідь дякую!", - "kickIdlePlayersText": "Викидати неактивних гравців", + "insecureConnectionsDescriptionText": "не рекомендується, але може дозволити онлайн-гру\nз країн або мереж з обмеженим доступом", + "insecureConnectionsText": "Використання ненадійних з'єднань", + "kickIdlePlayersText": "Викидати непрацюючих гравців", "kidFriendlyModeText": "Сімейний режим (менше насильства, і т.д.)", "languageText": "Мова", "moddingGuideText": "Інструкція по модінгу", + "moddingToolsText": "Інструменти для моддингу", "mustRestartText": "Необхідно перезапустити гру, щоб зміни вступили в силу.", "netTestingText": "Тестування мережі", "resetText": "Скинути", + "sendInfoText": "Надіслати інформацію", "showBombTrajectoriesText": "Показувати траєкторію бомби", + "showDemosWhenIdleText": "Показувати демонстрації в режимі очікування", + "showDeprecatedLoginTypesText": "Показати застарілі типи входу", + "showDevConsoleButtonText": "Показати кнопку консолі розробника", "showInGamePingText": "Показувати пінг у грі", "showPlayerNamesText": "Показувати імена гравців", "showUserModsText": "Показати теку модів", @@ -1272,8 +1343,8 @@ "translationFetchErrorText": "статус перекладу недоступний", "translationFetchingStatusText": "перевірка статусу перекладу...", "translationInformMe": "Повідомляйте мене, коли моя мова потребує оновлення", - "translationNoUpdateNeededText": "дана мова повністю оновлена, ура!", - "translationUpdateNeededText": "** дана мова потребує оновлення!! **", + "translationNoUpdateNeededText": "Поточна мова оновлена; ураа!", + "translationUpdateNeededText": "** Поточна мова потребує оновлення!! **", "vrTestingText": "Тестування VR" }, "shareText": "Поділитися", @@ -1283,6 +1354,9 @@ "signInWithGameCenterText": "Щоб використовувати аккаунт GameCenter,\nувійдіть через GameCenter.", "singleGamePlaylistNameText": "Просто ${GAME}", "singlePlayerCountText": "1 гравець", + "sizeLargeText": "Великий", + "sizeMediumText": "Середній", + "sizeSmallText": "Малий", "soloNameFilterText": "${NAME} соло", "soundtrackTypeNames": { "CharSelect": "Вибір персонажа", @@ -1308,6 +1382,7 @@ }, "spaceKeyText": "пробіл", "statsText": "Статистика", + "stopRemindingMeText": "Більше не нагадувати", "storagePermissionAccessText": "Це вимагає доступу до сховища", "store": { "alreadyOwnText": "У вас вже є ${NAME}!", @@ -1355,6 +1430,8 @@ "storeText": "Магазин", "submitText": "Відправити", "submittingPromoCodeText": "Активація коду...", + "successText": "Успішно!", + "supportEmailText": "Якщо у вас виникли проблеми з програмою,\nнадішліть електронний лист на ${EMAIL}.", "teamNamesColorText": "імена/кольори команд", "telnetAccessGrantedText": "Доступ Telnet включений.", "telnetAccessText": "Виявлено доступ Telnet. Дозволити?", @@ -1364,6 +1441,7 @@ "testBuildValidatedText": "Тестова збірка перевірена. Насолоджуйтесь!", "thankYouText": "Дякую за вашу підтримку! Веселої гри!!", "threeKillText": "ТРЬОХ ЗА РАЗ!!", + "ticketsDescriptionText": "За квитки можна розблокувати персонажів,\nкарти, міні-ігри та більше в магазині.\n\nКвитки можна знайти у скринях, виграних в\nкампаніях, турнірах та досягненнях.", "timeBonusText": "Бонус часу", "timeElapsedText": "Пройшло часу", "timeExpiredText": "Час вийшов", @@ -1374,10 +1452,24 @@ "tipText": "Підказка", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Отримати жетони", + "notEnoughTokensText": "Недостатньо жетонів!", + "numTokensText": "${COUNT} Жетонів", + "openNowDescriptionText": "Ти маєш достатньо жетонів щоб \nвідкрити це зараз - ти не \nмусиш чекати.", + "shinyNewCurrencyText": "Нова блискуча валюта BombSquad.", + "tokenPack1Text": "Малий пакет жетонів", + "tokenPack2Text": "Середній пакет жетонів", + "tokenPack3Text": "Великий пакет жетонів", + "tokenPack4Text": "Джамбо Пакет жетонів", + "tokensDescriptionText": "Жетони використовуються для прискорення відкриття скрині,\nа такох для інших функцій гри та акаунта.\n\nТи можеш виграти жетони у грі, чи придбати їх\nу наборі. Або ж придбай Золотий Пропуск для нескінченних\nжетонів і більше ніколи про них не чуй ані слова.", + "youHaveGoldPassText": "У вас є Gold Pass.\nУсі покупки жетонів безкоштовні.\nНасолоджуйтесь!" + }, "topFriendsText": "Топ друзів", "tournamentCheckingStateText": "Перевірка статусу турніру, будь ласка, зачекайте...", "tournamentEndedText": "Турнір закінчився. Скоро почнеться новий.", "tournamentEntryText": "Вхід в турнір", + "tournamentFinalStandingsText": "Фінальна Таблиця", "tournamentResultsRecentText": "Останні Результати турніру", "tournamentStandingsText": "Позиції в турнірі", "tournamentText": "Турнір", @@ -1433,6 +1525,18 @@ "Uber Onslaught": "Убер атака", "Uber Runaround": "Убер маневр" }, + "displayItemNames": { + "${C} Tickets": "${C} Квитки(-ів)", + "${C} Tokens": "${C} Жетони(-ів)", + "Chest": "Скриня", + "L1 Chest": "Скриня 1Р", + "L2 Chest": "Скриня 2Р", + "L3 Chest": "Скриня 3Р", + "L4 Chest": "Скриня 4Р", + "L5 Chest": "Скриня 5Р", + "L6 Chest": "Скриня 6Р", + "Unknown Chest": "Невідома Скриня" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Щоб перемогти, стань обраним на деякий час.\nЩоб стати обраним, вбий обраного.", "Bomb as many targets as you can.": "Підірвіть стільки мішеней, скільки зможете.", @@ -1537,6 +1641,7 @@ "Korean": "Корейська", "Malay": "Малайська", "Persian": "Перська", + "PirateSpeak": "Піратська мова", "Polish": "Польська", "Portuguese": "Португальська", "Romanian": "Румунська", @@ -1608,6 +1713,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Ах ти, чітер; Очки і нагороди заморожені на ${COUNT} днів.", "Could not establish a secure connection.": "Не вдалося встановити безпечне з'єднання.", "Daily maximum reached.": "Досить на сьогодні.", + "Daily sign-in reward": "Щоденна Винагорода", "Entering tournament...": "Вхід в турнір...", "Invalid code.": "Невірний код.", "Invalid payment; purchase canceled.": "Щось пішло не так. Купівля скасована.", @@ -1617,11 +1723,14 @@ "Item unlocked!": "Предмет разблоковано!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "Об'єднання не дозволено. ${ACCOUNT} містить \nважливі дані і вони ВСІ ЗНИКНУТЬ.\nТи можеш об'єднанати у зворотньому порядку, якщо ти цього захочеш\n(І втратити дані ЦЬОГО акаунта)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Зв'язати ${ACCOUNT} акаунт з цим?\nВсі існуючі дані на ${ACCOUNT} будуть втрачені.\nЦя дія не може бути скасовано. Ви впевнені?", + "Longer streaks lead to better rewards.": "Довший страйк - краща винагорода", "Max number of playlists reached.": "Досягнуто максимальну кількість плейлистів.", "Max number of profiles reached.": "Максимальна кількість профілів досягнута.", "Maximum friend code rewards reached.": "Досягнуто ліміт кодів", "Message is too long.": "Повідомлення занадто довге.", + "New tournament result!": "Новий результат турніру!", "No servers are available. Please try again soon.": "Немає доступних серверів. Будь ласка, поспробуйте пізніше.", + "No slots available. Free a slot and try again.": "Немає вільних комірок. Звільни комірку й спробуй ще раз.", "Profile \"${NAME}\" upgraded successfully.": "Профіль \"${NAME}\" оновлений успішно.", "Profile could not be upgraded.": "Профіль не може бути оновлений.", "Purchase successful!": "Успішна транзакція!", @@ -1631,7 +1740,9 @@ "Sorry, this code has already been used.": "Ой, цей код вже використаний.", "Sorry, this code has expired.": "Ой, час дії коду минув.", "Sorry, this code only works for new accounts.": "Ой, цей код працює тільки для нових акаунтів.", + "Sorry, this has expired.": "Вибач, це вже закінчилося.", "Still searching for nearby servers; please try again soon.": "Все ще йде пошук сусідніх серверів; будь-ласка, спробуйте ще раз найближчим часом.", + "Streak: ${NUM} days": "Страйк: ${NUM} дня/днів", "Temporarily unavailable; please try again later.": "Тимчасово недоступний; будь ласка, спробуйте ще раз пізніше.", "The tournament ended before you finished.": "Турнір закінчився раніше, ніж ви закінчили.", "This account cannot be unlinked for ${NUM} days.": "Цей обліковий запис неможливо відв'язати протягом ${NUM} днів.", @@ -1642,19 +1753,28 @@ "Tournaments require ${VERSION} or newer": "Для турнірів потрібна версія ${VERSION} або вище.", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Відв'язати ${ACCOUNT} від цього акаунта?\nВсі дані на ${ACCOUNT} будуть скинуті.\n(За винятком досягнень в деяких випадках)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ПОПЕРЕДЖЕННЯ: скарги на хакерство були видані на ваш обліковий запис.\nОблікові записи, які вважаються зламаними, будуть заблоковані. Будь ласка, грайте чесно.", + "Wait reduced!": "Час скорочено!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Попередження: Ця версія гри обмежена старими даними облікового запису; деякі речі можуть бути відсутніми або застарілими. \nБудь ласка, оновіть гру до новішої версії, щоб побачити актуальні дані вашого облікового запису.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Бажаєте пов'язати обліковий запис пристрою з цим?\n\nАкаунт пристрою ${ACCOUNT1}\nПоточний акаунт ${ACCOUNT2}\n\nЦе дозволить зберегти ваші нинішні досягнення.\nУвага: скасування неможлива!", "You already own this!": "Ви це вже придбали!", "You can join in ${COUNT} seconds.": "Ти зможеш увійти через ${COUNT} секунд", "You don't have enough tickets for this!": "У вас недостатньо квитків для цієї покупки!", "You don't own that.": "Вам це не належить", "You got ${COUNT} tickets!": "Ви отримали ${COUNT} квитків!", + "You got ${COUNT} tokens!": "Ти отримав ${COUNT} Жетонів!", "You got a ${ITEM}!": "Ви отримали ${ITEM}!", + "You got a chest!": "Ти отримав скриню!", + "You got an achievement reward!": "Ви отримали нагороду за досягнення!", "You have been promoted to a new league; congratulations!": "Вас підвищили і перевели в нову лігу; вітаємо!", + "You lost a chest! (All your chest slots were full)": "Ви втратили скриню! (Всі ваші слоти для скринь заповненні)", + "You must update the app to view this.": "Щоб переглянути це, потрібно оновити програму.", "You must update to a newer version of the app to do this.": "Щоб це зробити, ви повинні оновити додаток.", "You must update to the newest version of the game to do this.": "Ви повинні оновитися до нової версії гри, щоб зробити це.", "You must wait a few seconds before entering a new code.": "Зачекайте кілька секунд, перш ніж вводити новий код.", + "You placed #${RANK} in a tournament!": "Ти посів #${RANK} місце в турнірі!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ваш ранг в останньому турнірі: ${RANK}! Дякуємо за гру!", "Your account was rejected. Are you signed in?": "Вашу обліковку відхилено. Ви ввійшли?", + "Your ad views are not registering. Ad options will be limited for a while.": "Твої перегляди реклами не реєструються. На деякий час можливості реклами будуть обмежені.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версія гри була модифікована.\nПриберіть всі зміни і спробуйте знову", "Your friend code was used by ${ACCOUNT}": "Ваш код був використаний ${ACCOUNT}" }, @@ -1803,11 +1923,14 @@ "toSkipPressAnythingText": "(торкніться або натисніть що-небудь щоб пропустити туторіал)" }, "twoKillText": "ДВОХ ЗА РАЗ!", + "uiScaleText": "Зміна розміру інтерфейсу", "unavailableText": "недоступно", + "unclaimedPrizesText": "В тебе залишились не зібрані призи!", "unconfiguredControllerDetectedText": "Виявлено налаштований контролер:", "unlockThisInTheStoreText": "Це повинно бути розблоковано в магазині.", "unlockThisProfilesText": "Щоб створити більш ${NUM} профіль, Вам необхідно:", "unlockThisText": "Щоб розблокувати це, вам потрібно:", + "unsupportedControllerText": "Вибачте, контролер \"${NAME}\" не підтримується.", "unsupportedHardwareText": "На жаль, це устаткування не підтримується в цій збірці гри.", "upFirstText": "Для початку:", "upNextText": "Далі в грі ${COUNT}:", @@ -1815,11 +1938,15 @@ "upgradeText": "Оновлення", "upgradeToPlayText": "Розблокуйте \"${PRO}\" в магазині щоб грати в це.", "useDefaultText": "Використовувати стандартні", + "userSystemScriptsCreateText": "Створення системних сценаріїв користувача", + "userSystemScriptsDeleteText": "Видалити системні сценарії користувача", "usesExternalControllerText": "Ця гра може використовувати зовнішній контролер для управління.", "usingItunesText": "Використання музикального додатку для саундтрека...", "usingItunesTurnRepeatAndShuffleOnText": "Будь ласка, переконайтеся, що випадковий порядок і повтор усіх пісень включений в Itunes.", "v2AccountLinkingInfoText": "Щоб підключити V2-акаунти, використовуйте кнопку 'Керування акаунтом'.", + "v2AccountRequiredText": "Для цього потрібен обліковий запис V2. Оновіть обліковий запис і повторіть спробу.", "validatingTestBuildText": "Перевірка тестової збірки...", + "viaText": "через", "victoryText": "Перемога!", "voteDelayText": "Ви зможете почати голосування через ${NUMBER} секунд", "voteInProgressText": "Голосування ще триває.", @@ -1885,5 +2012,6 @@ }, "yesAllowText": "Так, дозволити!", "yourBestScoresText": "Ваші кращі результати", - "yourBestTimesText": "Ваш кращий час" + "yourBestTimesText": "Ваш кращий час", + "yourPrizeText": "Твій приз:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/venetian.json b/dist/ba_data/data/languages/venetian.json index d87d9a87..88feeca3 100644 --- a/dist/ba_data/data/languages/venetian.json +++ b/dist/ba_data/data/languages/venetian.json @@ -6,7 +6,9 @@ "campaignProgressText": "Progreso canpagna [Defìsiłe]: ${PROGRESS}", "changeOncePerSeason": "Te połi canbiar ’sto dato soło na volta par stajon.", "changeOncePerSeasonError": "Par canbiarlo te ghè da spetar ła pròsema stajon (${NUM} days).", + "createAnAccountText": "Fà un Conto", "customName": "Nome parsonałizà", + "deleteAccountText": "Cancellare 'sto account?", "googlePlayGamesAccountSwitchText": "Se te vołi doparar un account Google defarente,\ndòpara l'apl Google Play Giochi par canbiarlo.", "linkAccountsEnterCodeText": "Insarisi còdaze", "linkAccountsGenerateCodeText": "Jènara còdaze", @@ -14,30 +16,33 @@ "linkAccountsInstructionsNewText": "Par cołegar do account, jènara un còdaze inte'l primo\ndispozidivo e insarìseło inte’l segondo. I dati de’l\nsegondo account i vegnarà sparpagnài so tuti do i account\n(i dati de’l primo account i ndarà perdesti).\n\nTe połi cołegar fin a ${COUNT} account.\n\nINPORTANTE: cołega soło i account de to propiedà.\nSe te cołeghi account de calche to amigo, no sarè\npì boni de zugar online inte’l mèdemo momento.", "linkAccountsText": "Cołega account", "linkedAccountsText": "Account cołegài:", - "manageAccountText": "Jestisi account", + "manageAccountText": "Gestir el conto", "nameChangeConfirm": "Vutu canbiar el nome de’l to account co ${NAME}?", "resetProgressConfirmNoAchievementsText": "Te si drio ełimenar i to progresi so ła modałidà\ncooparadiva e i to punteji łogałi (ma miga i to biłieti).\n’Sta asion no ła połe pì èsar anułada. Vutu ndar vanti?", "resetProgressConfirmText": "Te si drio ełimenar i to progresi so ła\nmodałidà cooparadiva, i to obietivi e i to punteji\nłogałi (ma miga i to biłieti). ’Sta asion\nno ła połe pì èsar anułada. Vutu ndar vanti?", "resetProgressText": "Ełìmena progresi", "setAccountName": "Inposta un nome utente", "setAccountNameDesc": "Sełesiona el nome da vizuałizar so’l to account.\nTe połi doparar el nome da uno de i to account\ncołegài o crear un nome parsonałizà ma ùnivogo.", - "signInInfoText": "Conétate par tirar sù biłieti, batajar online e\nsparpagnar i to progresi infrà dispozidivi defarenti.", - "signInText": "Conétate", + "signInInfoText": "Acedi par tirar sù biłieti, batajar online e\nsparpagnar i tó progresi infrà dispozidivi defarenti.", + "signInText": "Acedi", + "signInWithAnEmailAddressText": "Acedi co un ndariso mail", "signInWithDeviceInfoText": "(par 'sto dispozidivo ze disponìbiłe un soło account automàtego)", - "signInWithDeviceText": "Conétate co un account łogałe", + "signInWithDeviceText": "Acedi co un account łogałe", "signInWithGameCircleText": "Conétate co Game Circle", "signInWithGooglePlayText": "Conétate co Google Play", "signInWithTestAccountInfoText": "(account de proa vecio: in fuduro dòpara un account łogałe)", "signInWithTestAccountText": "Conétate co un account de proa", + "signInWithText": "Acedi co ${SERVICE}", "signInWithV2InfoText": "(un account che fusiona so tute łe piataforme)", - "signInWithV2Text": "Acedi co un account BombSquad", - "signOutText": "Sortisi da l'account", - "signingInText": "Conesion in corso...", + "signInWithV2Text": "Acedi co' un account ${APP_NAME}", + "signOutText": "Và fora", + "signingInText": "Aceso in corso...", "signingOutText": "Sortìa in corso...", "ticketsText": "Biłieti: ${COUNT}", "titleText": "Account", "unlinkAccountsInstructionsText": "Sełesiona un account da descołegar", "unlinkAccountsText": "Descołega account", + "unlinkLegacyV1AccountsText": "Descołega i account veci (V1)", "v2LinkInstructionsText": "Acedi o dòpara 'sto link par crear un account.", "viaAccount": "(doparando ${NAME})", "youAreSignedInAsText": "Te zugarè cofà:" @@ -245,7 +250,7 @@ "Sharing is Caring": { "descriptionFull": "Sparpagna el zugo co un amigo co suceso", "descriptionFullComplete": "Zugo sparpagnà co suceso co un amigo", - "name": "Sparpagnar A vołe dir tegnerghe" + "name": "Sparpagnar vołe dir tegnerghe" }, "Stayin' Alive": { "description": "Vinsi sensa mai crepar", @@ -331,9 +336,14 @@ "getMoreGamesText": "Otien pì łevełi...", "titleText": "Zonta zugo" }, + "addToFavoritesText": "Zonta so i prefarìi", + "addedToFavoritesText": "'${NAME}' zontà so i prefarìi.", + "allText": "Tuto", "allowText": "Parmeti", "alreadySignedInText": "El to account el ze in dòparo inte n’antro\ndispozidivo: canbia account o sara sù el zugo\ninte cheł’altro to dispozidivo e proa danovo.", "apiVersionErrorText": "Inposìbiłe cargar el mòduło ${NAME}, el se refarise a ła varsion ${VERSION_USED}. Serve invese ła ${VERSION_REQUIRED}.", + "applyText": "Aplicar", + "areYouSureText": "Te sé secùro?", "audioSettingsWindow": { "headRelativeVRAudioInfoText": "(Ativa \"Auto\" soło co te tachi sù łe fonarołe par ła realtà virtuałe)", "headRelativeVRAudioText": "Àudio par fonarołe VR", @@ -355,14 +365,23 @@ "boostText": "Potensiador", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} el se configura rento l'apl mèdema.", "buttonText": "boton", - "canWeDebugText": "Ghetu caro che BombSquad el reporte in automàtego bai,\nblochi e informasion baze só'l so dòparo a'l dezviłupador?\n\n'Sti dati no i contien miga informasion parsonałi ma i ło\njuta a far ndar ben el zugo sensa blochi o bai.", + "canWeDebugText": "Ghetu caro che ${APP_NAME} el reporte in automàtego bai,\nblochi e informasion baze só'l so dòparo a'l dezviłupador?\n\n'Sti dati no i contien miga informasion parsonałi ma i ło\njuta a far ndar ben el zugo sensa blochi o bai.", "cancelText": "Anuła", "cantConfigureDeviceText": "Ne despiaze, ${DEVICE} no'l ze miga configuràbiłe.", "challengeEndedText": "'Sta sfida ła ze fenìa.", "chatMuteText": "Siłensia ciacołada", "chatMutedText": "Ciacołada siłensiada", "chatUnMuteText": "Reativa son", + "chests": { + "prizeOddsText": "Speriensa de vinzar", + "reduceWaitText": "Cala L'aspeto", + "slotDescriptionText": "Sto spaziò pò tener na cassa.\n\nCata casse zugando ai łivelli de la campagna,\nClasificandose nei tornei, e compiando\nobiettivi.", + "slotText": "Spaziò cassa ${NUM}", + "slotsFullWarningText": "ATENZION: Tuti i to spazi càsa xe pieni.\nQualsiasi càsa che te ciapi da 'sta partia la andrà persa." + }, "choosingPlayerText": "", + "claimText": "Ciapa", + "codesExplainText": "I còdazi i vien fornìi da'l dezviłupador par\ndiagnostegar e corèjar problemi so l'account.", "completeThisLevelToProceedText": "Par ndar vanti te ghè\nda conpletar 'sto łeveło!", "completionBonusText": "Premio de concruzion", "configControllersWindow": { @@ -439,10 +458,11 @@ "movementText": "Movimento a", "resetText": "Reinposta", "swipeControlsHiddenText": "Scondi i comandi a zlizo", - "swipeInfoText": "Par bituarse co i controłi a \"zlizo\" A serve un fià de pì tenpo.\nMa sensa dover vardar i controłi, el zugo el deventarà pì senpio.", + "swipeInfoText": "Par bituarse co i controłi a \"zlizo\" serve un fià de tenpo.\nMa sensa dover vardar i controłi, el zugo el deventarà pì senpio.", "swipeText": "zlizo", "titleText": "Configura schermo tàtiłe" }, + "configureDeviceInSystemSettingsText": "Se połe configurar ${DEVICE} so łe Inpostasion de Sistema.", "configureItNowText": "Vutu configurarlo deso?", "configureText": "Configura", "connectMobileDevicesWindow": { @@ -470,7 +490,7 @@ "customText": "E in pì...", "entryFeeText": "Costo", "forfeitConfirmText": "Vutu dabon dàrgheła vinta?", - "forfeitNotAllowedYetText": "Deso A no te połi miga dàrgheła vinta suito.", + "forfeitNotAllowedYetText": "No te połi miga dàrgheła vinta suito.", "forfeitText": "Dàgheła vinta", "multipliersText": "Moltiplegadori", "nextChallengeText": "Sfida pròsema", @@ -493,7 +513,7 @@ "toRankedText": "par ndar sù de pozision", "totalText": "totałe", "tournamentInfoText": "Conpeti co cheł'altri zugadori par\nndar sù de puntejo inte ła to łega.\n\nCo'l tornèo el fenirà, i zugadori pì\nbrai i vegnarà reconpensài co i premi.", - "welcome1Text": "Benrivài inte ła ${LEAGUE}. A te połi mejorar ła to\npozision vadagnando stełe inte i łevełi, conpletando\ni obietivi o vinsendo i trofèi inte i tornèi.", + "welcome1Text": "Benrivài inte ła ${LEAGUE}. Te połi mejorar ła to\npozision vadagnando stełe inte i łevełi, conpletando\ni obietivi o vinsendo i trofèi inte i tornèi.", "welcome2Text": "Fazendo racuante atividà de 'sto tipo te połi anca vadagnar biłieti.\nI biłieti i połe èsar doparài par dezblocar parsonaji novi, łevełi e\nminizughi ma anca par ndar rento a tornèi o ver funsion in pì.", "yourPowerRankingText": "Ła to pozision:" }, @@ -525,7 +545,7 @@ "deathsText": "Crepà", "debugText": "dezbao", "debugWindow": { - "reloadBenchmarkBestResultsText": "Nota: par 'sta proa A sarìa mejo inpostar ła Defenision so 'Alta' so Inpostasion > Gràfega > Defenision.", + "reloadBenchmarkBestResultsText": "Nota: par 'sta proa sarìa mejo inpostar ła Defenision so 'Alta' so Inpostasion > Gràfega > Defenision.", "runCPUBenchmarkText": "Saja prestasion CPU", "runGPUBenchmarkText": "Saja prestasion GPU", "runMediaReloadBenchmarkText": "Saja prestasion recargamento gràfega", @@ -545,6 +565,7 @@ "demoText": "Demo", "denyText": "Refuda", "deprecatedText": "Roba vecia", + "descriptionText": "Descrision", "desktopResText": "Resołusion PC", "deviceAccountUpgradeText": "Ocio:\nte ghè fazesto l'aceso co l'account łogałe ${NAME}.\nCo un pròsemo ajornamento i account łogałi i vegnarà cavài via.\nSe te vołi tegnerte i to progresi ajorna el to account a ła varsion V2.", "difficultyEasyText": "Fàsiłe", @@ -555,6 +576,10 @@ "disableRemoteAppConnectionsText": "Dezativa conesion co BombSquad Remote", "disableXInputDescriptionText": "Dòpara pì de 4 controładori (ma co'l riscio che no i funsione ben).", "disableXInputText": "Dezativa XInput", + "disabledText": "Dezativà", + "discardText": "Scartà", + "discordFriendsText": "Ghetu caro catar parsone nove par zugarghe insenbre?\nZóntate so'l nostro canałe Discord e cata fora amighi novi!", + "discordJoinText": "Zóntate so Discord", "doneText": "Fato", "drawText": "Pata", "duplicateText": "Zdopia", @@ -579,7 +604,7 @@ "colorText": "cołor", "getMoreCharactersText": "Otien pì parsonaji...", "getMoreIconsText": "Otien pì icone...", - "globalProfileInfoText": "I profiłi zugador globałi i gà nomi ùgnołi garantìi.\nIn pì A se połe zontarghe anca icone parsonałizàe.", + "globalProfileInfoText": "I profiłi zugador globałi i gà nomi ùgnołi garantìi.\nIn pì se połe zontarghe anca icone parsonałizàe.", "globalProfileText": "(profiło globałe)", "highlightText": "detaji", "iconText": "icona", @@ -587,6 +612,7 @@ "localProfileText": "(profiło łogałe)", "nameDescriptionText": "Nome zugador", "nameText": "Nome", + "profileAlreadyExistsText": "Eziste dezà un profiło co 'sto nome.", "randomText": "", "titleEditText": "Muda profiło", "titleNewText": "Profiło novo", @@ -622,6 +648,7 @@ "useMusicFolderText": "Carteła de file muzegałi" }, "editText": "Muda", + "enabledText": "Ativà", "endText": "Moła", "enjoyText": "Profìtaghine e gòdateła!", "epicDescriptionFilterText": "${DESCRIPTION} in movensa camoma.", @@ -633,6 +660,8 @@ "errorText": "Eror", "errorUnknownText": "eror miga conosesto", "exitGameText": "Vutu ndar fora da ${APP_NAME}?", + "expiredAgoText": "Xe scadù ${T} fà.", + "expiresInText": "Scade tra ${T}", "exportSuccessText": "'${NAME}' esportà.", "externalStorageText": "Memoria esterna", "failText": "Desfata", @@ -667,6 +696,8 @@ "duplicateText": "Zdopia\nłista de zugo", "editText": "Muda\nłista de zugo", "newText": "Nova\nłista de zugo", + "pointsToWinText": "Punti par vìnsar", + "seriesLengthText": "Łonghesa serie", "showTutorialText": "Demostrasion", "shuffleGameOrderText": "Zmisia òrdene łevełi", "titleText": "Parsonałiza łiste de zugo \"${TYPE}\"" @@ -692,6 +723,7 @@ "copyCodeConfirmText": "Còdaze copià inte łe note.", "copyCodeText": "Copia còdaze", "dedicatedServerInfoText": "Inposta un server dedegà par rezultài pì boni. Daghe un ocio so bombsquadgame.com/server par capir come far.", + "descriptionShortText": "Dota de usar el tasto \"crea grupo\" par far na festa.", "disconnectClientsText": "'Sta oparasion ła desconetarà ${COUNT} zugador/i\nda'l to grupo. Vutu ndar vanti?", "earnTicketsForRecommendingAmountText": "Se i provarà el zugo, i to amighi i resevarà ${COUNT} biłieti\n(e ti te ghin resevarè ${YOU_COUNT} par caun de łori che'l ło dopararà)", "earnTicketsForRecommendingText": "Sparpagna el zugo par\nver biłieti gratùidi...", @@ -704,14 +736,14 @@ "friendHasSentPromoCodeText": "Par ti ${COUNT} biłieti de ${APP_NAME} da ${NAME}!", "friendPromoCodeAwardText": "Tute łe 'olte che'l vegnarà doparà te resevarè ${COUNT} biłieti.", "friendPromoCodeExpireText": "El còdaze el ze soło par i zugaduri novi e el terminarà tenpo ${EXPIRE_HOURS} ore.", - "friendPromoCodeInstructionsText": "Par dopararlo, verzi ${APP_NAME} e và so \"Inpostasion > Avansàe > Insarisi còdaze\".\nDaghe un ocio so bombsquadgame.com par i link de descargamento de'l zugo par tute łe piataforme conpatìbiłi.", + "friendPromoCodeInstructionsText": "Par dopararlo, verzi ${APP_NAME} e và so \"Inpostasion > Avansàe > Manda informasion\".\nVarda bombsquadgame.com par i link de descargamento de'l zugo par tute łe piataforme suportàe.", "friendPromoCodeRedeemLongText": "El połe èsar scanbià par ${COUNT} biłieti gratùidi da ${MAX_USES} parsone.", "friendPromoCodeRedeemShortText": "El połe èsar scanbià inte'l zugo par ${COUNT} biłieti gratùidi.", - "friendPromoCodeWhereToEnterText": "(so \"Inpostasion > Avansàe > Insarisi còdaze\")", + "friendPromoCodeWhereToEnterText": "(so \"Inpostasion > Avansàe > Manda informasion\")", "getFriendInviteCodeText": "Jènara còdaze de invido", "googlePlayDescriptionText": "Invida zugadori de Google Play inte'l to grupo:", "googlePlayInviteText": "Invida", - "googlePlayReInviteText": "Se A te mandi un invido novo el/i ${COUNT} zugador(i) de\nGoogle Play inte'l to grupo el/i vegnarà desconetesto/i.\nPar tegnerlo/i in grupo màndaghe anca a łù/łori l'invido novo.", + "googlePlayReInviteText": "Se te mandi un invido novo el/i ${COUNT} zugador(i) de\nGoogle Play inte'l to grupo el/i vegnarà desconetesto/i.\nPar tegnerlo/i in grupo màndaghe anca a łù/łori l'invido novo.", "googlePlaySeeInvitesText": "Mostra invidi", "googlePlayText": "Google Play", "googlePlayVersionOnlyText": "(soło inte ła varsion Android / Google Play)", @@ -739,13 +771,14 @@ "manualYourLocalAddressText": "El to ndariso łogałe:", "nearbyText": "Łogałe", "noConnectionText": "", + "noPartiesAddedText": "Gnaun grupo zontà", "otherVersionsText": "(par altre varsion)", "partyCodeText": "Còdaze de'l grupo", "partyInviteAcceptText": "Và ben", "partyInviteDeclineText": "Miga deso", "partyInviteGooglePlayExtraText": "(varda el paneło 'Google Play' inte ła fenestra 'Crea grupo')", "partyInviteIgnoreText": "Ignora", - "partyInviteText": "A te ze rivà un invido de ${NAME}\npar zontarte inte'l só grupo!", + "partyInviteText": "Te ze rivà un invido de ${NAME}\npar zontarte inte'l só grupo!", "partyNameText": "Nome grupo", "partyServerRunningText": "Server pa'l grupo ativo.", "partySizeText": "grandesa", @@ -777,7 +810,7 @@ "wifiDirectText": "Wifi direto", "worksBetweenAllPlatformsText": "(el funsiona intrà tute łe piataforme)", "worksWithGooglePlayDevicesText": "(el funsiona co tuti i dispozidivi co ła varsion de’l zugo de Google Play par Android)", - "youHaveBeenSentAPromoCodeText": "A te ze stà mandà un còdaze promosionałe de ${APP_NAME}:" + "youHaveBeenSentAPromoCodeText": "Te ze stà mandà un còdaze promosionałe de ${APP_NAME}:" }, "getTicketsWindow": { "freeText": "GRATIS!", @@ -795,12 +828,18 @@ "ticketsFromASponsorText": "Varda na reclan e\notien ${COUNT} biłieti", "ticketsText": "${COUNT} biłieti", "titleText": "Otien biłieti", - "unavailableLinkAccountText": "No se połe miga cronpar so 'sta piataforma.\nVołendo, te połi cołegar 'sto account co uno inte\nn'antra piataforma e cronpar calcosa da łà.", + "unavailableLinkAccountText": "No se połe miga conprar so 'sta piataforma.\nVołendo, te połi cołegar 'sto account co uno inte\nn'antra piataforma e conprar calcosa da łà.", "unavailableTemporarilyText": "'Sta funsion no ła ze miga disponìbiłe par deso: proa danovo pì tardi.", "unavailableText": "Ne despiaze, 'sta funsion no ła ze miga disponìbiłe.", "versionTooOldText": "Ne despiaze, 'sta varsion ła ze masa vecia: ajorna el zugo co cheła nova.", - "youHaveShortText": "A te ghè ${COUNT}", - "youHaveText": "A te ghè ${COUNT} biłieti" + "youHaveShortText": "Te ghè ${COUNT}", + "youHaveText": "Te ghè ${COUNT} biłieti" + }, + "goldPass": { + "desc1InfTokensText": "Token infinidi.", + "desc2NoAdsText": "No reclan.", + "desc3ForeverText": "Par sempre.", + "goldPassText": "Pass Dorà" }, "googleMultiplayerDiscontinuedText": "Me despiaze, el sarviso multizugador de Google no'l ze miga pì disponìbiłe.\nA sò drio łaorar a un renpiaso pì in presa che se połe.\nIntanto proa n'antro mètodo de conesion.\n-Eric", "googlePlayPurchasesNotAvailableText": "Łe cronpe vecie no łe ze miga disponìbiłi.\nPodarìa èsarghe bezogno de ajornar l'apl Google Play.", @@ -810,10 +849,12 @@ "alwaysText": "Senpre", "fullScreenCmdText": "Schermo pien (Cmd-F)", "fullScreenCtrlText": "Schermo pien (Ctrl-F)", + "fullScreenText": "Schermo pien", "gammaText": "Gama", "highText": "Alta", "higherText": "Màsema", "lowText": "Basa", + "maxFPSText": "FPS màsemi", "mediumText": "Mezana", "neverText": "Mai", "resolutionText": "Resołusion", @@ -841,7 +882,7 @@ "pickUpInfoText": "- Łeva sù -\nBrinca sù bandiere, nemighi o calsìase\naltra roba miga inciodada par tera.\nStruca danovo par trarla in jiro.", "powerupBombDescriptionText": "El te parmete de trar in jiro fin\na 3 bonbe drioman invese che 1.", "powerupBombNameText": "Bonbe triple", - "powerupCurseDescriptionText": "Probabilmente A te vorè schivarla\n'sta chive. ...o dìzitu de nò?", + "powerupCurseDescriptionText": "Probabilmente te vorè schivarla\n'sta cuà. ...o dìzitu de nò?", "powerupCurseNameText": "Małedision", "powerupHealthDescriptionText": "El te recarga de'l tuto ła vida.\nA no te ło gavarisi mai pensà, ahn?", "powerupHealthNameText": "Parecio mèdego", @@ -860,10 +901,10 @@ "powerupsSubtitleText": "Par forsa, gnaun zugo el sarìe conpleto sensa potensiadori:", "powerupsText": "Potensiadori", "punchInfoText": "- Crogno -\nPì che te te movi ràpidamente,\npì i to crogni i farà małe, donca\ncori, salta e và torno cofà un mato.", - "runInfoText": "- Corsa -\nTien strucà CALSÌASE boton par córar. I botoni de testa o i griłeti nałòzeghi i ze i pì adati se\nA te łi ghè. Corendo A te rivarè prima inte i posti ma sarà pì dura voltar, donca ocio a łe crode.", + "runInfoText": "- Corsa -\nTien strucà CALSÌASE boton par córar. I botoni de testa o i griłeti nałòzeghi i ze i pì adati se\nte łi ghè. Corendo te rivarè prima inte i posti ma sarà pì dura voltar, donca ocio a łe crode.", "someDaysText": "In serti dì A se gà soło voja de tirarghe crogni a calcosa. O de farla saltar par aria.", "titleText": "Istrusion de ${APP_NAME}", - "toGetTheMostText": "Par tirar fora el mejo da 'sto zugo A te serve:", + "toGetTheMostText": "Par tirar fora el mejo da 'sto zugo te serve:", "welcomeText": "Benrivài so ${APP_NAME}!" }, "holdAnyButtonText": "", @@ -874,14 +915,15 @@ "importText": "Inporta", "importingText": "Inportasion...", "inGameClippedNameText": "rento el zugo:\n\"${NAME}\"", + "inboxText": "Posta", "installDiskSpaceErrorText": "EROR: inposìbiłe fenir l’instałasion.\nEl to dispozidivo el podarìa èsar sensa spasio.\nŁìbara un fià de memoria e proa danovo.", "internal": { "arrowsToExitListText": "struca ${LEFT} o ${RIGHT} par ndar fora da ła serie", "buttonText": "boton", "cantKickHostError": "A no te połi miga parar vìa l'ospitador.", "chatBlockedText": "${NAME} ze stà tajà fora da ła chat par ${TIME} segondi.", - "connectedToGameText": "A te te si zontà so '${NAME}'", - "connectedToPartyText": "A te te si zontà so'l grupo de ${NAME}!", + "connectedToGameText": "Te te si zontà so '${NAME}'", + "connectedToPartyText": "Te te si zontà so'l grupo de ${NAME}!", "connectingToPartyText": "Conesion...", "connectionFailedHostAlreadyInPartyText": "Conesion fałìa: l'ospitador el ze inte n'antro grupo.", "connectionFailedPartyFullText": "Conesion fałìa: el grupo el ze pien.", @@ -913,9 +955,9 @@ "keyboardText": "Botonera", "kickIdlePlayersKickedText": "Ze stà parà fora ${NAME} par masa sonera.", "kickIdlePlayersWarning1Text": "Se ła só sonera ła sèvita, ${NAME} vegnarà parà fora tenpo ${COUNT} segondi.", - "kickIdlePlayersWarning2Text": "(A te połi dezativarlo so Inpostasion > Avansàe)", - "leftGameText": "A te si ndà fora da '${NAME}'.", - "leftPartyText": "A te si ndà fora da'l grupo de ${NAME}.", + "kickIdlePlayersWarning2Text": "(Te połi dezativarlo so Inpostasion > Avansàe)", + "leftGameText": "Te si ndà fora da '${NAME}'.", + "leftPartyText": "Te si ndà fora da'l grupo de ${NAME}.", "noMusicFilesInFolderText": "Ła carteła no ła gà rento gnaun file muzegałe.", "playerJoinedPartyText": "${NAME} l'se gà zontà inte'l grupo!", "playerLeftPartyText": "${NAME} gà mołà el grupo!", @@ -926,14 +968,16 @@ "signInNoConnectionText": "Inposìbiłe acédar. (sensa conesion internet?)", "telnetAccessDeniedText": "EROR: l'utente no'l gà miga parmeso l'aceso co telnet.", "timeOutText": "(tocarà a ti tenpo ${TIME} segondi)", - "touchScreenJoinWarningText": "A te te si zontà co'l touchscreen.\nSe ła ze stà na capeła, struca 'Menù > Moła łeveło'.", + "touchScreenJoinWarningText": "Te te si zontà co'l touchscreen.\nSe ła ze stà na capeła, struca 'Menù > Moła łeveło'.", "touchScreenText": "TouchScreen", - "unableToResolveHostText": "Eror: A no ze mìa posìbiłe conétarse co l'ospitador.", - "unavailableNoConnectionText": "Par deso mìa disponìbiłe (gnauna conesion a internet?)", + "unableToCompleteTryAgainText": "No se pol completar par deso.\nPar piaser, riprova.", + "unableToResolveHostText": "Eror: no ze miga posìbiłe conétarse co l'ospitador.", + "unavailableNoConnectionText": "Par deso miga disponìbiłe (gnauna conesion a internet?)", "vrOrientationResetCardboardText": "Dopàreło par reinpostar l'orientasion de'l VR.\nA te servirà un controłador esterno par zugar.", "vrOrientationResetText": "Reinposta orientasion VR.", "willTimeOutText": "(ma se in sonera el ghe vegnarà cavà)." }, + "inventoryText": "Inventario", "jumpBoldText": "SALTO", "jumpText": "Salto", "keepText": "Tien", @@ -944,8 +988,8 @@ "kickOccurredText": "${NAME} ze stà parà fora.", "kickQuestionText": "Vutu parar vìa ${NAME}?", "kickText": "Para fora", - "kickVoteCantKickAdminsText": "I aministradori no i połe mìa èsar parài vìa.", - "kickVoteCantKickSelfText": "A no te połi mìa pararte vìa da soło.", + "kickVoteCantKickAdminsText": "I aministradori no i połe miga èsar parài vìa.", + "kickVoteCantKickSelfText": "No te połi miga pararte vìa da soło.", "kickVoteFailedNotEnoughVotersText": "A ghe ze masa pochi zugadori par na votasion.", "kickVoteFailedText": "Votasion de zlontanamento fałìa.", "kickVoteStartedText": "A se gà tacà na votasion par parar vìa ${NAME}.", @@ -979,13 +1023,16 @@ "seasonEndsHoursText": "Ła stajon ła fenirà tenpo ${NUMBER} ore.", "seasonEndsMinutesText": "Ła stajon ła fenirà tenpo ${NUMBER} menuti.", "seasonText": "Stajon ${NUMBER}", - "tournamentLeagueText": "A te ghè da rivar inte ła łega ${NAME} par zugar inte 'sto tornèo.", - "trophyCountsResetText": "Par ła stajon che ła vien el puntejo\nde i trofèi el se zerarà." + "tournamentLeagueText": "Par zugar inte 'sto tornèo te ghè da rivar inte ła łega ${NAME}.", + "trophyCountsResetText": "Par ła stajon che ła vien el puntejo\nde i trofèi el se zerarà.", + "upToDateBonusDescriptionText": "I zugadori che dopara 'na versiòn pì nuova de'l\nzugo i rivè 'na ${PERCENT}% de premia qua.", + "upToDateBonusText": "Premia atualizà" }, + "learnMoreText": "De Pì", "levelBestScoresText": "I punteji mejo so ${LEVEL}", "levelBestTimesText": "I tenpi mejo so ${LEVEL}", "levelIsLockedText": "${LEVEL} el ze blocà.", - "levelMustBeCompletedFirstText": "Prima A te ghè da conpletar ${LEVEL}.", + "levelMustBeCompletedFirstText": "Prima te ghè da conpletar ${LEVEL}.", "levelText": "Łeveło ${NUMBER}", "levelUnlockedText": "Łeveło dezblocà!", "livesBonusText": "Vite bonus", @@ -1021,9 +1068,12 @@ "maxConnectionsText": "Łìmite conesion", "maxPartySizeText": "Łìmite grandesa grupo", "maxPlayersText": "Łìmite zugadori", + "merchText": "Marcansìa BombSquad!", "modeArcadeText": "Modałidà arcade", "modeClassicText": "Modałidà clàsega", "modeDemoText": "Modałidà demo", + "moreSoonText": "De pì in arrivo...", + "mostDestroyedPlayerText": "Zugador Pì Sbarazado", "mostValuablePlayerText": "Zugador pì zgajo", "mostViolatedPlayerText": "Zugador pì sacagnà", "mostViolentPlayerText": "Zugador pì viołento", @@ -1040,6 +1090,7 @@ "nameSuicideText": "${NAME} l'se gà eutanà.", "nameText": "Nome", "nativeText": "Nadiva", + "newExclaimText": "Nòvo!", "newPersonalBestText": "Novo record parsonałe!", "newTestBuildAvailableText": "A ze disponìbiłe na varsion de proa nova. (${VERSION} beta ${BUILD}).\nDescàrgheła da ${ADDRESS}", "newText": "Novo", @@ -1050,16 +1101,20 @@ "noContinuesText": "(sensa continui)", "noExternalStorageErrorText": "So ’sto dispozidivo no ze stà catada gnauna memoria esterna", "noGameCircleText": "Eror: no te si miga conetesto co GameCircle", + "noMessagesText": "Nisun messaggio.", + "noPluginsInstalledText": "Gnauna estension instałada", "noScoresYetText": "Gnancora gnaun puntejo.", + "noServersFoundText": "Gnaun server catà.", "noThanksText": "Nò, grasie", "noTournamentsInTestBuildText": "AVERTENSA: i punteji de'l tornèo de 'sta varsion de proa i vegnarà ignorài.", - "noValidMapsErrorText": "A no ze stà catà gnaun łeveło vàłido par 'sto tipo de zugo.", + "noValidMapsErrorText": "No ze stà catà gnaun łeveło vàłido par 'sto tipo de zugo.", "notEnoughPlayersRemainingText": "A no ghe ze pì zugadori che basta: sortisi e taca na partìa nova.", "notEnoughPlayersText": "A serve almanco ${COUNT} zugadori par tacar 'sta partìa!", + "notEnoughTicketsText": "Biłieti insuficienti!", "notNowText": "Miga deso", - "notSignedInErrorText": "Par partesipar A te ghè da conétarte.", - "notSignedInGooglePlayErrorText": "Far farlo A te ghè da conétarte co Google Play.", - "notSignedInText": "gnancora cołegà", + "notSignedInErrorText": "Par partesipar te ghè da acédar.", + "notSignedInGooglePlayErrorText": "Far farlo te ghè da acédar co Google Play.", + "notSignedInText": "serve l'aceso", "notUsingAccountText": "Ocio: ze stà łasà in parte l'account ${SERVICE}.\nSe te vołi dopararlo và so 'Account > Acedi co ${SERVICE}'.", "nothingIsSelectedErrorText": "A no ze sełesionà gnente!", "numberText": "#${NUMBER}", @@ -1068,6 +1123,8 @@ "onText": "Ativa", "oneMomentText": "Un segondo...", "onslaughtRespawnText": "Rejenerasion de ${PLAYER} inte l'ondada ${WAVE}", + "openNowText": "Dèsa Deso", + "openText": "Dèsa", "orText": "${A} o ${B}", "otherText": "Altro...", "outOfText": "(#${RANK} de ${ALL})", @@ -1111,15 +1168,19 @@ "titleText": "Profiłi zugador" }, "playerText": "Zugador", - "playlistNoValidGamesErrorText": "'Sta łista de zugo ła gà rento łevełi dezblocài mìa vàłidi.", - "playlistNotFoundText": "łista de zugo mìa catada", + "playlistNoValidGamesErrorText": "'Sta łista de zugo ła gà rento łevełi dezblocài miga vàłidi.", + "playlistNotFoundText": "łista de zugo miga catada", "playlistText": "Łista de zugo", "playlistsText": "Łiste de zugo", "pleaseRateText": "Se ${APP_NAME} el ze drio piazerte, tote un àtemo par\nłasarghe zó na vałudasion o scrìvarghe zó un comento. 'Ste\nopinion łe tornarà còmode par dezviłupi fuduri de'l zugo.\n\ngrasie!\n-eric", "pleaseWaitText": "Speta n'àtemo...", "pluginClassLoadErrorText": "Eror de cargamento de ła clase de estension '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Eror de inisiałizasion de l'estension '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Inpostasion estension", + "pluginsAutoEnableNewText": "Ativa in automàtego łe estension nove", "pluginsDetectedText": "Estension nove rełevàe. Retaca el zugo par ativarle, o configùrełe so łe inpostasion.", + "pluginsDisableAllText": "Dezativa tute łe estension", + "pluginsEnableAllText": "Ativa tute łe estension", "pluginsRemovedText": "Estension miga catàe: ${NUM}", "pluginsText": "Estension", "practiceText": "Pràtega", @@ -1149,6 +1210,8 @@ "punchText": "Crogno", "purchaseForText": "Cronpa par ${PRICE}", "purchaseGameText": "Cronpa el zugo", + "purchaseNeverAvailableText": "Scusa, i comprì no se poł far in 'sta build.\nFai ‘na prova a fare la registrazión del to account su ‘na altra piattaforma e conpra lì.", + "purchaseNotAvailableText": "Conpera no disponibile.", "purchasingText": "Cronpa in corso...", "quitGameText": "Vutu sortir da ${APP_NAME}?", "quittingIn5SecondsText": "Sortìa tenpo 5 segondi...", @@ -1165,7 +1228,7 @@ "app_name_short": "BSRemote", "button_position": "Pozision botoni", "button_size": "Grandesa botoni", - "cant_resolve_host": "A no ze mìa posìbiłe catar fora l'ospitador.", + "cant_resolve_host": "No ze miga posìbiłe catar fora l'ospitador.", "capturing": "Drio spetar i zugadori…", "connected": "Conetesto.", "description": "Dòpara el to tełèfono o tołeto cofà controłador par BombSquad.\nPołe conétarse so un schermo ùgnoło fin a 8 dispozidivi insenbre, par un feston bueło multizugador!", @@ -1190,12 +1253,13 @@ "version_mismatch": "Varsion zbałiada.\nSegùrate che BombSquad e BombSquad Remote i\nsipie ajornài a ła varsion ùltema e proa danovo." }, "removeInGameAdsText": "Par cavar vìa łe reclan, dezbloca \"${PRO}\" inte ła botega.", + "removeInGameAdsTokenPurchaseText": "OFERTA PAR UN TEMPO LIMITÀ: cronpa qualsevò pacchète de getoni par cavare le reclan de'l zugo.", "renameText": "Renòmena", "replayEndText": "Sara sù Revardo", "replayNameDefaultText": "Revardo partìa ùltema", "replayReadErrorText": "Eror de łedura de'l file de revardo.", "replayRenameWarningText": "Par salvar na partìa fenìa, renòmena \"${REPLAY}\". Senò te sevitarè sorascrìvarle.", - "replayVersionErrorText": "Ne despiaze, 'sto revardo el ze stà fato co na varsion\nde'l zugo defarente e no'l połe mìa èsar doparà.", + "replayVersionErrorText": "'Sto revardo el ze stà fato co na varsion de'l\nzugo defarente e no'l połe miga èsar doparà.", "replayWatchText": "Varda revardo", "replayWriteErrorText": "Eror de salvatajo de'l revardo.", "replaysText": "Revardi", @@ -1210,9 +1274,11 @@ "revertText": "Anuła", "runText": "Cori", "saveText": "Salva", - "scanScriptsErrorText": "Tirando sù i script A se gà catà erori: varda el rejistro eventi par i detaji.", + "scanScriptsErrorText": "Eror de scansion de i script: varda el rejistro eventi par i detaji.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} n'antro/i mòduło/i el/i gà èsar ajornà/i par l'api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} el gà èsar ajornà par l'api ${API}.", "scoreChallengesText": "Puntejo sfide", - "scoreListUnavailableText": "Łista de puntejo mìa disponìbiłe.", + "scoreListUnavailableText": "Łista de puntejo miga disponìbiłe.", "scoreText": "Puntejo", "scoreUnits": { "millisecondsText": "Miłesegondi", @@ -1221,6 +1287,7 @@ }, "scoreWasText": "(prima ${COUNT})", "selectText": "Sełesiona", + "sendInfoDescriptionText": "Par mandarghe informasion so'l stado de account e apl a'l dezviłupador.\nZóntaghe el tó nome e ła rajon de'l parché te ghe scrivi.", "seriesWinLine1PlayerText": "GÀ VINTO ŁA", "seriesWinLine1TeamText": "GÀ VINTO ŁA", "seriesWinLine1Text": "GÀ VINTO ŁA", @@ -1238,40 +1305,52 @@ "alwaysUseInternalKeyboardDescriptionText": "(na botonera so schermo, senpia e còmoda, par scrìvar testi)", "alwaysUseInternalKeyboardText": "Dòpara botonera integrada", "benchmarksText": "Prestasion & Proe soto sforso", - "disableCameraGyroscopeMotionText": "Dezativa movimento de ła prospetiva łigada a'l jiroscopio", - "disableCameraShakeText": "Dezativa i zgorlamenti de ła videocàmara", - "disableThisNotice": "(A te połi dezativar 'sta notìfega inte łe inpostasion avansàe)", + "devToolsText": "Strumenti dezviłupador", + "disableCameraGyroscopeMotionText": "Dezativa movimento de ła prospetiva co'l jiroscopio", + "disableCameraShakeText": "Dezativa zgorlamenti de ła videocàmara", + "disableThisNotice": "(Te połi dezativar 'sta notìfega inte łe inpostasion avansàe)", "enablePackageModsDescriptionText": "(l'ativasion de ła capasidà de modifegasion ła dezativa el zugo in rede)", "enablePackageModsText": "Ativa pacheti mod łogałi", "enterPromoCodeText": "Insarisi còdaze", "forTestingText": "Nota: vałori vàłidi soło par proe. Sortendo da l'apl łi vegnarà perdesti.", "helpTranslateText": "Łe tradusion de ${APP_NAME} łe ze curàe da vołontari.\nSe te vołi darghe na ociada a cheła veneta, struca so'l boton\ncuà soto. Curada da VeC: venetianlanguage@gmail.com", + "insecureConnectionsDescriptionText": "sconsiglià, ma podrìa dar la possibilità de zugar \nin-rete da reti o paesi restrèti", + "insecureConnectionsText": "Dòpara conesioni no sicurè", "kickIdlePlayersText": "Para fora zugadori in sonera", "kidFriendlyModeText": "Modałidà bocia (viołensa reduzesta, evc)", "languageText": "Łengua", "moddingGuideText": "Guida par modifegasion", - "mustRestartText": "Par rèndar efetive łe modìfeghe, A te ghè da retacar el zugo.", + "moddingToolsText": "Strumenti de modifegasion", + "mustRestartText": "Par rèndar efetive łe modìfeghe, te ghè da retacar el zugo.", "netTestingText": "Proa de rede", "resetText": "Reinposta", + "sendInfoText": "Manda informasion", "showBombTrajectoriesText": "Mostra trajetore bonbe", + "showDemosWhenIdleText": "Mostra demostrasion in sonera", + "showDeprecatedLoginTypesText": "Mostra tipi de aceso veci", + "showDevConsoleButtonText": "Mostra boton de i comandi dezviłupador", + "showInGamePingText": "Mostra łatensa de'l zugo", "showPlayerNamesText": "Mostra nomi zugadori", "showUserModsText": "Mostra carteła modifegasion", "titleText": "Avansàe", "translationEditorButtonText": "Piataforma de tradusion de ${APP_NAME}", - "translationFetchErrorText": "stado de ła tradusion mìa disponìbiłe", + "translationFetchErrorText": "stado de ła tradusion miga disponìbiłe", "translationFetchingStatusText": "controło stado de ła tradusion...", - "translationInformMe": "Infòrmame co A ghe ze tochi novi da tradùzar", - "translationNoUpdateNeededText": "ła tradusion in veneto ła ze aposto: un aereo!", - "translationUpdateNeededText": "** A ghe ze testi novi da tradùzar!! **", + "translationInformMe": "Infòrmame co ghe ze tochi novi da tradùzar", + "translationNoUpdateNeededText": "Ła tradusion in veneto ła ze a posto: un aèreo!", + "translationUpdateNeededText": "** Ghe ze testi novi da tradùzar!! **", "vrTestingText": "Proa VR" }, "shareText": "Sparpagna", "sharingText": "Sparpagnasion...", "showText": "Mostra", - "signInForPromoCodeText": "Conétate co un account par poder far funsionar el còdaze.", + "signInForPromoCodeText": "Par far funsionar el còdaze acedi co un account.", "signInWithGameCenterText": "Par doparar un account Game Center,\nconétate da rento l'apl Game Center.", "singleGamePlaylistNameText": "Tuti \"${GAME}\"", "singlePlayerCountText": "1 zugador", + "sizeLargeText": "Granda", + "sizeMediumText": "Mezana", + "sizeSmallText": "Ceła", "soloNameFilterText": "\"${NAME}\" 1 VS 1", "soundtrackTypeNames": { "CharSelect": "Sełesion parsonajo", @@ -1312,14 +1391,14 @@ "howToUseIconsText": "(par dopararle, crea un profiło zugador globałe inte ła sesion account)", "howToUseMapsText": "(dòpara 'sti łevełi inte łe to łiste de zugo: scuadre/tuti contro tuti)", "iconsText": "Icone", - "loadErrorText": "A no ze mìa posìbiłe cargar ła pàjina.\nDaghe na ociada a ła to conesion internet.", + "loadErrorText": "No ze miga posìbiłe cargar ła pàjina.\nDaghe na ociada a ła tó conesion internet.", "loadingText": "cargamento", "mapsText": "Łevełi", "miniGamesText": "Minizughi", "oneTimeOnlyText": "(ocazion ùgnoła)", "purchaseAlreadyInProgressText": "Cronpa de 'sto ojeto dezà drio conpirse.", "purchaseConfirmText": "Vutu cronpar ${ITEM}?", - "purchaseNotValidError": "Cronpa mìa vàłida.\nSe'l ze un eror, contata ${EMAIL}.", + "purchaseNotValidError": "Cronpa miga vàłida.\nSe'l ze un eror, contata ${EMAIL}.", "purchaseText": "Cronpa", "saleBundleText": "Pacheto in oferta!", "saleExclaimText": "Oferta!", @@ -1344,15 +1423,18 @@ "storeText": "Botega", "submitText": "Manda", "submittingPromoCodeText": "Trazmision còdaze...", + "successText": "A posto!", + "supportEmailText": "Se te vedi calche problema so l'apl,\nmanda na mail a ${EMAIL}.", "teamNamesColorText": "Nome/Cołor scuadra...", "telnetAccessGrantedText": "Aceso a telnet ativà.", "telnetAccessText": "Rełevà aceso a telnet: vutu autorizarlo?", "testBuildErrorText": "'Sta varsion de proa no ła ze miga pì ativa. Controła se A ghin ze una pì resente.", "testBuildText": "Varsion de proa", - "testBuildValidateErrorText": "A no ze mìa posìbiłe varifegar ła varsion de proa. (gnauna conesion a internet?)", + "testBuildValidateErrorText": "No ze miga posìbiłe varifegar ła varsion de proa. (gnauna conesion a internet?)", "testBuildValidatedText": "Varsion de proa aposto. Gòdateła!", "thankYouText": "Grasie par el to suporto! Gùstate el zugo!", "threeKillText": "NO GHE N'È 2 SENSA 3!!", + "ticketsDescriptionText": "I biłieti se pol usar par sbloccar parsonaji,\nmappe, minigiochi e altre robe ne la botega.\n\nI biłieti se pol trovar nelle càse\no vìnzi ne le campagne, nei tornei o nei obietivi.", "timeBonusText": "Tenpo bonus", "timeElapsedText": "Tenpo pasà", "timeExpiredText": "Tenpo fenìo", @@ -1363,10 +1445,23 @@ "tipText": "Drita", "titleText": "BombSquad", "titleVRText": "BombSquad VR", + "tokens": { + "getTokensText": "Ottieni Getoni", + "notEnoughTokensText": "Getoni insufficienti!", + "numTokensText": "${COUNT} Getoni", + "shinyNewCurrencyText": "Ła nova moneta brillante de BombSquad.", + "tokenPack1Text": "Pachetto de Getoni Pico", + "tokenPack2Text": "Pachetto de Getoni Mezo", + "tokenPack3Text": "Pachetto de Getoni Grande", + "tokenPack4Text": "Pachetto di Getoni Gigante", + "tokensDescriptionText": "I getoni se usa par velocizzar el sbloco de le càse\ne par altri vantagi de'l zogo e de'l conto.\n\nTe pol vinzer getoni nel zogo o comprargli\nin pacchetti. O cronpando el Pass Dorà par getoni\ninfiniti e no sentirli mai più.", + "youHaveGoldPassText": "Te gha na Pass Dorà.\nTuti i conpra de gettoni xè gratis.\nGodeli!" + }, "topFriendsText": "Mejori amighi", "tournamentCheckingStateText": "Verìfega stado de'l tornèo: speta n'àtemo...", "tournamentEndedText": "'Sto tornèo el ze fenìo. A ghin tacarà presto uno novo.", "tournamentEntryText": "Entrada tornèo", + "tournamentFinalStandingsText": "Posti Finali", "tournamentResultsRecentText": "Rezultài tornèi resenti", "tournamentStandingsText": "Clasìfega tornèo", "tournamentText": "Tornèo", @@ -1422,9 +1517,21 @@ "Uber Onslaught": "Dezìo - ultra", "Uber Runaround": "Mena torno - ultra" }, + "displayItemNames": { + "${C} Tickets": "${C} Biłieti", + "${C} Tokens": "${C} Getoni", + "Chest": "Càsa", + "L1 Chest": "Càsa L1", + "L2 Chest": "Càsa L2", + "L3 Chest": "Càsa L3", + "L4 Chest": "Càsa L4", + "L5 Chest": "Càsa L5", + "L6 Chest": "Càsa L6", + "Unknown Chest": "Càsa Sconossùa" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Copa l'ełeto par ciapar el só posto!\nPar vìnsar resta l'ełeto par un serto tenpo.", - "Bomb as many targets as you can.": "Bonbarda tuti i sentri che A te pol!", + "Bomb as many targets as you can.": "Bonbarda tuti i sentri che te połi!", "Carry the flag for ${ARG1} seconds.": "Tiente ła bandiera par ${ARG1} segondi.", "Carry the flag for a set length of time.": "Tiente ła bandiera par un serto tenpo.", "Crush ${ARG1} of your enemies.": "Copa ${ARG1} nemighi.", @@ -1524,7 +1631,9 @@ "Italian": "Itałian", "Japanese": "Japoneze", "Korean": "Corean", + "Malay": "Maleze", "Persian": "Persian", + "PirateSpeak": "Léngua de pirati", "Polish": "Połaco", "Portuguese": "Portogheze", "Romanian": "Romen", @@ -1590,59 +1699,70 @@ "An error has occurred; please try again later.": "A se gà verifegà un eror: proa danovo pì tardi.", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Vutu dabon cołegar 'sti profiłi?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n'Sta asion no ła połe pì èsar anułada!", "BombSquad Pro unlocked!": "BombSquad Pro dezblocà!", - "Can't link 2 accounts of this type.": "A no se połe mìa cołegar 2 profiłi de 'sto tipo.", - "Can't link 2 diamond league accounts.": "A no se połe mìa cołegar 2 profiłi de ła łega de damante.", - "Can't link; would surpass maximum of ${COUNT} linked accounts.": "A no se połe mìa cołegarlo: A ze dezà stà cołegài un màsemo de ${COUNT} profiłi.", + "Can't link 2 accounts of this type.": "No se połe miga cołegar 2 profiłi de 'sto tipo.", + "Can't link 2 diamond league accounts.": "No se połe miga cołegar 2 profiłi de ła łega de damante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se połe miga cołegarlo: ze dezà stà cołegài un màsemo de ${COUNT} profiłi.", "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Rełevà un inbrojo: punteji e premi sospendesti par ${COUNT} dì.", - "Could not establish a secure connection.": "A no ze mìa posìbiłe stabiłir na conesion segura.", + "Could not establish a secure connection.": "No ze miga posìbiłe stabiłir na conesion segura.", "Daily maximum reached.": "Màsemo jornałiero pasà.", "Entering tournament...": "Entrada inte'l tornèo...", - "Invalid code.": "Còdaze mìa vàłido.", + "Invalid code.": "Còdaze miga vàłido.", "Invalid payment; purchase canceled.": "Pagamento miga vàłido: cronpa anułada.", - "Invalid promo code.": "Còdaze promosionałe mìa vàłido.", - "Invalid purchase.": "Cronpa mìa vàłida.", - "Invalid tournament entry; score will be ignored.": "Entrada inte'l tornèo mìa vàłida: el puntejo el vegnarà ignorà.", + "Invalid promo code.": "Còdaze promosionałe miga vàłido.", + "Invalid purchase.": "Cronpa miga vàłida.", + "Invalid tournament entry; score will be ignored.": "Entrada inte'l tornèo miga vàłida: el puntejo el vegnarà ignorà.", "Item unlocked!": "Ojeto dezblocà!", - "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "COŁEGAMENTO REFUDÀ. ${ACCOUNT} el contien dati\ninportanti che i ndarà PERDESTI.\nSe te vołi A te połi cołegarli in òrdane raverso\n(e pèrdar a'l só posto i dati de 'STO account cuà).", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "COŁEGAMENTO REFUDÀ. ${ACCOUNT} el contien dati\ninportanti che i ndarà PERDESTI.\nSe te vołi te połi cołegarli in òrdane raverso\n(e pèrdar a'l só posto i dati de 'STO account cuà).", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vutu dabon cołegar l'account ${ACCOUNT} a 'sto account?\nTuti i dati so ${ACCOUNT} i ndarà perdesti.\n'Sta asion no ła połe pì èsar anułada: vutu ndar vanti?", "Max number of playlists reached.": "Nùmaro màsemo de łiste de scolto pasà.", "Max number of profiles reached.": "Nùmaro màsemo de profiłi pasà.", "Maximum friend code rewards reached.": "Brincà el nùmaro màsemo de premi da'l còdaze amigo.", "Message is too long.": "Mesajo masa łongo.", + "New tournament result!": "Novo risultato de'l tornèo!", "No servers are available. Please try again soon.": "Gnaun server disponìbiłe. Proa pì tardi.", + "No slots available. Free a slot and try again.": "No ghe xe spazi disponibiłi, łibera un spazi e riprova.", "Profile \"${NAME}\" upgraded successfully.": "Profiło \"${NAME}\" mejorà co suceso.", - "Profile could not be upgraded.": "El profiło no'l połe mìa èsar mejorà.", + "Profile could not be upgraded.": "El profiło no'l połe miga èsar mejorà.", "Purchase successful!": "Cronpà co suceso!", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "A te ghè resevesto ${COUNT} biłieti par ver verto el zugo.\nTorna anca doman par brincàrghine ${TOMORROW_COUNT}.", - "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Ła funsionałidà de'l server no ła ze mìa pì suportada inte 'sta varsion de'l zugo.\nAjòrneło a ła varsion nova.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "So 'sta varsion de'l zugo ła funsionałidà de'l server no ła ze miga pì suportada.\nAjòrneło a ła varsion nova.", "Sorry, there are no uses remaining on this code.": "Ne despiaze, 'sto còdaze el ze dezà stà doparà a'l màsemo.", "Sorry, this code has already been used.": "Ne despiaze, 'sto còdaze el ze dezà stà doparà.", "Sorry, this code has expired.": "Ne despiaze, ła vałidità de 'sto còdaze ła ze terminada.", "Sorry, this code only works for new accounts.": "Ne despiaze, 'sto còdaze el funsiona soło so i account novi.", + "Sorry, this has expired.": "Scusa, 'sto xe scadù.", "Still searching for nearby servers; please try again soon.": "Reserca de server visini in corso: proa danovo pì tardi.", "Temporarily unavailable; please try again later.": "Par deso miga disponìbiłe: proa danovo pì tardi.", "The tournament ended before you finished.": "El tornèo el ze terminà prima che te ghesi fenìo.", - "This account cannot be unlinked for ${NUM} days.": "'Sto account no'l połe mìa èsar descołegà prima de ${NUM} dì.", - "This code cannot be used on the account that created it.": "'Sto còdaze no'l połe mìa èsar doparà inte l'account che'l ło gà creà.", + "This account cannot be unlinked for ${NUM} days.": "'Sto account no'l połe miga èsar descołegà prima de ${NUM} dì.", + "This code cannot be used on the account that created it.": "'Sto còdaze no'l połe miga èsar doparà inte l'account che'l ło gà creà.", "This is currently unavailable; please try again later.": "Par deso, funsion miga disponìbiłe. Proa danovo pì tardi.", "This requires version ${VERSION} or newer.": "A ghe serve ła varsion ${VERSION} o una pì nova.", "Tournaments disabled due to rooted device.": "Tornèi dezativài parvìa de'l dispozidivo co'l root.", - "Tournaments require ${VERSION} or newer": "Par i tornèi A serve ła varsion ${VERSION} o una pì resente", + "Tournaments require ${VERSION} or newer": "Par i tornèi serve ła varsion ${VERSION} o una pì resente", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Vutu descołegar l'account ${ACCOUNT} da 'sto account?\nTuti i dati de ${ACCOUNT} i vegnarà ełimenài.\n(obietivi a parte in calche cazo)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "AVERTENSA: el to account el ze stà segnałà par el dòparo de truchi.\nI zugaduri catài a doparar truchi i vegnarà blocài. Zuga da gałantomo.", - "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ghetu caro cołegar el to account łogałe co 'sto cuà?\n\nEl to account łogałe el ze ${ACCOUNT1}\n'Sto account el ze ${ACCOUNT2}\n\n'Sta oparasion ła te parmetarà de mantegner i to progresi ezistenti.\nOcio: 'sta asion no ła połe pì èsar anułada!", + "Wait reduced!": "Spèta calà!", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ghetu caro cołegar el tó account łogałe co 'sto cuà?\n\nEl tó account łogałe el ze ${ACCOUNT1}\n'Sto account el ze ${ACCOUNT2}\n\n'Sta oparasion ła te parmetarà de mantegner i tó progresi ezistenti.\nOcio: 'sta asion no ła połe pì èsar anułada!", "You already own this!": "Dezà cronpà!", - "You can join in ${COUNT} seconds.": "A te połi zontarte tenpo ${COUNT} segondi.", + "You can join in ${COUNT} seconds.": "Te połi zontarte tenpo ${COUNT} segondi.", "You don't have enough tickets for this!": "A no te ghè miga biłieti che basta par cronparlo!", "You don't own that.": "Gnancora cronpà!", "You got ${COUNT} tickets!": "A te ghè otegnesto ${COUNT} biłieti!", + "You got ${COUNT} tokens!": "A te ghè otegnesto ${COUNT} getoni!", "You got a ${ITEM}!": "A te ghè otegnesto un ${ITEM}!", + "You got a chest!": "A te ghè otegnesto 'na càsa!", + "You got an achievement reward!": "A te ghè otegnesto 'na recompensa da obietivo!", "You have been promoted to a new league; congratulations!": "Promosion a ła łega suparior: congratułasion!", + "You lost a chest! (All your chest slots were full)": "Te gh'è perduda 'na càsa!(Tuti i spazi càsa jera pieni)", + "You must update the app to view this.": "Bisogna ajornà pa' vedare", "You must update to a newer version of the app to do this.": "Par ndar vanti A te ghè da ajornar l'apl a ła varsion pì resente.", "You must update to the newest version of the game to do this.": "Par ndar vanti A te ghè da ajornar el zugo a ła varsion pì resente.", "You must wait a few seconds before entering a new code.": "A te ghè da spetar calche segondo prima de insarir un còdaze novo.", + "You placed #${RANK} in a tournament!": "Te se ze clasificà #${RANK} ne'l tornèo!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Inte'l tornèo ùltemo A te si rivà #${RANK}. Grasie par ver zugà!", "Your account was rejected. Are you signed in?": "El to account el ze stà refudà. Ghetu fato l'aceso?", + "Your ad views are not registering. Ad options will be limited for a while.": "Łe vostre vixuałixasion de l’inserission no łe se registra. Łe opsion publicitarie łe sarà limitae pa un fià.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ła to copia de'l zugo ła ze stada modifegada.\nPar piaser, anuła łe modìfeghe e proa danovo.", "Your friend code was used by ${ACCOUNT}": "El to còdaze amigo el ze stà doparà da ${ACCOUNT}" }, @@ -1702,9 +1822,9 @@ "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Co'l justo tenpo de corsa, salto e rodasion, un crogno el połe copar inte un\ncolpo soło e farte vadagnar el respeto de i to amighi par tuta ła vida.", "Always remember to floss.": "Recòrdate senpre de doparar el fiło intardentałe.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Invese de doparàrghine de fati a cazo, par ti e i to\namighi crea profiłi zugador co nomi e parense parsonałizàe.", - "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Łe case małedision łe te transforma inte na bonba a tenpo.\nA te połi curarte soło tołendo in presa un pacheto sałude.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Łe case małedision łe te transforma inte na bonba a tenpo.\nTe połi curarte soło tołendo in presa un pacheto sałude.", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Anca se drio ła siera A no par, łe abiłidà de tuti i parsonaji\nłe ze conpagne, donca tote sù cheło che'l te połe somejar de pì.", - "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Mai far masa i gałeti co'l scudo nerjètego: A te połi uncora farte trar baso da na croda.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Mai far masa i gałeti co'l scudo nerjètego: te połi uncora farte trar baso da na croda.", "Don't run all the time. Really. You will fall off cliffs.": "No stà córar tuto el tenpo. Dabon. Te fenirè zó par na croda.", "Don't spin for too long; you'll become dizzy and fall.": "No stà ndar torno par masa tenpo: te vegnarà na storniroła e te cascarè.", "Hold any button to run. (Trigger buttons work well if you have them)": "Tien strucà un boton calsìase par córar. (I griłeti nałòzeghi i ze i pì adati, se A te łi ghè)", @@ -1719,14 +1839,14 @@ "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se te te cati tanti zugadori che và e vien, e inte'l cazo che calchedun el se dezménteghe de\nmołar el zugo, ativa ła funsion automàtega 'Para fora zugadori in sonera' inte łe inpostasion.", "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se'l to dispozidivo el taca scotar o se te ghè caro sparagnar batarìa,\ncała ła \"Prospetiva\" o ła \"Resołusion\" so Inpostasion > Gràfega", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se el zugo el và a scati, proa całar ła resołusion\no ła prospetiva inte l'inpostasion gràfega.", - "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Par far ponto so 'Brinca ła bandiera', A te ghè da portar ła bandiera fin so ła to\nbaze. Se cheł'altra scuadra ła ze drio far ponto, A te połi fermarla anca robàndogheła.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Par far ponto so 'Brinca ła bandiera', te ghè da portar ła bandiera fin so ła tó\nbaze. Se cheł'altra scuadra ła ze drio far ponto, te połi fermarla anca robàndogheła.", "In hockey, you'll maintain more speed if you turn gradually.": "Inte l'hockey, voltando gradualmente A te mantien alta ła vełosidà.", "It's easier to win with a friend or two helping.": "A ze pì fàsiłe vìnsar se un amigo o do i te dà na man.", "Jump just as you're throwing to get bombs up to the highest levels.": "Co A te si drio tirar na bonba, salta par farla rivar pì alta posìbiłe.", "Land-mines are a good way to stop speedy enemies.": "Łe mine łe ze fantàsteghe par fermar i nemighi pì ràpidi.", - "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "A te połi łevar sù e tirar racuante robe, anca cheł'altri zugadori. Trar zó da na croda\ni to nemighi ła połe èsar na stratejìa efisente che ła połe cavarte anca calche spisa.", - "No, you can't get up on the ledge. You have to throw bombs.": "Nò, A no te połi mìa montar so'l bordo. A te ghè da tirar bonbe.", - "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "I zugadori i połe zontarse e ndar vìa inte'l medo de ła majornasa de łe\npartìe. Ti A te połi anca tacar e destacar un controłador a'l voło.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Te połi łevar sù e tirar racuante robe, anca cheł'altri zugadori. Trar zó da na croda\ni tó nemighi ła połe èsar na stratejìa efisente che ła połe cavarte anca calche spisa.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nò, no te połi miga montar so'l bordo. Te ghè da tirar bonbe.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "I zugadori i połe zontarse e ndar vìa inte'l medo de ła majornasa de łe\npartìe. Ti te połi anca tacar e destacar un controłador a'l voło.", "Practice using your momentum to throw bombs more accurately.": "Fà pràtega tirardo bonbe corendo par far crèsar ła to presizion.", "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pì vełosi che se move łe to man, pì dano i farà i to\ncrogni! Donca proa córar, saltar e ndar torno cofà un mato.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Prima de tirar na bonba cori prima indrìo e daspò in\nvanti par darghe na \"scuriatada\" e trarla pì distante.", @@ -1739,9 +1859,9 @@ "Try tricking enemies into killing eachother or running off cliffs.": "Frega i to nemighi parché i se cope infrà de łori o i cora zó par na croda.", "Use the pick-up button to grab the flag < ${PICKUP} >": "Dòpara el boton 'łeva sù' par brincar ła bandiera < ${PICKUP} >", "Whip back and forth to get more distance on your throws..": "Cori prima indrìo e daspò in vanti par rivar pì distante co i to tiri...", - "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "A te połi 'mirar' i to crogni ndando torno par drita o sanca. A torna\ncòmodo par trar baso i cataràdeghi da łe crode o par far ponto so l'hockey.", - "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "A te połi capir el tenpo de esplozion de na bonba drio el cołor\nde łe fałive de ła micia: zało.. naranson.. roso.. e BUM!!", - "You can throw bombs higher if you jump just before throwing.": "A te połi tirar łe bonbe pì alte, se te salti pena prima de tirarle.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Te połi 'mirar' i tó crogni ndando torno par drita o sanca. Na comodidà\npar trar baso i cataràdeghi da łe crode o par far ponto so l'hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Te połi capir el tenpo de esplozion de na bonba drio el cołor\nde łe fałive de ła micia: zało.. naranson.. roso.. e BUM!!", + "You can throw bombs higher if you jump just before throwing.": "Se te salti pena prima de tirarle te trè łe bonbe pì alte.", "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Se A te bati ła testa da calche parte A te te fè małe,\ndonca proa a no zbàtar da gnauna parte.", "Your punches do much more damage if you are running or spinning.": "I to crogni i fà pì małe se A te si drio córar o ndar torno." } @@ -1764,7 +1884,7 @@ "phrase11Text": "Tien strucà un boton CALSÌASE par córar.", "phrase12Text": "Par crogni uncora pì fisi, proa córar e ndar torno INSENBRE.", "phrase13Text": "Orpo! Colpa mia ${NAME}.", - "phrase14Text": "A te połi łevar sù e tirar robe cofà łe bandiere o anca cofà... ${NAME}.", + "phrase14Text": "Te połi łevar sù e tirar robe cofà bandiere, ojeti o anca... ${NAME}.", "phrase15Text": "In ùltema, A ghe ze łe bonbe.", "phrase16Text": "A serve pràtega par tirar ben łe bonbe.", "phrase17Text": "Òstrega! Un tiro miga masa beło...", @@ -1791,22 +1911,28 @@ "toSkipPressAnythingText": "(toca o struca un boton par saltar ła demostrasion)" }, "twoKillText": "E 2 DE COPÀI!", + "uiScaleText": "Grandesa interfasa", "unavailableText": "miga disponìbiłe", "unconfiguredControllerDetectedText": "Rełevà controłador miga configurà:", "unlockThisInTheStoreText": "Da dezblocar inte ła botega.", "unlockThisProfilesText": "Par crear pì de ${NUM} profiłi, A te serve:", "unlockThisText": "Par dezblocar 'sta funsion A te serve:", - "unsupportedHardwareText": "Ne despiaze, 'sto hardware no'l ze mìa conpatìbiłe co 'sta varsion de'l zugo.", + "unsupportedControllerText": "El controłador \"${NAME}\" no'l ze miga suportà.", + "unsupportedHardwareText": "'Sto hardware no'l ze miga conpatìbiłe co 'sta varsion de'l zugo.", "upFirstText": "Par tacar:", "upNextText": "Inte'l łeveło n°${COUNT}:", "updatingAccountText": "Ajornamento de'l to account...", "upgradeText": "Mejora", "upgradeToPlayText": "Par zugarghe, dezbloca \"${PRO}\" inte ła botega.", "useDefaultText": "Reinposta", + "userSystemScriptsCreateText": "Crea script de sistema de l'utente", + "userSystemScriptsDeleteText": "Ełìmena script de sistema de l'utente", "usesExternalControllerText": "'Sto zugo el dòpara un controłador esterno cofà dispozidivo de entrada.", "usingItunesText": "Doparar l'apl de mùzega par el son de fondo...", "v2AccountLinkingInfoText": "Par łigar un account V2 dòpara el boton 'Jestisi account'.", + "v2AccountRequiredText": "Questo gà bisogno de un account V2. Agiorna el to account e riprova.", "validatingTestBuildText": "Confermasion varsion de proa...", + "viaText": "co", "victoryText": "Vitoria!", "voteDelayText": "A no te połi tacar n'antra votasion par ${NUMBER} segondi", "voteInProgressText": "A ze dezà in corso na votasion.", @@ -1830,8 +1956,8 @@ "replayDeleteErrorText": "A se gà verifegà un eror ełimenando el revardo.", "replayNameText": "Nome de'l revardo", "replayRenameErrorAlreadyExistsText": "A eziste dezà un revardo co 'sto nome.", - "replayRenameErrorInvalidName": "A no ze mìa posìbiłe renomenar el revardo: nome mìa vàłido.", - "replayRenameErrorText": "A se gà verifegà un eror renomenando el revardo.", + "replayRenameErrorInvalidName": "No ze miga posìbiłe renomenar el revardo: nome miga vàłido.", + "replayRenameErrorText": "Se gà verifegà un eror renomenando el revardo.", "sharedReplaysText": "Revardi sparpagnài", "titleText": "Varda", "watchReplayButtonText": "Varda\nrevardo" @@ -1864,12 +1990,13 @@ "worldsBestTimesText": "I tenpi mejo de'l mondo", "xbox360ControllersWindow": { "getDriverText": "Descarga el driver", - "macInstructions2Text": "Par doparar sensa fiło i controładori, A te serve anca el resevidor\nche'l riva co l''Xbox 360 Wireless Controller par Windows'.\nUn resevidor el te parmete de conétar fin a 4 controładori.\n\nInportante: i resevidori de terse parti no i funsionarà miga co 'sto driver;\nsegùrate che'l to resevidor el sipia 'Microsoft' e miga 'XBOX 360'.\nŁa Microsoft no łi vende pì destacài, donca te servirà par forsa cheło\nvendesto insebre co'l controłador, o senò, proa sercar so Ebay.\n\nSe te cati ùtiłe el driver, ciapa in considerasion de farghe na\ndonasion a'l só dezviłupador so 'sto sito.", + "macInstructions2Text": "Par doparar sensa fiło i controładori, te serve anca el resevidor\nche'l riva co l''Xbox 360 Wireless Controller par Windows'.\nUn resevidor el te parmete de conétar fin a 4 controładori.\n\nInportante: i resevidori de terse parti no i funsionarà miga co 'sto driver;\nsegùrate che'l to resevidor el sipia 'Microsoft' e miga 'XBOX 360'.\nŁa Microsoft no łi vende pì destacài, donca te servirà par forsa cheło\nvendesto insebre co'l controłador, o senò, proa sercar so Ebay.\n\nSe te cati ùtiłe el driver, ciapa in considerasion de farghe na\ndonasion a'l só dezviłupador so 'sto sito.", "macInstructionsText": "Per doparar i controładori co'l fiło de ła Xbox 360, te ghè\nda instałar el driver Mac disponìbiłe so'l link cuà soto.\nEl funsiona co anbo i controładori, co'l fiło o sensa.", "ouyaInstructionsText": "Par doparar so Bombsquad un controłador de l'Xbox 360 co'l fiło,\ntàcheło sù inte ła porta USB de’l to dispozidivo. Te połi anca\ntacar sù pì controładori insenbre doparando un hub USB.\n\nPar doparar i controładori sensa fiło invese, te serve un resevidor\nde segnałe. Te połi catarlo, o rento ła scàtoła \"Controładori sensa fiło\nXbox 360 par Windows\", o vendesto a parte. Caun resevidor el và tacà so\nna porta USB e el te parmete de conétar fin a 4 controładori.", "titleText": "Doparar un controłador Xbox 360 co ${APP_NAME}:" }, "yesAllowText": "Sì, parmeti!", "yourBestScoresText": "I to punteji mejo", - "yourBestTimesText": "I to tenpi mejo" + "yourBestTimesText": "I to tenpi mejo", + "yourPrizeText": "El to premio:" } \ No newline at end of file diff --git a/dist/ba_data/data/languages/vietnamese.json b/dist/ba_data/data/languages/vietnamese.json index 6165104b..940c04c1 100644 --- a/dist/ba_data/data/languages/vietnamese.json +++ b/dist/ba_data/data/languages/vietnamese.json @@ -2,62 +2,69 @@ "accountSettingsWindow": { "accountNameRules": "Tên tài khoản không được chứa biểu tượng cảm xúc và kí tự đặc biệt", "accountProfileText": "Tài Khoản", - "accountsText": "Tài khoản", - "achievementProgressText": "Huy Hiệu:${COUNT} trong ${TOTAL}", - "campaignProgressText": "Tiến trình(khó) :${PROGRESS}", + "accountsText": "Tài Khoản", + "achievementProgressText": "Thành tựu: ${COUNT} trên ${TOTAL}", + "campaignProgressText": "Tiến độ chiến dịch [Khó]: ${PROGRESS}", "changeOncePerSeason": "Bạn chỉ có thể thay đổi một lần mỗi mùa.", - "changeOncePerSeasonError": "Bạn có thể đổi nó vào mùa sau (${NUM} days)", + "changeOncePerSeasonError": "Bạn chỉ có thể đổi vào mùa sau (${NUM} ngày)", + "createAnAccountText": "Tạo tài khoản", "customName": "Tên tùy chỉnh", + "deleteAccountText": "Xóa Tài khoản", + "googlePlayGamesAccountSwitchText": "Nếu bạn muốn sử dụng một tài khoản Google khác,\nhãy sử dụng ứng dụng Google Play Games để đổi.", "linkAccountsEnterCodeText": "Nhập Mã", - "linkAccountsGenerateCodeText": "Tạo mã", + "linkAccountsGenerateCodeText": "Tạo Mã", "linkAccountsInfoText": "(Chia sẽ dữ liệu giữa các máy)", - "linkAccountsInstructionsNewText": "Để kết nối hai tài khoản, tạo mã trên tài khoản thứ\nnhất rồi nhập vào tài khoản thứ hai. Dữ liệu trên tài\nkhoản thứ hai sẽ được đồng bộ.\n(Dữ liệu trên tài khoản thứ nhất sẽ bị xóa vĩnh viễn)\n\nBạn có thể kết nối lên đến ${COUNT} tài khoản.\n\nLƯU Ý: chỉ kết nối tài khoản của bạn;\nNếu bạn kết nối tài khoản của người khác thì\ncả hai người sẽ không thể trực tuyến cùng một lúc.", + "linkAccountsInstructionsNewText": "Để liên kết hai tài khoản, tạo mã trên tài khoản thứ\nnhất và nhập vào tài khoản thứ hai. Dữ liệu trên tài\nkhoản thứ hai sẽ được đồng bộ.\n(Dữ liệu trên tài khoản thứ nhất sẽ bị xóa vĩnh viễn)\n\nBạn có thể kết nối lên đến ${COUNT} tài khoản.\n\nLƯU Ý: chỉ kết nối tài khoản của bạn;\nNếu bạn kết nối tài khoản của người khác\ncả hai sẽ không thể chơi trực tuyến cùng một lúc.", "linkAccountsInstructionsText": "Để kết nối 2 tài khoản khác nhau, tạo mã ở\nmột máy và nhập mã ở máy còn lại.\nDữ liệu sẽ được liên kết giữa các máy\nBạn có thể kết nối đến ${COUNT} thiết bị.\n\nQUAN TRỌNG: Chỉ kết nối tài khoản của bạn!\nNếu bạn kết nối tài khoản với bạn bè\nbạn không thể chơi cùng một lúc!\n\nNgoài ra: nó không thể hoàn tác, nên hãy cẩn thận!", - "linkAccountsText": "kết nối máy khác", - "linkedAccountsText": "Tài khoản kết nối:", + "linkAccountsText": "Liên kết Tài khoản", + "linkedAccountsText": "Tài khoản đã liên kết:", + "manageAccountText": "Quản lý Tài khoản", "nameChangeConfirm": "Đổi tên tài khoản thành ${NAME}?", - "resetProgressConfirmNoAchievementsText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nngoại trừ số tiền của ban\nđiều này không thể hoàn tác. Chắc chắn?", - "resetProgressConfirmText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nvà cả huy hiệu\nngoại trừ số tiền của ban\nđiều này không thể hoàn tác. Chắc chắn?", - "resetProgressText": "Xóa dữ liệu", - "setAccountName": "Đặt lại tên tài khoản", - "setAccountNameDesc": "Chọn tên cho tài khoản của bạn.\nBạn có thể dùng tên từ tài khoản đã kết nối\nhoặc tạo tên khác.", - "signInInfoText": "Đăng nhập để lưu dữ liệu giữa các máy \nchơi online và tham gia giải đấu", + "resetProgressConfirmNoAchievementsText": "Việc này sẽ đặt lại tiến trình của bạn \n(ngoại trừ vé của bạn).\nĐiều này không thể hoàn tác. Xác nhận?", + "resetProgressConfirmText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nbao gồm cả thành tựu,\n(ngoại trừ vé của bạn). Điều này không thể hoàn tác. \nXác nhận?", + "resetProgressText": "Xóa Tiến trình", + "setAccountName": "Đặt lại Tên Tài khoản", + "setAccountNameDesc": "Chọn tên hiển thị cho tài khoản của bạn.\nBạn có thể dùng tên từ tài khoản đã liên kết\nhoặc tạo tên mới.", + "signInInfoText": "Đăng nhập để thu thập vé, chơi trực tuyến, \nvà lưu dữ liệu giữa các thiết bị.", "signInText": "Đăng Nhập", - "signInWithDeviceInfoText": "(một tài khoản ở máy khác sẽ tự động đăng nhập)", - "signInWithDeviceText": "đăng nhập bằng tài khoản của máy tính", + "signInWithAnEmailAddressText": "Đăng nhập bằng địa chỉ email", + "signInWithDeviceInfoText": "(thiết bị này chỉ cho phép tài khoản mặc định)", + "signInWithDeviceText": "Đăng nhập bằng tài khoản thiết bị", "signInWithGameCircleText": "Đăng nhập với Game Circle", "signInWithGooglePlayText": "đăng nhập bằng google chơi trò chơi", "signInWithTestAccountInfoText": "(loại tài khoản đặc biệt; chỉ đăng nhập trên máy này)", "signInWithTestAccountText": "Đăng nhập bằng tài khoản máy tính", - "signInWithV2InfoText": "(một tài khoản hoạt động trên tất cả các nền tảng)", - "signInWithV2Text": "Đăng nhập bằng tài khoản BombSquad", + "signInWithText": "Đăng nhập bằng ${SERVICE}", + "signInWithV2InfoText": "(tài khoản hoạt động trên tất cả các nền tảng)", + "signInWithV2Text": "Đăng nhập bằng tài khoản ${APP_NAME}", "signOutText": "Đăng Xuất", "signingInText": "Đang đăng nhập...", - "signingOutText": "Đang Đăng xuất...", + "signingOutText": "Đang đăng xuất...", "testAccountWarningCardboardText": "Cảnh Báo: bạn đang Đang Chơi tài Khoản 'Thử'\ndữ liệu sẽ bị thay thế bởi tài khoản\nvà nó sẽ đè lên TK thử\n\nBây giờ bạn sẽ có tất cả tiền trong Game\n(Bạn hãy chơi Boomsquad Pro miẽn phí", "testAccountWarningOculusText": "Cảnh báo:bạn đang đăng nhập với kí tự chữ.Chúng sẽ được thay thế bằng kí tự ô.\nTài khoản này sẽ được dùng để mua vé và các tính năng khác.\n\n\nVà bây giờ bạn sẽ được học cách thu thập các vé trong game.\n(Mách nhỏ bạn có thể cập nhật BombSquad Pro miễn phí bằng vé)", "testAccountWarningText": "Cảnh báo:bạn đang đăng nhập bằng tài khoản thử nghiệm.\nTài khoản này sẽ xác thưc thiết bị của bạn và sẽ xóa mất dữ liệu.\n(vì vậy chúng tôi khuyên bạn đừng bỏ nhiều thời gian thu thập \nhoặc mở các vật phẩm trong game.\n\nHãy dùng phiên bản bày bán để có tài khoản thực(vd:Game-Center,Google Plus,...)\nViệc này sẽ giúp bạn lưu trữ các quá trình \nkhi chơi bằng dữ liệu đám mây \nvà bạn có thể chơi trên các thiết bị khác.", - "ticketsText": "Số Tiền: ${COUNT}", + "ticketsText": "Vé: ${COUNT}", "titleText": "Tài Khoản", - "unlinkAccountsInstructionsText": "Chọn tài khoản để hủy kết nối", - "unlinkAccountsText": "Hủy kết nối", + "unlinkAccountsInstructionsText": "Chọn tài khoản để hủy liên kết", + "unlinkAccountsText": "Hủy liên kết Tài khoản", + "unlinkLegacyV1AccountsText": "Hủy liên kết tài khoản (V1)", "v2LinkInstructionsText": "Sử dụng liên kết này để tạo tài khoản hoặc đăng nhập.", "viaAccount": "(qua tài khoản ${NAME})", - "youAreSignedInAsText": "Bạn đang đăng nhập tài khoản:" + "youAreSignedInAsText": "Bạn đang đăng nhập bằng:" }, - "achievementChallengesText": "Các thành tựu đạt được.", + "achievementChallengesText": "Thành tựu Thử thách", "achievementText": "Thành tựu", "achievements": { "Boom Goes the Dynamite": { "description": "Tiêu diệt 3 kẻ xấu bằng TNT", - "descriptionComplete": "Giết 3 kẻ xấu với TNT", - "descriptionFull": "Tiêu diệt 3 kẻ xấu bằng TNT với ${LEVEL}", + "descriptionComplete": "Tiêu diệt 3 kẻ xấu bằng TNT", + "descriptionFull": "Tiêu diệt 3 kẻ xấu bằng TNT trong ${LEVEL}", "descriptionFullComplete": "Tiêu diệt 3 kẻ xấu bằng TNT với ${LEVEL}", - "name": "Bom tạo ra sức mạnh" + "name": "Bom Tạo Ra Sức Mạnh" }, "Boxer": { "description": "Chiến thắng mà không sử dụng bom", - "descriptionComplete": "Đã chiến thắng mà không sử dụng bom", + "descriptionComplete": "Chiến thắng mà không sử dụng bom", "descriptionFull": "Hoàn thành ${LEVEL} mà không sử dụng bom", "descriptionFullComplete": "Hoàn thành ${LEVEL} mà không sử dụng bom", "name": "Tay đấm xuất sắc" @@ -65,243 +72,243 @@ "Dual Wielding": { "descriptionFull": "Kết nối 2 điều khiển (thiết bị hoặc ứng dụng)", "descriptionFullComplete": "Kết nối 2 điều khiển (thiết bị hoặc ứng dụng)", - "name": "Gấp đôi điều khiển" + "name": "Song Kiếm" }, "Flawless Victory": { - "description": "Chiến thắng mà không đánh đối thủ", - "descriptionComplete": "Đã chiến thắng mà không đánh đối thủ", - "descriptionFull": "Nhận được ${LEVEL} mà không đánh đối thủ", - "descriptionFullComplete": "Đã thắng ${LEVEL} mà không đánh đối thủ", - "name": "Chiến thắng vinh quang" + "description": "Chiến thắng mà không nhận sát thương", + "descriptionComplete": "Chiến thắng mà không nhận sát thương", + "descriptionFull": "Chiến thắng ${LEVEL} mà không nhận sát thương", + "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không nhận sát thương", + "name": "Chiến thắng Hoàn hảo" }, "Free Loader": { - "descriptionFull": "Chơi Đánh đơn với 2+ người chơi", - "descriptionFullComplete": "Chơi Đánh đơn với 2+ người chơi", - "name": "Chơi Vô Hạn" + "descriptionFull": "Chơi một trận Đánh đơn với 2+ người chơi", + "descriptionFullComplete": "Chơi một trận Đánh đơn với 2+ người chơi", + "name": "Cuộc chiến Đơn độc" }, "Gold Miner": { "description": "Tiêu diệt 6 kẻ xấu bằng mìn", - "descriptionComplete": "Đã tiêu diệt 6 kẻ xấu bằng mìn", - "descriptionFull": "Tiêu diệt 6 kẻ xấu bằng mìn trên ${LEVEL}", - "descriptionFullComplete": "Đã tiêu diệt 6 kẻ xấu bằng mìn trên ${LEVEL}", - "name": "Người đào vàng" + "descriptionComplete": "Tiêu diệt 6 kẻ xấu bằng mìn", + "descriptionFull": "Tiêu diệt 6 kẻ xấu bằng mìn trong ${LEVEL}", + "descriptionFullComplete": "Tiêu diệt 6 kẻ xấu bằng mìn trong ${LEVEL}", + "name": "Kẻ Đào vàng" }, "Got the Moves": { - "description": "Chiến thắng mà không đấm đối thủ hoặc sử dụng bom", - "descriptionComplete": "Đã thắng mà không đấm đối thủ hoặc sử dụng bom", - "descriptionFull": "Nhận được ${LEVEL} mà không đấm đối thủ hoặc sử dụng bom", - "descriptionFullComplete": "Đã thắng ${LEVEL} mà không đắm đối thủ hoặc không sử đụng bom", - "name": "Hãy di chuyển" + "description": "Chiến thắng mà không sử dụng nắm đấm hoặc bom", + "descriptionComplete": "Chiến thắng mà không sử dụng nắm đấm hoặc bom", + "descriptionFull": "Chiến thắng ${LEVEL} mà không sử dụng nắm đấm hoặc bom", + "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không sử dụng nắm đấm hoặc bom", + "name": "Bước chân Thanh thoát" }, "In Control": { - "descriptionFull": "Kết nối với điều khiển (thiết bị hoặc ứng dụng)", - "descriptionFullComplete": "Kết nối với điều khiển (thiết bị hoặc ứng dụng)", - "name": "Trong điều khiển" + "descriptionFull": "Kết nối điều khiển (thiết bị hoặc ứng dụng)", + "descriptionFullComplete": "Kết nối điều khiển (thiết bị hoặc ứng dụng)", + "name": "Trong Tầm Kiểm Soát" }, "Last Stand God": { "description": "Ghi 1000 điểm", - "descriptionComplete": "Đã ghi được 1000 điểm", - "descriptionFull": "Ghi 1000 điểm trên ${LEVEL}", - "descriptionFullComplete": "Đã ghi 1000 điểm trên ${LEVEL}", - "name": "${LEVEL} Thánh" + "descriptionComplete": "Ghi 1000 điểm", + "descriptionFull": "Ghi 1000 điểm trong ${LEVEL}", + "descriptionFullComplete": "Ghi 1000 điểm trong ${LEVEL}", + "name": "Bậc Thầy ${LEVEL}" }, "Last Stand Master": { "description": "Ghi 250 điểm", "descriptionComplete": "Đạt 250 điểm", - "descriptionFull": "Điểm 250 trong vòng ${LEVEL}", - "descriptionFullComplete": "Đạt 250 điểm trong vòng ${LEVEL}", - "name": "Sư phụ của vòng ${LEVEL}" + "descriptionFull": "Ghi 250 điểm trong ${LEVEL}", + "descriptionFullComplete": "Đạt 250 điểm trong ${LEVEL}", + "name": "Nắm vững ${LEVEL}" }, "Last Stand Wizard": { - "description": "Điểm đạt 500", + "description": "Ghi 500 điểm", "descriptionComplete": "Đạt 500 điểm", - "descriptionFull": "Đạt 500 điểm tại ${LEVEL}", - "descriptionFullComplete": "Đạt 500 điểm tại ${LEVEL}", - "name": "${LEVEL} Wizard" + "descriptionFull": "Ghi 500 điểm trong ${LEVEL}", + "descriptionFullComplete": "Đạt 500 điểm trong ${LEVEL}", + "name": "Thông thạo ${LEVEL}" }, "Mine Games": { - "description": "Giết 3 kẻ xấu vứi land-mines", - "descriptionComplete": "Giết 3 kẻ xấu với land-mines", - "descriptionFull": "Giết 3 kẻ xấu với land-mines tại ${LEVEL}", - "descriptionFullComplete": "Giết 3 kẻ xấu với land-mines tại ${LEVEL}", - "name": "Trò chơi Mine" + "description": "Tiêu diệt 3 kẻ xấu bằng mìn", + "descriptionComplete": "Tiêu diệt 3 kẻ xấu bằng mìn", + "descriptionFull": "Tiêu diệt 3 kẻ xấu bằng mìn trong ${LEVEL}", + "descriptionFullComplete": "Tiêu diệt 3 kẻ xấu bằng mìn trong ${LEVEL}", + "name": "Minesweeper" }, "Off You Go Then": { - "description": "Ném 3 đối thủ khỏi bản đồ", - "descriptionComplete": "Ném 3 kẻ xấu ra khỏi bản đồ", - "descriptionFull": "Ném 3 kẻ xấu ra khỏi bản đồ tại ${LEVEL}", - "descriptionFullComplete": "Ném 3 kẻ xấu ra khỏi bản đồ tại ${LEVEL}", - "name": "Đến Ai Tiếp Theo" + "description": "Ném 3 kẻ xấu xuống vực", + "descriptionComplete": "Ném 3 kẻ xấu xuống vực", + "descriptionFull": "Ném 3 kẻ xấu xuống vực trong ${LEVEL}", + "descriptionFullComplete": "Ném 3 kẻ xấu xuống vực trong ${LEVEL}", + "name": "Tiễn Khách" }, "Onslaught God": { - "description": "Đạt 5000 điểm", + "description": "Ghi 5000 điểm", "descriptionComplete": "Đạt 5000 điểm", - "descriptionFull": "Đạt 5000 điểm tại ${LEVEL}", - "descriptionFullComplete": "Đạt 5000 điểm tại ${LEVEL}", - "name": "${LEVEL} thánh" + "descriptionFull": "Ghi 5000 điểm trong ${LEVEL}", + "descriptionFullComplete": "Đạt 5000 điểm trong ${LEVEL}", + "name": "Bậc thầy ${LEVEL}" }, "Onslaught Master": { - "description": "Đạt 500 điểm", + "description": "Ghi 500 điểm", "descriptionComplete": "Đạt 500 điểm", - "descriptionFull": "Đạt 500 điểm tại ${LEVEL}", - "descriptionFullComplete": "Đạt 500 điểm tại ${LEVEL}", - "name": "${LEVEL} Sư phụ" + "descriptionFull": "Ghi 500 điểm trong ${LEVEL}", + "descriptionFullComplete": "Đạt 500 điểm trong ${LEVEL}", + "name": "Nắm vững ${LEVEL}" }, "Onslaught Training Victory": { - "description": "Thắng tất cả các ải", - "descriptionComplete": "Thắng tất cả các ải", - "descriptionFull": "Thắng tất cả các ải tại ${LEVEL}", - "descriptionFullComplete": "Thắng tất cả các ải tại ${LEVEL}", + "description": "Thắng tất cả các vòng", + "descriptionComplete": "Thắng tất cả các vòng", + "descriptionFull": "Thắng tất cả các vòng trong ${LEVEL}", + "descriptionFullComplete": "Thắng tất cả các vòng trong ${LEVEL}", "name": "${LEVEL} Chiến thắng" }, "Onslaught Wizard": { - "description": "Đạt 1000 điểm", + "description": "Ghi 1000 điểm", "descriptionComplete": "Đạt 1000 điểm", - "descriptionFull": "Đạt 1000 điểm tại ${LEVEL}", - "descriptionFullComplete": "Đạt 1000 điểm tại ${LEVEL}", - "name": "${LEVEL} phù thủy" + "descriptionFull": "Ghi 1000 điểm trong ${LEVEL}", + "descriptionFullComplete": "Đạt 1000 điểm trong ${LEVEL}", + "name": "Thông thạo ${LEVEL}" }, "Precision Bombing": { - "description": "Thắng mà không cần powerups", - "descriptionComplete": "Thắng mà không cần powerups", - "descriptionFull": "Thắng tại ${LEVEL} mà không cần powerups", - "descriptionFullComplete": "Hoàn thành ${LEVEL} mà không sử dụng Power-ups", - "name": "Tự Tin Ném Bom" + "description": "Chiến thắng mà không sử dụng vật phẩm", + "descriptionComplete": "Chiến thắng mà không sử dụng vật phẩm", + "descriptionFull": "Chiến thắng trong ${LEVEL} mà không sử dụng vật phẩm", + "descriptionFullComplete": "Chiến thắng trong ${LEVEL} mà không sử dụng vật phẩm", + "name": "Ném bom Chiến lược" }, "Pro Boxer": { "description": "Thắng mà không sử dụng bom", "descriptionComplete": "Thắng mà không sử dụng bom", "descriptionFull": "Hoàn thành ${LEVEL} không sử dụng bom", "descriptionFullComplete": "Hoàn thành ${LEVEL} không sử dụng bom", - "name": "Đấm Bốc Chuyên Nhiệp" + "name": "Đấm Bốc Chuyên Nghiệp" }, "Pro Football Shutout": { - "description": "Thắng mà không để đội bên ghi điểm", - "descriptionComplete": "Thắng mà không để đội bên ghi điểm", + "description": "Chiến thắng mà không để đội đối thủ ghi điểm", + "descriptionComplete": "Chiến thắng mà không để đội đối thủ ghi điểm", "descriptionFull": "Hoàn thành ${LEVEL} mà không để đội bên ghi điểm", - "descriptionFullComplete": "Hoàn thành ${LEVEL} mà không để đội bên ghi điểm", - "name": "Xuất Sắc ${LEVEL}" + "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không để đội đối thủ ghi điểm", + "name": "${LEVEL} Chuyên nghiệp" }, "Pro Football Victory": { - "description": "Hoàn thành vòng", - "descriptionComplete": "Hoàn thành vòng", - "descriptionFull": "Hoàn thành vòng ${LEVEL}", - "descriptionFullComplete": "Hoàn thành vòng ${LEVEL}", + "description": "Chiến thắng", + "descriptionComplete": "Chiến thắng", + "descriptionFull": "Chiến thắng trong ${LEVEL}", + "descriptionFullComplete": "Chiến thắng trong ${LEVEL}", "name": "Chiến thắng ${LEVEL}" }, "Pro Onslaught Victory": { - "description": "Đánh bại tất cả", - "descriptionComplete": "Đánh bại tất cả", - "descriptionFull": "Đánh bại tất cả ở ${LEVEL}", - "descriptionFullComplete": "Đánh bại tất cả ở ${LEVEL}", - "name": "Chiến thang ${LEVEL}" + "description": "Thắng tất cả các vòng", + "descriptionComplete": "Thắng tất cả các vòng", + "descriptionFull": "Thắng tất cả các vòng trong ${LEVEL}", + "descriptionFullComplete": "Thắng tất cả các vòng trong ${LEVEL}", + "name": "Chiến thắng ${LEVEL}" }, "Pro Runaround Victory": { "description": "Hoàn thành tất cả các vòng", - "descriptionComplete": "Đã hoàn thành tất cả các vòng", - "descriptionFull": "Hoàn thành tất cả các vòng tại ${LEVEL}", - "descriptionFullComplete": "Đã hoàn thành tất cả các vòng tại ${LEVEL}", + "descriptionComplete": "Hoàn thành tất cả các vòng", + "descriptionFull": "Hoàn thành tất cả các vòng trong ${LEVEL}", + "descriptionFullComplete": "Hoàn thành tất cả các vòng trong ${LEVEL}", "name": "${LEVEL} Chiến thắng" }, "Rookie Football Shutout": { - "description": "Thắng mà không để đối phương ghi bàn nào", - "descriptionComplete": "Chiến thắng mà không để kẻ xấu ghi điểm", - "descriptionFull": "Chiến thắng ${LEVEL} mà không để kẻ xấu ghi điểm", - "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không để kẻ xấu ghi điểm", - "name": "${LEVEL} Bắn ra" + "description": "Chiến thắng mà không để đội đối thủ ghi điểm", + "descriptionComplete": "Chiến thắng mà không để đội đối thủ ghi điểm", + "descriptionFull": "Chiến thắng ${LEVEL} mà không để đội đối thủ ghi điểm", + "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không để đội đối thủ ghi điểm", + "name": "Chiến thắng ${LEVEL}" }, "Rookie Football Victory": { - "description": "Hoàn Thành Trò Chơi", - "descriptionComplete": "Hoàn Thành Trò Chơi", - "descriptionFull": "Hoàn Thành Trò Chơi ở ${LEVEL}", - "descriptionFullComplete": "Hoàn Thành Trò Chơi ở ${LEVEL}", + "description": "Chiến thắng", + "descriptionComplete": "Chiến thắng", + "descriptionFull": "Chiến thắng trong ${LEVEL}", + "descriptionFullComplete": "Chiến thắng trong ${LEVEL}", "name": "Chiến Thắng ${LEVEL}" }, "Rookie Onslaught Victory": { - "description": "Vượt qua tất cả vòng", - "descriptionComplete": "Vượt qua tất cả vòng", - "descriptionFull": "Vượt qua tất cả vòng ở ${LEVEL}", - "descriptionFullComplete": "Vượt qua tất cả vòng ở ${LEVEL}", + "description": "Chiến thắng tất cả các vòng", + "descriptionComplete": "Chiến thắng tất cả các vòng", + "descriptionFull": "Chiến thắng tất cả các vòng trong ${LEVEL}", + "descriptionFullComplete": "Chiến thắng tất cả các vòng trong ${LEVEL}", "name": "${LEVEL} Chiến thắng" }, "Runaround God": { - "description": "Đạt 2000 điểm", + "description": "Ghi 2000 điểm", "descriptionComplete": "Đạt 2000 điểm", - "descriptionFull": "Đạt 2000 điểm tại ${LEVEL}", - "descriptionFullComplete": "Đạt 2000 điểm tại ${LEVEL}", - "name": "${LEVEL} Thánh" + "descriptionFull": "Ghi 2000 điểm trong ${LEVEL}", + "descriptionFullComplete": "Ghi 2000 điểm trong ${LEVEL}", + "name": "${LEVEL} Bậc Thầy" }, "Runaround Master": { - "description": "Đạt 500 điểm", + "description": "Ghi 500 điểm", "descriptionComplete": "Đạt 500 điểm", - "descriptionFull": "Đạt 500 điểm tại ${LEVEL}", + "descriptionFull": "Ghi 500 điểm tại ${LEVEL}", "descriptionFullComplete": "Đạt 500 điểm tại ${LEVEL}", - "name": "${LEVEL} Sư phụ" + "name": "Nắm Vững ${LEVEL}" }, "Runaround Wizard": { - "description": "Đạt 1000 điểm", + "description": "Ghi 1000 điểm", "descriptionComplete": "Đạt 1000 điểm", - "descriptionFull": "Đạt 1000 điểm tại ${LEVEL}", - "descriptionFullComplete": "Đạt 1000 điểm tại ${LEVEL}", - "name": "${LEVEL} Phù thủy" + "descriptionFull": "Ghi 1000 điểm trong ${LEVEL}", + "descriptionFullComplete": "Đạt 1000 điểm trong ${LEVEL}", + "name": "${LEVEL} Thông Thạo" }, "Sharing is Caring": { - "descriptionFull": "Chia sẻ thành công trò chơi này với bạn bè", - "descriptionFullComplete": "Đã chia sẻ trò chơi này với bạn bè", - "name": "Chia sẻ là Quan tâm" + "descriptionFull": "Chia sẻ với bạn bè thành công", + "descriptionFullComplete": "Chia sẻ với bạn bè thành công", + "name": "Lá Lành Đùm Lá Rách" }, "Stayin' Alive": { "description": "Thắng mà không chết", "descriptionComplete": "Thắng mà không chết", "descriptionFull": "Thắng ${LEVEL} mà không chết", - "descriptionFullComplete": "Đã thắng ${LEVEL} mà không chết", - "name": "Sống sót" + "descriptionFullComplete": "Thắng ${LEVEL} mà không chết", + "name": "Sống Sót" }, "Super Mega Punch": { - "description": "Gây sát thương 100% với một cú đấm", - "descriptionComplete": "Gây sát thương 100% với một cú đấm", - "descriptionFull": "Gây sát thương 100% với một cú đấm trong ${LEVEL}", - "descriptionFullComplete": "Gây sát thương 100% với một cú đấm trong ${LEVEL}", - "name": "Cú đấm siêu hạng" + "description": "Gây 100% sát thương với một cú đấm", + "descriptionComplete": "Gây 100% sát thương với một cú đấm", + "descriptionFull": "Gây 100% sát thương với một cú đấm trong ${LEVEL}", + "descriptionFullComplete": "Gây 100% sát thương với một cú đấm ${LEVEL}", + "name": "Một Đấm Là Nằm" }, "Super Punch": { - "description": "Gây sát thương 50% với một cú đấm", - "descriptionComplete": "Gây sát thương 50% với một cú đấm", - "descriptionFull": "Gây sát thương 50% với một cú đấm trong ${LEVEL}", - "descriptionFullComplete": "Gây sát thương 50% với một cú đấm trong ${LEVEL}", + "description": "Gây 50% sát thương với một cú đấm", + "descriptionComplete": "Gây 50% sát thương với một cú đấm", + "descriptionFull": "Gây 50% sát thương với một cú đấm trong ${LEVEL}", + "descriptionFullComplete": "Gây 50% sát thương với một cú đấm trong ${LEVEL}", "name": "Siêu đấm" }, "TNT Terror": { - "description": "Giết 6 kẻ địch với TNT", - "descriptionComplete": "Giết 6 kẻ địch với TNT", - "descriptionFull": "Giết 6 kẻ địch với TNT trong ${LEVEL}", - "descriptionFullComplete": "Giết 6 kẻ địch với TNT trong ${LEVEL}", - "name": "Nỗi khiếp sợ TNT" + "description": "Tiêu diệt 6 kẻ xấu với TNT", + "descriptionComplete": "Tiêu diệt 6 kẻ xấu với TNT", + "descriptionFull": "Tiêu diệt 6 kẻ xấu với TNT trong ${LEVEL}", + "descriptionFullComplete": "Tiêu diệt 6 kẻ xấu với TNT trong ${LEVEL}", + "name": "Thuốc Nổ Tung" }, "Team Player": { - "descriptionFull": "Chơi cùng với 4+ người khác", - "descriptionFullComplete": "Chơi cùng với 4+ người khác", + "descriptionFull": "Bắt đầu một Trận đấu đội với 4+ người chơi", + "descriptionFullComplete": "Bắt đầu một Trận đấu đội với 4+ người chơi", "name": "Đồng đội" }, "The Great Wall": { - "description": "Chặn toàn bộ kẻ địch", - "descriptionComplete": "Chặn toàn bộ kẻ địch", - "descriptionFull": "Chặn toàn bộ kẻ địch trong ${LEVEL}", - "descriptionFullComplete": "Chặn toàn bộ kẻ địch trong ${LEVEL}", - "name": "Bức tường vĩ đại" + "description": "Chặn toàn bộ kẻ xấu", + "descriptionComplete": "Chặn toàn bộ kẻ xấu", + "descriptionFull": "Chặn toàn bộ kẻ xấu trong ${LEVEL}", + "descriptionFullComplete": "Chặn toàn bộ kẻ xấu trong ${LEVEL}", + "name": "Vạn Lý Trường Thành" }, "The Wall": { - "description": "Chặn tất cả kẻ địch", - "descriptionComplete": "Chặn tất cả kẻ địch", - "descriptionFull": "Chặn tất cả kẻ địch trong ${LEVEL}", + "description": "Chặn toàn bộ kẻ xấu", + "descriptionComplete": "Chặn toàn bộ kẻ xấu", + "descriptionFull": "Chặn toàn bộ kẻ xấu trong ${LEVEL}", "descriptionFullComplete": "Chặn tất cả kẻ địch trong ${LEVEL}", - "name": "Bức tường" + "name": "Bức Tường" }, "Uber Football Shutout": { - "description": "Chiến thấng mà không cho kẻ địch ghi điểm", - "descriptionComplete": "Chiến thấng mà không cho kẻ địch ghi điểm", - "descriptionFull": "Chiến thấng ${LEVEL} mà không cho kẻ địch ghi điểm", - "descriptionFullComplete": "Chiến thấng ${LEVEL} mà không cho kẻ địch ghi điểm", + "description": "Chiến thắng mà không để đội đối thủ ghi điểm", + "descriptionComplete": "Chiến thắng mà không để đội đối thủ ghi điểm", + "descriptionFull": "Chiến thắng ${LEVEL} mà không để đội đối thủ ghi điểm", + "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không để đội đối thủ ghi điểm", "name": "${LEVEL} Áp đảo" }, "Uber Football Victory": { @@ -312,215 +319,231 @@ "name": "${LEVEL} Chiến thắng" }, "Uber Onslaught Victory": { - "description": "Thắng tất cả các vòng", - "descriptionComplete": "Thấng tất cả các ải", - "descriptionFull": "Thấng tất cả các ải trong ${LEVEL}", - "descriptionFullComplete": "Thấng tất cả các ải trong ${LEVEL}", + "description": "Chiến thắng tất cả các vòng", + "descriptionComplete": "Chiến thắng tất cả các vòng", + "descriptionFull": "Chiến thắng tất cả các vòng trong ${LEVEL}", + "descriptionFullComplete": "Chiến thắng tất cả các vòng trong ${LEVEL}", "name": "${LEVEL} Chiến thấng" }, "Uber Runaround Victory": { - "description": "Thấng tất cả các ải", - "descriptionComplete": "Thấng tất cả các ải", - "descriptionFull": "Thấng tất cả các ải trong ${LEVEL}", - "descriptionFullComplete": "Thấng tất cả các ải trong ${LEVEL}", + "description": "Chiến thắng tất cả các vòng", + "descriptionComplete": "Chiến thắng tất cả các vòng", + "descriptionFull": "Chiến thắng tất cả các vòng trong ${LEVEL}", + "descriptionFullComplete": "Chiến thắng tất cả các vòng trong ${LEVEL}", "name": "${LEVEL} Chiến thắng" } }, - "achievementsRemainingText": "Các thành tựu tiếp theo:", - "achievementsText": "Các thành tựu", - "achievementsUnavailableForOldSeasonsText": "Xin lỗi , huy hiệu này không có ở mùa trước", + "achievementsRemainingText": "Thành tựu Còn lại:", + "achievementsText": "Thành tựu", + "achievementsUnavailableForOldSeasonsText": "Xin lỗi, chi tiết thành tựu không có sẵn ở mùa cũ.", "activatedText": "${THING} đã được kích hoạt.", "addGameWindow": { - "getMoreGamesText": "Thêm các thể loại chơi", - "titleText": "Thêm trận đấu" + "getMoreGamesText": "Thêm chế độ chơi", + "titleText": "Thêm Trò chơi" }, + "addToFavoritesText": "Thêm vào Mục yêu thích", + "addedToFavoritesText": "Đã thêm '${NAME}' vào Mục yêu thích.", + "allText": "Tất cả", "allowText": "Cho phép", "alreadySignedInText": "Tài khoản của bạn đã được đăng nhập trên thiết bị khác;\nhãy đổi tài khoản hoặc đăng xuất khỏi thiết bị khác\nvà thử lại.", - "apiVersionErrorText": "Không thể tải ${NAME}; phiên bản ${VERSION_USED}; yêu cầu ${VERSION_REQUIRED}.", + "apiVersionErrorText": "Không thể tải ${NAME}; phiên bản của bản Mod này là ${VERSION_USED}; yêu cầu phiên bản ${VERSION_REQUIRED}.", + "applyText": "Áp dụng", + "areYouSureText": "Xác nhận?", "audioSettingsWindow": { - "headRelativeVRAudioInfoText": "(tự động bật chức năng này khi cắm tai phone vào)", - "headRelativeVRAudioText": "Tai nghe VR Audio", - "musicVolumeText": "Mức âm lượng", - "soundVolumeText": "Mức độ âm thanh nền", - "soundtrackButtonText": "Các bản nhạc khác", - "soundtrackDescriptionText": "(sử dụng bài nhạc của bạn khi đang chơi game)", + "headRelativeVRAudioInfoText": "(tự động bật chức năng này khi cắm tai nghe )", + "headRelativeVRAudioText": "Âm thanh tai nghe VR", + "musicVolumeText": "Âm lượng Nhạc", + "soundVolumeText": "Âm lượng Âm thanh", + "soundtrackButtonText": "Nhạc Nền", + "soundtrackDescriptionText": "(thiết lập nhạc của bạn trong trò chơi)", "titleText": "Âm thanh" }, "autoText": "Tự động", "backText": "Quay lại", - "banThisPlayerText": "Khóa người chơi này", - "bestOfFinalText": "Đứng đầu ${COUNT} ván", - "bestOfSeriesText": "Đứng đầu ${COUNT} ván", + "banThisPlayerText": "Cấm Người chơi", + "bestOfFinalText": "Tổng kết ${COUNT} ván", + "bestOfSeriesText": "Đứng đầu ${COUNT} ván:", "bestRankText": "Thành tích cao nhất của bạn #${RANK}", "bestRatingText": "Đánh giá cao nhất của bạn ${RATING}", "bombBoldText": "BOM", "bombText": "Bom", "boostText": "Tăng Lực", - "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} sẽ từ được điều chỉnh.", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} sẽ tự được điều chỉnh.", "buttonText": "Nút", - "canWeDebugText": "Bạn có muốn BombSquad tự động gửi bug,lỗi \ngame và thồn tin cơ bản cho nhà phát triển?\n\nNhững dữ liệu này không chứa thông tin \ncá nhân và chúng giúp game chạy mượt và không gặp bug.", + "canWeDebugText": "Bạn có muốn ${APP_NAME} tự động báo cáo\nlỗi, sự cố và thông tin sử dụng cơ bản cho nhà phát triển không?\n\nDữ liệu này không chứa thông tin cá nhân và giúp\ntrò chơi chạy ổn định và không có lỗi.", "cancelText": "Hủy", - "cantConfigureDeviceText": "Rất tiếc,${DEVICE} không định cấu hình được", + "cantConfigureDeviceText": "Rất tiếc, ${DEVICE} không thể điều chỉnh được", "challengeEndedText": "Thử thách này đã kết thúc.", "chatMuteText": "Ẩn trò chuyện", "chatMutedText": "Đã ẩn trò chuyện", "chatUnMuteText": "Khôi phục trò chuyện", - "choosingPlayerText": "<đang chọn nhân vật>", + "chests": { + "prizeOddsText": "Xác Suất", + "reduceWaitText": "Giảm Thời Gian Chờ", + "slotDescriptionText": "Đây là ô chứa rương.\n\nKiếm rương bằng cách chơi chiến dịchl\nđạt thứ hạng trong giải đấu, và hoàn thành \nthành tựu.", + "slotText": "Ô Số ${NUM}", + "slotsFullWarningText": "CẢNH BÁO: Đã hết ô chứa rương.\nRương bạn nhận được thêm sẽ bị mất.", + "unlocksInText": "Mở khóa sau" + }, + "choosingPlayerText": "<đang chọn>", + "claimText": "Nhận", + "codesExplainText": "Mã được nhà phát triển cung cấp để\nchẩn đoán và khắc phục các vấn đề về tài khoản.", "completeThisLevelToProceedText": "Bạn phải hoàn thành \ncấp độ này để tiếp tục!", - "completionBonusText": "Hoàn thành phần thưởng", + "completionBonusText": "Phần Thưởng Hoàn Thành", "configControllersWindow": { - "configureControllersText": "Điều chỉnh bộ điều khiển", + "configureControllersText": "Điều chỉnh Điều khiển", "configureKeyboard2Text": "Điều chỉnh bàn phím P2", "configureKeyboardText": "Điều chỉnh bàn phím", - "configureMobileText": "Thiết bị di động đang là bộ điều khiển", - "configureTouchText": "Điều chỉnh màn hình cảm ứng", + "configureMobileText": "Điều khiển Thiết bị di động", + "configureTouchText": "Điều chỉnh Màn hình cảm ứng", "ps3Text": "Bộ điều khiển PS3", - "titleText": "Các bộ điều khiển", + "titleText": "Bộ điều khiển", "wiimotesText": "Bộ điều khiển Wii", "xbox360Text": "Bộ điều khiển Xbox 360" }, "configGamepadSelectWindow": { - "androidNoteText": "Lưu ý:bộ điều khiển sẽ hỗ trợ khác nhau tùy theo thiết bị và hệ thống Android", + "androidNoteText": "Lưu ý: bộ điều khiển sẽ hỗ trợ khác nhau tùy theo thiết bị và hệ thống Android", "pressAnyButtonText": "Nhấn phím bất kỳ trên bộ điều khiển \nmà bạn muốn điều chỉnh....", - "titleText": "Điều chỉnh bộ điều khiển" + "titleText": "Điều chỉnh Bộ điều khiển" }, "configGamepadWindow": { - "advancedText": "Phát triển", - "advancedTitleText": "Cài đặt bộ điều khiển", - "analogStickDeadZoneDescriptionText": "(Bật cái này nếu nhân vật của bạn trượt khi bạn nhấn cần điều hướng)", - "analogStickDeadZoneText": "Điểm chết trên Điều khiển Analog", - "appliesToAllText": "(áp dụng cho tất cả các bộ điều khiển với kiểu này)", - "autoRecalibrateDescriptionText": "(bật cái này nếu nhân vật không chạy được)", + "advancedText": "Nâng Cao", + "advancedTitleText": "Cài đặt Bộ điều khiển Nâng cao", + "analogStickDeadZoneDescriptionText": "(Bật nếu nhân vật của bạn 'trượt' khi bạn nhấn cần điều hướng)", + "analogStickDeadZoneText": "Điểm chết Trên Cần điều khiển Analog", + "appliesToAllText": "(áp dụng cho tất cả cần điều khiển cùng kiểu)", + "autoRecalibrateDescriptionText": "(bật lên nếu nhân vật không chạy được tốc độ tối đa)", "autoRecalibrateText": "Tự Đông Hiệu Chỉnh Điều Khiển Analog", "axisText": "Trục", "clearText": "xóa", - "dpadText": "Màn Hình", - "extraStartButtonText": "Thêm nút Start", - "ifNothingHappensTryAnalogText": "Nếu không sử dụng được,thử thay thế nút điều hướng khác", - "ifNothingHappensTryDpadText": "Nếu không sử dụng được,thử thay thế D-pad", + "dpadText": "4 nút di chuyển", + "extraStartButtonText": "Nút Bắt đầu Khác", + "ifNothingHappensTryAnalogText": "Nếu không sử dụng được, thử thay thế bằng cần điều khiển.", + "ifNothingHappensTryDpadText": "Nếu không sử dụng được, thử thay thế bằng 4 nút di chuyển.", "ignoreCompletelyDescriptionText": "(ngăn chặn bộ điều khiển ảnh hưởng tới trò chơi hay menus)", - "ignoreCompletelyText": "Bỏ qua toàn bộ", + "ignoreCompletelyText": "Bỏ qua Toàn bộ", "ignoredButton1Text": "Bỏ qua Nút 1", "ignoredButton2Text": "Bỏ qua Nút 2", "ignoredButton3Text": "Bỏ qua Nút 3", "ignoredButton4Text": "Bỏ qua Nút 4", "ignoredButtonDescriptionText": "(dùng để ngăn nút 'home' hoặc 'sync' ảnh hưởng đến giao diện)", - "pressAnyAnalogTriggerText": "Nhấn bất kì nút trigger", - "pressAnyButtonOrDpadText": "Nhấn bất kì nút hay dpad nào...", + "pressAnyAnalogTriggerText": "Nhấn nút vật lý bất kỳ...", + "pressAnyButtonOrDpadText": "Nhấn nút hoặc 4 nút điều khiển bất kỳ...", "pressAnyButtonText": "Nhấn nút bất kỳ...", - "pressLeftRightText": "Nhấn nút trái hay phải...", - "pressUpDownText": "Nhấn nut lên hoặc xuống...", + "pressLeftRightText": "Nhấn trái hoặc phải...", + "pressUpDownText": "Nhấn lên hoặc xuống...", "runButton1Text": "Bật nút 1", "runButton2Text": "Bật nút 2", "runTrigger1Text": "Bật nút Trigger 1", "runTrigger2Text": "Bật nút Trigger 2", "runTriggerDescriptionText": "(nút Triggers có thể chạy với tốc độ khác nhau)", - "secondHalfText": "Sử dụng cái này để cấu hình nửa thứ hai\ncủa thiết bị 2 bộ điều khiển trong 1\nhiển thị như một bộ điều khiển duy nhất.", + "secondHalfText": "Sử dụng để cấu hình \nnửa thứ hai của 1 thiết bị \ncó 2 bộ điều khiển.", "secondaryEnableText": "Kích hoạt", "secondaryText": "Bộ điều khiển thứ hai", - "startButtonActivatesDefaultDescriptionText": "(tắt cái này đi nếu nút bắt đầu của bạn có nhiều nút 'menu' hơn)", - "startButtonActivatesDefaultText": "Nút bắt đầu kích hoạt widget mặc định", - "titleText": "Thiết lập điều khiển", - "twoInOneSetupText": "Thiết lập cần điều khiển 2-trong-1", - "uiOnlyDescriptionText": "(ngăn bộ điều khiển này thực sự tham gia một trò chơi)", - "uiOnlyText": "Giới hạn sử dụng Menu", - "unassignedButtonsRunText": "Tất cả các nút chưa được gắn Chạy", + "startButtonActivatesDefaultDescriptionText": "(tắt đi nếu nút bắt đầu của bạn có chức năng như nút 'menu')", + "startButtonActivatesDefaultText": "Nút bắt đầu Kích hoạt Widget Mặc định", + "titleText": "Thiết lập Điều khiển", + "twoInOneSetupText": "Thiết lập Cần điều khiển 2-trong-1", + "uiOnlyDescriptionText": "(ngăn bộ điều khiển này tham gia trò chơi)", + "uiOnlyText": "Giới hạn cho Sử dụng điều khiển màn hình", + "unassignedButtonsRunText": "Nút chưa được gán sẽ là nút Chạy", "unsetText": "", "vrReorientButtonText": "Nút định hướng VR" }, "configKeyboardWindow": { "configuringText": "Cấu hình ${DEVICE}", - "keyboard2NoteText": "Lưu ý: hầu hết các bàn phím chỉ có thể đăng ký một vài phím bấm tại\nmột lần, vì vậy có một trình phát bàn phím thứ hai có thể hoạt động tốt hơn\nnếu có một bàn phím riêng kèm theo để họ sử dụng.\nLưu ý rằng bạn vẫn sẽ cần gán các khóa duy nhất cho\nHai người chơi ngay cả trong trường hợp đó." + "keyboard2NoteText": "Lưu ý: hầu hết các bàn phím chỉ có thể nhận một vài phím trong \nmột lần, vì vậy người chơi bàn phím thứ hai nên có một bàn phím riêng \nsẽ mang lại trải nghiệm sử dụng tốt hơn.\nLưu ý rằng bạn vẫn sẽ cần gán nút khác nhau cho\nhai bàn phím." }, "configTouchscreenWindow": { - "actionControlScaleText": "Độ lớn phím hành động", - "actionsText": "Các hành động", - "buttonsText": "các nút", - "dragControlsText": "< di chuyển phím điều khiển để thay đổi vi trí chúng>", - "joystickText": "Phím xoay", - "movementControlScaleText": "Độ lớn phím di chuyển", + "actionControlScaleText": "Độ lớn Các nút Hành động", + "actionsText": "Hành động", + "buttonsText": "nút", + "dragControlsText": "< di chuyển phím điều khiển để thay đổi vi trí >", + "joystickText": "phím xoay", + "movementControlScaleText": "Độ lớn Phím Di chuyển", "movementText": "Di chuyển", - "resetText": "Chơi lại từ đầu", - "swipeControlsHiddenText": "Ân nút di chuyển", - "swipeInfoText": "Kiểu điều khiển 'Swipe'làm cho việc điều khiển dễ dàng hơn \nmà không cần nhìn phím", - "swipeText": "Trượt", - "titleText": "Điều chinh màn hình cảm ứng" + "resetText": "Mặc Định", + "swipeControlsHiddenText": "Ẩn Nút Di chuyển", + "swipeInfoText": "Điều khiển kiểu 'Lướt' cần thời gian làm quen nhưng \nsẽ làm cho việc chơi không nhìn phím dễ dàng hơn.", + "swipeText": "lướt", + "titleText": "Điều chinh Màn hình cảm ứng" }, - "configureItNowText": "Điều chỉnh nó ngay ?", + "configureDeviceInSystemSettingsText": "${DEVICE} có thể được điều khiển trong ứng dụng Cài đặt hệ thống.", + "configureItNowText": "Điều chỉnh ngay?", "configureText": "Điều chỉnh", "connectMobileDevicesWindow": { "amazonText": "Cửa hàng Amazon", - "appStoreText": "Cửa hàng", - "bestResultsText": "Để chơi game tốt hơn bạn nên sử dụng wifi mạnh.\nBạn cũng có thể tắt các thiết bị đang sử dụng \nwifi khác để giảm lag,chơi game gần người chơi \nkhác trong vong phát sóng wifi và có thể kết nối wifi direct.", - "explanationText": "Để sử dụng điên thoại thông minh hoặc máy tính bảng để làm thiết bị điều khiển,\ncài đặt ứng dụng \"${REMOTE_APP_NAME}\" lên cấc thiết bị đó.\nTất cả các thiêt bị đều có thể kết nối với ${APP_NAME} game thông qua wifi và hoàn toàn miễn phí", - "forAndroidText": "Cho Adndroid:", + "appStoreText": "App Store", + "bestResultsText": "Để cho kết quả tốt nhất bạn nên sử dụng Ưifi với độ trễ thấp.\nBạn có thể giảm độ trễ bằng cách tắt các thiết bị sử dụng Wifi khác,\nchơi trò chơi gần bộ phát sóng Wifi, và bằng cách kết nối tới \nngười tổ chức trực tiếp qua Ethernet.", + "explanationText": "Để sử dụng điên thoại thông minh hoặc máy tính bảng để làm thiết bị điều khiển,\ncài đặt ứng dụng \"${REMOTE_APP_NAME}\" lên các thiết bị đó.\nKhông giới hạn thiết bị có thể kết nối với ${APP_NAME} thông qua Wifi, và nó hoàn toàn miễn phí!", + "forAndroidText": "cho Android:", "forIOSText": "cho iOS:", - "getItForText": "Tải ${REMOTE_APP_NAME} cho IOS và Android tại App Store \nhoặc cho Android tại cửa hàng Google Play hoặc Amazone Appstore", + "getItForText": "Tải ${REMOTE_APP_NAME} cho IOS tại Apple App Store \nhoặc cho Android tại cửa hàng Google Play hoặc Amazon Appstore", "googlePlayText": "Google play", - "titleText": "Sử dụng thiết bị di động như bộ điều khiển." + "titleText": "Sử dụng Thiết bị di động như Bộ điều khiển:" }, - "continuePurchaseText": "Tiếp tục cho ${PRICE}?", + "continuePurchaseText": "Tiếp tục với giá ${PRICE}?", "continueText": "Tiếp tục", - "controlsText": "Các bộ điều khiển", + "controlsText": "Điều khiển", "coopSelectWindow": { - "activenessAllTimeInfoText": "Nó không được áp dụng cho tất cả các xếp hạng", - "activenessInfoText": "Những người chơi cùng sẽ tăng khi \nbạn chơi hoặc giảm khi bạn nghỉ.", + "activenessAllTimeInfoText": "Điều này không áp dụng cho bảng xếp hạng toàn thời gian.", + "activenessInfoText": "Hệ số này sẽ tăng vào những ngày bạn chơi \nvà giảm vào những ngày bạn không hoạt động.", "activityText": "Hoạt động", - "campaignText": "Đi cảnh", - "challengesInfoText": "Nhận giải thưởng khi hoàn thành xong các minigames.\n\nPhần thưởng và độ khó tăng \nmỗi khi hoàn thành thử thách và \ngiảm xuống khi thử thách đó bị hết hạn hoặc hủy bỏ", + "campaignText": "Chiến dịch", + "challengesInfoText": "Nhận giải thưởng khi hoàn thành các Minigames.\n\nPhần thưởng và độ khó tăng lên\nmỗi khi hoàn thành thử thách và \ngiảm xuống khi thử thách đó hết hạn hoặc bị hủy bỏ.", "challengesText": "Thử thách", - "currentBestText": "Cao nhất hiện tại", - "customText": "Tùy chỉnh", - "entryFeeText": "Mục", - "forfeitConfirmText": "Thím muốn Hủy bỏ thử thách này ?", - "forfeitNotAllowedYetText": "Thím chưa hủy bỏ đc cái thử thách này đâu.", + "currentBestText": "Cao nhất Hiện tại", + "customText": "Thêm", + "entryFeeText": "Phí tham gia", + "forfeitConfirmText": "Bạn muốn hủy bỏ thử thách này?", + "forfeitNotAllowedYetText": "Bạn chưa thể hủy bỏ thử thách này.", "forfeitText": "Hủy bỏ", - "multipliersText": "Người chơi khác", - "nextChallengeText": "Thử thách tiếp", - "nextPlayText": "Lần chơi tiếp theo", - "ofTotalTimeText": "của ${TOTAL}", - "playNowText": "Chơi bây giờ", + "multipliersText": "Hệ số", + "nextChallengeText": "Thử thách tiếp theo", + "nextPlayText": "Lần chơi Tiếp theo", + "ofTotalTimeText": "trên ${TOTAL}", + "playNowText": "Chơi Ngay", "pointsText": "Điểm", - "powerRankingFinishedSeasonUnrankedText": "(Hoàn thành mùa không đánh giá)", - "powerRankingNotInTopText": "(không ở top ${NUMBER})", - "powerRankingPointsEqualsText": "= ${NUMBER} Điểm", - "powerRankingPointsMultText": "(x ${NUMBER} Điểm)", + "powerRankingFinishedSeasonUnrankedText": "(không có hạng)", + "powerRankingNotInTopText": "(không trong top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} điểm", + "powerRankingPointsMultText": "(x ${NUMBER} điểm)", "powerRankingPointsText": "${NUMBER} Điểm", - "powerRankingPointsToRankedText": "(${CURRENT} của ${REMAINING} Điểm)", - "powerRankingText": "Xếp hạng sức mạnh", - "prizesText": "Thưởng", - "proMultInfoText": "Người chơi với ${PRO} nâng cấp\nnhận thêm ${PERCENT}% điểm", + "powerRankingPointsToRankedText": "(${CURRENT} trên ${REMAINING} điểm)", + "powerRankingText": "Xếp Hạng", + "prizesText": "Phần Thưởng", + "proMultInfoText": "Người chơi với ${PRO} sẽ\nnhận thêm ${PERCENT}%.", "seeMoreText": "Thêm...", - "skipWaitText": "Bỏ qua việc chờ đợi", - "timeRemainingText": "Thời gian kết thúc", - "toRankedText": "Xêp hạng", + "skipWaitText": "Bỏ qua Thời gian chờ", + "timeRemainingText": "Thời gian Còn lại", + "toRankedText": "Để vào Xếp hạng", "totalText": "tổng cộng", - "tournamentInfoText": "Hoàn thành điểm cao để cùng thi\nđấu với người chơi khác cùng giải.\n\nGiải thưởng được trao cho những người\ncó điểm cao nhất khi giải đấu kết thúc.", - "welcome1Text": "Chào mừng đến ${LEAGUE}.Bạn có thể nâng cao hạng giải đấu của bạn \nbằng cách đánh giá,hoàn thành các thành tựu và giành các cúp ở \nphần chơi hướng dẫn.", - "welcome2Text": "Bạn có thể kiếm vé từ các hoạt động giống nhau.\nVé có thể sử dụng để mở khóa nhân vật,màn chơi mới \nvà mini games các hướng dẫn mới và nhiều cái khác", - "yourPowerRankingText": "Xếp hạng sức mạnh của bạn" + "tournamentInfoText": "Thi đấu với người chơi \nkhác trong cùng giải đấu với bạn.\n\nGiải thưởng sẽ được trao cho những người chơi \ncó điểm cao nhất khi giải đấu kết thúc.", + "welcome1Text": "Chào mừng đến ${LEAGUE}. Bạn có thể nâng cao hạng giải đấu của bạn \nbằng cách kiếm điểm đánh giá, hoàn thành thành tựu và giành cúp ở \ncác giải đấu.", + "welcome2Text": "Bạn cũng có thể kiếm vé từ các hoạt động giống nhau.\nVé có thể sử dụng để mở khóa nhân vật mới, màn chơi mới \nvà mini games, tham gia các giải đấu và nhiều hơn nữa.", + "yourPowerRankingText": "Xếp hạng của bạn:" }, - "copyConfirmText": "sao chép vào clipboard", - "copyOfText": "${NAME} copy", + "copyConfirmText": "Đã sao chép.", + "copyOfText": "Bản sao của ${NAME}", "copyText": "Sao chép", - "createEditPlayerText": "", + "createEditPlayerText": "", "createText": "Tạo", "creditsWindow": { - "additionalAudioArtIdeasText": "Thêm vào âm thanh,hình ảnh mới và ý kiến bởi ${NAME}", - "additionalMusicFromText": "Thêm âm nhạc từ ${NAME}", - "allMyFamilyText": "Người thân và bạn bè tôi đã thử nghiệm", - "codingGraphicsAudioText": "Mã hóa,đồ họa và âm thanh bởi ${NAME}", - "languageTranslationsText": "Phiên dịch:", + "additionalAudioArtIdeasText": "Âm thanh khác, Bản vẽ ban đầu, và Ý tưởng bởi ${NAME}", + "additionalMusicFromText": "Âm nhạc khác từ ${NAME}", + "allMyFamilyText": "Những người thân và bạn bè đã giúp chơi thử trò chơi", + "codingGraphicsAudioText": "Code, Đồ họa và Âm thanh bởi ${NAME}", + "languageTranslationsText": "Phiên dịch Ngôn ngữ:", "legalText": "Pháp lý:", - "publicDomainMusicViaText": "Nhạc của nhóm cộng đồng qua ${NAME}", + "publicDomainMusicViaText": "Nhạc của cộng đồng qua ${NAME}", "softwareBasedOnText": "Phần mềm này được phát triển trong một dự án của ${NAME}", - "songCreditText": "${TITLE} Phát triển bởi ${PERFORMER}\nTác giả ${COMPOSER}, Sắp xếp bởi ${ARRANGER},Phát hành bởi ${PUBLISHER},\nNguồn ${SOURCE}", - "soundAndMusicText": "Âm thanh và nhạc:", + "songCreditText": "${TITLE} Được trình bày bởi ${PERFORMER}\nSoạn nhạc bởi ${COMPOSER}, Sắp xếp bởi ${ARRANGER}, Phát hành bởi ${PUBLISHER},\nNguồn ${SOURCE}", + "soundAndMusicText": "Âm thanh và Nhạc:", "soundsText": "Âm thanh (${SOURCE}):", - "specialThanksText": "Dành lời cảm ơn đặc biệt cho :", + "specialThanksText": "Cảm ơn tới:", "thanksEspeciallyToText": "Vô cùng cảm ơn đến ${NAME}", "titleText": "Nhóm Sáng Tạo ${APP_NAME}", - "whoeverInventedCoffeeText": "Ai đó tạo ra cà phê" + "whoeverInventedCoffeeText": "Người tạo ra cà phê" }, "currentStandingText": "Vị trí hiện tại của bạn là #${RANK}", "customizeText": "Tùy chinh...", @@ -528,18 +551,18 @@ "deathsText": "Chết", "debugText": "Sửa lỗi", "debugWindow": { - "reloadBenchmarkBestResultsText": "Lưu ý:khuyến nghị bật Cài Đặt->Đồ Họa->Khung Cảnh thành cao khi thử nghiệm", - "runCPUBenchmarkText": "Chấm điểm CPU benchmark", - "runGPUBenchmarkText": "Chấm điểm đồ họa", - "runMediaReloadBenchmarkText": "Chạy lại nội dung chuẩn", - "runStressTestText": "Chạy thử nghiệm", - "stressTestPlayerCountText": "Đếm người chơi", - "stressTestPlaylistDescriptionText": "Danh sách thử độ trễ", - "stressTestPlaylistNameText": "Danh sách tên", - "stressTestPlaylistTypeText": "Kiểu danh sách", + "reloadBenchmarkBestResultsText": "Lưu ý: Bạn nên vào Cài Đặt->Đồ Họa->Kết Cấu thành 'Cao' khi thử nghiệm.", + "runCPUBenchmarkText": "Chạy Kiểm tra CPU", + "runGPUBenchmarkText": "Chạy Kiểm tra GPU", + "runMediaReloadBenchmarkText": "Chạy Kiểm tra Tải đồ họa", + "runStressTestText": "Chạy Kiểm tra độ nặng", + "stressTestPlayerCountText": "Số lượng Người chơi", + "stressTestPlaylistDescriptionText": "Danh sách Thử Độ nặng", + "stressTestPlaylistNameText": "Tên danh sách", + "stressTestPlaylistTypeText": "Loại danh sách", "stressTestRoundDurationText": "Thời hạn Vòng", - "stressTestTitleText": "Thử độ trễ", - "titleText": "Chấm điểm và đo độ trễ", + "stressTestTitleText": "Kiểm tra độ nặng", + "titleText": "Kiểm tra và đo độ nặng", "totalReloadTimeText": "Tổng cộng thời gian lặp lại :${TIME} (xem danh sách để biết chi tiết)" }, "defaultGameListNameText": "Danh Sách Mặc Định ${PLAYMODE}", @@ -547,7 +570,10 @@ "deleteText": "Xóa", "demoText": "Giới thiệu", "denyText": "Từ chối", + "deprecatedText": "Không thể dùng", + "descriptionText": "Mô tả", "desktopResText": "Độ phân giải", + "deviceAccountUpgradeText": "Cảnh báo:\nBạn đã đăng nhập với tài khoản thiết bị (${NAME}).\nTài khoản thiết bị sẽ bị xóa trong những cập nhật tương lai.\nNâng cấp lên tài khoản V2 nếu bạn muốn giữ tiến trình.", "difficultyEasyText": "Dễ", "difficultyHardOnlyText": "Chỉ chế độ khó", "difficultyHardText": "Khó", @@ -556,6 +582,10 @@ "disableRemoteAppConnectionsText": "Tắt Trình Điều Khiên", "disableXInputDescriptionText": "Cho phép trên 4 thiết bị điều khiển nhưng nó có thể hoạt động không tốt", "disableXInputText": "Ngắt Kết NỐi XInput", + "disabledText": "Vô hiệu hóa", + "discardText": "Hủy", + "discordFriendsText": "Bạn muốn tìm người mới để chơi cùng?\nTham gia Discord của chúng tôi và tìm những người bạn mới!", + "discordJoinText": "Tham gia Disscord", "doneText": "Xong", "drawText": "Hòa", "duplicateText": "Nhân Đôi", @@ -589,6 +619,7 @@ "localProfileText": "(tài khoản cố định)", "nameDescriptionText": "Tên nhân vật", "nameText": "Tên", + "profileAlreadyExistsText": "Hồ sơ có tên đó đã tồn tại.", "randomText": "Ngẫu nhiên", "titleEditText": "Chỉnh sửa thông tin", "titleNewText": "Tạo mới", @@ -624,6 +655,7 @@ "useMusicFolderText": "Thư mục của files nhạc" }, "editText": "Sửa", + "enabledText": "Hiển thị", "endText": "kết thúc", "enjoyText": "Chúc vui vẻ!", "epicDescriptionFilterText": "${DESCRIPTION} trong chế độ quay chậm.", @@ -635,6 +667,8 @@ "errorText": "Lỗi", "errorUnknownText": "Không rõ lỗi", "exitGameText": "Thoát ${APP_NAME}?", + "expiredAgoText": "Đã hết hạn ${T} trước", + "expiresInText": "Hết hạn sau ${T}", "exportSuccessText": "'${NAME}' Đã xuất", "externalStorageText": "Bộ nhớ ngoài", "failText": "Thất bại", @@ -669,6 +703,8 @@ "duplicateText": "Nhân đôi \nDanh sách", "editText": "Đặt lại \nDanh sách", "newText": "Danh sách\nMới", + "pointsToWinText": "Điểm để thắng", + "seriesLengthText": "Độ dài loạt phim", "showTutorialText": "Hiện Hướng dẫn", "shuffleGameOrderText": "Xáo trộn thứ tự trò chơi", "titleText": "Tùy chỉnh ${TYPE} Danh sách phát" @@ -694,6 +730,7 @@ "copyCodeConfirmText": "Mã đã sao chép vào bộ nhớ", "copyCodeText": "Sao chép mã", "dedicatedServerInfoText": "Để có kết quả tốt nhất, hãy thiết lập một máy chủ chuyên dụng.Vào bombsquadgame.com/server để tìm hiểu cách.", + "descriptionShortText": "Sử dụng cửa sổ thu thập để thành lập tổ đội.", "disconnectClientsText": "Điều này sẽ ngắt kết nối (các) người chơi ${COUNT}\n trong tổ đội của bạn.Bạn có chắc không?", "earnTicketsForRecommendingAmountText": "Bạn bè sẽ nhận được vé ${COUNT} nếu họ thử trò chơi\n (và bạn sẽ nhận được ${YOU_COUNT} cho mỗi người làm)", "earnTicketsForRecommendingText": "Chia sẻ trò chơi này với bạn bè\nđể có thêm vé miễn phí...", @@ -706,10 +743,10 @@ "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} vé từ ${NAME}", "friendPromoCodeAwardText": "Bạn sẽ nhận được ${COUNT} vé mỗi lần nó được sử dụng", "friendPromoCodeExpireText": "Mã code sẽ hết hạn trong ${EXPIRE_HOURS} và chỉ hoạt động với người chơi mới.", - "friendPromoCodeInstructionsText": "Để dùng nó,mở ${APP_NAME} và tới \"Cài đặt ->Nâng cao->Nhập mã\".\nXem bombsquadgame.com cho đường dẫn tải xuống cho tất cả hệ điều hành hỗ trợ.", + "friendPromoCodeInstructionsText": "Để dùng nó, mở ${APP_NAME} và tới \"Cài đặt ->Nâng cao->Gửi Thông tin\".\nTruy cập bombsquadgame.com cho đường dẫn tải xuống cho tất cả hệ điều hành hỗ trợ.", "friendPromoCodeRedeemLongText": "Nó có thể được đổi lấy ${COUNT} vé miễn phí cho tối đa ${MAX_USES} người", "friendPromoCodeRedeemShortText": "Nó có thể được đổi lấy vé ${COUNT} trong trò chơi.", - "friendPromoCodeWhereToEnterText": "(trong \"Cài đặt-> Nâng cao-> Nhập mã\")", + "friendPromoCodeWhereToEnterText": "(trong \"Cài đặt-> Nâng cao-> Gửi Thông tin\")", "getFriendInviteCodeText": "Nhận mã mời bạn bè", "googlePlayDescriptionText": "Mời bạn bè trên google play đến party của bạn:", "googlePlayInviteText": "Mời", @@ -741,6 +778,7 @@ "manualYourLocalAddressText": "Địa chỉ nội bộ:", "nearbyText": "Gần nhất", "noConnectionText": "(không có kết nối)", + "noPartiesAddedText": "Không có bên nào được thêm vào", "otherVersionsText": "(phiên bản khác)", "partyCodeText": "Mã phòng", "partyInviteAcceptText": "Chấp nhận", @@ -804,17 +842,26 @@ "youHaveShortText": "Bạn có ${COUNT}", "youHaveText": "Bạn có ${COUNT} vé" }, + "goldPass": { + "desc1InfTokensText": "Mã thông báo vô hạn.", + "desc2NoAdsText": "Không có quảng cáo.", + "desc3ForeverText": "Mãi mãi.", + "goldPassText": "Thẻ Vàng" + }, "googleMultiplayerDiscontinuedText": "Xin lỗi, dịch vụ Google nhiều người chơi không còn nữa.\nTôi đang cố gắng thay thế nhanh nhất có thể.\nTrong lúc đó, vui lòng thử cách kết nối khác.\n-Eric", "googlePlayPurchasesNotAvailableText": "Các giao dịch mua trên Google Play không khả dụng.\nBạn có thể cần cập nhật ứng dụng cửa hàng của mình.", + "googlePlayServicesNotAvailableText": "Dịch vụ của Google Play không có sẵn.\nMột số chức năng ứng dụng sẽ bụ vô hiệu hóa.", "googlePlayText": "Google Trò chơi", "graphicsSettingsWindow": { "alwaysText": "Luôn Luôn", "fullScreenCmdText": "Toàn màn hình (Cmd-F)", "fullScreenCtrlText": "Toàn màn hình (Ctrl-F)", + "fullScreenText": "Toàn màn hình", "gammaText": "Gam-ma", "highText": "Cao", "higherText": "Cao hơn", "lowText": "Thấp", + "maxFPSText": "FPS tối đa", "mediumText": "Vừa", "neverText": "Không bao giờ", "resolutionText": "Độ phân giải", @@ -875,6 +922,7 @@ "importText": "Xuất", "importingText": "Đang nhập...", "inGameClippedNameText": "trong game sẽ là \n\"${NAME}\"", + "inboxText": "Hộp Thư", "installDiskSpaceErrorText": "Lỗi: Không thể hoàn thành tải xuống.\nBạn có thể hết dung lượng trên thiết bị của bạn.\nDọn một số chỗ và thử lại.", "internal": { "arrowsToExitListText": "nhấn ${LEFT} hoặc ${RIGHT} để rời khỏi danh sách", @@ -929,12 +977,14 @@ "timeOutText": "(hết giờ trong ${TIME} giây)", "touchScreenJoinWarningText": "Bạn đã gia nhập với màn hình cảm ứng.\nNếu đây là lỗi, nhấn 'Menu-> Rời trò chơi '.", "touchScreenText": "Màn hình Cảm ứng", + "unableToCompleteTryAgainText": "Không thể hoàn thành bây giờ.\nVui lòng thử lại sau.", "unableToResolveHostText": "Lỗi: không thể giải quyết máy chủ.", "unavailableNoConnectionText": "Hiện tại không có sẵn (không có kết nối mạng?)", "vrOrientationResetCardboardText": "Sử dụng cái này để cài lại VR định hướng.\nĐể chơi trò chơi bạn sẽ cần một cần điều khiển bên ngoài.", "vrOrientationResetText": "Cài lại định hướng VR.", "willTimeOutText": "(sẽ hết giờ nếu không hoạt động)" }, + "inventoryText": "Túi Đồ", "jumpBoldText": "NHẢY", "jumpText": "Nhảy", "keepText": "Giữ", @@ -981,8 +1031,11 @@ "seasonEndsMinutesText": "Mùa kết thúc ${NUMBER} phúc trước.", "seasonText": "Mùa ${NUMBER}", "tournamentLeagueText": "Bạn phải đạt giải đấu ${NAME} để tham gia giải đấu này.", - "trophyCountsResetText": "Số lượng cúp sẽ thiết lập lại vào mùa giải tới." + "trophyCountsResetText": "Số lượng cúp sẽ thiết lập lại vào mùa giải tới.", + "upToDateBonusDescriptionText": "Người chơi chạy phiên bản gần đây của trò chơi\nđược nhận thêm ${PERCENT}%.", + "upToDateBonusText": "Thưởng Phiên bản mới nhất" }, + "learnMoreText": "Tìm hiểu thêm", "levelBestScoresText": "Điểm số tốt nhất trên ${LEVEL}", "levelBestTimesText": "Thời gian tốt nhất trên ${LEVEL}", "levelIsLockedText": "${LEVEL} đã bị khóa.", @@ -1002,6 +1055,7 @@ "creditsText": "Giới thiệu", "demoMenuText": "Cài đặt Demo", "endGameText": "kết thúc game", + "endTestText": "Kết thúc thử nghiệm", "exitGameText": "Thoat game", "exitToMenuText": "Quay về Menu?", "howToPlayText": "Hướng dẫn chơi", @@ -1021,9 +1075,12 @@ "maxConnectionsText": "Kết nối tối đa", "maxPartySizeText": "Số người trong bữa tiệc tối đa", "maxPlayersText": "Người chơi tối đa", + "merchText": "Cửa hàng!", "modeArcadeText": "Chế độ giải trí", "modeClassicText": "Chế độ cổ điển", "modeDemoText": "Chế độ thử nghiệm", + "moreSoonText": "Sắp có mặt...", + "mostDestroyedPlayerText": "Người chơi bị đánh bại nhiều nhất", "mostValuablePlayerText": "Người chơi đáng giá nhất", "mostViolatedPlayerText": "Người chơi bị chết nhiều nhất", "mostViolentPlayerText": "Người chơi bạo lực nhất", @@ -1040,6 +1097,7 @@ "nameSuicideText": "${NAME} tự tử.", "nameText": "Tên", "nativeText": "Tự nhiên", + "newExclaimText": "Mới!", "newPersonalBestText": "Mới tốt nhất cá nhân!", "newTestBuildAvailableText": "Một bản dựng thử nghiệm mới hơn có sẵn! (${VERSION} xây dựng ${BUILD}).\nNhận nó tại ${ADDRESS}", "newText": "Mới", @@ -1050,16 +1108,21 @@ "noContinuesText": "(không tiếp tục)", "noExternalStorageErrorText": "Không tìm thấy bộ nhớ ngoài trên thiết bị này", "noGameCircleText": "Lỗi: không đăng nhập vào GameCircle", + "noMessagesText": "Không có Tin nhắn", + "noPluginsInstalledText": "Không có plugin nào được cài đặt", "noScoresYetText": "Chưa có điểm nào.", + "noServersFoundText": "Không tìm thấy máy chủ nào.", "noThanksText": "Không cảm ơn", "noTournamentsInTestBuildText": "CẢNH BÁO: Điểm thi đấu từ bản dựng thử nghiệm này sẽ bị bỏ qua.", "noValidMapsErrorText": "Không tìm thấy bản đồ hợp lệ cho loại trò chơi này.", "notEnoughPlayersRemainingText": "Không đủ người chơi còn lại; thoát ra và bắt đầu một trò chơi mới", "notEnoughPlayersText": "Bạn cần ít nhất ${COUNT} người chơi để bắt đầu trò chơi này!", + "notEnoughTicketsText": "Không đủ vé!", "notNowText": "Không phải bây giờ", "notSignedInErrorText": "Bạn phải đăng nhập để làm điều này.", "notSignedInGooglePlayErrorText": "Bạn phải đăng nhập bằng Google Play để làm điều này.", "notSignedInText": "chưa đăng nhập", + "notUsingAccountText": "Ghi chú: phớt lờ cái tài khoản ${SERVICE} đi.\nHãy đi đến 'Tài khoản -> Đăng nhập với ${SERVICE}' nếu bạn muốn sử dụng nó.", "nothingIsSelectedErrorText": "Bạn chưa chọn cái nào!", "numberText": "#${NUMBER}", "offText": "Tắt", @@ -1067,6 +1130,9 @@ "onText": "Bật", "oneMomentText": "Một lúc...", "onslaughtRespawnText": "${PLAYER} sẽ hồi sinh trong ải ${WAVE}", + "openMeText": "Mở tôi ra!", + "openNowText": "Mở Ngay", + "openText": "Mở", "orText": "${A} hoặc ${B}", "otherText": "Khác ...", "outOfText": "(#${RANK} ra khỏi ${ALL})", @@ -1118,7 +1184,11 @@ "pleaseWaitText": "Vui lòng chờ...", "pluginClassLoadErrorText": "Lỗi khi tải lớp plugin '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Lỗi khi nhập plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Các thiết đặt giác cắm", + "pluginsAutoEnableNewText": "Tự động hiển thị những Giác cắm mới", "pluginsDetectedText": "Đã phát hiện (các) plugin mới. Khởi động lại để kích hoạt chúng hoặc định cấu hình chúng trong cài đặt.", + "pluginsDisableAllText": "Vô hiệu hóa tất cả các giác cắm", + "pluginsEnableAllText": "Hiển thị tất cả các giác cắm", "pluginsRemovedText": "Không còn tìm thấy ${NUM} plugin nào nữa.", "pluginsText": "Cắm", "practiceText": "Luyện tập", @@ -1148,10 +1218,12 @@ "punchText": "Đấm", "purchaseForText": "Mua với ${PRICE}", "purchaseGameText": "Mua trò chơi", + "purchaseNeverAvailableText": "Rất tiếc, không có giao dịch mua nào khả dụng trên bản dựng này.\nHãy thử đăng nhập vào tài khoản của bạn trên nền tảng khác và thực hiện giao dịch mua từ đó.", + "purchaseNotAvailableText": "Giao dịch mua này không khả dụng.", "purchasingText": "Đang mua...", "quitGameText": "Rời ${APP_NAME}?", "quittingIn5SecondsText": "Rời đi trong 5 giây...", - "randomPlayerNamesText": "Tên_Mặcđịnh", + "randomPlayerNamesText": "Việt Nam, Anh, Dung, Hanh, Hoa, Hong, Khanh, Lan, Liem, Nhung, Duy, Xuan", "randomText": "Ngẫu nhiên", "rankText": "Xếp hạng", "ratingText": "Đánh giá", @@ -1189,6 +1261,7 @@ "version_mismatch": "Không trùng phiên bản.\nChắc chắn rằng Bombsquad và\nBombsquad Remote là phiên bản mới nhất và thử lại." }, "removeInGameAdsText": "Mở khóa \"${PRO}\" trong cửa hàng để loại bỏ quảng cáo.", + "removeInGameAdsTokenPurchaseText": "KHUYẾN MÃI GIỚI HẠN: Mua gói xu BẤT KỲ để loại bỏ quảng cáo trong trò chơi.", "renameText": "Đặt lại tên", "replayEndText": "Kết thúc phát lại", "replayNameDefaultText": "Xem lại trò chơi vừa rồi", @@ -1209,7 +1282,9 @@ "revertText": "Hủy bỏ", "runText": "Chạy", "saveText": "Lưu", - "scanScriptsErrorText": "Lỗi trong lúc quét mã bản thảo; xem bản thông báo cho chi tiết.", + "scanScriptsErrorText": "Lỗi trong lúc quét mã bản thảo. Xem bảng thông báo để biết thêm chi tiết.", + "scanScriptsMultipleModulesNeedUpdatesText": "${PATH} và ${NUM} mô-đun khác cần phải được cập nhật cho api ${API}.", + "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} cần được nâng cấp cho api ${API}", "scoreChallengesText": "Thử thách Điểm số", "scoreListUnavailableText": "Danh sách điểm số không có sẵn.", "scoreText": "Điểm số", @@ -1220,6 +1295,7 @@ }, "scoreWasText": "(Cao nhất ${COUNT})", "selectText": "Chọn", + "sendInfoDescriptionText": "Gửi thông tin trạng thái tài khoản và ứng dụng cho nhà phát triển.\nBao gồm tên của bạn và lý do cho việc gửi.", "seriesWinLine1PlayerText": "ĐÃ THẮNG", "seriesWinLine1TeamText": "ĐÃ THẮNG", "seriesWinLine1Text": "ĐÃ THẮNG", @@ -1234,25 +1310,34 @@ "titleText": "Cài đặt" }, "settingsWindowAdvanced": { - "alwaysUseInternalKeyboardDescriptionText": "(một bàn phím trên màn hình đơn giản, thân thiện với tay cầm cho nhập văn bản)", - "alwaysUseInternalKeyboardText": "Luôn sử dụng bàn phím nội bộ", + "alwaysUseInternalKeyboardDescriptionText": "(một bàn phím trên màn hình đơn giản, thân thiện với bộ điều khiển để chỉnh sửa văn bản)", + "alwaysUseInternalKeyboardText": "Luôn sử dụng bàn phím của cục bộ.", "benchmarksText": "Điểm chuẩn & Kiểm tra độ trễ", - "disableCameraGyroscopeMotionText": "Vô hiệu hóa Camera Gyroscope Motion", - "disableCameraShakeText": "Vô hiệu hóa Camera Shake", + "devToolsText": "Công cụ cho Nhà phát triển", + "disableCameraGyroscopeMotionText": "Vô hiệu hoá chuyển động con quay hồi chuyển", + "disableCameraShakeText": "Vô hiệu hoá lắc màn hình", "disableThisNotice": "(bạn có thể tắt thông báo này trong cài đặt nâng cao)", "enablePackageModsDescriptionText": "(thêm tối đa chỗ mod nhưng tắt chơi qua mạng)", "enablePackageModsText": "Bật Gói Mod Cục bộ", "enterPromoCodeText": "Nhập mã", "forTestingText": "Ghi chú: những giá trị này chỉ dành cho kiểm tra và sẽ bị mất khi rời khỏi ứng dụng.", "helpTranslateText": "Cộng đồng dịch ${APP_NAME} là một cộng đồng được hỗ trợ.\nNếu bạn muốn góp phần hoặc sửa bản dịch,\nđi theo đường dẫn bên dưới.", - "kickIdlePlayersText": "Đuổi người chơi không hoạt động", + "insecureConnectionsDescriptionText": "không khuyến khích,nhưng có thể cho phép chơi online từ các quốc gia hoặc mạng bị hạn chế", + "insecureConnectionsText": "Sử dụng kết nối mạng không bảo mật", + "kickIdlePlayersText": "Đuổi người chơi AFK", "kidFriendlyModeText": "Chế độ thân thiện với trẻ em (giảm bạo lực , vân vân)", - "languageText": "Ngôn ngữ", + "languageText": "Ngôn ngữ vietnamese", "moddingGuideText": "Hướng dẫn mod", + "moddingToolsText": "Công cụ sửa đổi", "mustRestartText": "Bạn phải khởi động lại trò chơi để áp dụng cài đặt", "netTestingText": "Kiểm tra mạng", "resetText": "Cài lại", + "sendInfoText": "Gửi thông tin", "showBombTrajectoriesText": "Hiển thị quỹ đạo của bom", + "showDemosWhenIdleText": "Hiện bản demo khi không hoạt động", + "showDeprecatedLoginTypesText": "Hiển thị các loại đăng nhập đã bay màu", + "showDevConsoleButtonText": "Hiện nút Bảng điều khiển cho nhà phát triển", + "showInGamePingText": "Hiển thị Ping trong Game", "showPlayerNamesText": "Hiển thị tên người chơi", "showUserModsText": "Hiển thị Thư mục Mod", "titleText": "Nâng cao", @@ -1260,8 +1345,8 @@ "translationFetchErrorText": "trạng thái bản dịch không có sẵn", "translationFetchingStatusText": "kiểm tra trạng thái bản dịch...", "translationInformMe": "Thông báo tôi khi ngôn ngữ cần được nâng cấp", - "translationNoUpdateNeededText": "Ngôn ngữ hiện tại đã được nâng cấp; quẩy đi!", - "translationUpdateNeededText": "** ngôn ngữ hiện tại cần được nâng cấp!! **", + "translationNoUpdateNeededText": "Ngôn ngữ hiện tại đã được nâng cấp; quẩy lên!", + "translationUpdateNeededText": "** Ngôn ngữ hiện tại cần được cập nhật!! **", "vrTestingText": "Thử nghiệm VR" }, "shareText": "Chia sẻ", @@ -1271,6 +1356,9 @@ "signInWithGameCenterText": "Để sử dụng một tài khoản Trung tâm trò chơi,\n đăng nhập với ứng dụng Trung Tâm Trò Chơi", "singleGamePlaylistNameText": "Chỉ ${GAME}", "singlePlayerCountText": "1 người chơi", + "sizeLargeText": "Lớn", + "sizeMediumText": "Trung bình", + "sizeSmallText": "Nhỏ", "soloNameFilterText": "Solo ${NAME}", "soundtrackTypeNames": { "CharSelect": "Chọn nhân vật", @@ -1296,6 +1384,7 @@ }, "spaceKeyText": "dấu cách", "statsText": "Thống kê", + "stopRemindingMeText": "Đừng nhắc lại tôi", "storagePermissionAccessText": "Yêu cầu truy cập lưu trữ", "store": { "alreadyOwnText": "Bạn đã có ${NAME}!", @@ -1343,6 +1432,8 @@ "storeText": "Cửa hàng", "submitText": "Gửi", "submittingPromoCodeText": "Đang xác nhận mã code...", + "successText": "Thành công!", + "supportEmailText": "Nếu bạn đang gặp bất kỳ vấn đề nào với\nứng dụng, vui lòng gửi email tới ${EMAIL}.", "teamNamesColorText": "Tên/Màu sắc đội...", "telnetAccessGrantedText": "Đã kích hoạt truy cập giao thức.", "telnetAccessText": "Phát hiện truy cập giao thức; cho phép?", @@ -1352,6 +1443,7 @@ "testBuildValidatedText": "Kiểm tra bản dựng được xác thực; Tận hưởng!", "thankYouText": "Cảm ơn vì sự hỗ trợ của bạn! Hãy tận hưởng trò chơi!!", "threeKillText": "Tam Sát!!", + "ticketsDescriptionText": "Vé có thể dùng để mở khóa nhân vật, bản đồ, \nmini-game, và nhiều thứ khác trong cửa hàng.\n\nVé có thể kiếm được từ rương nhận được từ \nchiến dịch, giải đấu, và thành tựu.", "timeBonusText": "Thưởng thời gian", "timeElapsedText": "Thời gian còn lại", "timeExpiredText": "Hết giờ", @@ -1362,10 +1454,24 @@ "tipText": "Gợi ý", "titleText": "Bombsquad", "titleVRText": "Bombsquad Thực tế ảo", + "tokens": { + "getTokensText": "Nhận Token", + "notEnoughTokensText": "Không đủ token!", + "numTokensText": "${COUNT} Mã thông báo", + "openNowDescriptionText": "Bạn có đủ token để\nmở ngay bây giờ - bạn không\ncần phải chờ đợi.", + "shinyNewCurrencyText": "Tiền tệ mới sáng bóng của BombSquad.", + "tokenPack1Text": "Gói Token Nhỏ", + "tokenPack2Text": "Gói Token trung bình", + "tokenPack3Text": "Gói Token Lớn", + "tokenPack4Text": "Gói Mã thông báo Jumbo", + "tokensDescriptionText": "Xu dùng để tăng tốc độ mở rương và \nnhiều chức năng trò chơi và tài khoản khác. \n\nBạn có thể nhận được Xu trong trò chơi hoặc \nmua theo gói. Hoặc bạn sẽ nhận được vô hạn xu khi mua Gold Pass và \nkhông bao giờ quan tâm tới chúng thêm lần nào nữa.", + "youHaveGoldPassText": "Bạn có Thẻ Vàng.\nTất cả các giao dịch mua token đều miễn phí.\nHãy tận hưởng!" + }, "topFriendsText": "Bạn bè đứng đầu", "tournamentCheckingStateText": "Đang kiểm tra trạng thái giải đấu; vui lòng chờ...", "tournamentEndedText": "Giải đấu này đã kết thúc. Giải đấu mới sẽ bắt đầu sớm.", "tournamentEntryText": "Lệ phí", + "tournamentFinalStandingsText": "Thứ hạng Cuối cùng", "tournamentResultsRecentText": "Kết quả giải đấu gần đây", "tournamentStandingsText": "Bảng xếp hạng giải đấu", "tournamentText": "Giải đấu", @@ -1421,6 +1527,18 @@ "Uber Onslaught": "Tử chiến (Bậc thầy)", "Uber Runaround": "Thủ thành (Bậc thầy)" }, + "displayItemNames": { + "${C} Tickets": "${C} Vé", + "${C} Tokens": "${C} Xu", + "Chest": "Rương", + "L1 Chest": "Rương cấp 1", + "L2 Chest": "Rương cấp 2", + "L3 Chest": "Rương cấp 3", + "L4 Chest": "Rương cấp 4", + "L5 Chest": "Rương cấp 5", + "L6 Chest": "Rương cấp 6", + "Unknown Chest": "Rương ???" + }, "gameDescriptions": { "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Làm người được chọn trong thời gian nhất định để chiến thắng.\nGiết người được chọn để trở thành họ.", "Bomb as many targets as you can.": "Dội bom nhiều mục tiêu nhất có thể.", @@ -1523,7 +1641,9 @@ "Italian": "Tiếng Ý", "Japanese": "Tiếng Nhật", "Korean": "Tiếng Hàn", + "Malay": "Tiếng Mã Lai", "Persian": "Tiếng Ba Tư", + "PirateSpeak": "Tiếng Hải tặc", "Polish": "Tiếng Polish", "Portuguese": "Tiếng Bồ Đào Nha", "Romanian": "Tiếng Rumani", @@ -1595,6 +1715,7 @@ "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Phát hiện gian lận; không được ghi điểm số và nhận giải thưởng trong ${COUNT} ngày.", "Could not establish a secure connection.": "Không thể thiết lập kết nối an toàn.", "Daily maximum reached.": "Đã đạt tối đa số lượng hàng ngày.", + "Daily sign-in reward": "Phần thưởng đăng nhập hàng ngày", "Entering tournament...": "Gia nhập giải đấu...", "Invalid code.": "Mã code không hợp lệ.", "Invalid payment; purchase canceled.": "Thành toán không hợp lệ, mua thất bại.", @@ -1604,11 +1725,14 @@ "Item unlocked!": "Vật phẩm đã mở khóa!", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LIÊN KẾT TỪ CHỐI. ${ACCOUNT} chứa\ndữ liệu quan trọng mà TẤT CẢ ĐƯỢC.\nBạn có thể liên kết theo thứ tự ngược lại nếu bạn muốn\n(và mất dữ liệu của tài khoản NÀY thay thế)", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Liên kết tài khoản ${ACCOUNT} với tài khoản này?\nTất cả dữ liệu tồn tại trên ${ACCOUNT} sẽ bị mất.\nKhông thể hủy. Bạn chắc chứ?", + "Longer streaks lead to better rewards.": "Chuỗi càng dài thì phần thưởng càng tốt.", "Max number of playlists reached.": "Đã đạt tối đa danh sách.", "Max number of profiles reached.": "Đã đạt tối đa số lượng hồ sơ.", "Maximum friend code rewards reached.": "Đã đạt tối đa thưởng từ mã code bạn bè.", "Message is too long.": "Tin nhắn quá dài.", + "New tournament result!": "Kết quả giải đấu!", "No servers are available. Please try again soon.": "Không có server có sẵn. Hãy thử lại sau.", + "No slots available. Free a slot and try again.": "Không còn ô trống. Giải phóng một ô và thử lại.", "Profile \"${NAME}\" upgraded successfully.": "Hồ sơ \"${NAME}\" nâng cấp thành công.", "Profile could not be upgraded.": "Hồ sơ không thể nâng cấp.", "Purchase successful!": "Mua thành công!", @@ -1618,7 +1742,9 @@ "Sorry, this code has already been used.": "Xin lỗi bạn, mã code này đã đc sử dụng", "Sorry, this code has expired.": "Xin lỗi, mã code này đã hết hạn.", "Sorry, this code only works for new accounts.": "Xin lỗi,mã code này chỉ dành cho người chơi mới.", + "Sorry, this has expired.": "Xin lỗi, vật phẩm đã hết hạn.", "Still searching for nearby servers; please try again soon.": "Vẫn đang tìm những server gần nhất; Hãy thử lại sau", + "Streak: ${NUM} days": "Chuỗi: ${NUM} ngày", "Temporarily unavailable; please try again later.": "Tạm thời không có; vui lòng thử lại sau.", "The tournament ended before you finished.": "Giải đấu đã kết thúc trước khi bạn hoàn thành.", "This account cannot be unlinked for ${NUM} days.": "Tài khoản này không thể ngừng liên kết trong ${NUM} ngày.", @@ -1629,19 +1755,28 @@ "Tournaments require ${VERSION} or newer": "Giải đấu yêu cầu phiên bản ${VERSION} hoặc mới hơn.", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Ngừng liên kết ${ACCOUNT} từ tài khoản này? \nTất cả dữ liệu trên ${ACCOUNT} sẽ bị cài lại.\n(ngoại trừ thành tựu trong một số trường hợp)", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "Cảnh báo: Khiếu nại về hack đã được đưa ra về tài khoản của bạn.\nTài khoản phát hiện hack sẽ bị cấm chơi vĩnh viễn. Vui lòng chơi trung thực.", + "Wait reduced!": "Đã giảm thời gian!", + "Warning: This version of the game is limited to old account data; things may appear missing or out of date.\nPlease upgrade to a newer version of the game to see your latest account data.": "Cảnh báo: Phiên bản trò chơi này chỉ giới hạn ở dữ liệu tài khoản cũ; một số thứ có thể bị thiếu hoặc lỗi thời.\nVui lòng nâng cấp lên phiên bản trò chơi mới hơn để xem dữ liệu tài khoản mới nhất của bạn.", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Bạn có muốn lên kết tài khoản thiết bị của bạn với cái này?\n\nTài khoản thiết bị là\n ${ACCOUNT1}\nTài khoản này là ${ACCOUNT2}", "You already own this!": "Bạn đã có cái này!", "You can join in ${COUNT} seconds.": "Bạn có thể tham gia trong ${COUNT} giây.", "You don't have enough tickets for this!": "Bạn không đủ vé để mua!", "You don't own that.": "Bạn không có cái đó.", "You got ${COUNT} tickets!": "Bạn đã nhận được ${COUNT} vé!", + "You got ${COUNT} tokens!": "Bạn nhận được ${COUNT} xu!", "You got a ${ITEM}!": "Bạn đã nhận được một ${ITEM}!", + "You got a chest!": "Bạn nhận được một rương!", + "You got an achievement reward!": "Bạn nhận được một phần thưởng từ thành tựu!", "You have been promoted to a new league; congratulations!": "Bạn đã được thăng hạng lên một giải đấu mới; xin chúc mừng!", + "You lost a chest! (All your chest slots were full)": "Bạn đã mất một rương! (Tất cả ô rương đã đầy)", + "You must update the app to view this.": "Vui lòng cập nhật trò chơi để xem.", "You must update to a newer version of the app to do this.": "Bạn phải nâng cấp lên phiên bản mới hơn của ứng dụng để làm điều này.", "You must update to the newest version of the game to do this.": "Bạn phải nâng cấp trò chơi lên phiên bản mới nhất để làm điều này.", "You must wait a few seconds before entering a new code.": "Bạn phải chờ một vài giây trước khi nhập một mã mới.", + "You placed #${RANK} in a tournament!": "Bạn đạt hạng #${RANK} trong giải đấu!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Bạn đứng thứ #${RANK} trong giải đấu vừa rồi. Cảm ơn vì đã tham gia!", "Your account was rejected. Are you signed in?": "Tài khoản của bạn đã bị từ chối. Bạn đã đăng nhập chưa?", + "Your ad views are not registering. Ad options will be limited for a while.": "Lượt xem quảng cáo của bạn không được ghi lại. Tùy chọn quảng cáo sẽ bị giới hạn trong một thời gian.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Bản sao của trò chơi đã bị sửa đổi.\nVui lòng sửa lại bất kỳ thay đổi lại như cũ và thử lại.", "Your friend code was used by ${ACCOUNT}": "Mã của bạn bè của bạn đã được dùng bởi ${ACCOUNT}" }, @@ -1790,11 +1925,14 @@ "toSkipPressAnythingText": "(chạm hoặc nhấn bất kì đâu để bỏ qua hướng dẩn)" }, "twoKillText": "Hai Mạng!", + "uiScaleText": "Quy mô giao diện", "unavailableText": "Không Khả Dụng", + "unclaimedPrizesText": "Bạn có giải thưởng chưa nhận!", "unconfiguredControllerDetectedText": "Tay cầm không cấu hình được phát hiện:", "unlockThisInTheStoreText": "Nó phải được mở khóa trong cửa hàng.", "unlockThisProfilesText": "Để tạo nhiều hơn ${NUM} hồ sơ,bạn cần:", "unlockThisText": "Để mở khóa bạn cần", + "unsupportedControllerText": "Rất tiếc, bộ điều khiển \"${NAME}\" không được hỗ trợ.", "unsupportedHardwareText": "Xin lỗi, phần cứng này không được hỗ trợ bởi bản dựng này của trò chơi.", "upFirstText": "Game đầu:", "upNextText": "Trò chơi tiếp theo ${COUNT}:", @@ -1802,9 +1940,14 @@ "upgradeText": "Nâng cấp", "upgradeToPlayText": "Mở khóa \"${PRO}\" trong cửa hàng để chơi.", "useDefaultText": "Sử dụng mặc định", + "userSystemScriptsCreateText": "Tạo tập lệnh hệ thống người dùng", + "userSystemScriptsDeleteText": "Xóa tập lệnh hệ thống người dùng", "usesExternalControllerText": "Trò chơi này sử dụng tay cầm bên ngoài cho đầu vào.", "usingItunesText": "Sử dụng Ứng dụng âm nhạc cho nhạc nền", + "v2AccountLinkingInfoText": "Để đến tài khoản V2, sử dụng nút 'Thiết đặt tài khoản'.", + "v2AccountRequiredText": "Điều này yêu cầu tài khoản V2. Hãy nâng cấp tài khoản của bạn và thử lại.", "validatingTestBuildText": "Kiểm tra xác thực Xây dựng ...", + "viaText": "Thông qua", "victoryText": "Chiến thắng!", "voteDelayText": "Bạn không thể bắt đầu cuộc bầu chọn khác trong ${NUMBER} giây", "voteInProgressText": "Một cuộc bầu chọn đang tiến hành.", @@ -1836,6 +1979,7 @@ }, "waveText": "Vòng", "wellSureText": "Chắc chắn rồi!", + "whatIsThisText": "Đây là cái gì vậy?", "wiimoteLicenseWindow": { "titleText": "DarwiinRemote Bản quyền" }, @@ -1846,7 +1990,7 @@ }, "wiimoteSetupWindow": { "copyrightText": "Bản quyền của DarwiinRemote", - "listenText": "Lắng nghe", + "listenText": "Lắng nghe ", "macInstructionsText": "Hãy chắc chắn rằng Wii của bạn là tắt và Bluetooth được kích hoạt\ntrên máy Mac của bạn, sau đó nhấn 'Nghe'. Wiimote hỗ trợ có thể\nmột chút flaky, do đó, bạn có thể phải thử một vài lần\ntrước khi bạn nhận được một kết nối.\n\nBluetooth nên xử lý lên đến 7 thiết bị kết nối,\nmặc dù mileage của bạn có thể khác nhau.\n\nBombSquad hỗ trợ Wiimotes gốc, Nunchuk,\nvà bộ điều khiển cổ điển.\nCác mới Wii Remote Plus bây giờ hoạt động quá\nnhưng không phải với tập tin đính kèm", "thanksText": "Cảm ơn nhóm DarwiinRemote\nĐã làm thứ này có thật.", "titleText": "Thiết lập Wiimote" @@ -1868,5 +2012,6 @@ }, "yesAllowText": "Có, chấp nhận !", "yourBestScoresText": "Điểm kỉ lục của bạn", - "yourBestTimesText": "Thời gian kỉ lục của bạn" + "yourBestTimesText": "Thời gian kỉ lục của bạn", + "yourPrizeText": "Phần thưởng của bạn:" } \ No newline at end of file diff --git a/dist/ba_data/data/maps/bridgit.json b/dist/ba_data/data/maps/bridgit.json index 9a301226..96640a4d 100644 --- a/dist/ba_data/data/maps/bridgit.json +++ b/dist/ba_data/data/maps/bridgit.json @@ -53,41 +53,41 @@ "preview_texture": "bridgitPreview", "terrain_nodes": [ { - "collide_model": "bridgitLevelBottom", + "collision_mesh": "bridgitLevelBottom", "color_texture": "bridgitLevelColor", "comment": "Top portion of bridge.", "materials": ["footing"], - "model": "bridgitLevelTop" + "mesh": "bridgitLevelTop" }, { "color_texture": "bridgitLevelColor", "comment": "Bottom portion of bridge with no lighting effects.", "lighting": false, - "model": "bridgitLevelBottom" + "mesh": "bridgitLevelBottom" }, { "background": true, "color_texture": "natureBackgroundColor", "comment": "Visible background.", "lighting": false, - "model": "natureBackground" + "mesh": "natureBackground" }, { "background": true, - "color_texture": "model_bg_tex", + "color_texture": "mesh_bg_tex", "comment": "360 degree bg for vr.", "lighting": false, - "model": "bg_vr_fill_model", + "mesh": "bg_vr_fill_mesh", "vr_only": true }, { "bumper": true, - "collide_model": "railing_collide_model", + "collision_mesh": "railing_collide_mesh", "comment": "Invisible railing to help prevent falls.", "materials": ["railing"] }, { - "collide_model": "collide_bg", + "collision_mesh": "collide_bg", "comment": "Collision shape for bg", "materials": ["footing", "friction@10", "death"] } diff --git a/dist/ba_data/models/alwaysLandLevelCollide.cob b/dist/ba_data/meshes/alwaysLandLevelCollide.cob similarity index 100% rename from dist/ba_data/models/alwaysLandLevelCollide.cob rename to dist/ba_data/meshes/alwaysLandLevelCollide.cob diff --git a/dist/ba_data/models/bigGBumper.cob b/dist/ba_data/meshes/bigGBumper.cob similarity index 100% rename from dist/ba_data/models/bigGBumper.cob rename to dist/ba_data/meshes/bigGBumper.cob diff --git a/dist/ba_data/models/bigGCollide.cob b/dist/ba_data/meshes/bigGCollide.cob similarity index 100% rename from dist/ba_data/models/bigGCollide.cob rename to dist/ba_data/meshes/bigGCollide.cob diff --git a/dist/ba_data/models/bridgitLevelCollide.cob b/dist/ba_data/meshes/bridgitLevelCollide.cob similarity index 100% rename from dist/ba_data/models/bridgitLevelCollide.cob rename to dist/ba_data/meshes/bridgitLevelCollide.cob diff --git a/dist/ba_data/models/bridgitLevelRailingCollide.cob b/dist/ba_data/meshes/bridgitLevelRailingCollide.cob similarity index 100% rename from dist/ba_data/models/bridgitLevelRailingCollide.cob rename to dist/ba_data/meshes/bridgitLevelRailingCollide.cob diff --git a/dist/ba_data/models/courtyardLevelCollide.cob b/dist/ba_data/meshes/courtyardLevelCollide.cob similarity index 100% rename from dist/ba_data/models/courtyardLevelCollide.cob rename to dist/ba_data/meshes/courtyardLevelCollide.cob diff --git a/dist/ba_data/models/courtyardPlayerWall.cob b/dist/ba_data/meshes/courtyardPlayerWall.cob similarity index 100% rename from dist/ba_data/models/courtyardPlayerWall.cob rename to dist/ba_data/meshes/courtyardPlayerWall.cob diff --git a/dist/ba_data/models/cragCastleLevelBumper.cob b/dist/ba_data/meshes/cragCastleLevelBumper.cob similarity index 100% rename from dist/ba_data/models/cragCastleLevelBumper.cob rename to dist/ba_data/meshes/cragCastleLevelBumper.cob diff --git a/dist/ba_data/models/cragCastleLevelCollide.cob b/dist/ba_data/meshes/cragCastleLevelCollide.cob similarity index 100% rename from dist/ba_data/models/cragCastleLevelCollide.cob rename to dist/ba_data/meshes/cragCastleLevelCollide.cob diff --git a/dist/ba_data/models/doomShroomLevelCollide.cob b/dist/ba_data/meshes/doomShroomLevelCollide.cob similarity index 100% rename from dist/ba_data/models/doomShroomLevelCollide.cob rename to dist/ba_data/meshes/doomShroomLevelCollide.cob diff --git a/dist/ba_data/models/doomShroomStemCollide.cob b/dist/ba_data/meshes/doomShroomStemCollide.cob similarity index 100% rename from dist/ba_data/models/doomShroomStemCollide.cob rename to dist/ba_data/meshes/doomShroomStemCollide.cob diff --git a/dist/ba_data/models/footballStadiumCollide.cob b/dist/ba_data/meshes/footballStadiumCollide.cob similarity index 100% rename from dist/ba_data/models/footballStadiumCollide.cob rename to dist/ba_data/meshes/footballStadiumCollide.cob diff --git a/dist/ba_data/models/hockeyStadiumCollide.cob b/dist/ba_data/meshes/hockeyStadiumCollide.cob similarity index 100% rename from dist/ba_data/models/hockeyStadiumCollide.cob rename to dist/ba_data/meshes/hockeyStadiumCollide.cob diff --git a/dist/ba_data/models/lakeFrigidCollide.cob b/dist/ba_data/meshes/lakeFrigidCollide.cob similarity index 100% rename from dist/ba_data/models/lakeFrigidCollide.cob rename to dist/ba_data/meshes/lakeFrigidCollide.cob diff --git a/dist/ba_data/models/monkeyFaceLevelBumper.cob b/dist/ba_data/meshes/monkeyFaceLevelBumper.cob similarity index 100% rename from dist/ba_data/models/monkeyFaceLevelBumper.cob rename to dist/ba_data/meshes/monkeyFaceLevelBumper.cob diff --git a/dist/ba_data/models/monkeyFaceLevelCollide.cob b/dist/ba_data/meshes/monkeyFaceLevelCollide.cob similarity index 100% rename from dist/ba_data/models/monkeyFaceLevelCollide.cob rename to dist/ba_data/meshes/monkeyFaceLevelCollide.cob diff --git a/dist/ba_data/models/natureBackgroundCollide.cob b/dist/ba_data/meshes/natureBackgroundCollide.cob similarity index 100% rename from dist/ba_data/models/natureBackgroundCollide.cob rename to dist/ba_data/meshes/natureBackgroundCollide.cob diff --git a/dist/ba_data/models/rampageBumper.cob b/dist/ba_data/meshes/rampageBumper.cob similarity index 100% rename from dist/ba_data/models/rampageBumper.cob rename to dist/ba_data/meshes/rampageBumper.cob diff --git a/dist/ba_data/models/rampageLevelCollide.cob b/dist/ba_data/meshes/rampageLevelCollide.cob similarity index 100% rename from dist/ba_data/models/rampageLevelCollide.cob rename to dist/ba_data/meshes/rampageLevelCollide.cob diff --git a/dist/ba_data/models/roundaboutLevelBumper.cob b/dist/ba_data/meshes/roundaboutLevelBumper.cob similarity index 100% rename from dist/ba_data/models/roundaboutLevelBumper.cob rename to dist/ba_data/meshes/roundaboutLevelBumper.cob diff --git a/dist/ba_data/models/roundaboutLevelCollide.cob b/dist/ba_data/meshes/roundaboutLevelCollide.cob similarity index 100% rename from dist/ba_data/models/roundaboutLevelCollide.cob rename to dist/ba_data/meshes/roundaboutLevelCollide.cob diff --git a/dist/ba_data/models/stepRightUpLevelCollide.cob b/dist/ba_data/meshes/stepRightUpLevelCollide.cob similarity index 100% rename from dist/ba_data/models/stepRightUpLevelCollide.cob rename to dist/ba_data/meshes/stepRightUpLevelCollide.cob diff --git a/dist/ba_data/models/thePadLevelBumper.cob b/dist/ba_data/meshes/thePadLevelBumper.cob similarity index 100% rename from dist/ba_data/models/thePadLevelBumper.cob rename to dist/ba_data/meshes/thePadLevelBumper.cob diff --git a/dist/ba_data/models/thePadLevelCollide.cob b/dist/ba_data/meshes/thePadLevelCollide.cob similarity index 100% rename from dist/ba_data/models/thePadLevelCollide.cob rename to dist/ba_data/meshes/thePadLevelCollide.cob diff --git a/dist/ba_data/models/tipTopLevelBumper.cob b/dist/ba_data/meshes/tipTopLevelBumper.cob similarity index 100% rename from dist/ba_data/models/tipTopLevelBumper.cob rename to dist/ba_data/meshes/tipTopLevelBumper.cob diff --git a/dist/ba_data/models/tipTopLevelCollide.cob b/dist/ba_data/meshes/tipTopLevelCollide.cob similarity index 100% rename from dist/ba_data/models/tipTopLevelCollide.cob rename to dist/ba_data/meshes/tipTopLevelCollide.cob diff --git a/dist/ba_data/models/towerDLevelCollide.cob b/dist/ba_data/meshes/towerDLevelCollide.cob similarity index 100% rename from dist/ba_data/models/towerDLevelCollide.cob rename to dist/ba_data/meshes/towerDLevelCollide.cob diff --git a/dist/ba_data/models/towerDPlayerWall.cob b/dist/ba_data/meshes/towerDPlayerWall.cob similarity index 100% rename from dist/ba_data/models/towerDPlayerWall.cob rename to dist/ba_data/meshes/towerDPlayerWall.cob diff --git a/dist/ba_data/models/zigZagLevelBumper.cob b/dist/ba_data/meshes/zigZagLevelBumper.cob similarity index 100% rename from dist/ba_data/models/zigZagLevelBumper.cob rename to dist/ba_data/meshes/zigZagLevelBumper.cob diff --git a/dist/ba_data/models/zigZagLevelCollide.cob b/dist/ba_data/meshes/zigZagLevelCollide.cob similarity index 100% rename from dist/ba_data/models/zigZagLevelCollide.cob rename to dist/ba_data/meshes/zigZagLevelCollide.cob diff --git a/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst new file mode 100644 index 00000000..9d227a0c --- /dev/null +++ b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/METADATA b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/METADATA new file mode 100644 index 00000000..dfe37d52 --- /dev/null +++ b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/METADATA @@ -0,0 +1,93 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.5 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/markupsafe/ +Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + + >>> # escape replaces special characters and wraps in Markup + >>> escape("") + Markup('<script>alert(document.cookie);</script>') + + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup("Hello") + Markup('hello') + + >>> escape(Markup("Hello")) + Markup('hello') + + >>> # Markup is a str subclass + >>> # methods and operators escape their arguments + >>> template = Markup("Hello {name}") + >>> template.format(name='"World"') + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://markupsafe.palletsprojects.com/ +- Changes: https://markupsafe.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/MarkupSafe/ +- Source Code: https://github.com/pallets/markupsafe/ +- Issue Tracker: https://github.com/pallets/markupsafe/issues/ +- Chat: https://discord.gg/pallets diff --git a/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/RECORD b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/RECORD new file mode 100644 index 00000000..648ebd81 --- /dev/null +++ b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.5.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.1.5.dist-info/METADATA,sha256=2dRDPam6OZLfpX0wg1JN5P3u9arqACxVSfdGmsJU7o8,3003 +MarkupSafe-2.1.5.dist-info/RECORD,, +MarkupSafe-2.1.5.dist-info/WHEEL,sha256=vJMp7mUkE-fMIYyE5xJ9Q2cYPnWVgHf20clVdwMSXAg,152 +MarkupSafe-2.1.5.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=r7VOTjUq7EMQ4v3p4R1LoVOGJg6ysfYRncLr34laRBs,10958 +markupsafe/__pycache__/__init__.cpython-312.pyc,, +markupsafe/__pycache__/_native.cpython-312.pyc,, +markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713 +markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083 +markupsafe/_speedups.cpython-312-x86_64-linux-gnu.so,sha256=Y2jIPiSLPZlb82iRu9UUj27sbTui5o7SSoi-2SIXEUg,54072 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/WHEEL b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/WHEEL new file mode 100644 index 00000000..bd099b74 --- /dev/null +++ b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: false +Tag: cp312-cp312-manylinux_2_17_x86_64 +Tag: cp312-cp312-manylinux2014_x86_64 + diff --git a/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt new file mode 100644 index 00000000..75bf7292 --- /dev/null +++ b/dist/ba_data/python-site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-aarch64-linux-gnu.so b/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-aarch64-linux-gnu.so deleted file mode 100644 index f4b4204e..00000000 Binary files a/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-aarch64-linux-gnu.so and /dev/null differ diff --git a/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-x86_64-linux-gnu.so deleted file mode 100644 index af6999f6..00000000 Binary files a/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-x86_64-linux-gnu.so and /dev/null differ diff --git a/dist/ba_data/python-site-packages/_cffi_backend.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/_cffi_backend.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..867546ed Binary files /dev/null and b/dist/ba_data/python-site-packages/_cffi_backend.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/INSTALLER b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/LICENSE.txt b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/LICENSE.txt new file mode 100644 index 00000000..e497a322 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/LICENSE.txt @@ -0,0 +1,13 @@ + Copyright aio-libs contributors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/METADATA b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/METADATA new file mode 100644 index 00000000..cd312649 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/METADATA @@ -0,0 +1,245 @@ +Metadata-Version: 2.1 +Name: aiohttp +Version: 3.9.5 +Summary: Async http client/server framework (asyncio) +Home-page: https://github.com/aio-libs/aiohttp +Maintainer: aiohttp team +Maintainer-email: team@aiohttp.org +License: Apache 2 +Project-URL: Chat: Matrix, https://matrix.to/#/#aio-libs:matrix.org +Project-URL: Chat: Matrix Space, https://matrix.to/#/#aio-libs-space:matrix.org +Project-URL: CI: GitHub Actions, https://github.com/aio-libs/aiohttp/actions?query=workflow%3ACI +Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp +Project-URL: Docs: Changelog, https://docs.aiohttp.org/en/stable/changes.html +Project-URL: Docs: RTD, https://docs.aiohttp.org +Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues +Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: AsyncIO +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Internet :: WWW/HTTP +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE.txt +Requires-Dist: aiosignal >=1.1.2 +Requires-Dist: attrs >=17.3.0 +Requires-Dist: frozenlist >=1.1.1 +Requires-Dist: multidict <7.0,>=4.5 +Requires-Dist: yarl <2.0,>=1.0 +Requires-Dist: async-timeout <5.0,>=4.0 ; python_version < "3.11" +Provides-Extra: speedups +Requires-Dist: brotlicffi ; (platform_python_implementation != "CPython") and extra == 'speedups' +Requires-Dist: Brotli ; (platform_python_implementation == "CPython") and extra == 'speedups' +Requires-Dist: aiodns ; (sys_platform == "linux" or sys_platform == "darwin") and extra == 'speedups' + +================================== +Async http client/server framework +================================== + +.. image:: https://raw.githubusercontent.com/aio-libs/aiohttp/master/docs/aiohttp-plain.svg + :height: 64px + :width: 64px + :alt: aiohttp logo + +| + +.. image:: https://github.com/aio-libs/aiohttp/workflows/CI/badge.svg + :target: https://github.com/aio-libs/aiohttp/actions?query=workflow%3ACI + :alt: GitHub Actions status for master branch + +.. image:: https://codecov.io/gh/aio-libs/aiohttp/branch/master/graph/badge.svg + :target: https://codecov.io/gh/aio-libs/aiohttp + :alt: codecov.io status for master branch + +.. image:: https://badge.fury.io/py/aiohttp.svg + :target: https://pypi.org/project/aiohttp + :alt: Latest PyPI package version + +.. image:: https://readthedocs.org/projects/aiohttp/badge/?version=latest + :target: https://docs.aiohttp.org/ + :alt: Latest Read The Docs + +.. image:: https://img.shields.io/matrix/aio-libs:matrix.org?label=Discuss%20on%20Matrix%20at%20%23aio-libs%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat + :target: https://matrix.to/#/%23aio-libs:matrix.org + :alt: Matrix Room — #aio-libs:matrix.org + +.. image:: https://img.shields.io/matrix/aio-libs-space:matrix.org?label=Discuss%20on%20Matrix%20at%20%23aio-libs-space%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat + :target: https://matrix.to/#/%23aio-libs-space:matrix.org + :alt: Matrix Space — #aio-libs-space:matrix.org + + +Key Features +============ + +- Supports both client and server side of HTTP protocol. +- Supports both client and server Web-Sockets out-of-the-box and avoids + Callback Hell. +- Provides Web-server with middleware and pluggable routing. + + +Getting started +=============== + +Client +------ + +To get something from the web: + +.. code-block:: python + + import aiohttp + import asyncio + + async def main(): + + async with aiohttp.ClientSession() as session: + async with session.get('http://python.org') as response: + + print("Status:", response.status) + print("Content-type:", response.headers['content-type']) + + html = await response.text() + print("Body:", html[:15], "...") + + asyncio.run(main()) + +This prints: + +.. code-block:: + + Status: 200 + Content-type: text/html; charset=utf-8 + Body: ... + +Coming from `requests `_ ? Read `why we need so many lines `_. + +Server +------ + +An example using a simple server: + +.. code-block:: python + + # examples/server_simple.py + from aiohttp import web + + async def handle(request): + name = request.match_info.get('name', "Anonymous") + text = "Hello, " + name + return web.Response(text=text) + + async def wshandle(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + async for msg in ws: + if msg.type == web.WSMsgType.text: + await ws.send_str("Hello, {}".format(msg.data)) + elif msg.type == web.WSMsgType.binary: + await ws.send_bytes(msg.data) + elif msg.type == web.WSMsgType.close: + break + + return ws + + + app = web.Application() + app.add_routes([web.get('/', handle), + web.get('/echo', wshandle), + web.get('/{name}', handle)]) + + if __name__ == '__main__': + web.run_app(app) + + +Documentation +============= + +https://aiohttp.readthedocs.io/ + + +Demos +===== + +https://github.com/aio-libs/aiohttp-demos + + +External links +============== + +* `Third party libraries + `_ +* `Built with aiohttp + `_ +* `Powered by aiohttp + `_ + +Feel free to make a Pull Request for adding your link to these pages! + + +Communication channels +====================== + +*aio-libs Discussions*: https://github.com/aio-libs/aiohttp/discussions + +*gitter chat* https://gitter.im/aio-libs/Lobby + +We support `Stack Overflow +`_. +Please add *aiohttp* tag to your question there. + +Requirements +============ + +- async-timeout_ +- attrs_ +- multidict_ +- yarl_ +- frozenlist_ + +Optionally you may install the aiodns_ library (highly recommended for sake of speed). + +.. _aiodns: https://pypi.python.org/pypi/aiodns +.. _attrs: https://github.com/python-attrs/attrs +.. _multidict: https://pypi.python.org/pypi/multidict +.. _frozenlist: https://pypi.org/project/frozenlist/ +.. _yarl: https://pypi.python.org/pypi/yarl +.. _async-timeout: https://pypi.python.org/pypi/async_timeout + +License +======= + +``aiohttp`` is offered under the Apache 2 license. + + +Keepsafe +======== + +The aiohttp community would like to thank Keepsafe +(https://www.getkeepsafe.com) for its support in the early days of +the project. + + +Source code +=========== + +The latest developer version is available in a GitHub repository: +https://github.com/aio-libs/aiohttp + +Benchmarks +========== + +If you are interested in efficiency, the AsyncIO community maintains a +list of benchmarks on the official wiki: +https://github.com/python/asyncio/wiki/Benchmarks diff --git a/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/RECORD b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/RECORD new file mode 100644 index 00000000..6da9ccfe --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/RECORD @@ -0,0 +1,119 @@ +aiohttp-3.9.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +aiohttp-3.9.5.dist-info/LICENSE.txt,sha256=n4DQ2311WpQdtFchcsJw7L2PCCuiFd3QlZhZQu2Uqes,588 +aiohttp-3.9.5.dist-info/METADATA,sha256=TD5idczLj39MQNfk4DX6Dg33oZrl1YHK1vSnxNt5lOQ,7459 +aiohttp-3.9.5.dist-info/RECORD,, +aiohttp-3.9.5.dist-info/WHEEL,sha256=OvtvnbpcaxHa5TgXgfC48E6JA7zLr7svMspPP7Vk5o8,152 +aiohttp-3.9.5.dist-info/top_level.txt,sha256=iv-JIaacmTl-hSho3QmphcKnbRRYx1st47yjz_178Ro,8 +aiohttp/.hash/_cparser.pxd.hash,sha256=hYa9Vje-oMs2eh_7MfCPOh2QW_1x1yCjcZuc7AmwLd0,121 +aiohttp/.hash/_find_header.pxd.hash,sha256=_mbpD6vM-CVCKq3ulUvsOAz5Wdo88wrDzfpOsMQaMNA,125 +aiohttp/.hash/_helpers.pyi.hash,sha256=Ew4BZDc2LqFwszgZZUHHrJvw5P8HBhJ700n1Ntg52hE,121 +aiohttp/.hash/_helpers.pyx.hash,sha256=5JQ6BlMBE4HnRaCGdkK9_wpL3ZSWpU1gyLYva0Wwx2c,121 +aiohttp/.hash/_http_parser.pyx.hash,sha256=4RMfISkoa9dJKvYXpa_Qe7b_32v4k7HXpaGhgXcNK4k,125 +aiohttp/.hash/_http_writer.pyx.hash,sha256=3Qg3T3D-Ud73elzPHBufK0yEu9tP5jsu6g-aPKQY9gE,125 +aiohttp/.hash/_websocket.pyx.hash,sha256=M97f-Yti-4vnE4GNTD1s_DzKs-fG_ww3jle6EUvixnE,123 +aiohttp/.hash/hdrs.py.hash,sha256=2oEszMWjYFTHoF2w4OcFCoM7osv4vY9KLLJCu9HP0xI,116 +aiohttp/__init__.py,sha256=f4PQQkLHI2og_KChLyaIzT1iOTIajtmT62yHfpn-XhU,7762 +aiohttp/__pycache__/__init__.cpython-312.pyc,, +aiohttp/__pycache__/abc.cpython-312.pyc,, +aiohttp/__pycache__/base_protocol.cpython-312.pyc,, +aiohttp/__pycache__/client.cpython-312.pyc,, +aiohttp/__pycache__/client_exceptions.cpython-312.pyc,, +aiohttp/__pycache__/client_proto.cpython-312.pyc,, +aiohttp/__pycache__/client_reqrep.cpython-312.pyc,, +aiohttp/__pycache__/client_ws.cpython-312.pyc,, +aiohttp/__pycache__/compression_utils.cpython-312.pyc,, +aiohttp/__pycache__/connector.cpython-312.pyc,, +aiohttp/__pycache__/cookiejar.cpython-312.pyc,, +aiohttp/__pycache__/formdata.cpython-312.pyc,, +aiohttp/__pycache__/hdrs.cpython-312.pyc,, +aiohttp/__pycache__/helpers.cpython-312.pyc,, +aiohttp/__pycache__/http.cpython-312.pyc,, +aiohttp/__pycache__/http_exceptions.cpython-312.pyc,, +aiohttp/__pycache__/http_parser.cpython-312.pyc,, +aiohttp/__pycache__/http_websocket.cpython-312.pyc,, +aiohttp/__pycache__/http_writer.cpython-312.pyc,, +aiohttp/__pycache__/locks.cpython-312.pyc,, +aiohttp/__pycache__/log.cpython-312.pyc,, +aiohttp/__pycache__/multipart.cpython-312.pyc,, +aiohttp/__pycache__/payload.cpython-312.pyc,, +aiohttp/__pycache__/payload_streamer.cpython-312.pyc,, +aiohttp/__pycache__/pytest_plugin.cpython-312.pyc,, +aiohttp/__pycache__/resolver.cpython-312.pyc,, +aiohttp/__pycache__/streams.cpython-312.pyc,, +aiohttp/__pycache__/tcp_helpers.cpython-312.pyc,, +aiohttp/__pycache__/test_utils.cpython-312.pyc,, +aiohttp/__pycache__/tracing.cpython-312.pyc,, +aiohttp/__pycache__/typedefs.cpython-312.pyc,, +aiohttp/__pycache__/web.cpython-312.pyc,, +aiohttp/__pycache__/web_app.cpython-312.pyc,, +aiohttp/__pycache__/web_exceptions.cpython-312.pyc,, +aiohttp/__pycache__/web_fileresponse.cpython-312.pyc,, +aiohttp/__pycache__/web_log.cpython-312.pyc,, +aiohttp/__pycache__/web_middlewares.cpython-312.pyc,, +aiohttp/__pycache__/web_protocol.cpython-312.pyc,, +aiohttp/__pycache__/web_request.cpython-312.pyc,, +aiohttp/__pycache__/web_response.cpython-312.pyc,, +aiohttp/__pycache__/web_routedef.cpython-312.pyc,, +aiohttp/__pycache__/web_runner.cpython-312.pyc,, +aiohttp/__pycache__/web_server.cpython-312.pyc,, +aiohttp/__pycache__/web_urldispatcher.cpython-312.pyc,, +aiohttp/__pycache__/web_ws.cpython-312.pyc,, +aiohttp/__pycache__/worker.cpython-312.pyc,, +aiohttp/_cparser.pxd,sha256=8jGIg-VJ9p3llwCakUYDsPGxA4HiZe9dmK9Jmtlz-5g,4318 +aiohttp/_find_header.pxd,sha256=0GfwFCPN2zxEKTO1_MA5sYq2UfzsG8kcV3aTqvwlz3g,68 +aiohttp/_headers.pxi,sha256=n701k28dVPjwRnx5j6LpJhLTfj7dqu2vJt7f0O60Oyg,2007 +aiohttp/_helpers.cpython-312-x86_64-linux-gnu.so,sha256=7Ontevet_I6TNceZkVobXKqqoYO7-I9LBHdQi6lPjFY,613312 +aiohttp/_helpers.pyi,sha256=ZoKiJSS51PxELhI2cmIr5737YjjZcJt7FbIRO3ym1Ss,202 +aiohttp/_helpers.pyx,sha256=XeLbNft5X_4ifi8QB8i6TyrRuayijMSO3IDHeSA89uM,1049 +aiohttp/_http_parser.cpython-312-x86_64-linux-gnu.so,sha256=5daeJlbYN2v_gGfCjycRsaUwkrNjX4YKktYVIFLULdc,2791056 +aiohttp/_http_parser.pyx,sha256=q68Rq06MpW-QwLxriE3hIJmWIKc4lVFaWHU3clsHd4Y,28125 +aiohttp/_http_writer.cpython-312-x86_64-linux-gnu.so,sha256=zwR7Su1KC-IPDnC4IUAbCR3oM3dbu5ZsLQaJNKvui5w,503160 +aiohttp/_http_writer.pyx,sha256=aIHAp8g4ZV5kbGRdmZce-vXjELw2M6fGKyJuOdgYQqw,4575 +aiohttp/_websocket.cpython-312-x86_64-linux-gnu.so,sha256=egxd5kxts0IOTTIWVaK15qDADrWbquvqAumjJzMxLv8,278192 +aiohttp/_websocket.pyx,sha256=1XuOSNDCbyDrzF5uMA2isqausSs8l2jWTLDlNDLM9Io,1561 +aiohttp/abc.py,sha256=WGZ5HH0hoCH77qaISTb689ygpS9CxfKkgUCOcgjU2lo,5500 +aiohttp/base_protocol.py,sha256=HJ5SxzbzYewj-sjoKMbD6i5rDYEv9Zo7Q_cyV3Wvn6o,2876 +aiohttp/client.py,sha256=PPUMNromtwqttMy5rzxmZ9ZjMFvqglvPdYG-A96lHhU,47499 +aiohttp/client_exceptions.py,sha256=7lx_YWAauUQVOxg_RehW9HZE344ak3lGmVJHfCrmb-A,9411 +aiohttp/client_proto.py,sha256=kCRlCOYxiuUv83cHz-gDYF0bK4Ye_KgkhYibjqTpN_M,9910 +aiohttp/client_reqrep.py,sha256=bt5woKRdhImzsEqg39a-O0yqswY8adguODtE-ui2RxE,40075 +aiohttp/client_ws.py,sha256=nNrwu1wA0U3B0cNsVr61QfV2S60bbKfaZXHfW7klFl4,11010 +aiohttp/compression_utils.py,sha256=GCkBNJqrybMhiTQGwqqhORnaTLpRFZD_-UvRtnZ5lEQ,5015 +aiohttp/connector.py,sha256=meq8urjMWelJnG26VgkA3ibrIioaEWqujg3jjNAKG28,53796 +aiohttp/cookiejar.py,sha256=PdvsOiDasDYYUOPaaAfuuFJzR4CJyHHjut02YiZ_N8M,14015 +aiohttp/formdata.py,sha256=WjHA1mieKlWwI5O3hi3-siqN0dWz_X04oXNNZje2z7Q,6521 +aiohttp/hdrs.py,sha256=uzn5agn_jXid2h-ky6Y0ZAQ8BrPeTGLDGr-weiMctso,4613 +aiohttp/helpers.py,sha256=EAZ1V0pGfv2xRiWfhjubBqgLBI0aK-CXlUlYss3EYzo,30988 +aiohttp/http.py,sha256=8o8j8xH70OWjnfTWA9V44NR785QPxEPrUtzMXiAVpwc,1842 +aiohttp/http_exceptions.py,sha256=7LOFFUwq04fZsnZA-NP5nukd6c2i8daM8-ejj3ndbSQ,2716 +aiohttp/http_parser.py,sha256=zuG3C-WOUVjoNTqgsrdCorzCGoXbR0gHhma3G___zOA,36507 +aiohttp/http_websocket.py,sha256=9Kfp5e4TU1JJfEvJ7l1Kt6Cr2HZX3z_RIojN8BAriPI,26732 +aiohttp/http_writer.py,sha256=fxpyRj_S3WcBl9fxxF05t8YYAUA-0jW5b_PjVSluT3Y,5933 +aiohttp/locks.py,sha256=wRYFo1U82LwBBdqwU24JEPaoTAlKaaJd2FtfDKhkTb4,1136 +aiohttp/log.py,sha256=BbNKx9e3VMIm0xYjZI0IcBBoS7wjdeIeSaiJE7-qK2g,325 +aiohttp/multipart.py,sha256=xBmudauxLHuXajWQMVl647sNS9IzzMYeEMKay4C0qVw,34937 +aiohttp/payload.py,sha256=xK04Z-TSao-qiYVMnphKG9-6yOvoqGsZBM7egUS4n9A,13542 +aiohttp/payload_streamer.py,sha256=eAS8S-UWfLkEMavRjP2Uu9amC3PnbV79wHTNDoRmYn8,2087 +aiohttp/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7 +aiohttp/pytest_plugin.py,sha256=3IwpuxtFiUVFGS_ZitWuqvECSGgXQWvCW312B2TaVLY,11605 +aiohttp/resolver.py,sha256=8peXjB482v0hg1ESn87op6f-UeLXk_fAMxQo_23Ek6M,5070 +aiohttp/streams.py,sha256=LWlr0gE44cjKzBU9I15vWwlorPW8ZAU-M2Sgz_UdjWM,21128 +aiohttp/tcp_helpers.py,sha256=BSadqVWaBpMFDRWnhaaR941N9MiDZ7bdTrxgCb0CW-M,961 +aiohttp/test_utils.py,sha256=8-McpBCAzFbA17yeEW9UYVKBypu-Hm_407ppQy76XWU,20475 +aiohttp/tracing.py,sha256=W94gFgxFtXSBWMU4ajbrOH61mJ4mElRmfyxNUw6FwIA,15132 +aiohttp/typedefs.py,sha256=f-EzBBgQAxNLiTUtkjgMAL5LQt81HloYTesxnhNM03U,1471 +aiohttp/web.py,sha256=HFTQaoYVK5pM3YmxNJtZl9fGrRIdFs_Nhloxe7_lJj0,19263 +aiohttp/web_app.py,sha256=4cXDqZV-KR0xMnUhQ471bsEACIsoI4_BkDJ3haXyG_I,18311 +aiohttp/web_exceptions.py,sha256=7nIuiwhZ39vJJ9KrWqArA5QcWbUdqkz2CLwEpJapeN8,10360 +aiohttp/web_fileresponse.py,sha256=33VS-6CQd4ZiezNBVZaVxWBCLuOUK_vPMNTU1ojiV80,11569 +aiohttp/web_log.py,sha256=DOfOxGyh2U7K5K_w6O7ILdfGcs4qOdzHxOwj2-k3c6c,7801 +aiohttp/web_middlewares.py,sha256=q6i0GGiVvUlpGtsbZmp88-zFIKQHwYtDd5SpBvKFdEY,4032 +aiohttp/web_protocol.py,sha256=8kAxmDpRYczyCFtUS4vDEIORgbD4WV0CTjVi-fZVykE,23060 +aiohttp/web_request.py,sha256=UyDR4JQwogyX12FS8PpMl-1d6ZG-TE02Bt2nPOEk0HI,28986 +aiohttp/web_response.py,sha256=3jfYnRpsNnxGRUAm-VNGu18Ekw5XyuYp7c7fzbOwbqY,27858 +aiohttp/web_routedef.py,sha256=Y5DPVa7D1uJp37HP6YXrO8Cd1BrEtDyS-fljOUdPk30,6132 +aiohttp/web_runner.py,sha256=rGI6zeIXZNDepvJajc8ZXue9hn0O2wSmh8S7CuXhkUI,11951 +aiohttp/web_server.py,sha256=5P-9uPCoPEDkK9ILbvEXmkkJWPhnTxBzdwAXwveyyDk,2587 +aiohttp/web_urldispatcher.py,sha256=e9QueGUecnOZq44CpfKJCjWi_IXHqHADUmIh_mzli18,40132 +aiohttp/web_ws.py,sha256=eiLuPZnB6HFXagcdZzU9jD9aKXP3K6YNDXDIoOpN8co,18960 +aiohttp/worker.py,sha256=bkozEd2rAzQS0qs4knnnplOmaZ4TNdYtqWXSXx9djEc,7965 diff --git a/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/WHEEL b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/WHEEL new file mode 100644 index 00000000..db05d97d --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.43.0) +Root-Is-Purelib: false +Tag: cp312-cp312-manylinux_2_17_x86_64 +Tag: cp312-cp312-manylinux2014_x86_64 + diff --git a/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/top_level.txt b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/top_level.txt new file mode 100644 index 00000000..ee4ba4f3 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp-3.9.5.dist-info/top_level.txt @@ -0,0 +1 @@ +aiohttp diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash index 5d764977..65e3d4ba 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash @@ -1 +1 @@ -c6fb0b975dd95d7c871b26f652ced6b0b9dc9dd42bc61c860782979ef6ec46d4 *D:/a/aiohttp/aiohttp/aiohttp/_cparser.pxd +f2318883e549f69de597009a914603b0f1b10381e265ef5d98af499ad973fb98 /home/runner/work/aiohttp/aiohttp/aiohttp/_cparser.pxd diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash index 8af9f81d..f006c2de 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash @@ -1 +1 @@ -0455129b185e981b5b96ac738f31f7c74dc57f1696953cae0083b3f18679fe73 *D:/a/aiohttp/aiohttp/aiohttp/_find_header.pxd +d067f01423cddb3c442933b5fcc039b18ab651fcec1bc91c577693aafc25cf78 /home/runner/work/aiohttp/aiohttp/aiohttp/_find_header.pxd diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_frozenlist.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_frozenlist.pyx.hash deleted file mode 100644 index 01fdf2b1..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_frozenlist.pyx.hash +++ /dev/null @@ -1 +0,0 @@ -481f39d4a9ad5a9889d99074e53a68e3ce795640b246d80cb3ce375b3f2415e8 *D:/a/aiohttp/aiohttp/aiohttp/_frozenlist.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash index 82a670d9..6a30d632 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash @@ -1 +1 @@ -d87779202d197f8613109e35dacbb2ca1b21d64572543bf9838b2d832a362ac7 *D:/a/aiohttp/aiohttp/aiohttp/_helpers.pyi +6682a22524b9d4fc442e123672622be7bdfb6238d9709b7b15b2113b7ca6d52b /home/runner/work/aiohttp/aiohttp/aiohttp/_helpers.pyi diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash index 251b846c..8f38727d 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash @@ -1 +1 @@ -b6097b7d987440c4fa7237f88d227c89a3ba0dd403dc638ddbe487e0de7f1138 *D:/a/aiohttp/aiohttp/aiohttp/_helpers.pyx +5de2db35fb795ffe227e2f1007c8ba4f2ad1b9aca28cc48edc80c779203cf6e3 /home/runner/work/aiohttp/aiohttp/aiohttp/_helpers.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash index 5c431a9e..215a0da3 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash @@ -1 +1 @@ -83c05185224ad57f133f7fd5d56c331f4f9e101cd52f91237e7b6568b5459e1c *D:/a/aiohttp/aiohttp/aiohttp/_http_parser.pyx +abaf11ab4e8ca56f90c0bc6b884de120999620a73895515a587537725b077786 /home/runner/work/aiohttp/aiohttp/aiohttp/_http_parser.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash index e2a14a87..8e1aaab0 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash @@ -1 +1 @@ -ac1cdb93ec6b2163b6843d242a8e482ca48ab16fd4f177f5e4800f9ea487db74 *D:/a/aiohttp/aiohttp/aiohttp/_http_writer.pyx +6881c0a7c838655e646c645d99971efaf5e310bc3633a7c62b226e39d81842ac /home/runner/work/aiohttp/aiohttp/aiohttp/_http_writer.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash index 1a3346e3..ddbb4c7a 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash @@ -1 +1 @@ -a3d27bca2f5cdbe8d3063137754917c610d62af456273e4665fc8bb202506b7f *D:/a/aiohttp/aiohttp/aiohttp/_websocket.pyx +d57b8e48d0c26f20ebcc5e6e300da2b2a6aeb12b3c9768d64cb0e53432ccf48a /home/runner/work/aiohttp/aiohttp/aiohttp/_websocket.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/frozenlist.pyi.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/frozenlist.pyi.hash deleted file mode 100644 index 918409f9..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/frozenlist.pyi.hash +++ /dev/null @@ -1 +0,0 @@ -9011bd27ad72982aa252f064ae3b1119599f6a49a4ce4e8a1e665b76044b0996 *D:/a/aiohttp/aiohttp/aiohttp/frozenlist.pyi diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash index b69b16ad..e0b81d76 100644 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash @@ -1 +1 @@ -5f2bdc50368865ef87528ae8fd6820c8b35677209c5430b669c8857abedb9e94 *D:/a/aiohttp/aiohttp/aiohttp/hdrs.py +bb39f96a09ff8d789dda1fa4cba63464043c06b3de4c62c31abfb07a231cb6ca /home/runner/work/aiohttp/aiohttp/aiohttp/hdrs.py diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/signals.pyi.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/signals.pyi.hash deleted file mode 100644 index fc136a64..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/.hash/signals.pyi.hash +++ /dev/null @@ -1 +0,0 @@ -1273686ce37b6b3150d5f1d28a496f6ebbd07d05273993e2de7ffaa4a1335e83 *D:/a/aiohttp/aiohttp/aiohttp/signals.pyi diff --git a/dist/ba_data/python-site-packages/aiohttp/__init__.py b/dist/ba_data/python-site-packages/aiohttp/__init__.py index 12c73f4a..e82e790b 100644 --- a/dist/ba_data/python-site-packages/aiohttp/__init__.py +++ b/dist/ba_data/python-site-packages/aiohttp/__init__.py @@ -1,6 +1,6 @@ -__version__ = "3.7.4.post0" +__version__ = "3.9.5" -from typing import Tuple +from typing import TYPE_CHECKING, Tuple from . import hdrs as hdrs from .client import ( @@ -38,7 +38,7 @@ ) from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar from .formdata import FormData as FormData -from .helpers import BasicAuth as BasicAuth, ChainMapProxy as ChainMapProxy +from .helpers import BasicAuth, ChainMapProxy, ETag from .http import ( HttpVersion as HttpVersion, HttpVersion10 as HttpVersion10, @@ -78,7 +78,6 @@ DefaultResolver as DefaultResolver, ThreadedResolver as ThreadedResolver, ) -from .signals import Signal as Signal from .streams import ( EMPTY_PAYLOAD as EMPTY_PAYLOAD, DataQueue as DataQueue, @@ -105,6 +104,13 @@ TraceResponseChunkReceivedParams as TraceResponseChunkReceivedParams, ) +if TYPE_CHECKING: + # At runtime these are lazy-loaded at the bottom of the file. + from .worker import ( + GunicornUVLoopWebWorker as GunicornUVLoopWebWorker, + GunicornWebWorker as GunicornWebWorker, + ) + __all__: Tuple[str, ...] = ( "hdrs", # client @@ -147,6 +153,7 @@ # helpers "BasicAuth", "ChainMapProxy", + "ETag", # http "HttpVersion", "HttpVersion10", @@ -183,8 +190,7 @@ "AsyncResolver", "DefaultResolver", "ThreadedResolver", - # signals - "Signal", + # streams "DataQueue", "EMPTY_PAYLOAD", "EofStream", @@ -207,11 +213,28 @@ "TraceRequestRedirectParams", "TraceRequestStartParams", "TraceResponseChunkReceivedParams", + # workers (imported lazily with __getattr__) + "GunicornUVLoopWebWorker", + "GunicornWebWorker", ) -try: - from .worker import GunicornUVLoopWebWorker, GunicornWebWorker - __all__ += ("GunicornWebWorker", "GunicornUVLoopWebWorker") -except ImportError: # pragma: no cover - pass +def __dir__() -> Tuple[str, ...]: + return __all__ + ("__author__", "__doc__") + + +def __getattr__(name: str) -> object: + global GunicornUVLoopWebWorker, GunicornWebWorker + + # Importing gunicorn takes a long time (>100ms), so only import if actually needed. + if name in ("GunicornUVLoopWebWorker", "GunicornWebWorker"): + try: + from .worker import GunicornUVLoopWebWorker as guv, GunicornWebWorker as gw + except ImportError: + return None + + GunicornUVLoopWebWorker = guv # type: ignore[misc] + GunicornWebWorker = gw # type: ignore[misc] + return guv if name == "GunicornUVLoopWebWorker" else gw + + raise AttributeError(f"module {__name__} has no attribute {name}") diff --git a/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd b/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd index 0f9fc009..c2cd5a92 100644 --- a/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd +++ b/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd @@ -1,140 +1,158 @@ -from libc.stdint cimport uint16_t, uint32_t, uint64_t +from libc.stdint cimport int32_t, uint8_t, uint16_t, uint64_t -cdef extern from "../vendor/http-parser/http_parser.h": - ctypedef int (*http_data_cb) (http_parser*, - const char *at, - size_t length) except -1 +cdef extern from "../vendor/llhttp/build/llhttp.h": - ctypedef int (*http_cb) (http_parser*) except -1 - - struct http_parser: - unsigned int type - unsigned int flags - unsigned int state - unsigned int header_state - unsigned int index - - uint32_t nread + struct llhttp__internal_s: + int32_t _index + void* _span_pos0 + void* _span_cb0 + int32_t error + const char* reason + const char* error_pos + void* data + void* _current uint64_t content_length - - unsigned short http_major - unsigned short http_minor - unsigned int status_code - unsigned int method - unsigned int http_errno - - unsigned int upgrade - - void *data - - struct http_parser_settings: - http_cb on_message_begin - http_data_cb on_url - http_data_cb on_status - http_data_cb on_header_field - http_data_cb on_header_value - http_cb on_headers_complete - http_data_cb on_body - http_cb on_message_complete - http_cb on_chunk_header - http_cb on_chunk_complete - - enum http_parser_type: - HTTP_REQUEST, - HTTP_RESPONSE, - HTTP_BOTH - - enum http_errno: + uint8_t type + uint8_t method + uint8_t http_major + uint8_t http_minor + uint8_t header_state + uint8_t lenient_flags + uint8_t upgrade + uint8_t finish + uint16_t flags + uint16_t status_code + void* settings + + ctypedef llhttp__internal_s llhttp__internal_t + ctypedef llhttp__internal_t llhttp_t + + ctypedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length) except -1 + ctypedef int (*llhttp_cb)(llhttp_t*) except -1 + + struct llhttp_settings_s: + llhttp_cb on_message_begin + llhttp_data_cb on_url + llhttp_data_cb on_status + llhttp_data_cb on_header_field + llhttp_data_cb on_header_value + llhttp_cb on_headers_complete + llhttp_data_cb on_body + llhttp_cb on_message_complete + llhttp_cb on_chunk_header + llhttp_cb on_chunk_complete + + llhttp_cb on_url_complete + llhttp_cb on_status_complete + llhttp_cb on_header_field_complete + llhttp_cb on_header_value_complete + + ctypedef llhttp_settings_s llhttp_settings_t + + enum llhttp_errno: HPE_OK, - HPE_CB_message_begin, - HPE_CB_url, - HPE_CB_header_field, - HPE_CB_header_value, - HPE_CB_headers_complete, - HPE_CB_body, - HPE_CB_message_complete, - HPE_CB_status, - HPE_CB_chunk_header, - HPE_CB_chunk_complete, - HPE_INVALID_EOF_STATE, - HPE_HEADER_OVERFLOW, + HPE_INTERNAL, + HPE_STRICT, + HPE_LF_EXPECTED, + HPE_UNEXPECTED_CONTENT_LENGTH, HPE_CLOSED_CONNECTION, - HPE_INVALID_VERSION, - HPE_INVALID_STATUS, HPE_INVALID_METHOD, HPE_INVALID_URL, - HPE_INVALID_HOST, - HPE_INVALID_PORT, - HPE_INVALID_PATH, - HPE_INVALID_QUERY_STRING, - HPE_INVALID_FRAGMENT, - HPE_LF_EXPECTED, + HPE_INVALID_CONSTANT, + HPE_INVALID_VERSION, HPE_INVALID_HEADER_TOKEN, HPE_INVALID_CONTENT_LENGTH, HPE_INVALID_CHUNK_SIZE, - HPE_INVALID_CONSTANT, - HPE_INVALID_INTERNAL_STATE, - HPE_STRICT, + HPE_INVALID_STATUS, + HPE_INVALID_EOF_STATE, + HPE_INVALID_TRANSFER_ENCODING, + HPE_CB_MESSAGE_BEGIN, + HPE_CB_HEADERS_COMPLETE, + HPE_CB_MESSAGE_COMPLETE, + HPE_CB_CHUNK_HEADER, + HPE_CB_CHUNK_COMPLETE, HPE_PAUSED, - HPE_UNKNOWN + HPE_PAUSED_UPGRADE, + HPE_USER - enum flags: + ctypedef llhttp_errno llhttp_errno_t + + enum llhttp_flags: F_CHUNKED, - F_CONNECTION_KEEP_ALIVE, - F_CONNECTION_CLOSE, - F_CONNECTION_UPGRADE, - F_TRAILING, - F_UPGRADE, - F_SKIPBODY, - F_CONTENTLENGTH - - enum http_method: - DELETE, GET, HEAD, POST, PUT, CONNECT, OPTIONS, TRACE, COPY, - LOCK, MKCOL, MOVE, PROPFIND, PROPPATCH, SEARCH, UNLOCK, BIND, - REBIND, UNBIND, ACL, REPORT, MKACTIVITY, CHECKOUT, MERGE, - MSEARCH, NOTIFY, SUBSCRIBE, UNSUBSCRIBE, PATCH, PURGE, MKCALENDAR, - LINK, UNLINK - - void http_parser_init(http_parser *parser, http_parser_type type) - - size_t http_parser_execute(http_parser *parser, - const http_parser_settings *settings, - const char *data, - size_t len) - - int http_should_keep_alive(const http_parser *parser) - - void http_parser_settings_init(http_parser_settings *settings) - - const char *http_errno_name(http_errno err) - const char *http_errno_description(http_errno err) - const char *http_method_str(http_method m) - - # URL Parser - - enum http_parser_url_fields: - UF_SCHEMA = 0, - UF_HOST = 1, - UF_PORT = 2, - UF_PATH = 3, - UF_QUERY = 4, - UF_FRAGMENT = 5, - UF_USERINFO = 6, - UF_MAX = 7 - - struct http_parser_url_field_data: - uint16_t off - uint16_t len - - struct http_parser_url: - uint16_t field_set - uint16_t port - http_parser_url_field_data[UF_MAX] field_data - - void http_parser_url_init(http_parser_url *u) - - int http_parser_parse_url(const char *buf, - size_t buflen, - int is_connect, - http_parser_url *u) + F_CONTENT_LENGTH + + enum llhttp_type: + HTTP_REQUEST, + HTTP_RESPONSE, + HTTP_BOTH + + enum llhttp_method: + HTTP_DELETE, + HTTP_GET, + HTTP_HEAD, + HTTP_POST, + HTTP_PUT, + HTTP_CONNECT, + HTTP_OPTIONS, + HTTP_TRACE, + HTTP_COPY, + HTTP_LOCK, + HTTP_MKCOL, + HTTP_MOVE, + HTTP_PROPFIND, + HTTP_PROPPATCH, + HTTP_SEARCH, + HTTP_UNLOCK, + HTTP_BIND, + HTTP_REBIND, + HTTP_UNBIND, + HTTP_ACL, + HTTP_REPORT, + HTTP_MKACTIVITY, + HTTP_CHECKOUT, + HTTP_MERGE, + HTTP_MSEARCH, + HTTP_NOTIFY, + HTTP_SUBSCRIBE, + HTTP_UNSUBSCRIBE, + HTTP_PATCH, + HTTP_PURGE, + HTTP_MKCALENDAR, + HTTP_LINK, + HTTP_UNLINK, + HTTP_SOURCE, + HTTP_PRI, + HTTP_DESCRIBE, + HTTP_ANNOUNCE, + HTTP_SETUP, + HTTP_PLAY, + HTTP_PAUSE, + HTTP_TEARDOWN, + HTTP_GET_PARAMETER, + HTTP_SET_PARAMETER, + HTTP_REDIRECT, + HTTP_RECORD, + HTTP_FLUSH + + ctypedef llhttp_method llhttp_method_t; + + void llhttp_settings_init(llhttp_settings_t* settings) + void llhttp_init(llhttp_t* parser, llhttp_type type, + const llhttp_settings_t* settings) + + llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) + + int llhttp_should_keep_alive(const llhttp_t* parser) + + void llhttp_resume_after_upgrade(llhttp_t* parser) + + llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) + const char* llhttp_get_error_reason(const llhttp_t* parser) + const char* llhttp_get_error_pos(const llhttp_t* parser) + + const char* llhttp_method_name(llhttp_method_t method) + + void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) + void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled) + void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled) diff --git a/dist/ba_data/python-site-packages/aiohttp/_find_header.c b/dist/ba_data/python-site-packages/aiohttp/_find_header.c deleted file mode 100644 index 012cba33..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_find_header.c +++ /dev/null @@ -1,9870 +0,0 @@ -/* The file is autogenerated from aiohttp/hdrs.py -Run ./tools/gen.py to update it after the origin changing. */ - -#include "_find_header.h" - -#define NEXT_CHAR() \ -{ \ - count++; \ - if (count == size) { \ - /* end of search */ \ - return -1; \ - } \ - pchar++; \ - ch = *pchar; \ - last = (count == size -1); \ -} while(0); - -int -find_header(const char *str, int size) -{ - char *pchar = str; - int last; - char ch; - int count = -1; - pchar--; - - - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto A; - case 'a': - if (last) { - return -1; - } - goto A; - case 'C': - if (last) { - return -1; - } - goto C; - case 'c': - if (last) { - return -1; - } - goto C; - case 'D': - if (last) { - return -1; - } - goto D; - case 'd': - if (last) { - return -1; - } - goto D; - case 'E': - if (last) { - return -1; - } - goto E; - case 'e': - if (last) { - return -1; - } - goto E; - case 'F': - if (last) { - return -1; - } - goto F; - case 'f': - if (last) { - return -1; - } - goto F; - case 'H': - if (last) { - return -1; - } - goto H; - case 'h': - if (last) { - return -1; - } - goto H; - case 'I': - if (last) { - return -1; - } - goto I; - case 'i': - if (last) { - return -1; - } - goto I; - case 'K': - if (last) { - return -1; - } - goto K; - case 'k': - if (last) { - return -1; - } - goto K; - case 'L': - if (last) { - return -1; - } - goto L; - case 'l': - if (last) { - return -1; - } - goto L; - case 'M': - if (last) { - return -1; - } - goto M; - case 'm': - if (last) { - return -1; - } - goto M; - case 'O': - if (last) { - return -1; - } - goto O; - case 'o': - if (last) { - return -1; - } - goto O; - case 'P': - if (last) { - return -1; - } - goto P; - case 'p': - if (last) { - return -1; - } - goto P; - case 'R': - if (last) { - return -1; - } - goto R; - case 'r': - if (last) { - return -1; - } - goto R; - case 'S': - if (last) { - return -1; - } - goto S; - case 's': - if (last) { - return -1; - } - goto S; - case 'T': - if (last) { - return -1; - } - goto T; - case 't': - if (last) { - return -1; - } - goto T; - case 'U': - if (last) { - return -1; - } - goto U; - case 'u': - if (last) { - return -1; - } - goto U; - case 'V': - if (last) { - return -1; - } - goto V; - case 'v': - if (last) { - return -1; - } - goto V; - case 'W': - if (last) { - return -1; - } - goto W; - case 'w': - if (last) { - return -1; - } - goto W; - case 'X': - if (last) { - return -1; - } - goto X; - case 'x': - if (last) { - return -1; - } - goto X; - default: - return -1; - } - -A: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto AC; - case 'c': - if (last) { - return -1; - } - goto AC; - case 'G': - if (last) { - return -1; - } - goto AG; - case 'g': - if (last) { - return -1; - } - goto AG; - case 'L': - if (last) { - return -1; - } - goto AL; - case 'l': - if (last) { - return -1; - } - goto AL; - case 'U': - if (last) { - return -1; - } - goto AU; - case 'u': - if (last) { - return -1; - } - goto AU; - default: - return -1; - } - -AC: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto ACC; - case 'c': - if (last) { - return -1; - } - goto ACC; - default: - return -1; - } - -ACC: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCE; - case 'e': - if (last) { - return -1; - } - goto ACCE; - default: - return -1; - } - -ACCE: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto ACCEP; - case 'p': - if (last) { - return -1; - } - goto ACCEP; - case 'S': - if (last) { - return -1; - } - goto ACCES; - case 's': - if (last) { - return -1; - } - goto ACCES; - default: - return -1; - } - -ACCEP: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 0; - } - goto ACCEPT; - case 't': - if (last) { - return 0; - } - goto ACCEPT; - default: - return -1; - } - -ACCEPT: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCEPT_; - default: - return -1; - } - -ACCEPT_: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto ACCEPT_C; - case 'c': - if (last) { - return -1; - } - goto ACCEPT_C; - case 'E': - if (last) { - return -1; - } - goto ACCEPT_E; - case 'e': - if (last) { - return -1; - } - goto ACCEPT_E; - case 'L': - if (last) { - return -1; - } - goto ACCEPT_L; - case 'l': - if (last) { - return -1; - } - goto ACCEPT_L; - case 'R': - if (last) { - return -1; - } - goto ACCEPT_R; - case 'r': - if (last) { - return -1; - } - goto ACCEPT_R; - default: - return -1; - } - -ACCEPT_C: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto ACCEPT_CH; - case 'h': - if (last) { - return -1; - } - goto ACCEPT_CH; - default: - return -1; - } - -ACCEPT_CH: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCEPT_CHA; - case 'a': - if (last) { - return -1; - } - goto ACCEPT_CHA; - default: - return -1; - } - -ACCEPT_CHA: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCEPT_CHAR; - case 'r': - if (last) { - return -1; - } - goto ACCEPT_CHAR; - default: - return -1; - } - -ACCEPT_CHAR: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto ACCEPT_CHARS; - case 's': - if (last) { - return -1; - } - goto ACCEPT_CHARS; - default: - return -1; - } - -ACCEPT_CHARS: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCEPT_CHARSE; - case 'e': - if (last) { - return -1; - } - goto ACCEPT_CHARSE; - default: - return -1; - } - -ACCEPT_CHARSE: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 1; - } - goto ACCEPT_CHARSET; - case 't': - if (last) { - return 1; - } - goto ACCEPT_CHARSET; - default: - return -1; - } - -ACCEPT_E: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto ACCEPT_EN; - case 'n': - if (last) { - return -1; - } - goto ACCEPT_EN; - default: - return -1; - } - -ACCEPT_EN: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto ACCEPT_ENC; - case 'c': - if (last) { - return -1; - } - goto ACCEPT_ENC; - default: - return -1; - } - -ACCEPT_ENC: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCEPT_ENCO; - case 'o': - if (last) { - return -1; - } - goto ACCEPT_ENCO; - default: - return -1; - } - -ACCEPT_ENCO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto ACCEPT_ENCOD; - case 'd': - if (last) { - return -1; - } - goto ACCEPT_ENCOD; - default: - return -1; - } - -ACCEPT_ENCOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto ACCEPT_ENCODI; - case 'i': - if (last) { - return -1; - } - goto ACCEPT_ENCODI; - default: - return -1; - } - -ACCEPT_ENCODI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto ACCEPT_ENCODIN; - case 'n': - if (last) { - return -1; - } - goto ACCEPT_ENCODIN; - default: - return -1; - } - -ACCEPT_ENCODIN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return 2; - } - goto ACCEPT_ENCODING; - case 'g': - if (last) { - return 2; - } - goto ACCEPT_ENCODING; - default: - return -1; - } - -ACCEPT_L: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCEPT_LA; - case 'a': - if (last) { - return -1; - } - goto ACCEPT_LA; - default: - return -1; - } - -ACCEPT_LA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto ACCEPT_LAN; - case 'n': - if (last) { - return -1; - } - goto ACCEPT_LAN; - default: - return -1; - } - -ACCEPT_LAN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto ACCEPT_LANG; - case 'g': - if (last) { - return -1; - } - goto ACCEPT_LANG; - default: - return -1; - } - -ACCEPT_LANG: - NEXT_CHAR(); - switch (ch) { - case 'U': - if (last) { - return -1; - } - goto ACCEPT_LANGU; - case 'u': - if (last) { - return -1; - } - goto ACCEPT_LANGU; - default: - return -1; - } - -ACCEPT_LANGU: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCEPT_LANGUA; - case 'a': - if (last) { - return -1; - } - goto ACCEPT_LANGUA; - default: - return -1; - } - -ACCEPT_LANGUA: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto ACCEPT_LANGUAG; - case 'g': - if (last) { - return -1; - } - goto ACCEPT_LANGUAG; - default: - return -1; - } - -ACCEPT_LANGUAG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 3; - } - goto ACCEPT_LANGUAGE; - case 'e': - if (last) { - return 3; - } - goto ACCEPT_LANGUAGE; - default: - return -1; - } - -ACCEPT_R: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCEPT_RA; - case 'a': - if (last) { - return -1; - } - goto ACCEPT_RA; - default: - return -1; - } - -ACCEPT_RA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto ACCEPT_RAN; - case 'n': - if (last) { - return -1; - } - goto ACCEPT_RAN; - default: - return -1; - } - -ACCEPT_RAN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto ACCEPT_RANG; - case 'g': - if (last) { - return -1; - } - goto ACCEPT_RANG; - default: - return -1; - } - -ACCEPT_RANG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCEPT_RANGE; - case 'e': - if (last) { - return -1; - } - goto ACCEPT_RANGE; - default: - return -1; - } - -ACCEPT_RANGE: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 4; - } - goto ACCEPT_RANGES; - case 's': - if (last) { - return 4; - } - goto ACCEPT_RANGES; - default: - return -1; - } - -ACCES: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto ACCESS; - case 's': - if (last) { - return -1; - } - goto ACCESS; - default: - return -1; - } - -ACCESS: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCESS_; - default: - return -1; - } - -ACCESS_: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto ACCESS_C; - case 'c': - if (last) { - return -1; - } - goto ACCESS_C; - default: - return -1; - } - -ACCESS_C: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCESS_CO; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CO; - default: - return -1; - } - -ACCESS_CO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto ACCESS_CON; - case 'n': - if (last) { - return -1; - } - goto ACCESS_CON; - default: - return -1; - } - -ACCESS_CON: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto ACCESS_CONT; - case 't': - if (last) { - return -1; - } - goto ACCESS_CONT; - default: - return -1; - } - -ACCESS_CONT: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTR; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTR; - default: - return -1; - } - -ACCESS_CONTR: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCESS_CONTRO; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CONTRO; - default: - return -1; - } - -ACCESS_CONTRO: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto ACCESS_CONTROL; - case 'l': - if (last) { - return -1; - } - goto ACCESS_CONTROL; - default: - return -1; - } - -ACCESS_CONTROL: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCESS_CONTROL_; - default: - return -1; - } - -ACCESS_CONTROL_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_A; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_A; - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_E; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_E; - case 'M': - if (last) { - return -1; - } - goto ACCESS_CONTROL_M; - case 'm': - if (last) { - return -1; - } - goto ACCESS_CONTROL_M; - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTROL_R; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTROL_R; - default: - return -1; - } - -ACCESS_CONTROL_A: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto ACCESS_CONTROL_AL; - case 'l': - if (last) { - return -1; - } - goto ACCESS_CONTROL_AL; - default: - return -1; - } - -ACCESS_CONTROL_AL: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALL; - case 'l': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALL; - default: - return -1; - } - -ACCESS_CONTROL_ALL: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLO; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLO; - default: - return -1; - } - -ACCESS_CONTROL_ALLO: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW; - case 'w': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_C; - case 'c': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_C; - case 'H': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_H; - case 'h': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_H; - case 'M': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_M; - case 'm': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_M; - case 'O': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_O; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_O; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_C: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CR; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CR; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CR: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CRE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CRE; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CRE: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CRED; - case 'd': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CRED; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CRED: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDE; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CREDE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDEN; - case 'n': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDEN; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CREDEN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENT; - case 't': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENT; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CREDENT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENTI; - case 'i': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENTI; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CREDENTI: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENTIA; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENTIA; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CREDENTIA: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENTIAL; - case 'l': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_CREDENTIAL; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_CREDENTIAL: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 5; - } - goto ACCESS_CONTROL_ALLOW_CREDENTIALS; - case 's': - if (last) { - return 5; - } - goto ACCESS_CONTROL_ALLOW_CREDENTIALS; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_H: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HE; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_HE: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEA; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEA; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_HEA: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEAD; - case 'd': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEAD; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_HEAD: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEADE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEADE; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_HEADE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEADER; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_HEADER; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_HEADER: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 6; - } - goto ACCESS_CONTROL_ALLOW_HEADERS; - case 's': - if (last) { - return 6; - } - goto ACCESS_CONTROL_ALLOW_HEADERS; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_M: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ME; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ME; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_ME: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_MET; - case 't': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_MET; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_MET: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_METH; - case 'h': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_METH; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_METH: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_METHO; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_METHO; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_METHO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_METHOD; - case 'd': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_METHOD; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_METHOD: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 7; - } - goto ACCESS_CONTROL_ALLOW_METHODS; - case 's': - if (last) { - return 7; - } - goto ACCESS_CONTROL_ALLOW_METHODS; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_O: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_OR; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_OR; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_OR: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ORI; - case 'i': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ORI; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_ORI: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ORIG; - case 'g': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ORIG; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_ORIG: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ORIGI; - case 'i': - if (last) { - return -1; - } - goto ACCESS_CONTROL_ALLOW_ORIGI; - default: - return -1; - } - -ACCESS_CONTROL_ALLOW_ORIGI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 8; - } - goto ACCESS_CONTROL_ALLOW_ORIGIN; - case 'n': - if (last) { - return 8; - } - goto ACCESS_CONTROL_ALLOW_ORIGIN; - default: - return -1; - } - -ACCESS_CONTROL_E: - NEXT_CHAR(); - switch (ch) { - case 'X': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EX; - case 'x': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EX; - default: - return -1; - } - -ACCESS_CONTROL_EX: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXP; - case 'p': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXP; - default: - return -1; - } - -ACCESS_CONTROL_EXP: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPO; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPO; - default: - return -1; - } - -ACCESS_CONTROL_EXPO: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOS; - case 's': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOS; - default: - return -1; - } - -ACCESS_CONTROL_EXPOS: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_H; - case 'h': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_H; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_H: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HE; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_HE: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEA; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEA; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_HEA: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEAD; - case 'd': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEAD; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_HEAD: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEADE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEADE; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_HEADE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEADER; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTROL_EXPOSE_HEADER; - default: - return -1; - } - -ACCESS_CONTROL_EXPOSE_HEADER: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 9; - } - goto ACCESS_CONTROL_EXPOSE_HEADERS; - case 's': - if (last) { - return 9; - } - goto ACCESS_CONTROL_EXPOSE_HEADERS; - default: - return -1; - } - -ACCESS_CONTROL_M: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MA; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MA; - default: - return -1; - } - -ACCESS_CONTROL_MA: - NEXT_CHAR(); - switch (ch) { - case 'X': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX; - case 'x': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX; - default: - return -1; - } - -ACCESS_CONTROL_MAX: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX_; - default: - return -1; - } - -ACCESS_CONTROL_MAX_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX_A; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX_A; - default: - return -1; - } - -ACCESS_CONTROL_MAX_A: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX_AG; - case 'g': - if (last) { - return -1; - } - goto ACCESS_CONTROL_MAX_AG; - default: - return -1; - } - -ACCESS_CONTROL_MAX_AG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 10; - } - goto ACCESS_CONTROL_MAX_AGE; - case 'e': - if (last) { - return 10; - } - goto ACCESS_CONTROL_MAX_AGE; - default: - return -1; - } - -ACCESS_CONTROL_R: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_RE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_RE; - default: - return -1; - } - -ACCESS_CONTROL_RE: - NEXT_CHAR(); - switch (ch) { - case 'Q': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQ; - case 'q': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQ; - default: - return -1; - } - -ACCESS_CONTROL_REQ: - NEXT_CHAR(); - switch (ch) { - case 'U': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQU; - case 'u': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQU; - default: - return -1; - } - -ACCESS_CONTROL_REQU: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUE; - default: - return -1; - } - -ACCESS_CONTROL_REQUE: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUES; - case 's': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUES; - default: - return -1; - } - -ACCESS_CONTROL_REQUES: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST; - case 't': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_H; - case 'h': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_H; - case 'M': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_M; - case 'm': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_M; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_H: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HE; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_HE: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEA; - case 'a': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEA; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_HEA: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEAD; - case 'd': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEAD; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_HEAD: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEADE; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEADE; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_HEADE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEADER; - case 'r': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_HEADER; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_HEADER: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 11; - } - goto ACCESS_CONTROL_REQUEST_HEADERS; - case 's': - if (last) { - return 11; - } - goto ACCESS_CONTROL_REQUEST_HEADERS; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_M: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_ME; - case 'e': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_ME; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_ME: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_MET; - case 't': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_MET; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_MET: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_METH; - case 'h': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_METH; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_METH: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_METHO; - case 'o': - if (last) { - return -1; - } - goto ACCESS_CONTROL_REQUEST_METHO; - default: - return -1; - } - -ACCESS_CONTROL_REQUEST_METHO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return 12; - } - goto ACCESS_CONTROL_REQUEST_METHOD; - case 'd': - if (last) { - return 12; - } - goto ACCESS_CONTROL_REQUEST_METHOD; - default: - return -1; - } - -AG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 13; - } - goto AGE; - case 'e': - if (last) { - return 13; - } - goto AGE; - default: - return -1; - } - -AL: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto ALL; - case 'l': - if (last) { - return -1; - } - goto ALL; - default: - return -1; - } - -ALL: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto ALLO; - case 'o': - if (last) { - return -1; - } - goto ALLO; - default: - return -1; - } - -ALLO: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return 14; - } - goto ALLOW; - case 'w': - if (last) { - return 14; - } - goto ALLOW; - default: - return -1; - } - -AU: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto AUT; - case 't': - if (last) { - return -1; - } - goto AUT; - default: - return -1; - } - -AUT: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto AUTH; - case 'h': - if (last) { - return -1; - } - goto AUTH; - default: - return -1; - } - -AUTH: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto AUTHO; - case 'o': - if (last) { - return -1; - } - goto AUTHO; - default: - return -1; - } - -AUTHO: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto AUTHOR; - case 'r': - if (last) { - return -1; - } - goto AUTHOR; - default: - return -1; - } - -AUTHOR: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto AUTHORI; - case 'i': - if (last) { - return -1; - } - goto AUTHORI; - default: - return -1; - } - -AUTHORI: - NEXT_CHAR(); - switch (ch) { - case 'Z': - if (last) { - return -1; - } - goto AUTHORIZ; - case 'z': - if (last) { - return -1; - } - goto AUTHORIZ; - default: - return -1; - } - -AUTHORIZ: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto AUTHORIZA; - case 'a': - if (last) { - return -1; - } - goto AUTHORIZA; - default: - return -1; - } - -AUTHORIZA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto AUTHORIZAT; - case 't': - if (last) { - return -1; - } - goto AUTHORIZAT; - default: - return -1; - } - -AUTHORIZAT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto AUTHORIZATI; - case 'i': - if (last) { - return -1; - } - goto AUTHORIZATI; - default: - return -1; - } - -AUTHORIZATI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto AUTHORIZATIO; - case 'o': - if (last) { - return -1; - } - goto AUTHORIZATIO; - default: - return -1; - } - -AUTHORIZATIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 15; - } - goto AUTHORIZATION; - case 'n': - if (last) { - return 15; - } - goto AUTHORIZATION; - default: - return -1; - } - -C: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto CA; - case 'a': - if (last) { - return -1; - } - goto CA; - case 'O': - if (last) { - return -1; - } - goto CO; - case 'o': - if (last) { - return -1; - } - goto CO; - default: - return -1; - } - -CA: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto CAC; - case 'c': - if (last) { - return -1; - } - goto CAC; - default: - return -1; - } - -CAC: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto CACH; - case 'h': - if (last) { - return -1; - } - goto CACH; - default: - return -1; - } - -CACH: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto CACHE; - case 'e': - if (last) { - return -1; - } - goto CACHE; - default: - return -1; - } - -CACHE: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto CACHE_; - default: - return -1; - } - -CACHE_: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto CACHE_C; - case 'c': - if (last) { - return -1; - } - goto CACHE_C; - default: - return -1; - } - -CACHE_C: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CACHE_CO; - case 'o': - if (last) { - return -1; - } - goto CACHE_CO; - default: - return -1; - } - -CACHE_CO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CACHE_CON; - case 'n': - if (last) { - return -1; - } - goto CACHE_CON; - default: - return -1; - } - -CACHE_CON: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto CACHE_CONT; - case 't': - if (last) { - return -1; - } - goto CACHE_CONT; - default: - return -1; - } - -CACHE_CONT: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto CACHE_CONTR; - case 'r': - if (last) { - return -1; - } - goto CACHE_CONTR; - default: - return -1; - } - -CACHE_CONTR: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CACHE_CONTRO; - case 'o': - if (last) { - return -1; - } - goto CACHE_CONTRO; - default: - return -1; - } - -CACHE_CONTRO: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return 16; - } - goto CACHE_CONTROL; - case 'l': - if (last) { - return 16; - } - goto CACHE_CONTROL; - default: - return -1; - } - -CO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CON; - case 'n': - if (last) { - return -1; - } - goto CON; - case 'O': - if (last) { - return -1; - } - goto COO; - case 'o': - if (last) { - return -1; - } - goto COO; - default: - return -1; - } - -CON: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONN; - case 'n': - if (last) { - return -1; - } - goto CONN; - case 'T': - if (last) { - return -1; - } - goto CONT; - case 't': - if (last) { - return -1; - } - goto CONT; - default: - return -1; - } - -CONN: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto CONNE; - case 'e': - if (last) { - return -1; - } - goto CONNE; - default: - return -1; - } - -CONNE: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto CONNEC; - case 'c': - if (last) { - return -1; - } - goto CONNEC; - default: - return -1; - } - -CONNEC: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto CONNECT; - case 't': - if (last) { - return -1; - } - goto CONNECT; - default: - return -1; - } - -CONNECT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONNECTI; - case 'i': - if (last) { - return -1; - } - goto CONNECTI; - default: - return -1; - } - -CONNECTI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CONNECTIO; - case 'o': - if (last) { - return -1; - } - goto CONNECTIO; - default: - return -1; - } - -CONNECTIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 17; - } - goto CONNECTION; - case 'n': - if (last) { - return 17; - } - goto CONNECTION; - default: - return -1; - } - -CONT: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto CONTE; - case 'e': - if (last) { - return -1; - } - goto CONTE; - default: - return -1; - } - -CONTE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTEN; - case 'n': - if (last) { - return -1; - } - goto CONTEN; - default: - return -1; - } - -CONTEN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto CONTENT; - case 't': - if (last) { - return -1; - } - goto CONTENT; - default: - return -1; - } - -CONTENT: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto CONTENT_; - default: - return -1; - } - -CONTENT_: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto CONTENT_D; - case 'd': - if (last) { - return -1; - } - goto CONTENT_D; - case 'E': - if (last) { - return -1; - } - goto CONTENT_E; - case 'e': - if (last) { - return -1; - } - goto CONTENT_E; - case 'L': - if (last) { - return -1; - } - goto CONTENT_L; - case 'l': - if (last) { - return -1; - } - goto CONTENT_L; - case 'M': - if (last) { - return -1; - } - goto CONTENT_M; - case 'm': - if (last) { - return -1; - } - goto CONTENT_M; - case 'R': - if (last) { - return -1; - } - goto CONTENT_R; - case 'r': - if (last) { - return -1; - } - goto CONTENT_R; - case 'T': - if (last) { - return -1; - } - goto CONTENT_T; - case 't': - if (last) { - return -1; - } - goto CONTENT_T; - default: - return -1; - } - -CONTENT_D: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONTENT_DI; - case 'i': - if (last) { - return -1; - } - goto CONTENT_DI; - default: - return -1; - } - -CONTENT_DI: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto CONTENT_DIS; - case 's': - if (last) { - return -1; - } - goto CONTENT_DIS; - default: - return -1; - } - -CONTENT_DIS: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto CONTENT_DISP; - case 'p': - if (last) { - return -1; - } - goto CONTENT_DISP; - default: - return -1; - } - -CONTENT_DISP: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CONTENT_DISPO; - case 'o': - if (last) { - return -1; - } - goto CONTENT_DISPO; - default: - return -1; - } - -CONTENT_DISPO: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto CONTENT_DISPOS; - case 's': - if (last) { - return -1; - } - goto CONTENT_DISPOS; - default: - return -1; - } - -CONTENT_DISPOS: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONTENT_DISPOSI; - case 'i': - if (last) { - return -1; - } - goto CONTENT_DISPOSI; - default: - return -1; - } - -CONTENT_DISPOSI: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto CONTENT_DISPOSIT; - case 't': - if (last) { - return -1; - } - goto CONTENT_DISPOSIT; - default: - return -1; - } - -CONTENT_DISPOSIT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONTENT_DISPOSITI; - case 'i': - if (last) { - return -1; - } - goto CONTENT_DISPOSITI; - default: - return -1; - } - -CONTENT_DISPOSITI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CONTENT_DISPOSITIO; - case 'o': - if (last) { - return -1; - } - goto CONTENT_DISPOSITIO; - default: - return -1; - } - -CONTENT_DISPOSITIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 18; - } - goto CONTENT_DISPOSITION; - case 'n': - if (last) { - return 18; - } - goto CONTENT_DISPOSITION; - default: - return -1; - } - -CONTENT_E: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_EN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_EN; - default: - return -1; - } - -CONTENT_EN: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto CONTENT_ENC; - case 'c': - if (last) { - return -1; - } - goto CONTENT_ENC; - default: - return -1; - } - -CONTENT_ENC: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CONTENT_ENCO; - case 'o': - if (last) { - return -1; - } - goto CONTENT_ENCO; - default: - return -1; - } - -CONTENT_ENCO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto CONTENT_ENCOD; - case 'd': - if (last) { - return -1; - } - goto CONTENT_ENCOD; - default: - return -1; - } - -CONTENT_ENCOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONTENT_ENCODI; - case 'i': - if (last) { - return -1; - } - goto CONTENT_ENCODI; - default: - return -1; - } - -CONTENT_ENCODI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_ENCODIN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_ENCODIN; - default: - return -1; - } - -CONTENT_ENCODIN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return 19; - } - goto CONTENT_ENCODING; - case 'g': - if (last) { - return 19; - } - goto CONTENT_ENCODING; - default: - return -1; - } - -CONTENT_L: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto CONTENT_LA; - case 'a': - if (last) { - return -1; - } - goto CONTENT_LA; - case 'E': - if (last) { - return -1; - } - goto CONTENT_LE; - case 'e': - if (last) { - return -1; - } - goto CONTENT_LE; - case 'O': - if (last) { - return -1; - } - goto CONTENT_LO; - case 'o': - if (last) { - return -1; - } - goto CONTENT_LO; - default: - return -1; - } - -CONTENT_LA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_LAN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_LAN; - default: - return -1; - } - -CONTENT_LAN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto CONTENT_LANG; - case 'g': - if (last) { - return -1; - } - goto CONTENT_LANG; - default: - return -1; - } - -CONTENT_LANG: - NEXT_CHAR(); - switch (ch) { - case 'U': - if (last) { - return -1; - } - goto CONTENT_LANGU; - case 'u': - if (last) { - return -1; - } - goto CONTENT_LANGU; - default: - return -1; - } - -CONTENT_LANGU: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto CONTENT_LANGUA; - case 'a': - if (last) { - return -1; - } - goto CONTENT_LANGUA; - default: - return -1; - } - -CONTENT_LANGUA: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto CONTENT_LANGUAG; - case 'g': - if (last) { - return -1; - } - goto CONTENT_LANGUAG; - default: - return -1; - } - -CONTENT_LANGUAG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 20; - } - goto CONTENT_LANGUAGE; - case 'e': - if (last) { - return 20; - } - goto CONTENT_LANGUAGE; - default: - return -1; - } - -CONTENT_LE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_LEN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_LEN; - default: - return -1; - } - -CONTENT_LEN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto CONTENT_LENG; - case 'g': - if (last) { - return -1; - } - goto CONTENT_LENG; - default: - return -1; - } - -CONTENT_LENG: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto CONTENT_LENGT; - case 't': - if (last) { - return -1; - } - goto CONTENT_LENGT; - default: - return -1; - } - -CONTENT_LENGT: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return 21; - } - goto CONTENT_LENGTH; - case 'h': - if (last) { - return 21; - } - goto CONTENT_LENGTH; - default: - return -1; - } - -CONTENT_LO: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto CONTENT_LOC; - case 'c': - if (last) { - return -1; - } - goto CONTENT_LOC; - default: - return -1; - } - -CONTENT_LOC: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto CONTENT_LOCA; - case 'a': - if (last) { - return -1; - } - goto CONTENT_LOCA; - default: - return -1; - } - -CONTENT_LOCA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto CONTENT_LOCAT; - case 't': - if (last) { - return -1; - } - goto CONTENT_LOCAT; - default: - return -1; - } - -CONTENT_LOCAT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONTENT_LOCATI; - case 'i': - if (last) { - return -1; - } - goto CONTENT_LOCATI; - default: - return -1; - } - -CONTENT_LOCATI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CONTENT_LOCATIO; - case 'o': - if (last) { - return -1; - } - goto CONTENT_LOCATIO; - default: - return -1; - } - -CONTENT_LOCATIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 22; - } - goto CONTENT_LOCATION; - case 'n': - if (last) { - return 22; - } - goto CONTENT_LOCATION; - default: - return -1; - } - -CONTENT_M: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto CONTENT_MD; - case 'd': - if (last) { - return -1; - } - goto CONTENT_MD; - default: - return -1; - } - -CONTENT_MD: - NEXT_CHAR(); - switch (ch) { - case '5': - if (last) { - return 23; - } - goto CONTENT_MD5; - default: - return -1; - } - -CONTENT_R: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto CONTENT_RA; - case 'a': - if (last) { - return -1; - } - goto CONTENT_RA; - default: - return -1; - } - -CONTENT_RA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_RAN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_RAN; - default: - return -1; - } - -CONTENT_RAN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto CONTENT_RANG; - case 'g': - if (last) { - return -1; - } - goto CONTENT_RANG; - default: - return -1; - } - -CONTENT_RANG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 24; - } - goto CONTENT_RANGE; - case 'e': - if (last) { - return 24; - } - goto CONTENT_RANGE; - default: - return -1; - } - -CONTENT_T: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto CONTENT_TR; - case 'r': - if (last) { - return -1; - } - goto CONTENT_TR; - case 'Y': - if (last) { - return -1; - } - goto CONTENT_TY; - case 'y': - if (last) { - return -1; - } - goto CONTENT_TY; - default: - return -1; - } - -CONTENT_TR: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto CONTENT_TRA; - case 'a': - if (last) { - return -1; - } - goto CONTENT_TRA; - default: - return -1; - } - -CONTENT_TRA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_TRAN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_TRAN; - default: - return -1; - } - -CONTENT_TRAN: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto CONTENT_TRANS; - case 's': - if (last) { - return -1; - } - goto CONTENT_TRANS; - default: - return -1; - } - -CONTENT_TRANS: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto CONTENT_TRANSF; - case 'f': - if (last) { - return -1; - } - goto CONTENT_TRANSF; - default: - return -1; - } - -CONTENT_TRANSF: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto CONTENT_TRANSFE; - case 'e': - if (last) { - return -1; - } - goto CONTENT_TRANSFE; - default: - return -1; - } - -CONTENT_TRANSFE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto CONTENT_TRANSFER; - case 'r': - if (last) { - return -1; - } - goto CONTENT_TRANSFER; - default: - return -1; - } - -CONTENT_TRANSFER: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_; - default: - return -1; - } - -CONTENT_TRANSFER_: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_E; - case 'e': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_E; - default: - return -1; - } - -CONTENT_TRANSFER_E: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_EN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_EN; - default: - return -1; - } - -CONTENT_TRANSFER_EN: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENC; - case 'c': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENC; - default: - return -1; - } - -CONTENT_TRANSFER_ENC: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCO; - case 'o': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCO; - default: - return -1; - } - -CONTENT_TRANSFER_ENCO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCOD; - case 'd': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCOD; - default: - return -1; - } - -CONTENT_TRANSFER_ENCOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCODI; - case 'i': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCODI; - default: - return -1; - } - -CONTENT_TRANSFER_ENCODI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCODIN; - case 'n': - if (last) { - return -1; - } - goto CONTENT_TRANSFER_ENCODIN; - default: - return -1; - } - -CONTENT_TRANSFER_ENCODIN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return 25; - } - goto CONTENT_TRANSFER_ENCODING; - case 'g': - if (last) { - return 25; - } - goto CONTENT_TRANSFER_ENCODING; - default: - return -1; - } - -CONTENT_TY: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto CONTENT_TYP; - case 'p': - if (last) { - return -1; - } - goto CONTENT_TYP; - default: - return -1; - } - -CONTENT_TYP: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 26; - } - goto CONTENT_TYPE; - case 'e': - if (last) { - return 26; - } - goto CONTENT_TYPE; - default: - return -1; - } - -COO: - NEXT_CHAR(); - switch (ch) { - case 'K': - if (last) { - return -1; - } - goto COOK; - case 'k': - if (last) { - return -1; - } - goto COOK; - default: - return -1; - } - -COOK: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto COOKI; - case 'i': - if (last) { - return -1; - } - goto COOKI; - default: - return -1; - } - -COOKI: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 27; - } - goto COOKIE; - case 'e': - if (last) { - return 27; - } - goto COOKIE; - default: - return -1; - } - -D: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto DA; - case 'a': - if (last) { - return -1; - } - goto DA; - case 'E': - if (last) { - return -1; - } - goto DE; - case 'e': - if (last) { - return -1; - } - goto DE; - case 'I': - if (last) { - return -1; - } - goto DI; - case 'i': - if (last) { - return -1; - } - goto DI; - default: - return -1; - } - -DA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto DAT; - case 't': - if (last) { - return -1; - } - goto DAT; - default: - return -1; - } - -DAT: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 28; - } - goto DATE; - case 'e': - if (last) { - return 28; - } - goto DATE; - default: - return -1; - } - -DE: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto DES; - case 's': - if (last) { - return -1; - } - goto DES; - default: - return -1; - } - -DES: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto DEST; - case 't': - if (last) { - return -1; - } - goto DEST; - default: - return -1; - } - -DEST: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto DESTI; - case 'i': - if (last) { - return -1; - } - goto DESTI; - default: - return -1; - } - -DESTI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto DESTIN; - case 'n': - if (last) { - return -1; - } - goto DESTIN; - default: - return -1; - } - -DESTIN: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto DESTINA; - case 'a': - if (last) { - return -1; - } - goto DESTINA; - default: - return -1; - } - -DESTINA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto DESTINAT; - case 't': - if (last) { - return -1; - } - goto DESTINAT; - default: - return -1; - } - -DESTINAT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto DESTINATI; - case 'i': - if (last) { - return -1; - } - goto DESTINATI; - default: - return -1; - } - -DESTINATI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto DESTINATIO; - case 'o': - if (last) { - return -1; - } - goto DESTINATIO; - default: - return -1; - } - -DESTINATIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 29; - } - goto DESTINATION; - case 'n': - if (last) { - return 29; - } - goto DESTINATION; - default: - return -1; - } - -DI: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto DIG; - case 'g': - if (last) { - return -1; - } - goto DIG; - default: - return -1; - } - -DIG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto DIGE; - case 'e': - if (last) { - return -1; - } - goto DIGE; - default: - return -1; - } - -DIGE: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto DIGES; - case 's': - if (last) { - return -1; - } - goto DIGES; - default: - return -1; - } - -DIGES: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 30; - } - goto DIGEST; - case 't': - if (last) { - return 30; - } - goto DIGEST; - default: - return -1; - } - -E: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto ET; - case 't': - if (last) { - return -1; - } - goto ET; - case 'X': - if (last) { - return -1; - } - goto EX; - case 'x': - if (last) { - return -1; - } - goto EX; - default: - return -1; - } - -ET: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto ETA; - case 'a': - if (last) { - return -1; - } - goto ETA; - default: - return -1; - } - -ETA: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return 31; - } - goto ETAG; - case 'g': - if (last) { - return 31; - } - goto ETAG; - default: - return -1; - } - -EX: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto EXP; - case 'p': - if (last) { - return -1; - } - goto EXP; - default: - return -1; - } - -EXP: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto EXPE; - case 'e': - if (last) { - return -1; - } - goto EXPE; - case 'I': - if (last) { - return -1; - } - goto EXPI; - case 'i': - if (last) { - return -1; - } - goto EXPI; - default: - return -1; - } - -EXPE: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto EXPEC; - case 'c': - if (last) { - return -1; - } - goto EXPEC; - default: - return -1; - } - -EXPEC: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 32; - } - goto EXPECT; - case 't': - if (last) { - return 32; - } - goto EXPECT; - default: - return -1; - } - -EXPI: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto EXPIR; - case 'r': - if (last) { - return -1; - } - goto EXPIR; - default: - return -1; - } - -EXPIR: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto EXPIRE; - case 'e': - if (last) { - return -1; - } - goto EXPIRE; - default: - return -1; - } - -EXPIRE: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 33; - } - goto EXPIRES; - case 's': - if (last) { - return 33; - } - goto EXPIRES; - default: - return -1; - } - -F: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto FO; - case 'o': - if (last) { - return -1; - } - goto FO; - case 'R': - if (last) { - return -1; - } - goto FR; - case 'r': - if (last) { - return -1; - } - goto FR; - default: - return -1; - } - -FO: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto FOR; - case 'r': - if (last) { - return -1; - } - goto FOR; - default: - return -1; - } - -FOR: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto FORW; - case 'w': - if (last) { - return -1; - } - goto FORW; - default: - return -1; - } - -FORW: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto FORWA; - case 'a': - if (last) { - return -1; - } - goto FORWA; - default: - return -1; - } - -FORWA: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto FORWAR; - case 'r': - if (last) { - return -1; - } - goto FORWAR; - default: - return -1; - } - -FORWAR: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto FORWARD; - case 'd': - if (last) { - return -1; - } - goto FORWARD; - default: - return -1; - } - -FORWARD: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto FORWARDE; - case 'e': - if (last) { - return -1; - } - goto FORWARDE; - default: - return -1; - } - -FORWARDE: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return 34; - } - goto FORWARDED; - case 'd': - if (last) { - return 34; - } - goto FORWARDED; - default: - return -1; - } - -FR: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto FRO; - case 'o': - if (last) { - return -1; - } - goto FRO; - default: - return -1; - } - -FRO: - NEXT_CHAR(); - switch (ch) { - case 'M': - if (last) { - return 35; - } - goto FROM; - case 'm': - if (last) { - return 35; - } - goto FROM; - default: - return -1; - } - -H: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto HO; - case 'o': - if (last) { - return -1; - } - goto HO; - default: - return -1; - } - -HO: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto HOS; - case 's': - if (last) { - return -1; - } - goto HOS; - default: - return -1; - } - -HOS: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 36; - } - goto HOST; - case 't': - if (last) { - return 36; - } - goto HOST; - default: - return -1; - } - -I: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto IF; - case 'f': - if (last) { - return -1; - } - goto IF; - default: - return -1; - } - -IF: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto IF_; - default: - return -1; - } - -IF_: - NEXT_CHAR(); - switch (ch) { - case 'M': - if (last) { - return -1; - } - goto IF_M; - case 'm': - if (last) { - return -1; - } - goto IF_M; - case 'N': - if (last) { - return -1; - } - goto IF_N; - case 'n': - if (last) { - return -1; - } - goto IF_N; - case 'R': - if (last) { - return -1; - } - goto IF_R; - case 'r': - if (last) { - return -1; - } - goto IF_R; - case 'U': - if (last) { - return -1; - } - goto IF_U; - case 'u': - if (last) { - return -1; - } - goto IF_U; - default: - return -1; - } - -IF_M: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto IF_MA; - case 'a': - if (last) { - return -1; - } - goto IF_MA; - case 'O': - if (last) { - return -1; - } - goto IF_MO; - case 'o': - if (last) { - return -1; - } - goto IF_MO; - default: - return -1; - } - -IF_MA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto IF_MAT; - case 't': - if (last) { - return -1; - } - goto IF_MAT; - default: - return -1; - } - -IF_MAT: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto IF_MATC; - case 'c': - if (last) { - return -1; - } - goto IF_MATC; - default: - return -1; - } - -IF_MATC: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return 37; - } - goto IF_MATCH; - case 'h': - if (last) { - return 37; - } - goto IF_MATCH; - default: - return -1; - } - -IF_MO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto IF_MOD; - case 'd': - if (last) { - return -1; - } - goto IF_MOD; - default: - return -1; - } - -IF_MOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto IF_MODI; - case 'i': - if (last) { - return -1; - } - goto IF_MODI; - default: - return -1; - } - -IF_MODI: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto IF_MODIF; - case 'f': - if (last) { - return -1; - } - goto IF_MODIF; - default: - return -1; - } - -IF_MODIF: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto IF_MODIFI; - case 'i': - if (last) { - return -1; - } - goto IF_MODIFI; - default: - return -1; - } - -IF_MODIFI: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto IF_MODIFIE; - case 'e': - if (last) { - return -1; - } - goto IF_MODIFIE; - default: - return -1; - } - -IF_MODIFIE: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto IF_MODIFIED; - case 'd': - if (last) { - return -1; - } - goto IF_MODIFIED; - default: - return -1; - } - -IF_MODIFIED: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto IF_MODIFIED_; - default: - return -1; - } - -IF_MODIFIED_: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto IF_MODIFIED_S; - case 's': - if (last) { - return -1; - } - goto IF_MODIFIED_S; - default: - return -1; - } - -IF_MODIFIED_S: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto IF_MODIFIED_SI; - case 'i': - if (last) { - return -1; - } - goto IF_MODIFIED_SI; - default: - return -1; - } - -IF_MODIFIED_SI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto IF_MODIFIED_SIN; - case 'n': - if (last) { - return -1; - } - goto IF_MODIFIED_SIN; - default: - return -1; - } - -IF_MODIFIED_SIN: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto IF_MODIFIED_SINC; - case 'c': - if (last) { - return -1; - } - goto IF_MODIFIED_SINC; - default: - return -1; - } - -IF_MODIFIED_SINC: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 38; - } - goto IF_MODIFIED_SINCE; - case 'e': - if (last) { - return 38; - } - goto IF_MODIFIED_SINCE; - default: - return -1; - } - -IF_N: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto IF_NO; - case 'o': - if (last) { - return -1; - } - goto IF_NO; - default: - return -1; - } - -IF_NO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto IF_NON; - case 'n': - if (last) { - return -1; - } - goto IF_NON; - default: - return -1; - } - -IF_NON: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto IF_NONE; - case 'e': - if (last) { - return -1; - } - goto IF_NONE; - default: - return -1; - } - -IF_NONE: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto IF_NONE_; - default: - return -1; - } - -IF_NONE_: - NEXT_CHAR(); - switch (ch) { - case 'M': - if (last) { - return -1; - } - goto IF_NONE_M; - case 'm': - if (last) { - return -1; - } - goto IF_NONE_M; - default: - return -1; - } - -IF_NONE_M: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto IF_NONE_MA; - case 'a': - if (last) { - return -1; - } - goto IF_NONE_MA; - default: - return -1; - } - -IF_NONE_MA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto IF_NONE_MAT; - case 't': - if (last) { - return -1; - } - goto IF_NONE_MAT; - default: - return -1; - } - -IF_NONE_MAT: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto IF_NONE_MATC; - case 'c': - if (last) { - return -1; - } - goto IF_NONE_MATC; - default: - return -1; - } - -IF_NONE_MATC: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return 39; - } - goto IF_NONE_MATCH; - case 'h': - if (last) { - return 39; - } - goto IF_NONE_MATCH; - default: - return -1; - } - -IF_R: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto IF_RA; - case 'a': - if (last) { - return -1; - } - goto IF_RA; - default: - return -1; - } - -IF_RA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto IF_RAN; - case 'n': - if (last) { - return -1; - } - goto IF_RAN; - default: - return -1; - } - -IF_RAN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto IF_RANG; - case 'g': - if (last) { - return -1; - } - goto IF_RANG; - default: - return -1; - } - -IF_RANG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 40; - } - goto IF_RANGE; - case 'e': - if (last) { - return 40; - } - goto IF_RANGE; - default: - return -1; - } - -IF_U: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto IF_UN; - case 'n': - if (last) { - return -1; - } - goto IF_UN; - default: - return -1; - } - -IF_UN: - NEXT_CHAR(); - switch (ch) { - case 'M': - if (last) { - return -1; - } - goto IF_UNM; - case 'm': - if (last) { - return -1; - } - goto IF_UNM; - default: - return -1; - } - -IF_UNM: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto IF_UNMO; - case 'o': - if (last) { - return -1; - } - goto IF_UNMO; - default: - return -1; - } - -IF_UNMO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto IF_UNMOD; - case 'd': - if (last) { - return -1; - } - goto IF_UNMOD; - default: - return -1; - } - -IF_UNMOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto IF_UNMODI; - case 'i': - if (last) { - return -1; - } - goto IF_UNMODI; - default: - return -1; - } - -IF_UNMODI: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto IF_UNMODIF; - case 'f': - if (last) { - return -1; - } - goto IF_UNMODIF; - default: - return -1; - } - -IF_UNMODIF: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto IF_UNMODIFI; - case 'i': - if (last) { - return -1; - } - goto IF_UNMODIFI; - default: - return -1; - } - -IF_UNMODIFI: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto IF_UNMODIFIE; - case 'e': - if (last) { - return -1; - } - goto IF_UNMODIFIE; - default: - return -1; - } - -IF_UNMODIFIE: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto IF_UNMODIFIED; - case 'd': - if (last) { - return -1; - } - goto IF_UNMODIFIED; - default: - return -1; - } - -IF_UNMODIFIED: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto IF_UNMODIFIED_; - default: - return -1; - } - -IF_UNMODIFIED_: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto IF_UNMODIFIED_S; - case 's': - if (last) { - return -1; - } - goto IF_UNMODIFIED_S; - default: - return -1; - } - -IF_UNMODIFIED_S: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto IF_UNMODIFIED_SI; - case 'i': - if (last) { - return -1; - } - goto IF_UNMODIFIED_SI; - default: - return -1; - } - -IF_UNMODIFIED_SI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto IF_UNMODIFIED_SIN; - case 'n': - if (last) { - return -1; - } - goto IF_UNMODIFIED_SIN; - default: - return -1; - } - -IF_UNMODIFIED_SIN: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto IF_UNMODIFIED_SINC; - case 'c': - if (last) { - return -1; - } - goto IF_UNMODIFIED_SINC; - default: - return -1; - } - -IF_UNMODIFIED_SINC: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 41; - } - goto IF_UNMODIFIED_SINCE; - case 'e': - if (last) { - return 41; - } - goto IF_UNMODIFIED_SINCE; - default: - return -1; - } - -K: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto KE; - case 'e': - if (last) { - return -1; - } - goto KE; - default: - return -1; - } - -KE: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto KEE; - case 'e': - if (last) { - return -1; - } - goto KEE; - default: - return -1; - } - -KEE: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto KEEP; - case 'p': - if (last) { - return -1; - } - goto KEEP; - default: - return -1; - } - -KEEP: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto KEEP_; - default: - return -1; - } - -KEEP_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto KEEP_A; - case 'a': - if (last) { - return -1; - } - goto KEEP_A; - default: - return -1; - } - -KEEP_A: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto KEEP_AL; - case 'l': - if (last) { - return -1; - } - goto KEEP_AL; - default: - return -1; - } - -KEEP_AL: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto KEEP_ALI; - case 'i': - if (last) { - return -1; - } - goto KEEP_ALI; - default: - return -1; - } - -KEEP_ALI: - NEXT_CHAR(); - switch (ch) { - case 'V': - if (last) { - return -1; - } - goto KEEP_ALIV; - case 'v': - if (last) { - return -1; - } - goto KEEP_ALIV; - default: - return -1; - } - -KEEP_ALIV: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 42; - } - goto KEEP_ALIVE; - case 'e': - if (last) { - return 42; - } - goto KEEP_ALIVE; - default: - return -1; - } - -L: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto LA; - case 'a': - if (last) { - return -1; - } - goto LA; - case 'I': - if (last) { - return -1; - } - goto LI; - case 'i': - if (last) { - return -1; - } - goto LI; - case 'O': - if (last) { - return -1; - } - goto LO; - case 'o': - if (last) { - return -1; - } - goto LO; - default: - return -1; - } - -LA: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto LAS; - case 's': - if (last) { - return -1; - } - goto LAS; - default: - return -1; - } - -LAS: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto LAST; - case 't': - if (last) { - return -1; - } - goto LAST; - default: - return -1; - } - -LAST: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto LAST_; - default: - return -1; - } - -LAST_: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto LAST_E; - case 'e': - if (last) { - return -1; - } - goto LAST_E; - case 'M': - if (last) { - return -1; - } - goto LAST_M; - case 'm': - if (last) { - return -1; - } - goto LAST_M; - default: - return -1; - } - -LAST_E: - NEXT_CHAR(); - switch (ch) { - case 'V': - if (last) { - return -1; - } - goto LAST_EV; - case 'v': - if (last) { - return -1; - } - goto LAST_EV; - default: - return -1; - } - -LAST_EV: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto LAST_EVE; - case 'e': - if (last) { - return -1; - } - goto LAST_EVE; - default: - return -1; - } - -LAST_EVE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto LAST_EVEN; - case 'n': - if (last) { - return -1; - } - goto LAST_EVEN; - default: - return -1; - } - -LAST_EVEN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto LAST_EVENT; - case 't': - if (last) { - return -1; - } - goto LAST_EVENT; - default: - return -1; - } - -LAST_EVENT: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto LAST_EVENT_; - default: - return -1; - } - -LAST_EVENT_: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto LAST_EVENT_I; - case 'i': - if (last) { - return -1; - } - goto LAST_EVENT_I; - default: - return -1; - } - -LAST_EVENT_I: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return 43; - } - goto LAST_EVENT_ID; - case 'd': - if (last) { - return 43; - } - goto LAST_EVENT_ID; - default: - return -1; - } - -LAST_M: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto LAST_MO; - case 'o': - if (last) { - return -1; - } - goto LAST_MO; - default: - return -1; - } - -LAST_MO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto LAST_MOD; - case 'd': - if (last) { - return -1; - } - goto LAST_MOD; - default: - return -1; - } - -LAST_MOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto LAST_MODI; - case 'i': - if (last) { - return -1; - } - goto LAST_MODI; - default: - return -1; - } - -LAST_MODI: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto LAST_MODIF; - case 'f': - if (last) { - return -1; - } - goto LAST_MODIF; - default: - return -1; - } - -LAST_MODIF: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto LAST_MODIFI; - case 'i': - if (last) { - return -1; - } - goto LAST_MODIFI; - default: - return -1; - } - -LAST_MODIFI: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto LAST_MODIFIE; - case 'e': - if (last) { - return -1; - } - goto LAST_MODIFIE; - default: - return -1; - } - -LAST_MODIFIE: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return 44; - } - goto LAST_MODIFIED; - case 'd': - if (last) { - return 44; - } - goto LAST_MODIFIED; - default: - return -1; - } - -LI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto LIN; - case 'n': - if (last) { - return -1; - } - goto LIN; - default: - return -1; - } - -LIN: - NEXT_CHAR(); - switch (ch) { - case 'K': - if (last) { - return 45; - } - goto LINK; - case 'k': - if (last) { - return 45; - } - goto LINK; - default: - return -1; - } - -LO: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto LOC; - case 'c': - if (last) { - return -1; - } - goto LOC; - default: - return -1; - } - -LOC: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto LOCA; - case 'a': - if (last) { - return -1; - } - goto LOCA; - default: - return -1; - } - -LOCA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto LOCAT; - case 't': - if (last) { - return -1; - } - goto LOCAT; - default: - return -1; - } - -LOCAT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto LOCATI; - case 'i': - if (last) { - return -1; - } - goto LOCATI; - default: - return -1; - } - -LOCATI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto LOCATIO; - case 'o': - if (last) { - return -1; - } - goto LOCATIO; - default: - return -1; - } - -LOCATIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 46; - } - goto LOCATION; - case 'n': - if (last) { - return 46; - } - goto LOCATION; - default: - return -1; - } - -M: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto MA; - case 'a': - if (last) { - return -1; - } - goto MA; - default: - return -1; - } - -MA: - NEXT_CHAR(); - switch (ch) { - case 'X': - if (last) { - return -1; - } - goto MAX; - case 'x': - if (last) { - return -1; - } - goto MAX; - default: - return -1; - } - -MAX: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto MAX_; - default: - return -1; - } - -MAX_: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto MAX_F; - case 'f': - if (last) { - return -1; - } - goto MAX_F; - default: - return -1; - } - -MAX_F: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto MAX_FO; - case 'o': - if (last) { - return -1; - } - goto MAX_FO; - default: - return -1; - } - -MAX_FO: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto MAX_FOR; - case 'r': - if (last) { - return -1; - } - goto MAX_FOR; - default: - return -1; - } - -MAX_FOR: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto MAX_FORW; - case 'w': - if (last) { - return -1; - } - goto MAX_FORW; - default: - return -1; - } - -MAX_FORW: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto MAX_FORWA; - case 'a': - if (last) { - return -1; - } - goto MAX_FORWA; - default: - return -1; - } - -MAX_FORWA: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto MAX_FORWAR; - case 'r': - if (last) { - return -1; - } - goto MAX_FORWAR; - default: - return -1; - } - -MAX_FORWAR: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto MAX_FORWARD; - case 'd': - if (last) { - return -1; - } - goto MAX_FORWARD; - default: - return -1; - } - -MAX_FORWARD: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 47; - } - goto MAX_FORWARDS; - case 's': - if (last) { - return 47; - } - goto MAX_FORWARDS; - default: - return -1; - } - -O: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto OR; - case 'r': - if (last) { - return -1; - } - goto OR; - default: - return -1; - } - -OR: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto ORI; - case 'i': - if (last) { - return -1; - } - goto ORI; - default: - return -1; - } - -ORI: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto ORIG; - case 'g': - if (last) { - return -1; - } - goto ORIG; - default: - return -1; - } - -ORIG: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto ORIGI; - case 'i': - if (last) { - return -1; - } - goto ORIGI; - default: - return -1; - } - -ORIGI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 48; - } - goto ORIGIN; - case 'n': - if (last) { - return 48; - } - goto ORIGIN; - default: - return -1; - } - -P: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto PR; - case 'r': - if (last) { - return -1; - } - goto PR; - default: - return -1; - } - -PR: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto PRA; - case 'a': - if (last) { - return -1; - } - goto PRA; - case 'O': - if (last) { - return -1; - } - goto PRO; - case 'o': - if (last) { - return -1; - } - goto PRO; - default: - return -1; - } - -PRA: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto PRAG; - case 'g': - if (last) { - return -1; - } - goto PRAG; - default: - return -1; - } - -PRAG: - NEXT_CHAR(); - switch (ch) { - case 'M': - if (last) { - return -1; - } - goto PRAGM; - case 'm': - if (last) { - return -1; - } - goto PRAGM; - default: - return -1; - } - -PRAGM: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return 49; - } - goto PRAGMA; - case 'a': - if (last) { - return 49; - } - goto PRAGMA; - default: - return -1; - } - -PRO: - NEXT_CHAR(); - switch (ch) { - case 'X': - if (last) { - return -1; - } - goto PROX; - case 'x': - if (last) { - return -1; - } - goto PROX; - default: - return -1; - } - -PROX: - NEXT_CHAR(); - switch (ch) { - case 'Y': - if (last) { - return -1; - } - goto PROXY; - case 'y': - if (last) { - return -1; - } - goto PROXY; - default: - return -1; - } - -PROXY: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto PROXY_; - default: - return -1; - } - -PROXY_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto PROXY_A; - case 'a': - if (last) { - return -1; - } - goto PROXY_A; - default: - return -1; - } - -PROXY_A: - NEXT_CHAR(); - switch (ch) { - case 'U': - if (last) { - return -1; - } - goto PROXY_AU; - case 'u': - if (last) { - return -1; - } - goto PROXY_AU; - default: - return -1; - } - -PROXY_AU: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto PROXY_AUT; - case 't': - if (last) { - return -1; - } - goto PROXY_AUT; - default: - return -1; - } - -PROXY_AUT: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto PROXY_AUTH; - case 'h': - if (last) { - return -1; - } - goto PROXY_AUTH; - default: - return -1; - } - -PROXY_AUTH: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto PROXY_AUTHE; - case 'e': - if (last) { - return -1; - } - goto PROXY_AUTHE; - case 'O': - if (last) { - return -1; - } - goto PROXY_AUTHO; - case 'o': - if (last) { - return -1; - } - goto PROXY_AUTHO; - default: - return -1; - } - -PROXY_AUTHE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto PROXY_AUTHEN; - case 'n': - if (last) { - return -1; - } - goto PROXY_AUTHEN; - default: - return -1; - } - -PROXY_AUTHEN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto PROXY_AUTHENT; - case 't': - if (last) { - return -1; - } - goto PROXY_AUTHENT; - default: - return -1; - } - -PROXY_AUTHENT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto PROXY_AUTHENTI; - case 'i': - if (last) { - return -1; - } - goto PROXY_AUTHENTI; - default: - return -1; - } - -PROXY_AUTHENTI: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto PROXY_AUTHENTIC; - case 'c': - if (last) { - return -1; - } - goto PROXY_AUTHENTIC; - default: - return -1; - } - -PROXY_AUTHENTIC: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto PROXY_AUTHENTICA; - case 'a': - if (last) { - return -1; - } - goto PROXY_AUTHENTICA; - default: - return -1; - } - -PROXY_AUTHENTICA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto PROXY_AUTHENTICAT; - case 't': - if (last) { - return -1; - } - goto PROXY_AUTHENTICAT; - default: - return -1; - } - -PROXY_AUTHENTICAT: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 50; - } - goto PROXY_AUTHENTICATE; - case 'e': - if (last) { - return 50; - } - goto PROXY_AUTHENTICATE; - default: - return -1; - } - -PROXY_AUTHO: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto PROXY_AUTHOR; - case 'r': - if (last) { - return -1; - } - goto PROXY_AUTHOR; - default: - return -1; - } - -PROXY_AUTHOR: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto PROXY_AUTHORI; - case 'i': - if (last) { - return -1; - } - goto PROXY_AUTHORI; - default: - return -1; - } - -PROXY_AUTHORI: - NEXT_CHAR(); - switch (ch) { - case 'Z': - if (last) { - return -1; - } - goto PROXY_AUTHORIZ; - case 'z': - if (last) { - return -1; - } - goto PROXY_AUTHORIZ; - default: - return -1; - } - -PROXY_AUTHORIZ: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto PROXY_AUTHORIZA; - case 'a': - if (last) { - return -1; - } - goto PROXY_AUTHORIZA; - default: - return -1; - } - -PROXY_AUTHORIZA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto PROXY_AUTHORIZAT; - case 't': - if (last) { - return -1; - } - goto PROXY_AUTHORIZAT; - default: - return -1; - } - -PROXY_AUTHORIZAT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto PROXY_AUTHORIZATI; - case 'i': - if (last) { - return -1; - } - goto PROXY_AUTHORIZATI; - default: - return -1; - } - -PROXY_AUTHORIZATI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto PROXY_AUTHORIZATIO; - case 'o': - if (last) { - return -1; - } - goto PROXY_AUTHORIZATIO; - default: - return -1; - } - -PROXY_AUTHORIZATIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 51; - } - goto PROXY_AUTHORIZATION; - case 'n': - if (last) { - return 51; - } - goto PROXY_AUTHORIZATION; - default: - return -1; - } - -R: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto RA; - case 'a': - if (last) { - return -1; - } - goto RA; - case 'E': - if (last) { - return -1; - } - goto RE; - case 'e': - if (last) { - return -1; - } - goto RE; - default: - return -1; - } - -RA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto RAN; - case 'n': - if (last) { - return -1; - } - goto RAN; - default: - return -1; - } - -RAN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto RANG; - case 'g': - if (last) { - return -1; - } - goto RANG; - default: - return -1; - } - -RANG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 52; - } - goto RANGE; - case 'e': - if (last) { - return 52; - } - goto RANGE; - default: - return -1; - } - -RE: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto REF; - case 'f': - if (last) { - return -1; - } - goto REF; - case 'T': - if (last) { - return -1; - } - goto RET; - case 't': - if (last) { - return -1; - } - goto RET; - default: - return -1; - } - -REF: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto REFE; - case 'e': - if (last) { - return -1; - } - goto REFE; - default: - return -1; - } - -REFE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto REFER; - case 'r': - if (last) { - return -1; - } - goto REFER; - default: - return -1; - } - -REFER: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto REFERE; - case 'e': - if (last) { - return -1; - } - goto REFERE; - default: - return -1; - } - -REFERE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return 53; - } - goto REFERER; - case 'r': - if (last) { - return 53; - } - goto REFERER; - default: - return -1; - } - -RET: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto RETR; - case 'r': - if (last) { - return -1; - } - goto RETR; - default: - return -1; - } - -RETR: - NEXT_CHAR(); - switch (ch) { - case 'Y': - if (last) { - return -1; - } - goto RETRY; - case 'y': - if (last) { - return -1; - } - goto RETRY; - default: - return -1; - } - -RETRY: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto RETRY_; - default: - return -1; - } - -RETRY_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto RETRY_A; - case 'a': - if (last) { - return -1; - } - goto RETRY_A; - default: - return -1; - } - -RETRY_A: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto RETRY_AF; - case 'f': - if (last) { - return -1; - } - goto RETRY_AF; - default: - return -1; - } - -RETRY_AF: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto RETRY_AFT; - case 't': - if (last) { - return -1; - } - goto RETRY_AFT; - default: - return -1; - } - -RETRY_AFT: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto RETRY_AFTE; - case 'e': - if (last) { - return -1; - } - goto RETRY_AFTE; - default: - return -1; - } - -RETRY_AFTE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return 54; - } - goto RETRY_AFTER; - case 'r': - if (last) { - return 54; - } - goto RETRY_AFTER; - default: - return -1; - } - -S: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SE; - case 'e': - if (last) { - return -1; - } - goto SE; - default: - return -1; - } - -SE: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto SEC; - case 'c': - if (last) { - return -1; - } - goto SEC; - case 'R': - if (last) { - return -1; - } - goto SER; - case 'r': - if (last) { - return -1; - } - goto SER; - case 'T': - if (last) { - return -1; - } - goto SET; - case 't': - if (last) { - return -1; - } - goto SET; - default: - return -1; - } - -SEC: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto SEC_; - default: - return -1; - } - -SEC_: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto SEC_W; - case 'w': - if (last) { - return -1; - } - goto SEC_W; - default: - return -1; - } - -SEC_W: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SEC_WE; - case 'e': - if (last) { - return -1; - } - goto SEC_WE; - default: - return -1; - } - -SEC_WE: - NEXT_CHAR(); - switch (ch) { - case 'B': - if (last) { - return -1; - } - goto SEC_WEB; - case 'b': - if (last) { - return -1; - } - goto SEC_WEB; - default: - return -1; - } - -SEC_WEB: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto SEC_WEBS; - case 's': - if (last) { - return -1; - } - goto SEC_WEBS; - default: - return -1; - } - -SEC_WEBS: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SEC_WEBSO; - case 'o': - if (last) { - return -1; - } - goto SEC_WEBSO; - default: - return -1; - } - -SEC_WEBSO: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto SEC_WEBSOC; - case 'c': - if (last) { - return -1; - } - goto SEC_WEBSOC; - default: - return -1; - } - -SEC_WEBSOC: - NEXT_CHAR(); - switch (ch) { - case 'K': - if (last) { - return -1; - } - goto SEC_WEBSOCK; - case 'k': - if (last) { - return -1; - } - goto SEC_WEBSOCK; - default: - return -1; - } - -SEC_WEBSOCK: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SEC_WEBSOCKE; - case 'e': - if (last) { - return -1; - } - goto SEC_WEBSOCKE; - default: - return -1; - } - -SEC_WEBSOCKE: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto SEC_WEBSOCKET; - case 't': - if (last) { - return -1; - } - goto SEC_WEBSOCKET; - default: - return -1; - } - -SEC_WEBSOCKET: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_; - default: - return -1; - } - -SEC_WEBSOCKET_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_A; - case 'a': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_A; - case 'E': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_E; - case 'e': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_E; - case 'K': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_K; - case 'k': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_K; - case 'P': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_P; - case 'p': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_P; - case 'V': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_V; - case 'v': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_V; - default: - return -1; - } - -SEC_WEBSOCKET_A: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_AC; - case 'c': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_AC; - default: - return -1; - } - -SEC_WEBSOCKET_AC: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_ACC; - case 'c': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_ACC; - default: - return -1; - } - -SEC_WEBSOCKET_ACC: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_ACCE; - case 'e': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_ACCE; - default: - return -1; - } - -SEC_WEBSOCKET_ACCE: - NEXT_CHAR(); - switch (ch) { - case 'P': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_ACCEP; - case 'p': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_ACCEP; - default: - return -1; - } - -SEC_WEBSOCKET_ACCEP: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 55; - } - goto SEC_WEBSOCKET_ACCEPT; - case 't': - if (last) { - return 55; - } - goto SEC_WEBSOCKET_ACCEPT; - default: - return -1; - } - -SEC_WEBSOCKET_E: - NEXT_CHAR(); - switch (ch) { - case 'X': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EX; - case 'x': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EX; - default: - return -1; - } - -SEC_WEBSOCKET_EX: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXT; - case 't': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXT; - default: - return -1; - } - -SEC_WEBSOCKET_EXT: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTE; - case 'e': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTE; - default: - return -1; - } - -SEC_WEBSOCKET_EXTE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTEN; - case 'n': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTEN; - default: - return -1; - } - -SEC_WEBSOCKET_EXTEN: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENS; - case 's': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENS; - default: - return -1; - } - -SEC_WEBSOCKET_EXTENS: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENSI; - case 'i': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENSI; - default: - return -1; - } - -SEC_WEBSOCKET_EXTENSI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENSIO; - case 'o': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENSIO; - default: - return -1; - } - -SEC_WEBSOCKET_EXTENSIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENSION; - case 'n': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_EXTENSION; - default: - return -1; - } - -SEC_WEBSOCKET_EXTENSION: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return 56; - } - goto SEC_WEBSOCKET_EXTENSIONS; - case 's': - if (last) { - return 56; - } - goto SEC_WEBSOCKET_EXTENSIONS; - default: - return -1; - } - -SEC_WEBSOCKET_K: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_KE; - case 'e': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_KE; - default: - return -1; - } - -SEC_WEBSOCKET_KE: - NEXT_CHAR(); - switch (ch) { - case 'Y': - if (last) { - return 57; - } - goto SEC_WEBSOCKET_KEY; - case 'y': - if (last) { - return 57; - } - goto SEC_WEBSOCKET_KEY; - default: - return -1; - } - -SEC_WEBSOCKET_KEY: - NEXT_CHAR(); - switch (ch) { - case '1': - if (last) { - return 58; - } - goto SEC_WEBSOCKET_KEY1; - default: - return -1; - } - -SEC_WEBSOCKET_P: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PR; - case 'r': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PR; - default: - return -1; - } - -SEC_WEBSOCKET_PR: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PRO; - case 'o': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PRO; - default: - return -1; - } - -SEC_WEBSOCKET_PRO: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROT; - case 't': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROT; - default: - return -1; - } - -SEC_WEBSOCKET_PROT: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROTO; - case 'o': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROTO; - default: - return -1; - } - -SEC_WEBSOCKET_PROTO: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROTOC; - case 'c': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROTOC; - default: - return -1; - } - -SEC_WEBSOCKET_PROTOC: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROTOCO; - case 'o': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_PROTOCO; - default: - return -1; - } - -SEC_WEBSOCKET_PROTOCO: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return 59; - } - goto SEC_WEBSOCKET_PROTOCOL; - case 'l': - if (last) { - return 59; - } - goto SEC_WEBSOCKET_PROTOCOL; - default: - return -1; - } - -SEC_WEBSOCKET_V: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VE; - case 'e': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VE; - default: - return -1; - } - -SEC_WEBSOCKET_VE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VER; - case 'r': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VER; - default: - return -1; - } - -SEC_WEBSOCKET_VER: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VERS; - case 's': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VERS; - default: - return -1; - } - -SEC_WEBSOCKET_VERS: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VERSI; - case 'i': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VERSI; - default: - return -1; - } - -SEC_WEBSOCKET_VERSI: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VERSIO; - case 'o': - if (last) { - return -1; - } - goto SEC_WEBSOCKET_VERSIO; - default: - return -1; - } - -SEC_WEBSOCKET_VERSIO: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return 60; - } - goto SEC_WEBSOCKET_VERSION; - case 'n': - if (last) { - return 60; - } - goto SEC_WEBSOCKET_VERSION; - default: - return -1; - } - -SER: - NEXT_CHAR(); - switch (ch) { - case 'V': - if (last) { - return -1; - } - goto SERV; - case 'v': - if (last) { - return -1; - } - goto SERV; - default: - return -1; - } - -SERV: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto SERVE; - case 'e': - if (last) { - return -1; - } - goto SERVE; - default: - return -1; - } - -SERVE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return 61; - } - goto SERVER; - case 'r': - if (last) { - return 61; - } - goto SERVER; - default: - return -1; - } - -SET: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto SET_; - default: - return -1; - } - -SET_: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto SET_C; - case 'c': - if (last) { - return -1; - } - goto SET_C; - default: - return -1; - } - -SET_C: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SET_CO; - case 'o': - if (last) { - return -1; - } - goto SET_CO; - default: - return -1; - } - -SET_CO: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto SET_COO; - case 'o': - if (last) { - return -1; - } - goto SET_COO; - default: - return -1; - } - -SET_COO: - NEXT_CHAR(); - switch (ch) { - case 'K': - if (last) { - return -1; - } - goto SET_COOK; - case 'k': - if (last) { - return -1; - } - goto SET_COOK; - default: - return -1; - } - -SET_COOK: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto SET_COOKI; - case 'i': - if (last) { - return -1; - } - goto SET_COOKI; - default: - return -1; - } - -SET_COOKI: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 62; - } - goto SET_COOKIE; - case 'e': - if (last) { - return 62; - } - goto SET_COOKIE; - default: - return -1; - } - -T: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 63; - } - goto TE; - case 'e': - if (last) { - return 63; - } - goto TE; - case 'R': - if (last) { - return -1; - } - goto TR; - case 'r': - if (last) { - return -1; - } - goto TR; - default: - return -1; - } - -TR: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto TRA; - case 'a': - if (last) { - return -1; - } - goto TRA; - default: - return -1; - } - -TRA: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto TRAI; - case 'i': - if (last) { - return -1; - } - goto TRAI; - case 'N': - if (last) { - return -1; - } - goto TRAN; - case 'n': - if (last) { - return -1; - } - goto TRAN; - default: - return -1; - } - -TRAI: - NEXT_CHAR(); - switch (ch) { - case 'L': - if (last) { - return -1; - } - goto TRAIL; - case 'l': - if (last) { - return -1; - } - goto TRAIL; - default: - return -1; - } - -TRAIL: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto TRAILE; - case 'e': - if (last) { - return -1; - } - goto TRAILE; - default: - return -1; - } - -TRAILE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return 64; - } - goto TRAILER; - case 'r': - if (last) { - return 64; - } - goto TRAILER; - default: - return -1; - } - -TRAN: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto TRANS; - case 's': - if (last) { - return -1; - } - goto TRANS; - default: - return -1; - } - -TRANS: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto TRANSF; - case 'f': - if (last) { - return -1; - } - goto TRANSF; - default: - return -1; - } - -TRANSF: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto TRANSFE; - case 'e': - if (last) { - return -1; - } - goto TRANSFE; - default: - return -1; - } - -TRANSFE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto TRANSFER; - case 'r': - if (last) { - return -1; - } - goto TRANSFER; - default: - return -1; - } - -TRANSFER: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto TRANSFER_; - default: - return -1; - } - -TRANSFER_: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto TRANSFER_E; - case 'e': - if (last) { - return -1; - } - goto TRANSFER_E; - default: - return -1; - } - -TRANSFER_E: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto TRANSFER_EN; - case 'n': - if (last) { - return -1; - } - goto TRANSFER_EN; - default: - return -1; - } - -TRANSFER_EN: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto TRANSFER_ENC; - case 'c': - if (last) { - return -1; - } - goto TRANSFER_ENC; - default: - return -1; - } - -TRANSFER_ENC: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto TRANSFER_ENCO; - case 'o': - if (last) { - return -1; - } - goto TRANSFER_ENCO; - default: - return -1; - } - -TRANSFER_ENCO: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto TRANSFER_ENCOD; - case 'd': - if (last) { - return -1; - } - goto TRANSFER_ENCOD; - default: - return -1; - } - -TRANSFER_ENCOD: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto TRANSFER_ENCODI; - case 'i': - if (last) { - return -1; - } - goto TRANSFER_ENCODI; - default: - return -1; - } - -TRANSFER_ENCODI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto TRANSFER_ENCODIN; - case 'n': - if (last) { - return -1; - } - goto TRANSFER_ENCODIN; - default: - return -1; - } - -TRANSFER_ENCODIN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return 65; - } - goto TRANSFER_ENCODING; - case 'g': - if (last) { - return 65; - } - goto TRANSFER_ENCODING; - default: - return -1; - } - -U: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto UR; - case 'r': - if (last) { - return -1; - } - goto UR; - case 'P': - if (last) { - return -1; - } - goto UP; - case 'p': - if (last) { - return -1; - } - goto UP; - case 'S': - if (last) { - return -1; - } - goto US; - case 's': - if (last) { - return -1; - } - goto US; - default: - return -1; - } - -UR: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return 66; - } - goto URI; - case 'i': - if (last) { - return 66; - } - goto URI; - default: - return -1; - } - -UP: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto UPG; - case 'g': - if (last) { - return -1; - } - goto UPG; - default: - return -1; - } - -UPG: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto UPGR; - case 'r': - if (last) { - return -1; - } - goto UPGR; - default: - return -1; - } - -UPGR: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto UPGRA; - case 'a': - if (last) { - return -1; - } - goto UPGRA; - default: - return -1; - } - -UPGRA: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto UPGRAD; - case 'd': - if (last) { - return -1; - } - goto UPGRAD; - default: - return -1; - } - -UPGRAD: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 67; - } - goto UPGRADE; - case 'e': - if (last) { - return 67; - } - goto UPGRADE; - default: - return -1; - } - -US: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto USE; - case 'e': - if (last) { - return -1; - } - goto USE; - default: - return -1; - } - -USE: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto USER; - case 'r': - if (last) { - return -1; - } - goto USER; - default: - return -1; - } - -USER: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto USER_; - default: - return -1; - } - -USER_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto USER_A; - case 'a': - if (last) { - return -1; - } - goto USER_A; - default: - return -1; - } - -USER_A: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto USER_AG; - case 'g': - if (last) { - return -1; - } - goto USER_AG; - default: - return -1; - } - -USER_AG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto USER_AGE; - case 'e': - if (last) { - return -1; - } - goto USER_AGE; - default: - return -1; - } - -USER_AGE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto USER_AGEN; - case 'n': - if (last) { - return -1; - } - goto USER_AGEN; - default: - return -1; - } - -USER_AGEN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 68; - } - goto USER_AGENT; - case 't': - if (last) { - return 68; - } - goto USER_AGENT; - default: - return -1; - } - -V: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto VA; - case 'a': - if (last) { - return -1; - } - goto VA; - case 'I': - if (last) { - return -1; - } - goto VI; - case 'i': - if (last) { - return -1; - } - goto VI; - default: - return -1; - } - -VA: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto VAR; - case 'r': - if (last) { - return -1; - } - goto VAR; - default: - return -1; - } - -VAR: - NEXT_CHAR(); - switch (ch) { - case 'Y': - if (last) { - return 69; - } - goto VARY; - case 'y': - if (last) { - return 69; - } - goto VARY; - default: - return -1; - } - -VI: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return 70; - } - goto VIA; - case 'a': - if (last) { - return 70; - } - goto VIA; - default: - return -1; - } - -W: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto WW; - case 'w': - if (last) { - return -1; - } - goto WW; - case 'A': - if (last) { - return -1; - } - goto WA; - case 'a': - if (last) { - return -1; - } - goto WA; - default: - return -1; - } - -WW: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto WWW; - case 'w': - if (last) { - return -1; - } - goto WWW; - default: - return -1; - } - -WWW: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto WWW_; - default: - return -1; - } - -WWW_: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto WWW_A; - case 'a': - if (last) { - return -1; - } - goto WWW_A; - default: - return -1; - } - -WWW_A: - NEXT_CHAR(); - switch (ch) { - case 'U': - if (last) { - return -1; - } - goto WWW_AU; - case 'u': - if (last) { - return -1; - } - goto WWW_AU; - default: - return -1; - } - -WWW_AU: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto WWW_AUT; - case 't': - if (last) { - return -1; - } - goto WWW_AUT; - default: - return -1; - } - -WWW_AUT: - NEXT_CHAR(); - switch (ch) { - case 'H': - if (last) { - return -1; - } - goto WWW_AUTH; - case 'h': - if (last) { - return -1; - } - goto WWW_AUTH; - default: - return -1; - } - -WWW_AUTH: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto WWW_AUTHE; - case 'e': - if (last) { - return -1; - } - goto WWW_AUTHE; - default: - return -1; - } - -WWW_AUTHE: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto WWW_AUTHEN; - case 'n': - if (last) { - return -1; - } - goto WWW_AUTHEN; - default: - return -1; - } - -WWW_AUTHEN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto WWW_AUTHENT; - case 't': - if (last) { - return -1; - } - goto WWW_AUTHENT; - default: - return -1; - } - -WWW_AUTHENT: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto WWW_AUTHENTI; - case 'i': - if (last) { - return -1; - } - goto WWW_AUTHENTI; - default: - return -1; - } - -WWW_AUTHENTI: - NEXT_CHAR(); - switch (ch) { - case 'C': - if (last) { - return -1; - } - goto WWW_AUTHENTIC; - case 'c': - if (last) { - return -1; - } - goto WWW_AUTHENTIC; - default: - return -1; - } - -WWW_AUTHENTIC: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto WWW_AUTHENTICA; - case 'a': - if (last) { - return -1; - } - goto WWW_AUTHENTICA; - default: - return -1; - } - -WWW_AUTHENTICA: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto WWW_AUTHENTICAT; - case 't': - if (last) { - return -1; - } - goto WWW_AUTHENTICAT; - default: - return -1; - } - -WWW_AUTHENTICAT: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return 71; - } - goto WWW_AUTHENTICATE; - case 'e': - if (last) { - return 71; - } - goto WWW_AUTHENTICATE; - default: - return -1; - } - -WA: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto WAN; - case 'n': - if (last) { - return -1; - } - goto WAN; - case 'R': - if (last) { - return -1; - } - goto WAR; - case 'r': - if (last) { - return -1; - } - goto WAR; - default: - return -1; - } - -WAN: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto WANT; - case 't': - if (last) { - return -1; - } - goto WANT; - default: - return -1; - } - -WANT: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto WANT_; - default: - return -1; - } - -WANT_: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto WANT_D; - case 'd': - if (last) { - return -1; - } - goto WANT_D; - default: - return -1; - } - -WANT_D: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto WANT_DI; - case 'i': - if (last) { - return -1; - } - goto WANT_DI; - default: - return -1; - } - -WANT_DI: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return -1; - } - goto WANT_DIG; - case 'g': - if (last) { - return -1; - } - goto WANT_DIG; - default: - return -1; - } - -WANT_DIG: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto WANT_DIGE; - case 'e': - if (last) { - return -1; - } - goto WANT_DIGE; - default: - return -1; - } - -WANT_DIGE: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto WANT_DIGES; - case 's': - if (last) { - return -1; - } - goto WANT_DIGES; - default: - return -1; - } - -WANT_DIGES: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 72; - } - goto WANT_DIGEST; - case 't': - if (last) { - return 72; - } - goto WANT_DIGEST; - default: - return -1; - } - -WAR: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto WARN; - case 'n': - if (last) { - return -1; - } - goto WARN; - default: - return -1; - } - -WARN: - NEXT_CHAR(); - switch (ch) { - case 'I': - if (last) { - return -1; - } - goto WARNI; - case 'i': - if (last) { - return -1; - } - goto WARNI; - default: - return -1; - } - -WARNI: - NEXT_CHAR(); - switch (ch) { - case 'N': - if (last) { - return -1; - } - goto WARNIN; - case 'n': - if (last) { - return -1; - } - goto WARNIN; - default: - return -1; - } - -WARNIN: - NEXT_CHAR(); - switch (ch) { - case 'G': - if (last) { - return 73; - } - goto WARNING; - case 'g': - if (last) { - return 73; - } - goto WARNING; - default: - return -1; - } - -X: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto X_; - default: - return -1; - } - -X_: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto X_F; - case 'f': - if (last) { - return -1; - } - goto X_F; - default: - return -1; - } - -X_F: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto X_FO; - case 'o': - if (last) { - return -1; - } - goto X_FO; - default: - return -1; - } - -X_FO: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto X_FOR; - case 'r': - if (last) { - return -1; - } - goto X_FOR; - default: - return -1; - } - -X_FOR: - NEXT_CHAR(); - switch (ch) { - case 'W': - if (last) { - return -1; - } - goto X_FORW; - case 'w': - if (last) { - return -1; - } - goto X_FORW; - default: - return -1; - } - -X_FORW: - NEXT_CHAR(); - switch (ch) { - case 'A': - if (last) { - return -1; - } - goto X_FORWA; - case 'a': - if (last) { - return -1; - } - goto X_FORWA; - default: - return -1; - } - -X_FORWA: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto X_FORWAR; - case 'r': - if (last) { - return -1; - } - goto X_FORWAR; - default: - return -1; - } - -X_FORWAR: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto X_FORWARD; - case 'd': - if (last) { - return -1; - } - goto X_FORWARD; - default: - return -1; - } - -X_FORWARD: - NEXT_CHAR(); - switch (ch) { - case 'E': - if (last) { - return -1; - } - goto X_FORWARDE; - case 'e': - if (last) { - return -1; - } - goto X_FORWARDE; - default: - return -1; - } - -X_FORWARDE: - NEXT_CHAR(); - switch (ch) { - case 'D': - if (last) { - return -1; - } - goto X_FORWARDED; - case 'd': - if (last) { - return -1; - } - goto X_FORWARDED; - default: - return -1; - } - -X_FORWARDED: - NEXT_CHAR(); - switch (ch) { - case '-': - if (last) { - return -1; - } - goto X_FORWARDED_; - default: - return -1; - } - -X_FORWARDED_: - NEXT_CHAR(); - switch (ch) { - case 'F': - if (last) { - return -1; - } - goto X_FORWARDED_F; - case 'f': - if (last) { - return -1; - } - goto X_FORWARDED_F; - case 'H': - if (last) { - return -1; - } - goto X_FORWARDED_H; - case 'h': - if (last) { - return -1; - } - goto X_FORWARDED_H; - case 'P': - if (last) { - return -1; - } - goto X_FORWARDED_P; - case 'p': - if (last) { - return -1; - } - goto X_FORWARDED_P; - default: - return -1; - } - -X_FORWARDED_F: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto X_FORWARDED_FO; - case 'o': - if (last) { - return -1; - } - goto X_FORWARDED_FO; - default: - return -1; - } - -X_FORWARDED_FO: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return 74; - } - goto X_FORWARDED_FOR; - case 'r': - if (last) { - return 74; - } - goto X_FORWARDED_FOR; - default: - return -1; - } - -X_FORWARDED_H: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto X_FORWARDED_HO; - case 'o': - if (last) { - return -1; - } - goto X_FORWARDED_HO; - default: - return -1; - } - -X_FORWARDED_HO: - NEXT_CHAR(); - switch (ch) { - case 'S': - if (last) { - return -1; - } - goto X_FORWARDED_HOS; - case 's': - if (last) { - return -1; - } - goto X_FORWARDED_HOS; - default: - return -1; - } - -X_FORWARDED_HOS: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return 75; - } - goto X_FORWARDED_HOST; - case 't': - if (last) { - return 75; - } - goto X_FORWARDED_HOST; - default: - return -1; - } - -X_FORWARDED_P: - NEXT_CHAR(); - switch (ch) { - case 'R': - if (last) { - return -1; - } - goto X_FORWARDED_PR; - case 'r': - if (last) { - return -1; - } - goto X_FORWARDED_PR; - default: - return -1; - } - -X_FORWARDED_PR: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return -1; - } - goto X_FORWARDED_PRO; - case 'o': - if (last) { - return -1; - } - goto X_FORWARDED_PRO; - default: - return -1; - } - -X_FORWARDED_PRO: - NEXT_CHAR(); - switch (ch) { - case 'T': - if (last) { - return -1; - } - goto X_FORWARDED_PROT; - case 't': - if (last) { - return -1; - } - goto X_FORWARDED_PROT; - default: - return -1; - } - -X_FORWARDED_PROT: - NEXT_CHAR(); - switch (ch) { - case 'O': - if (last) { - return 76; - } - goto X_FORWARDED_PROTO; - case 'o': - if (last) { - return 76; - } - goto X_FORWARDED_PROTO; - default: - return -1; - } - -ACCEPT_CHARSET: -ACCEPT_ENCODING: -ACCEPT_LANGUAGE: -ACCEPT_RANGES: -ACCESS_CONTROL_ALLOW_CREDENTIALS: -ACCESS_CONTROL_ALLOW_HEADERS: -ACCESS_CONTROL_ALLOW_METHODS: -ACCESS_CONTROL_ALLOW_ORIGIN: -ACCESS_CONTROL_EXPOSE_HEADERS: -ACCESS_CONTROL_MAX_AGE: -ACCESS_CONTROL_REQUEST_HEADERS: -ACCESS_CONTROL_REQUEST_METHOD: -AGE: -ALLOW: -AUTHORIZATION: -CACHE_CONTROL: -CONNECTION: -CONTENT_DISPOSITION: -CONTENT_ENCODING: -CONTENT_LANGUAGE: -CONTENT_LENGTH: -CONTENT_LOCATION: -CONTENT_MD5: -CONTENT_RANGE: -CONTENT_TRANSFER_ENCODING: -CONTENT_TYPE: -COOKIE: -DATE: -DESTINATION: -DIGEST: -ETAG: -EXPECT: -EXPIRES: -FORWARDED: -FROM: -HOST: -IF_MATCH: -IF_MODIFIED_SINCE: -IF_NONE_MATCH: -IF_RANGE: -IF_UNMODIFIED_SINCE: -KEEP_ALIVE: -LAST_EVENT_ID: -LAST_MODIFIED: -LINK: -LOCATION: -MAX_FORWARDS: -ORIGIN: -PRAGMA: -PROXY_AUTHENTICATE: -PROXY_AUTHORIZATION: -RANGE: -REFERER: -RETRY_AFTER: -SEC_WEBSOCKET_ACCEPT: -SEC_WEBSOCKET_EXTENSIONS: -SEC_WEBSOCKET_KEY1: -SEC_WEBSOCKET_PROTOCOL: -SEC_WEBSOCKET_VERSION: -SERVER: -SET_COOKIE: -TE: -TRAILER: -TRANSFER_ENCODING: -UPGRADE: -URI: -USER_AGENT: -VARY: -VIA: -WANT_DIGEST: -WARNING: -WWW_AUTHENTICATE: -X_FORWARDED_FOR: -X_FORWARDED_HOST: -X_FORWARDED_PROTO: -missing: - /* nothing found */ - return -1; -} diff --git a/dist/ba_data/python-site-packages/aiohttp/_find_header.h b/dist/ba_data/python-site-packages/aiohttp/_find_header.h deleted file mode 100644 index 99b7b4f8..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_find_header.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _FIND_HEADERS_H -#define _FIND_HEADERS_H - -#ifdef __cplusplus -extern "C" { -#endif - -int find_header(const char *str, int size); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.c b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.c deleted file mode 100644 index 8588a951..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.c +++ /dev/null @@ -1,7512 +0,0 @@ -/* Generated by Cython 0.29.21 */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_21" -#define CYTHON_HEX_VERSION 0x001D15F0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__aiohttp___frozenlist -#define __PYX_HAVE_API__aiohttp___frozenlist -/* Early includes */ -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "aiohttp\\_frozenlist.pyx", - "stringsource", -}; - -/*--- Type declarations ---*/ -struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList; - -/* "aiohttp/_frozenlist.pyx":4 - * - * - * cdef class FrozenList: # <<<<<<<<<<<<<< - * - * cdef readonly bint frozen - */ -struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList { - PyObject_HEAD - struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *__pyx_vtab; - int frozen; - PyObject *_items; -}; - - - -struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList { - PyObject *(*_check_frozen)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *); - PyObject *(*_fast_len)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *); -}; -static struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *__pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList; -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *); - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* ObjectGetItem.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); -#else -#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallNoArg.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); -#else -#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* PyIntCompare.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); - -/* PySequenceContains.proto */ -static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { - int result = PySequence_Contains(seq, item); - return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); -} - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PyObjectGetMethod.proto */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -/* PyObjectCallMethod1.proto */ -static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); - -/* pop_index.proto */ -static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); -static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix); -#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ - (likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ?\ - __Pyx__PyList_PopIndex(L, py_ix, ix) : (\ - (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ - __Pyx__PyObject_PopIndex(L, py_ix))) -#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ - __Pyx_fits_Py_ssize_t(ix, type, is_signed) ?\ - __Pyx__PyList_PopIndex(L, py_ix, ix) : (\ - (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ - __Pyx__PyObject_PopIndex(L, py_ix))) -#else -#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func)\ - __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) -#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ - (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ - __Pyx__PyObject_PopIndex(L, py_ix)) -#endif - -/* ListAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* GetAttr.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); - -/* GetAttr3.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* HasAttr.proto */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* SetVTable.proto */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable); - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* SetupReduce.proto */ -static int __Pyx_setup_reduce(PyObject* type_obj); - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - -static PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__check_frozen(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto*/ - -/* Module declarations from 'aiohttp._frozenlist' */ -static PyTypeObject *__pyx_ptype_7aiohttp_11_frozenlist_FrozenList = 0; -static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *, PyObject *); /*proto*/ -#define __Pyx_MODULE_NAME "aiohttp._frozenlist" -extern int __pyx_module_is_main_aiohttp___frozenlist; -int __pyx_module_is_main_aiohttp___frozenlist = 0; - -/* Implementation of 'aiohttp._frozenlist' */ -static PyObject *__pyx_builtin_RuntimeError; -static const char __pyx_k_new[] = "__new__"; -static const char __pyx_k_pop[] = "pop"; -static const char __pyx_k_pos[] = "pos"; -static const char __pyx_k_dict[] = "__dict__"; -static const char __pyx_k_item[] = "item"; -static const char __pyx_k_iter[] = "__iter__"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_clear[] = "clear"; -static const char __pyx_k_count[] = "count"; -static const char __pyx_k_index[] = "index"; -static const char __pyx_k_items[] = "items"; -static const char __pyx_k_format[] = "format"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_pickle[] = "pickle"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_remove[] = "remove"; -static const char __pyx_k_update[] = "update"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_pyx_type[] = "__pyx_type"; -static const char __pyx_k_register[] = "register"; -static const char __pyx_k_reversed[] = "__reversed__"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_FrozenList[] = "FrozenList"; -static const char __pyx_k_pyx_result[] = "__pyx_result"; -static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; -static const char __pyx_k_PickleError[] = "PickleError"; -static const char __pyx_k_RuntimeError[] = "RuntimeError"; -static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; -static const char __pyx_k_stringsource[] = "stringsource"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_MutableSequence[] = "MutableSequence"; -static const char __pyx_k_collections_abc[] = "collections.abc"; -static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_FrozenList_frozen_r[] = ""; -static const char __pyx_k_aiohttp__frozenlist[] = "aiohttp._frozenlist"; -static const char __pyx_k_pyx_unpickle_FrozenList[] = "__pyx_unpickle_FrozenList"; -static const char __pyx_k_Cannot_modify_frozen_list[] = "Cannot modify frozen list."; -static const char __pyx_k_Incompatible_checksums_s_vs_0x94[] = "Incompatible checksums (%s vs 0x949a143 = (_items, frozen))"; -static PyObject *__pyx_kp_u_Cannot_modify_frozen_list; -static PyObject *__pyx_n_s_FrozenList; -static PyObject *__pyx_kp_u_FrozenList_frozen_r; -static PyObject *__pyx_kp_s_Incompatible_checksums_s_vs_0x94; -static PyObject *__pyx_n_s_MutableSequence; -static PyObject *__pyx_n_s_PickleError; -static PyObject *__pyx_n_s_RuntimeError; -static PyObject *__pyx_n_s_aiohttp__frozenlist; -static PyObject *__pyx_n_s_clear; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_collections_abc; -static PyObject *__pyx_n_s_count; -static PyObject *__pyx_n_s_dict; -static PyObject *__pyx_n_s_format; -static PyObject *__pyx_n_s_getstate; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_index; -static PyObject *__pyx_n_s_item; -static PyObject *__pyx_n_s_items; -static PyObject *__pyx_n_s_iter; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_new; -static PyObject *__pyx_n_s_pickle; -static PyObject *__pyx_n_s_pop; -static PyObject *__pyx_n_s_pos; -static PyObject *__pyx_n_s_pyx_PickleError; -static PyObject *__pyx_n_s_pyx_checksum; -static PyObject *__pyx_n_s_pyx_result; -static PyObject *__pyx_n_s_pyx_state; -static PyObject *__pyx_n_s_pyx_type; -static PyObject *__pyx_n_s_pyx_unpickle_FrozenList; -static PyObject *__pyx_n_s_pyx_vtable; -static PyObject *__pyx_n_s_reduce; -static PyObject *__pyx_n_s_reduce_cython; -static PyObject *__pyx_n_s_reduce_ex; -static PyObject *__pyx_n_s_register; -static PyObject *__pyx_n_s_remove; -static PyObject *__pyx_n_s_reversed; -static PyObject *__pyx_n_s_setstate; -static PyObject *__pyx_n_s_setstate_cython; -static PyObject *__pyx_kp_s_stringsource; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_update; -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList___init__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_2freeze(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_4__getitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6__setitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */ -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_8__delitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ -static Py_ssize_t __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_10__len__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_16__richcmp__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_18insert(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_pos, PyObject *__pyx_v_item); /* proto */ -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_20__contains__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_22__iadd__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_30extend(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_32reverse(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_34pop(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_36append(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_40__repr__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_tp_new_7aiohttp_11_frozenlist_FrozenList(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_int_0; -static PyObject *__pyx_int_1; -static PyObject *__pyx_int_2; -static PyObject *__pyx_int_3; -static PyObject *__pyx_int_4; -static PyObject *__pyx_int_5; -static PyObject *__pyx_int_155820355; -static PyObject *__pyx_int_neg_1; -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_codeobj__3; -/* Late includes */ - -/* "aiohttp/_frozenlist.pyx":9 - * cdef list _items - * - * def __init__(self, items=None): # <<<<<<<<<<<<<< - * self.frozen = False - * if items is not None: - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_items = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_items,0}; - PyObject* values[1] = {0}; - values[0] = ((PyObject *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_items); - if (value) { values[0] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 9, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_items = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 9, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList___init__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), __pyx_v_items); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList___init__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - __Pyx_INCREF(__pyx_v_items); - - /* "aiohttp/_frozenlist.pyx":10 - * - * def __init__(self, items=None): - * self.frozen = False # <<<<<<<<<<<<<< - * if items is not None: - * items = list(items) - */ - __pyx_v_self->frozen = 0; - - /* "aiohttp/_frozenlist.pyx":11 - * def __init__(self, items=None): - * self.frozen = False - * if items is not None: # <<<<<<<<<<<<<< - * items = list(items) - * else: - */ - __pyx_t_1 = (__pyx_v_items != Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":12 - * self.frozen = False - * if items is not None: - * items = list(items) # <<<<<<<<<<<<<< - * else: - * items = [] - */ - __pyx_t_3 = PySequence_List(__pyx_v_items); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_items, __pyx_t_3); - __pyx_t_3 = 0; - - /* "aiohttp/_frozenlist.pyx":11 - * def __init__(self, items=None): - * self.frozen = False - * if items is not None: # <<<<<<<<<<<<<< - * items = list(items) - * else: - */ - goto __pyx_L3; - } - - /* "aiohttp/_frozenlist.pyx":14 - * items = list(items) - * else: - * items = [] # <<<<<<<<<<<<<< - * self._items = items - * - */ - /*else*/ { - __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_items, __pyx_t_3); - __pyx_t_3 = 0; - } - __pyx_L3:; - - /* "aiohttp/_frozenlist.pyx":15 - * else: - * items = [] - * self._items = items # <<<<<<<<<<<<<< - * - * cdef object _check_frozen(self): - */ - if (!(likely(PyList_CheckExact(__pyx_v_items))||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_v_items)->tp_name), 0))) __PYX_ERR(0, 15, __pyx_L1_error) - __pyx_t_3 = __pyx_v_items; - __Pyx_INCREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __Pyx_GOTREF(__pyx_v_self->_items); - __Pyx_DECREF(__pyx_v_self->_items); - __pyx_v_self->_items = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "aiohttp/_frozenlist.pyx":9 - * cdef list _items - * - * def __init__(self, items=None): # <<<<<<<<<<<<<< - * self.frozen = False - * if items is not None: - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_items); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":17 - * self._items = items - * - * cdef object _check_frozen(self): # <<<<<<<<<<<<<< - * if self.frozen: - * raise RuntimeError("Cannot modify frozen list.") - */ - -static PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__check_frozen(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_check_frozen", 0); - - /* "aiohttp/_frozenlist.pyx":18 - * - * cdef object _check_frozen(self): - * if self.frozen: # <<<<<<<<<<<<<< - * raise RuntimeError("Cannot modify frozen list.") - * - */ - __pyx_t_1 = (__pyx_v_self->frozen != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_frozenlist.pyx":19 - * cdef object _check_frozen(self): - * if self.frozen: - * raise RuntimeError("Cannot modify frozen list.") # <<<<<<<<<<<<<< - * - * cdef inline object _fast_len(self): - */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 19, __pyx_L1_error) - - /* "aiohttp/_frozenlist.pyx":18 - * - * cdef object _check_frozen(self): - * if self.frozen: # <<<<<<<<<<<<<< - * raise RuntimeError("Cannot modify frozen list.") - * - */ - } - - /* "aiohttp/_frozenlist.pyx":17 - * self._items = items - * - * cdef object _check_frozen(self): # <<<<<<<<<<<<<< - * if self.frozen: - * raise RuntimeError("Cannot modify frozen list.") - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList._check_frozen", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":21 - * raise RuntimeError("Cannot modify frozen list.") - * - * cdef inline object _fast_len(self): # <<<<<<<<<<<<<< - * return len(self._items) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_fast_len", 0); - - /* "aiohttp/_frozenlist.pyx":22 - * - * cdef inline object _fast_len(self): - * return len(self._items) # <<<<<<<<<<<<<< - * - * def freeze(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_v_self->_items; - __Pyx_INCREF(__pyx_t_1); - if (unlikely(__pyx_t_1 == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(0, 22, __pyx_L1_error) - } - __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":21 - * raise RuntimeError("Cannot modify frozen list.") - * - * cdef inline object _fast_len(self): # <<<<<<<<<<<<<< - * return len(self._items) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList._fast_len", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":24 - * return len(self._items) - * - * def freeze(self): # <<<<<<<<<<<<<< - * self.frozen = True - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("freeze (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_2freeze(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_2freeze(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("freeze", 0); - - /* "aiohttp/_frozenlist.pyx":25 - * - * def freeze(self): - * self.frozen = True # <<<<<<<<<<<<<< - * - * def __getitem__(self, index): - */ - __pyx_v_self->frozen = 1; - - /* "aiohttp/_frozenlist.pyx":24 - * return len(self._items) - * - * def freeze(self): # <<<<<<<<<<<<<< - * self.frozen = True - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":27 - * self.frozen = True - * - * def __getitem__(self, index): # <<<<<<<<<<<<<< - * return self._items[index] - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_4__getitem__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_index)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_4__getitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 0); - - /* "aiohttp/_frozenlist.pyx":28 - * - * def __getitem__(self, index): - * return self._items[index] # <<<<<<<<<<<<<< - * - * def __setitem__(self, index, value): - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 28, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_self->_items, __pyx_v_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":27 - * self.frozen = True - * - * def __getitem__(self, index): # <<<<<<<<<<<<<< - * return self._items[index] - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":30 - * return self._items[index] - * - * def __setitem__(self, index, value): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items[index] = value - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_7__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_7__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6__setitem__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6__setitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 0); - - /* "aiohttp/_frozenlist.pyx":31 - * - * def __setitem__(self, index, value): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items[index] = value - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":32 - * def __setitem__(self, index, value): - * self._check_frozen() - * self._items[index] = value # <<<<<<<<<<<<<< - * - * def __delitem__(self, index): - */ - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 32, __pyx_L1_error) - } - if (unlikely(PyObject_SetItem(__pyx_v_self->_items, __pyx_v_index, __pyx_v_value) < 0)) __PYX_ERR(0, 32, __pyx_L1_error) - - /* "aiohttp/_frozenlist.pyx":30 - * return self._items[index] - * - * def __setitem__(self, index, value): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items[index] = value - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":34 - * self._items[index] = value - * - * def __delitem__(self, index): # <<<<<<<<<<<<<< - * self._check_frozen() - * del self._items[index] - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_9__delitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_9__delitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__delitem__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_8__delitem__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_index)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_8__delitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__delitem__", 0); - - /* "aiohttp/_frozenlist.pyx":35 - * - * def __delitem__(self, index): - * self._check_frozen() # <<<<<<<<<<<<<< - * del self._items[index] - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":36 - * def __delitem__(self, index): - * self._check_frozen() - * del self._items[index] # <<<<<<<<<<<<<< - * - * def __len__(self): - */ - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 36, __pyx_L1_error) - } - if (unlikely(PyObject_DelItem(__pyx_v_self->_items, __pyx_v_index) < 0)) __PYX_ERR(0, 36, __pyx_L1_error) - - /* "aiohttp/_frozenlist.pyx":34 - * self._items[index] = value - * - * def __delitem__(self, index): # <<<<<<<<<<<<<< - * self._check_frozen() - * del self._items[index] - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__delitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":38 - * del self._items[index] - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._fast_len() - * - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_10__len__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_10__len__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__len__", 0); - - /* "aiohttp/_frozenlist.pyx":39 - * - * def __len__(self): - * return self._fast_len() # <<<<<<<<<<<<<< - * - * def __iter__(self): - */ - __pyx_t_1 = __pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_2 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":38 - * del self._items[index] - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._fast_len() - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":41 - * return self._fast_len() - * - * def __iter__(self): # <<<<<<<<<<<<<< - * return self._items.__iter__() - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_13__iter__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_13__iter__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__iter__", 0); - - /* "aiohttp/_frozenlist.pyx":42 - * - * def __iter__(self): - * return self._items.__iter__() # <<<<<<<<<<<<<< - * - * def __reversed__(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_iter); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":41 - * return self._fast_len() - * - * def __iter__(self): # <<<<<<<<<<<<<< - * return self._items.__iter__() - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":44 - * return self._items.__iter__() - * - * def __reversed__(self): # <<<<<<<<<<<<<< - * return self._items.__reversed__() - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reversed__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reversed__", 0); - - /* "aiohttp/_frozenlist.pyx":45 - * - * def __reversed__(self): - * return self._items.__reversed__() # <<<<<<<<<<<<<< - * - * def __richcmp__(self, other, op): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_reversed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":44 - * return self._items.__iter__() - * - * def __reversed__(self): # <<<<<<<<<<<<<< - * return self._items.__reversed__() - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__reversed__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":47 - * return self._items.__reversed__() - * - * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< - * if op == 0: # < - * return list(self) < other - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_17__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_17__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op) { - PyObject *__pyx_v_op = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0); - __pyx_v_op = __Pyx_PyInt_From_int(__pyx_arg_op); if (unlikely(!__pyx_v_op)) __PYX_ERR(0, 47, __pyx_L3_error) - __Pyx_GOTREF(__pyx_v_op); - goto __pyx_L4_argument_unpacking_done; - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_16__richcmp__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_other), ((PyObject *)__pyx_v_op)); - - /* function exit code */ - __Pyx_XDECREF(__pyx_v_op); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_16__richcmp__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__richcmp__", 0); - - /* "aiohttp/_frozenlist.pyx":48 - * - * def __richcmp__(self, other, op): - * if op == 0: # < # <<<<<<<<<<<<<< - * return list(self) < other - * if op == 1: # <= - */ - __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":49 - * def __richcmp__(self, other, op): - * if op == 0: # < - * return list(self) < other # <<<<<<<<<<<<<< - * if op == 1: # <= - * return list(self) <= other - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 49, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_v_other, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 49, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":48 - * - * def __richcmp__(self, other, op): - * if op == 0: # < # <<<<<<<<<<<<<< - * return list(self) < other - * if op == 1: # <= - */ - } - - /* "aiohttp/_frozenlist.pyx":50 - * if op == 0: # < - * return list(self) < other - * if op == 1: # <= # <<<<<<<<<<<<<< - * return list(self) <= other - * if op == 2: # == - */ - __pyx_t_3 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 50, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":51 - * return list(self) < other - * if op == 1: # <= - * return list(self) <= other # <<<<<<<<<<<<<< - * if op == 2: # == - * return list(self) == other - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_other, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":50 - * if op == 0: # < - * return list(self) < other - * if op == 1: # <= # <<<<<<<<<<<<<< - * return list(self) <= other - * if op == 2: # == - */ - } - - /* "aiohttp/_frozenlist.pyx":52 - * if op == 1: # <= - * return list(self) <= other - * if op == 2: # == # <<<<<<<<<<<<<< - * return list(self) == other - * if op == 3: # != - */ - __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 52, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":53 - * return list(self) <= other - * if op == 2: # == - * return list(self) == other # <<<<<<<<<<<<<< - * if op == 3: # != - * return list(self) != other - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_v_other, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":52 - * if op == 1: # <= - * return list(self) <= other - * if op == 2: # == # <<<<<<<<<<<<<< - * return list(self) == other - * if op == 3: # != - */ - } - - /* "aiohttp/_frozenlist.pyx":54 - * if op == 2: # == - * return list(self) == other - * if op == 3: # != # <<<<<<<<<<<<<< - * return list(self) != other - * if op == 4: # > - */ - __pyx_t_3 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_3, 3, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":55 - * return list(self) == other - * if op == 3: # != - * return list(self) != other # <<<<<<<<<<<<<< - * if op == 4: # > - * return list(self) > other - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 55, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_other, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 55, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":54 - * if op == 2: # == - * return list(self) == other - * if op == 3: # != # <<<<<<<<<<<<<< - * return list(self) != other - * if op == 4: # > - */ - } - - /* "aiohttp/_frozenlist.pyx":56 - * if op == 3: # != - * return list(self) != other - * if op == 4: # > # <<<<<<<<<<<<<< - * return list(self) > other - * if op == 5: # => - */ - __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_4, 4, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":57 - * return list(self) != other - * if op == 4: # > - * return list(self) > other # <<<<<<<<<<<<<< - * if op == 5: # => - * return list(self) >= other - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_v_other, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":56 - * if op == 3: # != - * return list(self) != other - * if op == 4: # > # <<<<<<<<<<<<<< - * return list(self) > other - * if op == 5: # => - */ - } - - /* "aiohttp/_frozenlist.pyx":58 - * if op == 4: # > - * return list(self) > other - * if op == 5: # => # <<<<<<<<<<<<<< - * return list(self) >= other - * - */ - __pyx_t_3 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_5, 5, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 58, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_2) { - - /* "aiohttp/_frozenlist.pyx":59 - * return list(self) > other - * if op == 5: # => - * return list(self) >= other # <<<<<<<<<<<<<< - * - * def insert(self, pos, item): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_other, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":58 - * if op == 4: # > - * return list(self) > other - * if op == 5: # => # <<<<<<<<<<<<<< - * return list(self) >= other - * - */ - } - - /* "aiohttp/_frozenlist.pyx":47 - * return self._items.__reversed__() - * - * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< - * if op == 0: # < - * return list(self) < other - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":61 - * return list(self) >= other - * - * def insert(self, pos, item): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.insert(pos, item) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_pos = 0; - PyObject *__pyx_v_item = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("insert (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pos,&__pyx_n_s_item,0}; - PyObject* values[2] = {0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pos)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_item)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("insert", 1, 2, 2, 1); __PYX_ERR(0, 61, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "insert") < 0)) __PYX_ERR(0, 61, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - } - __pyx_v_pos = values[0]; - __pyx_v_item = values[1]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("insert", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 61, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.insert", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_18insert(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), __pyx_v_pos, __pyx_v_item); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_18insert(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_pos, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - int __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("insert", 0); - - /* "aiohttp/_frozenlist.pyx":62 - * - * def insert(self, pos, item): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items.insert(pos, item) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":63 - * def insert(self, pos, item): - * self._check_frozen() - * self._items.insert(pos, item) # <<<<<<<<<<<<<< - * - * def __contains__(self, item): - */ - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "insert"); - __PYX_ERR(0, 63, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_PyIndex_AsSsize_t(__pyx_v_pos); if (unlikely((__pyx_t_2 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 63, __pyx_L1_error) - __pyx_t_3 = PyList_Insert(__pyx_v_self->_items, __pyx_t_2, __pyx_v_item); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 63, __pyx_L1_error) - - /* "aiohttp/_frozenlist.pyx":61 - * return list(self) >= other - * - * def insert(self, pos, item): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.insert(pos, item) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.insert", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":65 - * self._items.insert(pos, item) - * - * def __contains__(self, item): # <<<<<<<<<<<<<< - * return item in self._items - * - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_21__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_21__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_20__contains__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_20__contains__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__contains__", 0); - - /* "aiohttp/_frozenlist.pyx":66 - * - * def __contains__(self, item): - * return item in self._items # <<<<<<<<<<<<<< - * - * def __iadd__(self, items): - */ - __pyx_t_1 = (__Pyx_PySequence_ContainsTF(__pyx_v_item, __pyx_v_self->_items, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 66, __pyx_L1_error) - __pyx_r = __pyx_t_1; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":65 - * self._items.insert(pos, item) - * - * def __contains__(self, item): # <<<<<<<<<<<<<< - * return item in self._items - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":68 - * return item in self._items - * - * def __iadd__(self, items): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items += list(items) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_23__iadd__(PyObject *__pyx_v_self, PyObject *__pyx_v_items); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_23__iadd__(PyObject *__pyx_v_self, PyObject *__pyx_v_items) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__iadd__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_22__iadd__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_items)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_22__iadd__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__iadd__", 0); - - /* "aiohttp/_frozenlist.pyx":69 - * - * def __iadd__(self, items): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items += list(items) - * return self - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":70 - * def __iadd__(self, items): - * self._check_frozen() - * self._items += list(items) # <<<<<<<<<<<<<< - * return self - * - */ - __pyx_t_1 = PySequence_List(__pyx_v_items); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_self->_items, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->_items); - __Pyx_DECREF(__pyx_v_self->_items); - __pyx_v_self->_items = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_frozenlist.pyx":71 - * self._check_frozen() - * self._items += list(items) - * return self # <<<<<<<<<<<<<< - * - * def index(self, item): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __pyx_r = ((PyObject *)__pyx_v_self); - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":68 - * return item in self._items - * - * def __iadd__(self, items): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items += list(items) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__iadd__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":73 - * return self - * - * def index(self, item): # <<<<<<<<<<<<<< - * return self._items.index(item) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("index (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("index", 0); - - /* "aiohttp/_frozenlist.pyx":74 - * - * def index(self, item): - * return self._items.index(item) # <<<<<<<<<<<<<< - * - * def remove(self, item): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":73 - * return self - * - * def index(self, item): # <<<<<<<<<<<<<< - * return self._items.index(item) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.index", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":76 - * return self._items.index(item) - * - * def remove(self, item): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.remove(item) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("remove (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("remove", 0); - - /* "aiohttp/_frozenlist.pyx":77 - * - * def remove(self, item): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items.remove(item) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":78 - * def remove(self, item): - * self._check_frozen() - * self._items.remove(item) # <<<<<<<<<<<<<< - * - * def clear(self): - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_remove); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":76 - * return self._items.index(item) - * - * def remove(self, item): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.remove(item) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.remove", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":80 - * self._items.remove(item) - * - * def clear(self): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.clear() - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("clear (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("clear", 0); - - /* "aiohttp/_frozenlist.pyx":81 - * - * def clear(self): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items.clear() - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":82 - * def clear(self): - * self._check_frozen() - * self._items.clear() # <<<<<<<<<<<<<< - * - * def extend(self, items): - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_clear); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":80 - * self._items.remove(item) - * - * def clear(self): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.clear() - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.clear", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":84 - * self._items.clear() - * - * def extend(self, items): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items += list(items) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend(PyObject *__pyx_v_self, PyObject *__pyx_v_items); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend(PyObject *__pyx_v_self, PyObject *__pyx_v_items) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("extend (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_30extend(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_items)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_30extend(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("extend", 0); - - /* "aiohttp/_frozenlist.pyx":85 - * - * def extend(self, items): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items += list(items) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":86 - * def extend(self, items): - * self._check_frozen() - * self._items += list(items) # <<<<<<<<<<<<<< - * - * def reverse(self): - */ - __pyx_t_1 = PySequence_List(__pyx_v_items); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 86, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_self->_items, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->_items); - __Pyx_DECREF(__pyx_v_self->_items); - __pyx_v_self->_items = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_frozenlist.pyx":84 - * self._items.clear() - * - * def extend(self, items): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items += list(items) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.extend", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":88 - * self._items += list(items) - * - * def reverse(self): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.reverse() - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("reverse (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_32reverse(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_32reverse(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("reverse", 0); - - /* "aiohttp/_frozenlist.pyx":89 - * - * def reverse(self): - * self._check_frozen() # <<<<<<<<<<<<<< - * self._items.reverse() - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":90 - * def reverse(self): - * self._check_frozen() - * self._items.reverse() # <<<<<<<<<<<<<< - * - * def pop(self, index=-1): - */ - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "reverse"); - __PYX_ERR(0, 90, __pyx_L1_error) - } - __pyx_t_2 = PyList_Reverse(__pyx_v_self->_items); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 90, __pyx_L1_error) - - /* "aiohttp/_frozenlist.pyx":88 - * self._items += list(items) - * - * def reverse(self): # <<<<<<<<<<<<<< - * self._check_frozen() - * self._items.reverse() - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.reverse", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":92 - * self._items.reverse() - * - * def pop(self, index=-1): # <<<<<<<<<<<<<< - * self._check_frozen() - * return self._items.pop(index) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_index = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("pop (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_index,0}; - PyObject* values[1] = {0}; - values[0] = ((PyObject *)__pyx_int_neg_1); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_index); - if (value) { values[0] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "pop") < 0)) __PYX_ERR(0, 92, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_index = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("pop", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 92, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.pop", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_34pop(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), __pyx_v_index); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_34pop(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("pop", 0); - - /* "aiohttp/_frozenlist.pyx":93 - * - * def pop(self, index=-1): - * self._check_frozen() # <<<<<<<<<<<<<< - * return self._items.pop(index) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":94 - * def pop(self, index=-1): - * self._check_frozen() - * return self._items.pop(index) # <<<<<<<<<<<<<< - * - * def append(self, item): - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "pop"); - __PYX_ERR(0, 94, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_2 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L1_error) - __pyx_t_1 = __Pyx_PyList_PopIndex(__pyx_v_self->_items, __pyx_v_index, __pyx_t_2, 1, Py_ssize_t, PyInt_FromSsize_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":92 - * self._items.reverse() - * - * def pop(self, index=-1): # <<<<<<<<<<<<<< - * self._check_frozen() - * return self._items.pop(index) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.pop", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":96 - * return self._items.pop(index) - * - * def append(self, item): # <<<<<<<<<<<<<< - * self._check_frozen() - * return self._items.append(item) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("append (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_36append(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_36append(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("append", 0); - - /* "aiohttp/_frozenlist.pyx":97 - * - * def append(self, item): - * self._check_frozen() # <<<<<<<<<<<<<< - * return self._items.append(item) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_frozenlist.pyx":98 - * def append(self, item): - * self._check_frozen() - * return self._items.append(item) # <<<<<<<<<<<<<< - * - * def count(self, item): - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_self->_items == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); - __PYX_ERR(0, 98, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_PyList_Append(__pyx_v_self->_items, __pyx_v_item); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 98, __pyx_L1_error) - __pyx_t_1 = __Pyx_Owned_Py_None(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":96 - * return self._items.pop(index) - * - * def append(self, item): # <<<<<<<<<<<<<< - * self._check_frozen() - * return self._items.append(item) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.append", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":100 - * return self._items.append(item) - * - * def count(self, item): # <<<<<<<<<<<<<< - * return self._items.count(item) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("count (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("count", 0); - - /* "aiohttp/_frozenlist.pyx":101 - * - * def count(self, item): - * return self._items.count(item) # <<<<<<<<<<<<<< - * - * def __repr__(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_count); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":100 - * return self._items.append(item) - * - * def count(self, item): # <<<<<<<<<<<<<< - * return self._items.count(item) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.count", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":103 - * return self._items.count(item) - * - * def __repr__(self): # <<<<<<<<<<<<<< - * return ''.format(self.frozen, - * self._items) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_41__repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_41__repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_40__repr__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_40__repr__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__repr__", 0); - - /* "aiohttp/_frozenlist.pyx":104 - * - * def __repr__(self): - * return ''.format(self.frozen, # <<<<<<<<<<<<<< - * self._items) - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FrozenList_frozen_r, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "aiohttp/_frozenlist.pyx":105 - * def __repr__(self): - * return ''.format(self.frozen, - * self._items) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_4 = NULL; - __pyx_t_5 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - __pyx_t_5 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_v_self->_items}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_v_self->_items}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else - #endif - { - __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (__pyx_t_4) { - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL; - } - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_t_3); - __Pyx_INCREF(__pyx_v_self->_items); - __Pyx_GIVEREF(__pyx_v_self->_items); - PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_self->_items); - __pyx_t_3 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_frozenlist.pyx":103 - * return self._items.count(item) - * - * def __repr__(self): # <<<<<<<<<<<<<< - * return ''.format(self.frozen, - * self._items) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_frozenlist.pyx":6 - * cdef class FrozenList: - * - * cdef readonly bint frozen # <<<<<<<<<<<<<< - * cdef list _items - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_6frozen_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_6frozen_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.frozen.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self._items, self.frozen) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_self->_items); - __Pyx_GIVEREF(__pyx_v_self->_items); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_self->_items); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_v_state = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self._items, self.frozen) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v__dict = __pyx_t_2; - __pyx_t_2 = 0; - - /* "(tree fragment)":7 - * state = (self._items, self.frozen) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_3 = (__pyx_v__dict != Py_None); - __pyx_t_4 = (__pyx_t_3 != 0); - if (__pyx_t_4) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: - */ - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__dict); - __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_1)); - __pyx_t_1 = 0; - - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self._items is not None - */ - __pyx_v_use_setstate = 1; - - /* "(tree fragment)":7 - * state = (self._items, self.frozen) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - goto __pyx_L3; - } - - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self._items is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state - */ - /*else*/ { - __pyx_t_4 = (__pyx_v_self->_items != ((PyObject*)Py_None)); - __pyx_v_use_setstate = __pyx_t_4; - } - __pyx_L3:; - - /* "(tree fragment)":12 - * else: - * use_setstate = self._items is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state - * else: - */ - __pyx_t_4 = (__pyx_v_use_setstate != 0); - if (__pyx_t_4) { - - /* "(tree fragment)":13 - * use_setstate = self._items is not None - * if use_setstate: - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_155820355); - __Pyx_GIVEREF(__pyx_int_155820355); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_155820355); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_2, 2, Py_None); - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_state); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "(tree fragment)":12 - * else: - * use_setstate = self._items is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state - * else: - */ - } - - /* "(tree fragment)":15 - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state - * else: - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_155820355); - __Pyx_GIVEREF(__pyx_int_155820355); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_155820355); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_state); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2); - __pyx_t_5 = 0; - __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - } - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_45__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_45__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cython__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":17 - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) # <<<<<<<<<<<<<< - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList = {"__pyx_unpickle_FrozenList", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_FrozenList", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_FrozenList", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_FrozenList") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_FrozenList", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList", 0); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0x949a143: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) - */ - __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x949a143) != 0); - if (__pyx_t_1) { - - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum != 0x949a143: - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) - * __pyx_result = FrozenList.__new__(__pyx_type) - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_2); - __pyx_v___pyx_PickleError = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":6 - * if __pyx_checksum != 0x949a143: - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) # <<<<<<<<<<<<<< - * __pyx_result = FrozenList.__new__(__pyx_type) - * if __pyx_state is not None: - */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_v___pyx_PickleError); - __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 6, __pyx_L1_error) - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0x949a143: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) - */ - } - - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) - * __pyx_result = FrozenList.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_11_frozenlist_FrozenList), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v___pyx_result = __pyx_t_3; - __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) - * __pyx_result = FrozenList.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_6 = (__pyx_t_1 != 0); - if (__pyx_t_6) { - - /* "(tree fragment)":9 - * __pyx_result = FrozenList.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) - * __pyx_result = FrozenList.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - } - - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; - goto __pyx_L0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":11 - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - */ - -static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList__set_state", 0); - - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[2]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyList_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->_items); - __Pyx_DECREF(__pyx_v___pyx_result->_items); - __pyx_v___pyx_result->_items = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v___pyx_result->frozen = __pyx_t_2; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[2]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 13, __pyx_L1_error) - } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_4 = ((__pyx_t_3 > 2) != 0); - if (__pyx_t_4) { - } else { - __pyx_t_2 = __pyx_t_4; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_5 = (__pyx_t_4 != 0); - __pyx_t_2 = __pyx_t_5; - __pyx_L4_bool_binop_done:; - if (__pyx_t_2) { - - /* "(tree fragment)":14 - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[2]) # <<<<<<<<<<<<<< - */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 14, __pyx_L1_error) - } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_8)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_8); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[2]) - */ - } - - /* "(tree fragment)":11 - * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} -static struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList __pyx_vtable_7aiohttp_11_frozenlist_FrozenList; - -static PyObject *__pyx_tp_new_7aiohttp_11_frozenlist_FrozenList(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o); - p->__pyx_vtab = __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList; - p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_11_frozenlist_FrozenList(PyObject *o) { - struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p = (struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->_items); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_7aiohttp_11_frozenlist_FrozenList(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p = (struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o; - if (p->_items) { - e = (*v)(p->_items, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_11_frozenlist_FrozenList(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p = (struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o; - tmp = ((PyObject*)p->_items); - p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} -static PyObject *__pyx_sq_item_7aiohttp_11_frozenlist_FrozenList(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; -} - -static int __pyx_mp_ass_subscript_7aiohttp_11_frozenlist_FrozenList(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_7__setitem__(o, i, v); - } - else { - return __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_9__delitem__(o, i); - } -} - -static PyObject *__pyx_getprop_7aiohttp_11_frozenlist_10FrozenList_frozen(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_6frozen_1__get__(o); -} - -static PyMethodDef __pyx_methods_7aiohttp_11_frozenlist_FrozenList[] = { - {"freeze", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze, METH_NOARGS, 0}, - {"__reversed__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__, METH_NOARGS, 0}, - {"insert", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert, METH_VARARGS|METH_KEYWORDS, 0}, - {"index", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index, METH_O, 0}, - {"remove", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove, METH_O, 0}, - {"clear", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear, METH_NOARGS, 0}, - {"extend", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend, METH_O, 0}, - {"reverse", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse, METH_NOARGS, 0}, - {"pop", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop, METH_VARARGS|METH_KEYWORDS, 0}, - {"append", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append, METH_O, 0}, - {"count", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count, METH_O, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_45__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7aiohttp_11_frozenlist_FrozenList[] = { - {(char *)"frozen", __pyx_getprop_7aiohttp_11_frozenlist_10FrozenList_frozen, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PyNumberMethods __pyx_tp_as_number_FrozenList = { - 0, /*nb_add*/ - 0, /*nb_subtract*/ - 0, /*nb_multiply*/ - #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) - 0, /*nb_divide*/ - #endif - 0, /*nb_remainder*/ - 0, /*nb_divmod*/ - 0, /*nb_power*/ - 0, /*nb_negative*/ - 0, /*nb_positive*/ - 0, /*nb_absolute*/ - 0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) - 0, /*nb_coerce*/ - #endif - 0, /*nb_int*/ - #if PY_MAJOR_VERSION < 3 - 0, /*nb_long*/ - #else - 0, /*reserved*/ - #endif - 0, /*nb_float*/ - #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) - 0, /*nb_oct*/ - #endif - #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) - 0, /*nb_hex*/ - #endif - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_23__iadd__, /*nb_inplace_add*/ - 0, /*nb_inplace_subtract*/ - 0, /*nb_inplace_multiply*/ - #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) - 0, /*nb_inplace_divide*/ - #endif - 0, /*nb_inplace_remainder*/ - 0, /*nb_inplace_power*/ - 0, /*nb_inplace_lshift*/ - 0, /*nb_inplace_rshift*/ - 0, /*nb_inplace_and*/ - 0, /*nb_inplace_xor*/ - 0, /*nb_inplace_or*/ - 0, /*nb_floor_divide*/ - 0, /*nb_true_divide*/ - 0, /*nb_inplace_floor_divide*/ - 0, /*nb_inplace_true_divide*/ - 0, /*nb_index*/ - #if PY_VERSION_HEX >= 0x03050000 - 0, /*nb_matrix_multiply*/ - #endif - #if PY_VERSION_HEX >= 0x03050000 - 0, /*nb_inplace_matrix_multiply*/ - #endif -}; - -static PySequenceMethods __pyx_tp_as_sequence_FrozenList = { - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_7aiohttp_11_frozenlist_FrozenList, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_21__contains__, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_FrozenList = { - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__, /*mp_length*/ - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_5__getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_7aiohttp_11_frozenlist_FrozenList, /*mp_ass_subscript*/ -}; - -static PyTypeObject __pyx_type_7aiohttp_11_frozenlist_FrozenList = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._frozenlist.FrozenList", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_11_frozenlist_FrozenList, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_41__repr__, /*tp_repr*/ - &__pyx_tp_as_number_FrozenList, /*tp_as_number*/ - &__pyx_tp_as_sequence_FrozenList, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_FrozenList, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_11_frozenlist_FrozenList, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_11_frozenlist_FrozenList, /*tp_clear*/ - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_17__richcmp__, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_13__iter__, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_11_frozenlist_FrozenList, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7aiohttp_11_frozenlist_FrozenList, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_1__init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_11_frozenlist_FrozenList, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__frozenlist(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__frozenlist}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "_frozenlist", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_Cannot_modify_frozen_list, __pyx_k_Cannot_modify_frozen_list, sizeof(__pyx_k_Cannot_modify_frozen_list), 0, 1, 0, 0}, - {&__pyx_n_s_FrozenList, __pyx_k_FrozenList, sizeof(__pyx_k_FrozenList), 0, 0, 1, 1}, - {&__pyx_kp_u_FrozenList_frozen_r, __pyx_k_FrozenList_frozen_r, sizeof(__pyx_k_FrozenList_frozen_r), 0, 1, 0, 0}, - {&__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_k_Incompatible_checksums_s_vs_0x94, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x94), 0, 0, 1, 0}, - {&__pyx_n_s_MutableSequence, __pyx_k_MutableSequence, sizeof(__pyx_k_MutableSequence), 0, 0, 1, 1}, - {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, - {&__pyx_n_s_aiohttp__frozenlist, __pyx_k_aiohttp__frozenlist, sizeof(__pyx_k_aiohttp__frozenlist), 0, 0, 1, 1}, - {&__pyx_n_s_clear, __pyx_k_clear, sizeof(__pyx_k_clear), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_collections_abc, __pyx_k_collections_abc, sizeof(__pyx_k_collections_abc), 0, 0, 1, 1}, - {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, - {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, - {&__pyx_n_s_item, __pyx_k_item, sizeof(__pyx_k_item), 0, 0, 1, 1}, - {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, - {&__pyx_n_s_iter, __pyx_k_iter, sizeof(__pyx_k_iter), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, - {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, - {&__pyx_n_s_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 0, 0, 1, 1}, - {&__pyx_n_s_pos, __pyx_k_pos, sizeof(__pyx_k_pos), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_FrozenList, __pyx_k_pyx_unpickle_FrozenList, sizeof(__pyx_k_pyx_unpickle_FrozenList), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_register, __pyx_k_register, sizeof(__pyx_k_register), 0, 0, 1, 1}, - {&__pyx_n_s_remove, __pyx_k_remove, sizeof(__pyx_k_remove), 0, 0, 1, 1}, - {&__pyx_n_s_reversed, __pyx_k_reversed, sizeof(__pyx_k_reversed), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 19, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "aiohttp/_frozenlist.pyx":19 - * cdef object _check_frozen(self): - * if self.frozen: - * raise RuntimeError("Cannot modify frozen list.") # <<<<<<<<<<<<<< - * - * cdef inline object _fast_len(self): - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_Cannot_modify_frozen_list); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "(tree fragment)":1 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_tuple__2 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - __pyx_codeobj__3 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_FrozenList, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__3)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_155820355 = PyInt_FromLong(155820355L); if (unlikely(!__pyx_int_155820355)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList = &__pyx_vtable_7aiohttp_11_frozenlist_FrozenList; - __pyx_vtable_7aiohttp_11_frozenlist_FrozenList._check_frozen = (PyObject *(*)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *))__pyx_f_7aiohttp_11_frozenlist_10FrozenList__check_frozen; - __pyx_vtable_7aiohttp_11_frozenlist_FrozenList._fast_len = (PyObject *(*)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *))__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len; - if (PyType_Ready(&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_dictoffset && __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_dict, __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FrozenList, (PyObject *)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) - __pyx_ptype_7aiohttp_11_frozenlist_FrozenList = &__pyx_type_7aiohttp_11_frozenlist_FrozenList; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_frozenlist(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_frozenlist(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__frozenlist(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_frozenlist' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_frozenlist", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_aiohttp___frozenlist) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "aiohttp._frozenlist")) { - if (unlikely(PyDict_SetItemString(modules, "aiohttp._frozenlist", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_type_import_code(); - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "aiohttp/_frozenlist.pyx":1 - * from collections.abc import MutableSequence # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_MutableSequence); - __Pyx_GIVEREF(__pyx_n_s_MutableSequence); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_MutableSequence); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_collections_abc, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_MutableSequence); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_MutableSequence, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_frozenlist.pyx":108 - * - * - * MutableSequence.register(FrozenList) # <<<<<<<<<<<<<< - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_MutableSequence); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_11_frozenlist_FrozenList)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, NULL, __pyx_n_s_aiohttp__frozenlist); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_FrozenList, __pyx_t_2) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_frozenlist.pyx":1 - * from collections.abc import MutableSequence # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._frozenlist", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init aiohttp._frozenlist"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* ObjectGetItem */ -#if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { - PyObject *runerr; - Py_ssize_t key_value; - PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; - if (unlikely(!(m && m->sq_item))) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); - return NULL; - } - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { - PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; - if (likely(m && m->mp_subscript)) { - return m->mp_subscript(obj, key); - } - return __Pyx_PyObject_GetIndex(obj, key); -} -#endif - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallNoArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, NULL, 0); - } -#endif -#ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) -#else - if (likely(PyCFunction_Check(func))) -#endif - { - if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { - return __Pyx_PyObject_CallMethO(func, NULL); - } - } - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); -} -#endif - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* PyIntCompare */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED long inplace) { - if (op1 == op2) { - Py_RETURN_TRUE; - } - #if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(op1))) { - const long b = intval; - long a = PyInt_AS_LONG(op1); - if (a == b) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } - #endif - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(PyLong_CheckExact(op1))) { - int unequal; - unsigned long uintval; - Py_ssize_t size = Py_SIZE(op1); - const digit* digits = ((PyLongObject*)op1)->ob_digit; - if (intval == 0) { - if (size == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } else if (intval < 0) { - if (size >= 0) - Py_RETURN_FALSE; - intval = -intval; - size = -size; - } else { - if (size <= 0) - Py_RETURN_FALSE; - } - uintval = (unsigned long) intval; -#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 4)) { - unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif -#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 3)) { - unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif -#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 2)) { - unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif -#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 1)) { - unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif - unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); - if (unequal == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } - #endif - if (PyFloat_CheckExact(op1)) { - const long b = intval; - double a = PyFloat_AS_DOUBLE(op1); - if ((double)a == (double)b) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } - return ( - PyObject_RichCompare(op1, op2, Py_EQ)); -} - -/* PyObjectCall2Args */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* PyObjectGetMethod */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { - PyObject *attr; -#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrgetfunc f = NULL; - PyObject **dictptr, *dict; - int meth_found = 0; - assert (*method == NULL); - if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; - } - if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { - return 0; - } - descr = _PyType_Lookup(tp, name); - if (likely(descr != NULL)) { - Py_INCREF(descr); -#if PY_MAJOR_VERSION >= 3 - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) - #endif -#else - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr))) - #endif -#endif - { - meth_found = 1; - } else { - f = Py_TYPE(descr)->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - } - } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - attr = __Pyx_PyDict_GetItemStr(dict, name); - if (attr != NULL) { - Py_INCREF(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - goto try_unpack; - } - Py_DECREF(dict); - } - if (meth_found) { - *method = descr; - return 1; - } - if (f != NULL) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - if (descr != NULL) { - *method = descr; - return 0; - } - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(name)); -#endif - return 0; -#else - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; -#endif -try_unpack: -#if CYTHON_UNPACK_METHODS - if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { - PyObject *function = PyMethod_GET_FUNCTION(attr); - Py_INCREF(function); - Py_DECREF(attr); - *method = function; - return 1; - } -#endif - *method = attr; - return 0; -} - -/* PyObjectCallMethod1 */ -static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { - PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); - Py_DECREF(method); - return result; -} -static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { - PyObject *method = NULL, *result; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_Call2Args(method, obj, arg); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) return NULL; - return __Pyx__PyObject_CallMethod1(method, arg); -} - -/* pop_index */ -static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) { - PyObject *r; - if (unlikely(!py_ix)) return NULL; - r = __Pyx__PyObject_PopIndex(L, py_ix); - Py_DECREF(py_ix); - return r; -} -static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) { - return __Pyx_PyObject_CallMethod1(L, __pyx_n_s_pop, py_ix); -} -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix) { - Py_ssize_t size = PyList_GET_SIZE(L); - if (likely(size > (((PyListObject*)L)->allocated >> 1))) { - Py_ssize_t cix = ix; - if (cix < 0) { - cix += size; - } - if (likely(__Pyx_is_valid_index(cix, size))) { - PyObject* v = PyList_GET_ITEM(L, cix); - __Pyx_SET_SIZE(L, Py_SIZE(L) - 1); - size -= 1; - memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size_t)(size-cix)*sizeof(PyObject*)); - return v; - } - } - if (py_ix == Py_None) { - return __Pyx__PyObject_PopNewIndex(L, PyInt_FromSsize_t(ix)); - } else { - return __Pyx__PyObject_PopIndex(L, py_ix); - } -} -#endif - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* GetAttr */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) -#else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); -#endif - return PyObject_GetAttr(o, n); -} - -/* GetAttr3 */ -static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r = __Pyx_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* HasAttr */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { - PyObject *r; - if (unlikely(!__Pyx_PyBaseString_Check(n))) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return -1; - } - r = __Pyx_GetAttr(o, n); - if (unlikely(!r)) { - PyErr_Clear(); - return 0; - } else { - Py_DECREF(r); - return 1; - } -} - -/* PyObject_GenericGetAttrNoDict */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, attr_name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(attr_name)); -#endif - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* SetVTable */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable) { -#if PY_VERSION_HEX >= 0x02070000 - PyObject *ob = PyCapsule_New(vtable, 0, 0); -#else - PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); -#endif - if (!ob) - goto bad; - if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; -} - -/* PyObjectGetAttrStrNoError */ -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -} - -/* SetupReduce */ -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#else - if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#endif -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); - } -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ip) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.cp39-win_amd64.pyd deleted file mode 100644 index db45bd98..00000000 Binary files a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.cp39-win_amd64.pyd and /dev/null differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.c b/dist/ba_data/python-site-packages/aiohttp/_helpers.c deleted file mode 100644 index e25f5ec9..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_helpers.c +++ /dev/null @@ -1,5433 +0,0 @@ -/* Generated by Cython 0.29.21 */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_21" -#define CYTHON_HEX_VERSION 0x001D15F0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__aiohttp___helpers -#define __PYX_HAVE_API__aiohttp___helpers -/* Early includes */ -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "aiohttp\\_helpers.pyx", - "stringsource", -}; - -/*--- Type declarations ---*/ -struct __pyx_obj_7aiohttp_8_helpers_reify; - -/* "aiohttp/_helpers.pyx":1 - * cdef class reify: # <<<<<<<<<<<<<< - * """Use as a class method decorator. It operates almost exactly like - * the Python `@property` decorator, but it puts the result of the - */ -struct __pyx_obj_7aiohttp_8_helpers_reify { - PyObject_HEAD - PyObject *wrapped; - PyObject *name; -}; - - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* ObjectGetItem.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); -#else -#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) -#endif - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* GetAttr.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); - -/* GetAttr3.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* HasAttr.proto */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* SetupReduce.proto */ -static int __Pyx_setup_reduce(PyObject* type_obj); - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - - -/* Module declarations from 'aiohttp._helpers' */ -static PyTypeObject *__pyx_ptype_7aiohttp_8_helpers_reify = 0; -static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(struct __pyx_obj_7aiohttp_8_helpers_reify *, PyObject *); /*proto*/ -#define __Pyx_MODULE_NAME "aiohttp._helpers" -extern int __pyx_module_is_main_aiohttp___helpers; -int __pyx_module_is_main_aiohttp___helpers = 0; - -/* Implementation of 'aiohttp._helpers' */ -static PyObject *__pyx_builtin_KeyError; -static PyObject *__pyx_builtin_AttributeError; -static const char __pyx_k_doc[] = "__doc__"; -static const char __pyx_k_new[] = "__new__"; -static const char __pyx_k_dict[] = "__dict__"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_cache[] = "_cache"; -static const char __pyx_k_reify[] = "reify"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_pickle[] = "pickle"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_update[] = "update"; -static const char __pyx_k_wrapped[] = "wrapped"; -static const char __pyx_k_KeyError[] = "KeyError"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_pyx_type[] = "__pyx_type"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_pyx_result[] = "__pyx_result"; -static const char __pyx_k_PickleError[] = "PickleError"; -static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; -static const char __pyx_k_stringsource[] = "stringsource"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_AttributeError[] = "AttributeError"; -static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_aiohttp__helpers[] = "aiohttp._helpers"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_pyx_unpickle_reify[] = "__pyx_unpickle_reify"; -static const char __pyx_k_reified_property_is_read_only[] = "reified property is read-only"; -static const char __pyx_k_Incompatible_checksums_s_vs_0x77[] = "Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))"; -static PyObject *__pyx_n_s_AttributeError; -static PyObject *__pyx_kp_s_Incompatible_checksums_s_vs_0x77; -static PyObject *__pyx_n_s_KeyError; -static PyObject *__pyx_n_s_PickleError; -static PyObject *__pyx_n_s_aiohttp__helpers; -static PyObject *__pyx_n_s_cache; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_dict; -static PyObject *__pyx_n_s_doc; -static PyObject *__pyx_n_s_getstate; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_new; -static PyObject *__pyx_n_s_pickle; -static PyObject *__pyx_n_s_pyx_PickleError; -static PyObject *__pyx_n_s_pyx_checksum; -static PyObject *__pyx_n_s_pyx_result; -static PyObject *__pyx_n_s_pyx_state; -static PyObject *__pyx_n_s_pyx_type; -static PyObject *__pyx_n_s_pyx_unpickle_reify; -static PyObject *__pyx_n_s_reduce; -static PyObject *__pyx_n_s_reduce_cython; -static PyObject *__pyx_n_s_reduce_ex; -static PyObject *__pyx_kp_u_reified_property_is_read_only; -static PyObject *__pyx_n_s_reify; -static PyObject *__pyx_n_s_setstate; -static PyObject *__pyx_n_s_setstate_cython; -static PyObject *__pyx_kp_s_stringsource; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_update; -static PyObject *__pyx_n_s_wrapped; -static int __pyx_pf_7aiohttp_8_helpers_5reify___init__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_wrapped); /* proto */ -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_7__doc_____get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_owner); /* proto */ -static int __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_value); /* proto */ -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_tp_new_7aiohttp_8_helpers_reify(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_int_124832655; -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_codeobj__3; -/* Late includes */ - -/* "aiohttp/_helpers.pyx":13 - * cdef object name - * - * def __init__(self, wrapped): # <<<<<<<<<<<<<< - * self.wrapped = wrapped - * self.name = wrapped.__name__ - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_8_helpers_5reify_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_8_helpers_5reify_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_wrapped = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_wrapped,0}; - PyObject* values[1] = {0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_wrapped)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 13, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_wrapped = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 13, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._helpers.reify.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify___init__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), __pyx_v_wrapped); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_8_helpers_5reify___init__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_wrapped) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - - /* "aiohttp/_helpers.pyx":14 - * - * def __init__(self, wrapped): - * self.wrapped = wrapped # <<<<<<<<<<<<<< - * self.name = wrapped.__name__ - * - */ - __Pyx_INCREF(__pyx_v_wrapped); - __Pyx_GIVEREF(__pyx_v_wrapped); - __Pyx_GOTREF(__pyx_v_self->wrapped); - __Pyx_DECREF(__pyx_v_self->wrapped); - __pyx_v_self->wrapped = __pyx_v_wrapped; - - /* "aiohttp/_helpers.pyx":15 - * def __init__(self, wrapped): - * self.wrapped = wrapped - * self.name = wrapped.__name__ # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_wrapped, __pyx_n_s_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->name); - __Pyx_DECREF(__pyx_v_self->name); - __pyx_v_self->name = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_helpers.pyx":13 - * cdef object name - * - * def __init__(self, wrapped): # <<<<<<<<<<<<<< - * self.wrapped = wrapped - * self.name = wrapped.__name__ - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._helpers.reify.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_helpers.pyx":18 - * - * @property - * def __doc__(self): # <<<<<<<<<<<<<< - * return self.wrapped.__doc__ - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__doc___1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__doc___1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_7__doc_____get__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_7__doc_____get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "aiohttp/_helpers.pyx":19 - * @property - * def __doc__(self): - * return self.wrapped.__doc__ # <<<<<<<<<<<<<< - * - * def __get__(self, inst, owner): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->wrapped, __pyx_n_s_doc); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_helpers.pyx":18 - * - * @property - * def __doc__(self): # <<<<<<<<<<<<<< - * return self.wrapped.__doc__ - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._helpers.reify.__doc__.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_helpers.pyx":21 - * return self.wrapped.__doc__ - * - * def __get__(self, inst, owner): # <<<<<<<<<<<<<< - * try: - * try: - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_3__get__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_owner); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_3__get__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_owner) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_2__get__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), ((PyObject *)__pyx_v_inst), ((PyObject *)__pyx_v_owner)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_owner) { - PyObject *__pyx_v_val = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - int __pyx_t_14; - int __pyx_t_15; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "aiohttp/_helpers.pyx":22 - * - * def __get__(self, inst, owner): - * try: # <<<<<<<<<<<<<< - * try: - * return inst._cache[self.name] - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "aiohttp/_helpers.pyx":23 - * def __get__(self, inst, owner): - * try: - * try: # <<<<<<<<<<<<<< - * return inst._cache[self.name] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - /*try:*/ { - - /* "aiohttp/_helpers.pyx":24 - * try: - * try: - * return inst._cache[self.name] # <<<<<<<<<<<<<< - * except KeyError: - * val = self.wrapped(inst) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_inst, __pyx_n_s_cache); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 24, __pyx_L9_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_t_7, __pyx_v_self->name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 24, __pyx_L9_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_r = __pyx_t_8; - __pyx_t_8 = 0; - goto __pyx_L13_try_return; - - /* "aiohttp/_helpers.pyx":23 - * def __get__(self, inst, owner): - * try: - * try: # <<<<<<<<<<<<<< - * return inst._cache[self.name] - * except KeyError: - */ - } - __pyx_L9_error:; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "aiohttp/_helpers.pyx":25 - * try: - * return inst._cache[self.name] - * except KeyError: # <<<<<<<<<<<<<< - * val = self.wrapped(inst) - * inst._cache[self.name] = val - */ - __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_9) { - __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_10) < 0) __PYX_ERR(0, 25, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_10); - - /* "aiohttp/_helpers.pyx":26 - * return inst._cache[self.name] - * except KeyError: - * val = self.wrapped(inst) # <<<<<<<<<<<<<< - * inst._cache[self.name] = val - * return val - */ - __Pyx_INCREF(__pyx_v_self->wrapped); - __pyx_t_12 = __pyx_v_self->wrapped; __pyx_t_13 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_12))) { - __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_12); - if (likely(__pyx_t_13)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_12); - __Pyx_INCREF(__pyx_t_13); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_12, function); - } - } - __pyx_t_11 = (__pyx_t_13) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_13, __pyx_v_inst) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_v_inst); - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - __pyx_v_val = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_helpers.pyx":27 - * except KeyError: - * val = self.wrapped(inst) - * inst._cache[self.name] = val # <<<<<<<<<<<<<< - * return val - * except AttributeError: - */ - __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_inst, __pyx_n_s_cache); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 27, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_11); - if (unlikely(PyObject_SetItem(__pyx_t_11, __pyx_v_self->name, __pyx_v_val) < 0)) __PYX_ERR(0, 27, __pyx_L11_except_error) - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - - /* "aiohttp/_helpers.pyx":28 - * val = self.wrapped(inst) - * inst._cache[self.name] = val - * return val # <<<<<<<<<<<<<< - * except AttributeError: - * if inst is None: - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_val); - __pyx_r = __pyx_v_val; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - goto __pyx_L12_except_return; - } - goto __pyx_L11_except_error; - __pyx_L11_except_error:; - - /* "aiohttp/_helpers.pyx":23 - * def __get__(self, inst, owner): - * try: - * try: # <<<<<<<<<<<<<< - * return inst._cache[self.name] - * except KeyError: - */ - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); - goto __pyx_L3_error; - __pyx_L13_try_return:; - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); - goto __pyx_L7_try_return; - __pyx_L12_except_return:; - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); - goto __pyx_L7_try_return; - } - - /* "aiohttp/_helpers.pyx":22 - * - * def __get__(self, inst, owner): - * try: # <<<<<<<<<<<<<< - * try: - * return inst._cache[self.name] - */ - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "aiohttp/_helpers.pyx":29 - * inst._cache[self.name] = val - * return val - * except AttributeError: # <<<<<<<<<<<<<< - * if inst is None: - * return self - */ - __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_AttributeError); - if (__pyx_t_9) { - __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_10, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 29, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_8); - - /* "aiohttp/_helpers.pyx":30 - * return val - * except AttributeError: - * if inst is None: # <<<<<<<<<<<<<< - * return self - * raise - */ - __pyx_t_14 = (__pyx_v_inst == Py_None); - __pyx_t_15 = (__pyx_t_14 != 0); - if (__pyx_t_15) { - - /* "aiohttp/_helpers.pyx":31 - * except AttributeError: - * if inst is None: - * return self # <<<<<<<<<<<<<< - * raise - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __pyx_r = ((PyObject *)__pyx_v_self); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - goto __pyx_L6_except_return; - - /* "aiohttp/_helpers.pyx":30 - * return val - * except AttributeError: - * if inst is None: # <<<<<<<<<<<<<< - * return self - * raise - */ - } - - /* "aiohttp/_helpers.pyx":32 - * if inst is None: - * return self - * raise # <<<<<<<<<<<<<< - * - * def __set__(self, inst, value): - */ - __Pyx_GIVEREF(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_7); - __Pyx_XGIVEREF(__pyx_t_8); - __Pyx_ErrRestoreWithState(__pyx_t_10, __pyx_t_7, __pyx_t_8); - __pyx_t_10 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; - __PYX_ERR(0, 32, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_helpers.pyx":22 - * - * def __get__(self, inst, owner): - * try: # <<<<<<<<<<<<<< - * try: - * return inst._cache[self.name] - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L7_try_return:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L0; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L0; - } - - /* "aiohttp/_helpers.pyx":21 - * return self.wrapped.__doc__ - * - * def __get__(self, inst, owner): # <<<<<<<<<<<<<< - * try: - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_XDECREF(__pyx_t_13); - __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_val); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_helpers.pyx":34 - * raise - * - * def __set__(self, inst, value): # <<<<<<<<<<<<<< - * raise AttributeError("reified property is read-only") - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_8_helpers_5reify_5__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_pw_7aiohttp_8_helpers_5reify_5__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__set__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), ((PyObject *)__pyx_v_inst), ((PyObject *)__pyx_v_value)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__set__", 0); - - /* "aiohttp/_helpers.pyx":35 - * - * def __set__(self, inst, value): - * raise AttributeError("reified property is read-only") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_AttributeError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 35, __pyx_L1_error) - - /* "aiohttp/_helpers.pyx":34 - * raise - * - * def __set__(self, inst, value): # <<<<<<<<<<<<<< - * raise AttributeError("reified property is read-only") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._helpers.reify.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self.name, self.wrapped) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_self->name); - __Pyx_GIVEREF(__pyx_v_self->name); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->name); - __Pyx_INCREF(__pyx_v_self->wrapped); - __Pyx_GIVEREF(__pyx_v_self->wrapped); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->wrapped); - __pyx_v_state = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self.name, self.wrapped) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v__dict = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":7 - * state = (self.name, self.wrapped) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_2 = (__pyx_v__dict != Py_None); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); - __pyx_t_4 = 0; - - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self.name is not None or self.wrapped is not None - */ - __pyx_v_use_setstate = 1; - - /* "(tree fragment)":7 - * state = (self.name, self.wrapped) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - goto __pyx_L3; - } - - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self.name is not None or self.wrapped is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_self->name != Py_None); - __pyx_t_5 = (__pyx_t_2 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->wrapped != Py_None); - __pyx_t_2 = (__pyx_t_5 != 0); - __pyx_t_3 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - __pyx_v_use_setstate = __pyx_t_3; - } - __pyx_L3:; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None or self.wrapped is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state - * else: - */ - __pyx_t_3 = (__pyx_v_use_setstate != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":13 - * use_setstate = self.name is not None or self.wrapped is not None - * if use_setstate: - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_124832655); - __Pyx_GIVEREF(__pyx_int_124832655); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_124832655); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_state); - __pyx_t_4 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L0; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None or self.wrapped is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state - * else: - */ - } - - /* "(tree fragment)":15 - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state - * else: - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_reify__set_state(self, __pyx_state) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_124832655); - __Pyx_GIVEREF(__pyx_int_124832655); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_124832655); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1); - __pyx_t_6 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - } - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("aiohttp._helpers.reify.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_reify__set_state(self, __pyx_state) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":17 - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_reify__set_state(self, __pyx_state) # <<<<<<<<<<<<<< - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_reify__set_state(self, __pyx_state) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._helpers.reify.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify = {"__pyx_unpickle_reify", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_reify (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_reify", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_reify", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_reify") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_reify", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_reify", 0); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0x770cb8f: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) - */ - __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x770cb8f) != 0); - if (__pyx_t_1) { - - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum != 0x770cb8f: - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) - * __pyx_result = reify.__new__(__pyx_type) - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_2); - __pyx_v___pyx_PickleError = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":6 - * if __pyx_checksum != 0x770cb8f: - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) # <<<<<<<<<<<<<< - * __pyx_result = reify.__new__(__pyx_type) - * if __pyx_state is not None: - */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x77, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_v___pyx_PickleError); - __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 6, __pyx_L1_error) - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0x770cb8f: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) - */ - } - - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) - * __pyx_result = reify.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_8_helpers_reify), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v___pyx_result = __pyx_t_3; - __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) - * __pyx_result = reify.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_6 = (__pyx_t_1 != 0); - if (__pyx_t_6) { - - /* "(tree fragment)":9 - * __pyx_result = reify.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) - * __pyx_result = reify.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - } - - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; - goto __pyx_L0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":11 - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - */ - -static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_reify__set_state", 0); - - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[2]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->name); - __Pyx_DECREF(__pyx_v___pyx_result->name); - __pyx_v___pyx_result->name = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->wrapped); - __Pyx_DECREF(__pyx_v___pyx_result->wrapped); - __pyx_v___pyx_result->wrapped = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[2]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 13, __pyx_L1_error) - } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_4 = ((__pyx_t_3 > 2) != 0); - if (__pyx_t_4) { - } else { - __pyx_t_2 = __pyx_t_4; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_5 = (__pyx_t_4 != 0); - __pyx_t_2 = __pyx_t_5; - __pyx_L4_bool_binop_done:; - if (__pyx_t_2) { - - /* "(tree fragment)":14 - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[2]) # <<<<<<<<<<<<<< - */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 14, __pyx_L1_error) - } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_8)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_8); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[2]) - */ - } - - /* "(tree fragment)":11 - * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] - * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_tp_new_7aiohttp_8_helpers_reify(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_obj_7aiohttp_8_helpers_reify *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7aiohttp_8_helpers_reify *)o); - p->wrapped = Py_None; Py_INCREF(Py_None); - p->name = Py_None; Py_INCREF(Py_None); - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_8_helpers_reify(PyObject *o) { - struct __pyx_obj_7aiohttp_8_helpers_reify *p = (struct __pyx_obj_7aiohttp_8_helpers_reify *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->wrapped); - Py_CLEAR(p->name); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_7aiohttp_8_helpers_reify(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_8_helpers_reify *p = (struct __pyx_obj_7aiohttp_8_helpers_reify *)o; - if (p->wrapped) { - e = (*v)(p->wrapped, a); if (e) return e; - } - if (p->name) { - e = (*v)(p->name, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_8_helpers_reify(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_8_helpers_reify *p = (struct __pyx_obj_7aiohttp_8_helpers_reify *)o; - tmp = ((PyObject*)p->wrapped); - p->wrapped = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->name); - p->name = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyObject *__pyx_tp_descr_get_7aiohttp_8_helpers_reify(PyObject *o, PyObject *i, PyObject *c) { - PyObject *r = 0; - if (!i) i = Py_None; - if (!c) c = Py_None; - r = __pyx_pw_7aiohttp_8_helpers_5reify_3__get__(o, i, c); - return r; -} - -static int __pyx_tp_descr_set_7aiohttp_8_helpers_reify(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_pw_7aiohttp_8_helpers_5reify_5__set__(o, i, v); - } - else { - PyErr_SetString(PyExc_NotImplementedError, "__delete__"); - return -1; - } -} - -static PyObject *__pyx_getprop_7aiohttp_8_helpers_5reify___doc__(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_8_helpers_5reify_7__doc___1__get__(o); -} - -static PyMethodDef __pyx_methods_7aiohttp_8_helpers_reify[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_8_helpers_5reify_9__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7aiohttp_8_helpers_reify[] = { - {(char *)"__doc__", __pyx_getprop_7aiohttp_8_helpers_5reify___doc__, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7aiohttp_8_helpers_reify = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._helpers.reify", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_8_helpers_reify), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_8_helpers_reify, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - "Use as a class method decorator. It operates almost exactly like\n the Python `@property` decorator, but it puts the result of the\n method it decorates into the instance dict after the first call,\n effectively replacing the function it decorates with an instance\n variable. It is, in Python parlance, a data descriptor.\n\n ", /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_8_helpers_reify, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_8_helpers_reify, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_8_helpers_reify, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7aiohttp_8_helpers_reify, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - __pyx_tp_descr_get_7aiohttp_8_helpers_reify, /*tp_descr_get*/ - __pyx_tp_descr_set_7aiohttp_8_helpers_reify, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_pw_7aiohttp_8_helpers_5reify_1__init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_8_helpers_reify, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__helpers(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__helpers}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "_helpers", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, - {&__pyx_kp_s_Incompatible_checksums_s_vs_0x77, __pyx_k_Incompatible_checksums_s_vs_0x77, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x77), 0, 0, 1, 0}, - {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, - {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_aiohttp__helpers, __pyx_k_aiohttp__helpers, sizeof(__pyx_k_aiohttp__helpers), 0, 0, 1, 1}, - {&__pyx_n_s_cache, __pyx_k_cache, sizeof(__pyx_k_cache), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, - {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, - {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_reify, __pyx_k_pyx_unpickle_reify, sizeof(__pyx_k_pyx_unpickle_reify), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_kp_u_reified_property_is_read_only, __pyx_k_reified_property_is_read_only, sizeof(__pyx_k_reified_property_is_read_only), 0, 1, 0, 0}, - {&__pyx_n_s_reify, __pyx_k_reify, sizeof(__pyx_k_reify), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, - {&__pyx_n_s_wrapped, __pyx_k_wrapped, sizeof(__pyx_k_wrapped), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 25, __pyx_L1_error) - __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 29, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "aiohttp/_helpers.pyx":35 - * - * def __set__(self, inst, value): - * raise AttributeError("reified property is read-only") # <<<<<<<<<<<<<< - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_reified_property_is_read_only); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "(tree fragment)":1 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_tuple__2 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - __pyx_codeobj__3 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_reify, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__3)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_124832655 = PyInt_FromLong(124832655L); if (unlikely(!__pyx_int_124832655)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - if (PyType_Ready(&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_8_helpers_reify.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_8_helpers_reify.tp_dictoffset && __pyx_type_7aiohttp_8_helpers_reify.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_8_helpers_reify.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_reify, (PyObject *)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_ptype_7aiohttp_8_helpers_reify = &__pyx_type_7aiohttp_8_helpers_reify; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_helpers(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_helpers(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__helpers(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__helpers(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__helpers(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_helpers' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__helpers(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_helpers", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_aiohttp___helpers) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "aiohttp._helpers")) { - if (unlikely(PyDict_SetItemString(modules, "aiohttp._helpers", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_type_import_code(); - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "(tree fragment)":1 - * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify, NULL, __pyx_n_s_aiohttp__helpers); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_reify, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_helpers.pyx":1 - * cdef class reify: # <<<<<<<<<<<<<< - * """Use as a class method decorator. It operates almost exactly like - * the Python `@property` decorator, but it puts the result of the - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._helpers", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init aiohttp._helpers"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* ObjectGetItem */ -#if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { - PyObject *runerr; - Py_ssize_t key_value; - PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; - if (unlikely(!(m && m->sq_item))) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); - return NULL; - } - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { - PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; - if (likely(m && m->mp_subscript)) { - return m->mp_subscript(obj, key); - } - return __Pyx_PyObject_GetIndex(obj, key); -} -#endif - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCall2Args */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* GetAttr */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) -#else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); -#endif - return PyObject_GetAttr(o, n); -} - -/* GetAttr3 */ -static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r = __Pyx_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* HasAttr */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { - PyObject *r; - if (unlikely(!__Pyx_PyBaseString_Check(n))) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return -1; - } - r = __Pyx_GetAttr(o, n); - if (unlikely(!r)) { - PyErr_Clear(); - return 0; - } else { - Py_DECREF(r); - return 1; - } -} - -/* PyObject_GenericGetAttrNoDict */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, attr_name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(attr_name)); -#endif - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* PyObjectGetAttrStrNoError */ -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -} - -/* SetupReduce */ -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#else - if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#endif -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ip) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_helpers.cp39-win_amd64.pyd deleted file mode 100644 index 46b55ca1..00000000 Binary files a/dist/ba_data/python-site-packages/aiohttp/_helpers.cp39-win_amd64.pyd and /dev/null differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/aiohttp/_helpers.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..a94caf5d Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_helpers.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.c b/dist/ba_data/python-site-packages/aiohttp/_http_parser.c deleted file mode 100644 index 9920ca9f..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_http_parser.c +++ /dev/null @@ -1,24607 +0,0 @@ -/* Generated by Cython 0.29.21 */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_21" -#define CYTHON_HEX_VERSION 0x001D15F0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__aiohttp___http_parser -#define __PYX_HAVE_API__aiohttp___http_parser -/* Early includes */ -#include -#include -#include "pythread.h" -#include -#include -#include "../vendor/http-parser/http_parser.h" -#include "_find_header.h" -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "aiohttp\\_http_parser.pyx", - "stringsource", - "type.pxd", - "bool.pxd", - "complex.pxd", - "aiohttp\\_headers.pxi", -}; - -/*--- Type declarations ---*/ -struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage; -struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage; -struct __pyx_obj_7aiohttp_12_http_parser_HttpParser; -struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser; -struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser; -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__; -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr; -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__; -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr; -struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init; - -/* "aiohttp/_http_parser.pyx":327 - * PyMem_Free(self._csettings) - * - * cdef _init(self, cparser.http_parser_type mode, # <<<<<<<<<<<<<< - * object protocol, object loop, int limit, - * object timer=None, - */ -struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init { - int __pyx_n; - PyObject *timer; - size_t max_line_size; - size_t max_headers; - size_t max_field_size; - PyObject *payload_exception; - int response_with_body; - int read_until_eof; - int auto_decompress; -}; - -/* "aiohttp/_http_parser.pyx":110 - * - * @cython.freelist(DEFAULT_FREELIST_SIZE) - * cdef class RawRequestMessage: # <<<<<<<<<<<<<< - * cdef readonly str method - * cdef readonly str path - */ -struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage { - PyObject_HEAD - PyObject *method; - PyObject *path; - PyObject *version; - PyObject *headers; - PyObject *raw_headers; - PyObject *should_close; - PyObject *compression; - PyObject *upgrade; - PyObject *chunked; - PyObject *url; -}; - - -/* "aiohttp/_http_parser.pyx":210 - * - * @cython.freelist(DEFAULT_FREELIST_SIZE) - * cdef class RawResponseMessage: # <<<<<<<<<<<<<< - * cdef readonly object version # HttpVersion - * cdef readonly int code - */ -struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage { - PyObject_HEAD - PyObject *version; - int code; - PyObject *reason; - PyObject *headers; - PyObject *raw_headers; - PyObject *should_close; - PyObject *compression; - PyObject *upgrade; - PyObject *chunked; -}; - - -/* "aiohttp/_http_parser.pyx":272 - * - * @cython.internal - * cdef class HttpParser: # <<<<<<<<<<<<<< - * - * cdef: - */ -struct __pyx_obj_7aiohttp_12_http_parser_HttpParser { - PyObject_HEAD - struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *__pyx_vtab; - struct http_parser *_cparser; - struct http_parser_settings *_csettings; - PyObject *_raw_name; - PyObject *_raw_value; - int _has_value; - PyObject *_protocol; - PyObject *_loop; - PyObject *_timer; - size_t _max_line_size; - size_t _max_field_size; - size_t _max_headers; - int _response_with_body; - int _read_until_eof; - int _started; - PyObject *_url; - PyObject *_buf; - PyObject *_path; - PyObject *_reason; - PyObject *_headers; - PyObject *_raw_headers; - int _upgraded; - PyObject *_messages; - PyObject *_payload; - int _payload_error; - PyObject *_payload_exception; - PyObject *_last_error; - int _auto_decompress; - int _limit; - PyObject *_content_encoding; - Py_buffer py_buf; -}; - - -/* "aiohttp/_http_parser.pyx":563 - * - * - * cdef class HttpRequestParser(HttpParser): # <<<<<<<<<<<<<< - * - * def __init__(self, protocol, loop, int limit, timer=None, - */ -struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser __pyx_base; -}; - - -/* "aiohttp/_http_parser.pyx":591 - * - * - * cdef class HttpResponseParser(HttpParser): # <<<<<<<<<<<<<< - * - * def __init__(self, protocol, loop, int limit, timer=None, - */ -struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser __pyx_base; -}; - - -/* "aiohttp/_http_parser.pyx":135 - * self.url = url - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("method", self.method)) - */ -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ { - PyObject_HEAD - PyObject *__pyx_v_info; -}; - - -/* "aiohttp/_http_parser.pyx":147 - * info.append(("chunked", self.chunked)) - * info.append(("url", self.url)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< - * return '' - * - */ -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr { - PyObject_HEAD - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *__pyx_outer_scope; - PyObject *__pyx_v_name; - PyObject *__pyx_v_val; -}; - - -/* "aiohttp/_http_parser.pyx":233 - * self.chunked = chunked - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("version", self.version)) - */ -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ { - PyObject_HEAD - PyObject *__pyx_v_info; -}; - - -/* "aiohttp/_http_parser.pyx":244 - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< - * return '' - * - */ -struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr { - PyObject_HEAD - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *__pyx_outer_scope; - PyObject *__pyx_v_name; - PyObject *__pyx_v_val; -}; - - - -/* "aiohttp/_http_parser.pyx":272 - * - * @cython.internal - * cdef class HttpParser: # <<<<<<<<<<<<<< - * - * cdef: - */ - -struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser { - PyObject *(*_init)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, enum http_parser_type, PyObject *, PyObject *, int, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args); - PyObject *(*_process_header)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - PyObject *(*_on_header_field)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t); - PyObject *(*_on_header_value)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t); - PyObject *(*_on_headers_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - PyObject *(*_on_message_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - PyObject *(*_on_chunk_header)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - PyObject *(*_on_chunk_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - PyObject *(*_on_status_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - PyObject *(*http_version)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); -}; -static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *__pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); - - -/* "aiohttp/_http_parser.pyx":563 - * - * - * cdef class HttpRequestParser(HttpParser): # <<<<<<<<<<<<<< - * - * def __init__(self, protocol, loop, int limit, timer=None, - */ - -struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser { - struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser __pyx_base; -}; -static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser *__pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser; - - -/* "aiohttp/_http_parser.pyx":591 - * - * - * cdef class HttpResponseParser(HttpParser): # <<<<<<<<<<<<<< - * - * def __init__(self, protocol, loop, int limit, timer=None, - */ - -struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser { - struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser __pyx_base; -}; -static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser *__pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser; - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* decode_c_string_utf16.proto */ -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 0; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16LE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = -1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16BE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} - -/* decode_c_bytes.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( - const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); - -/* decode_bytes.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_bytes( - PyObject* string, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - return __Pyx_decode_c_bytes( - PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string), - start, stop, encoding, errors, decode_func); -} - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* None.proto */ -static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname); - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* IterFinish.proto */ -static CYTHON_INLINE int __Pyx_IterFinish(void); - -/* UnpackItemEndCheck.proto */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); - -/* ListCompAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len)) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) -#endif - -/* ListAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) -#endif - -/* KeywordStringCheck.proto */ -static int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); - -/* ExtTypeTest.proto */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); - -/* PyDictContains.proto */ -static CYTHON_INLINE int __Pyx_PyDict_ContainsTF(PyObject* item, PyObject* dict, int eq) { - int result = PyDict_Contains(dict, item); - return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); -} - -/* DictGetItem.proto */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); -#define __Pyx_PyObject_Dict_GetItem(obj, name)\ - (likely(PyDict_CheckExact(obj)) ?\ - __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) -#else -#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) -#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* GetAttr.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); - -/* GetAttr3.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallNoArg.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); -#else -#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PySequenceContains.proto */ -static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { - int result = PySequence_Contains(seq, item); - return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); -} - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* IncludeStringH.proto */ -#include - -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); - -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); - -/* SliceObject.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( - PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, - PyObject** py_start, PyObject** py_stop, PyObject** py_slice, - int has_cstart, int has_cstop, int wraparound); - -/* decode_bytearray.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_bytearray( - PyObject* string, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - return __Pyx_decode_c_bytes( - PyByteArray_AS_STRING(string), PyByteArray_GET_SIZE(string), - start, stop, encoding, errors, decode_func); -} - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* SwapException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* decode_c_string.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_string( - const char* cstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); - -/* UnpackUnboundCMethod.proto */ -typedef struct { - PyObject *type; - PyObject **method_name; - PyCFunction func; - PyObject *method; - int flag; -} __Pyx_CachedCFunction; - -/* CallUnboundCMethod1.proto */ -static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); -#else -#define __Pyx_CallUnboundCMethod1(cfunc, self, arg) __Pyx__CallUnboundCMethod1(cfunc, self, arg) -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* HasAttr.proto */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* SetupReduce.proto */ -static int __Pyx_setup_reduce(PyObject* type_obj); - -/* SetVTable.proto */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable); - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 -}; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); -#endif - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint16_t(uint16_t value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE enum http_method __Pyx_PyInt_As_enum__http_method(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* FetchCommonType.proto */ -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); - -/* PyObjectGetMethod.proto */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -/* PyObjectCallMethod1.proto */ -static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); - -/* CoroutineBase.proto */ -typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyThreadState *, PyObject *); -#if CYTHON_USE_EXC_INFO_STACK -#define __Pyx_ExcInfoStruct _PyErr_StackItem -#else -typedef struct { - PyObject *exc_type; - PyObject *exc_value; - PyObject *exc_traceback; -} __Pyx_ExcInfoStruct; -#endif -typedef struct { - PyObject_HEAD - __pyx_coroutine_body_t body; - PyObject *closure; - __Pyx_ExcInfoStruct gi_exc_state; - PyObject *gi_weakreflist; - PyObject *classobj; - PyObject *yieldfrom; - PyObject *gi_name; - PyObject *gi_qualname; - PyObject *gi_modulename; - PyObject *gi_code; - int resume_label; - char is_running; -} __pyx_CoroutineObject; -static __pyx_CoroutineObject *__Pyx__Coroutine_New( - PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, - PyObject *name, PyObject *qualname, PyObject *module_name); -static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( - __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, - PyObject *name, PyObject *qualname, PyObject *module_name); -static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); -static int __Pyx_Coroutine_clear(PyObject *self); -static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); -static PyObject *__Pyx_Coroutine_Close(PyObject *self); -static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); -#if CYTHON_USE_EXC_INFO_STACK -#define __Pyx_Coroutine_SwapException(self) -#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) -#else -#define __Pyx_Coroutine_SwapException(self) {\ - __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ - __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ - } -#define __Pyx_Coroutine_ResetAndClearException(self) {\ - __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ - (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ - } -#endif -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ - __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) -#else -#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ - __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) -#endif -static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); -static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); - -/* PatchModuleWithCoroutine.proto */ -static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); - -/* PatchGeneratorABC.proto */ -static int __Pyx_patch_abc(void); - -/* Generator.proto */ -#define __Pyx_Generator_USED -static PyTypeObject *__pyx_GeneratorType = 0; -#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType) -#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\ - __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name) -static PyObject *__Pyx_Generator_Next(PyObject *self); -static int __pyx_Generator_init(void); - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__init(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, enum http_parser_type __pyx_v_mode, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__process_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_field(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_value(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_status_complete(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_18HttpResponseParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self); /* proto*/ - -/* Module declarations from 'cpython.version' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'cpython.ref' */ - -/* Module declarations from 'cpython.exc' */ - -/* Module declarations from 'cpython.module' */ - -/* Module declarations from 'cpython.mem' */ - -/* Module declarations from 'cpython.tuple' */ - -/* Module declarations from 'cpython.list' */ - -/* Module declarations from 'cpython.sequence' */ - -/* Module declarations from 'cpython.mapping' */ - -/* Module declarations from 'cpython.iterator' */ - -/* Module declarations from 'cpython.number' */ - -/* Module declarations from 'cpython.int' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.bool' */ -static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; - -/* Module declarations from 'cpython.long' */ - -/* Module declarations from 'cpython.float' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.complex' */ -static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; - -/* Module declarations from 'cpython.string' */ - -/* Module declarations from 'cpython.unicode' */ - -/* Module declarations from 'cpython.dict' */ - -/* Module declarations from 'cpython.instance' */ - -/* Module declarations from 'cpython.function' */ - -/* Module declarations from 'cpython.method' */ - -/* Module declarations from 'cpython.weakref' */ - -/* Module declarations from 'cpython.getargs' */ - -/* Module declarations from 'cpython.pythread' */ - -/* Module declarations from 'cpython.pystate' */ - -/* Module declarations from 'cpython.cobject' */ - -/* Module declarations from 'cpython.oldbuffer' */ - -/* Module declarations from 'cpython.set' */ - -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'cpython.bytes' */ - -/* Module declarations from 'cpython.pycapsule' */ - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'libc.limits' */ - -/* Module declarations from 'cython' */ - -/* Module declarations from 'aiohttp' */ - -/* Module declarations from 'libc.stdint' */ - -/* Module declarations from 'aiohttp._cparser' */ - -/* Module declarations from 'aiohttp._find_header' */ - -/* Module declarations from 'aiohttp._http_parser' */ -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_HttpParser = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_HttpRequestParser = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_HttpResponseParser = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = 0; -static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_headers = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_URL = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_URL_build = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_CIMultiDict = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_HttpVersion = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_HttpVersion10 = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_HttpVersion11 = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1 = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_StreamReader = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser_DeflateBuffer = 0; -static PyObject *__pyx_v_7aiohttp_12_http_parser__http_method = 0; -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_extend(PyObject *, char const *, size_t); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_http_method_str(int); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_find_header(PyObject *); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser__new_request_message(PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *, int, int, PyObject *); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser__new_response_message(PyObject *, int, PyObject *, PyObject *, PyObject *, int, PyObject *, int, int); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin(struct http_parser *); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_url(struct http_parser *, char const *, size_t); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_status(struct http_parser *, char const *, size_t); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_field(struct http_parser *, char const *, size_t); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_value(struct http_parser *, char const *, size_t); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_headers_complete(struct http_parser *); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *, char const *, size_t); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_complete(struct http_parser *); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_header(struct http_parser *); /*proto*/ -static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_complete(struct http_parser *); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum http_errno); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *, size_t); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *, PyObject *); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *, PyObject *); /*proto*/ -#define __Pyx_MODULE_NAME "aiohttp._http_parser" -extern int __pyx_module_is_main_aiohttp___http_parser; -int __pyx_module_is_main_aiohttp___http_parser = 0; - -/* Implementation of 'aiohttp._http_parser' */ -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_MemoryError; -static PyObject *__pyx_builtin_TypeError; -static PyObject *__pyx_builtin_BaseException; -static const char __pyx_k_[] = "="; -static const char __pyx_k_i[] = "i"; -static const char __pyx_k_TE[] = "TE"; -static const char __pyx_k__2[] = ", "; -static const char __pyx_k__3[] = ")>"; -static const char __pyx_k__4[] = ""; -static const char __pyx_k_br[] = "br"; -static const char __pyx_k_AGE[] = "AGE"; -static const char __pyx_k_URI[] = "URI"; -static const char __pyx_k_URL[] = "URL"; -static const char __pyx_k_VIA[] = "VIA"; -static const char __pyx_k__11[] = ":"; -static const char __pyx_k_add[] = "add"; -static const char __pyx_k_all[] = "__all__"; -static const char __pyx_k_new[] = "__new__"; -static const char __pyx_k_url[] = "url"; -static const char __pyx_k_DATE[] = "DATE"; -static const char __pyx_k_ETAG[] = "ETAG"; -static const char __pyx_k_FROM[] = "FROM"; -static const char __pyx_k_HOST[] = "HOST"; -static const char __pyx_k_LINK[] = "LINK"; -static const char __pyx_k_VARY[] = "VARY"; -static const char __pyx_k_args[] = "args"; -static const char __pyx_k_code[] = "code"; -static const char __pyx_k_dict[] = "__dict__"; -static const char __pyx_k_gzip[] = "gzip"; -static const char __pyx_k_hdrs[] = "hdrs"; -static const char __pyx_k_host[] = "host"; -static const char __pyx_k_loop[] = "loop"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_path[] = "path"; -static const char __pyx_k_port[] = "port"; -static const char __pyx_k_send[] = "send"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_user[] = "user"; -static const char __pyx_k_yarl[] = "yarl"; -static const char __pyx_k_ALLOW[] = "ALLOW"; -static const char __pyx_k_RANGE[] = "RANGE"; -static const char __pyx_k_URL_2[] = "_URL"; -static const char __pyx_k_build[] = "build"; -static const char __pyx_k_close[] = "close"; -static const char __pyx_k_limit[] = "limit"; -static const char __pyx_k_lower[] = "lower"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_throw[] = "throw"; -static const char __pyx_k_timer[] = "timer"; -static const char __pyx_k_ACCEPT[] = "ACCEPT"; -static const char __pyx_k_COOKIE[] = "COOKIE"; -static const char __pyx_k_DIGEST[] = "DIGEST"; -static const char __pyx_k_EXPECT[] = "EXPECT"; -static const char __pyx_k_ORIGIN[] = "ORIGIN"; -static const char __pyx_k_PRAGMA[] = "PRAGMA"; -static const char __pyx_k_SERVER[] = "SERVER"; -static const char __pyx_k_format[] = "format"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_method[] = "method"; -static const char __pyx_k_pickle[] = "pickle"; -static const char __pyx_k_py_buf[] = "py_buf"; -static const char __pyx_k_reason[] = "reason"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_scheme[] = "scheme"; -static const char __pyx_k_update[] = "update"; -static const char __pyx_k_EXPIRES[] = "EXPIRES"; -static const char __pyx_k_REFERER[] = "REFERER"; -static const char __pyx_k_TRAILER[] = "TRAILER"; -static const char __pyx_k_UPGRADE[] = "UPGRADE"; -static const char __pyx_k_WARNING[] = "WARNING"; -static const char __pyx_k_aiohttp[] = "aiohttp"; -static const char __pyx_k_chunked[] = "chunked"; -static const char __pyx_k_deflate[] = "deflate"; -static const char __pyx_k_encoded[] = "encoded"; -static const char __pyx_k_genexpr[] = "genexpr"; -static const char __pyx_k_headers[] = "headers"; -static const char __pyx_k_streams[] = "streams"; -static const char __pyx_k_unknown[] = ""; -static const char __pyx_k_upgrade[] = "upgrade"; -static const char __pyx_k_version[] = "version"; -static const char __pyx_k_IF_MATCH[] = "IF_MATCH"; -static const char __pyx_k_IF_RANGE[] = "IF_RANGE"; -static const char __pyx_k_LOCATION[] = "LOCATION"; -static const char __pyx_k_buf_data[] = "buf_data"; -static const char __pyx_k_feed_eof[] = "feed_eof"; -static const char __pyx_k_fragment[] = "fragment"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_password[] = "password"; -static const char __pyx_k_protocol[] = "protocol"; -static const char __pyx_k_pyx_type[] = "__pyx_type"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_FORWARDED[] = "FORWARDED"; -static const char __pyx_k_TypeError[] = "TypeError"; -static const char __pyx_k_feed_data[] = "feed_data"; -static const char __pyx_k_multidict[] = "multidict"; -static const char __pyx_k_parse_url[] = "parse_url"; -static const char __pyx_k_partition[] = "partition"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_CONNECTION[] = "CONNECTION"; -static const char __pyx_k_KEEP_ALIVE[] = "KEEP_ALIVE"; -static const char __pyx_k_SET_COOKIE[] = "SET_COOKIE"; -static const char __pyx_k_USER_AGENT[] = "USER_AGENT"; -static const char __pyx_k_pyx_result[] = "__pyx_result"; -static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; -static const char __pyx_k_CIMultiDict[] = "CIMultiDict"; -static const char __pyx_k_CONTENT_MD5[] = "CONTENT_MD5"; -static const char __pyx_k_DESTINATION[] = "DESTINATION"; -static const char __pyx_k_HttpVersion[] = "HttpVersion"; -static const char __pyx_k_LineTooLong[] = "LineTooLong"; -static const char __pyx_k_MemoryError[] = "MemoryError"; -static const char __pyx_k_PickleError[] = "PickleError"; -static const char __pyx_k_RETRY_AFTER[] = "RETRY_AFTER"; -static const char __pyx_k_WANT_DIGEST[] = "WANT_DIGEST"; -static const char __pyx_k_compression[] = "compression"; -static const char __pyx_k_http_parser[] = "http_parser"; -static const char __pyx_k_http_writer[] = "http_writer"; -static const char __pyx_k_max_headers[] = "max_headers"; -static const char __pyx_k_raw_headers[] = "raw_headers"; -static const char __pyx_k_CONTENT_TYPE[] = "CONTENT_TYPE"; -static const char __pyx_k_MAX_FORWARDS[] = "MAX_FORWARDS"; -static const char __pyx_k_StreamReader[] = "StreamReader"; -static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; -static const char __pyx_k_query_string[] = "query_string"; -static const char __pyx_k_should_close[] = "should_close"; -static const char __pyx_k_stringsource[] = "stringsource"; -static const char __pyx_k_ACCEPT_RANGES[] = "ACCEPT_RANGES"; -static const char __pyx_k_AUTHORIZATION[] = "AUTHORIZATION"; -static const char __pyx_k_BadStatusLine[] = "BadStatusLine"; -static const char __pyx_k_BaseException[] = "BaseException"; -static const char __pyx_k_CACHE_CONTROL[] = "CACHE_CONTROL"; -static const char __pyx_k_CIMultiDict_2[] = "_CIMultiDict"; -static const char __pyx_k_CONTENT_RANGE[] = "CONTENT_RANGE"; -static const char __pyx_k_DeflateBuffer[] = "DeflateBuffer"; -static const char __pyx_k_EMPTY_PAYLOAD[] = "EMPTY_PAYLOAD"; -static const char __pyx_k_HttpVersion10[] = "HttpVersion10"; -static const char __pyx_k_HttpVersion11[] = "HttpVersion11"; -static const char __pyx_k_HttpVersion_2[] = "_HttpVersion"; -static const char __pyx_k_IF_NONE_MATCH[] = "IF_NONE_MATCH"; -static const char __pyx_k_InvalidHeader[] = "InvalidHeader"; -static const char __pyx_k_LAST_EVENT_ID[] = "LAST_EVENT_ID"; -static const char __pyx_k_LAST_MODIFIED[] = "LAST_MODIFIED"; -static const char __pyx_k_invalid_url_r[] = "invalid url {!r}"; -static const char __pyx_k_max_line_size[] = "max_line_size"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_set_exception[] = "set_exception"; -static const char __pyx_k_ACCEPT_CHARSET[] = "ACCEPT_CHARSET"; -static const char __pyx_k_BadHttpMessage[] = "BadHttpMessage"; -static const char __pyx_k_CONTENT_LENGTH[] = "CONTENT_LENGTH"; -static const char __pyx_k_StreamReader_2[] = "_StreamReader"; -static const char __pyx_k_max_field_size[] = "max_field_size"; -static const char __pyx_k_read_until_eof[] = "read_until_eof"; -static const char __pyx_k_ACCEPT_ENCODING[] = "ACCEPT_ENCODING"; -static const char __pyx_k_ACCEPT_LANGUAGE[] = "ACCEPT_LANGUAGE"; -static const char __pyx_k_DeflateBuffer_2[] = "_DeflateBuffer"; -static const char __pyx_k_EMPTY_PAYLOAD_2[] = "_EMPTY_PAYLOAD"; -static const char __pyx_k_HttpVersion10_2[] = "_HttpVersion10"; -static const char __pyx_k_HttpVersion11_2[] = "_HttpVersion11"; -static const char __pyx_k_InvalidURLError[] = "InvalidURLError"; -static const char __pyx_k_X_FORWARDED_FOR[] = "X_FORWARDED_FOR"; -static const char __pyx_k_auto_decompress[] = "auto_decompress"; -static const char __pyx_k_http_exceptions[] = "http_exceptions"; -static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_CIMultiDictProxy[] = "CIMultiDictProxy"; -static const char __pyx_k_CONTENT_ENCODING[] = "CONTENT_ENCODING"; -static const char __pyx_k_CONTENT_LANGUAGE[] = "CONTENT_LANGUAGE"; -static const char __pyx_k_CONTENT_LOCATION[] = "CONTENT_LOCATION"; -static const char __pyx_k_WWW_AUTHENTICATE[] = "WWW_AUTHENTICATE"; -static const char __pyx_k_X_FORWARDED_HOST[] = "X_FORWARDED_HOST"; -static const char __pyx_k_HttpRequestParser[] = "HttpRequestParser"; -static const char __pyx_k_IF_MODIFIED_SINCE[] = "IF_MODIFIED_SINCE"; -static const char __pyx_k_RawRequestMessage[] = "_http_method[i] - */ - -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_http_method_str(int __pyx_v_i) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("http_method_str", 0); - - /* "aiohttp/_http_parser.pyx":93 - * - * cdef inline str http_method_str(int i): - * if i < METHODS_COUNT: # <<<<<<<<<<<<<< - * return _http_method[i] - * else: - */ - __pyx_t_1 = ((__pyx_v_i < 34) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":94 - * cdef inline str http_method_str(int i): - * if i < METHODS_COUNT: - * return _http_method[i] # <<<<<<<<<<<<<< - * else: - * return "" - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_7aiohttp_12_http_parser__http_method == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 94, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_7aiohttp_12_http_parser__http_method, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject*)__pyx_t_2)); - __pyx_r = ((PyObject*)__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":93 - * - * cdef inline str http_method_str(int i): - * if i < METHODS_COUNT: # <<<<<<<<<<<<<< - * return _http_method[i] - * else: - */ - } - - /* "aiohttp/_http_parser.pyx":96 - * return _http_method[i] - * else: - * return "" # <<<<<<<<<<<<<< - * - * cdef inline object find_header(bytes raw_header): - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_kp_u_unknown); - __pyx_r = __pyx_kp_u_unknown; - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":92 - * - * - * cdef inline str http_method_str(int i): # <<<<<<<<<<<<<< - * if i < METHODS_COUNT: - * return _http_method[i] - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._http_parser.http_method_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":98 - * return "" - * - * cdef inline object find_header(bytes raw_header): # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * cdef char *buf - */ - -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_find_header(PyObject *__pyx_v_raw_header) { - Py_ssize_t __pyx_v_size; - char *__pyx_v_buf; - int __pyx_v_idx; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("find_header", 0); - - /* "aiohttp/_http_parser.pyx":102 - * cdef char *buf - * cdef int idx - * PyBytes_AsStringAndSize(raw_header, &buf, &size) # <<<<<<<<<<<<<< - * idx = _find_header.find_header(buf, size) - * if idx == -1: - */ - __pyx_t_1 = PyBytes_AsStringAndSize(__pyx_v_raw_header, (&__pyx_v_buf), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 102, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":103 - * cdef int idx - * PyBytes_AsStringAndSize(raw_header, &buf, &size) - * idx = _find_header.find_header(buf, size) # <<<<<<<<<<<<<< - * if idx == -1: - * return raw_header.decode('utf-8', 'surrogateescape') - */ - __pyx_v_idx = find_header(__pyx_v_buf, __pyx_v_size); - - /* "aiohttp/_http_parser.pyx":104 - * PyBytes_AsStringAndSize(raw_header, &buf, &size) - * idx = _find_header.find_header(buf, size) - * if idx == -1: # <<<<<<<<<<<<<< - * return raw_header.decode('utf-8', 'surrogateescape') - * return headers[idx] - */ - __pyx_t_2 = ((__pyx_v_idx == -1L) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":105 - * idx = _find_header.find_header(buf, size) - * if idx == -1: - * return raw_header.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * return headers[idx] - * - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_raw_header == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "decode"); - __PYX_ERR(0, 105, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_decode_bytes(__pyx_v_raw_header, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 105, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":104 - * PyBytes_AsStringAndSize(raw_header, &buf, &size) - * idx = _find_header.find_header(buf, size) - * if idx == -1: # <<<<<<<<<<<<<< - * return raw_header.decode('utf-8', 'surrogateescape') - * return headers[idx] - */ - } - - /* "aiohttp/_http_parser.pyx":106 - * if idx == -1: - * return raw_header.decode('utf-8', 'surrogateescape') - * return headers[idx] # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_7aiohttp_12_http_parser_headers == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 106, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_GetItemInt_Tuple(__pyx_v_7aiohttp_12_http_parser_headers, __pyx_v_idx, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":98 - * return "" - * - * cdef inline object find_header(bytes raw_header): # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * cdef char *buf - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.find_header", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":122 - * cdef readonly object url # yarl.URL - * - * def __init__(self, method, path, version, headers, raw_headers, # <<<<<<<<<<<<<< - * should_close, compression, upgrade, chunked, url): - * self.method = method - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_method = 0; - PyObject *__pyx_v_path = 0; - PyObject *__pyx_v_version = 0; - PyObject *__pyx_v_headers = 0; - PyObject *__pyx_v_raw_headers = 0; - PyObject *__pyx_v_should_close = 0; - PyObject *__pyx_v_compression = 0; - PyObject *__pyx_v_upgrade = 0; - PyObject *__pyx_v_chunked = 0; - PyObject *__pyx_v_url = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_method,&__pyx_n_s_path,&__pyx_n_s_version,&__pyx_n_s_headers,&__pyx_n_s_raw_headers,&__pyx_n_s_should_close,&__pyx_n_s_compression,&__pyx_n_s_upgrade,&__pyx_n_s_chunked,&__pyx_n_s_url,0}; - PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); - CYTHON_FALLTHROUGH; - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_method)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_path)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 1); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_version)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 2); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_headers)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 3); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_raw_headers)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 4); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 5: - if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_should_close)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 5); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 6: - if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_compression)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 6); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 7: - if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_upgrade)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 7); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 8: - if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_chunked)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 8); __PYX_ERR(0, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 9: - if (likely((values[9] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_url)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 9); __PYX_ERR(0, 122, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 122, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 10) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - values[9] = PyTuple_GET_ITEM(__pyx_args, 9); - } - __pyx_v_method = values[0]; - __pyx_v_path = values[1]; - __pyx_v_version = values[2]; - __pyx_v_headers = values[3]; - __pyx_v_raw_headers = values[4]; - __pyx_v_should_close = values[5]; - __pyx_v_compression = values[6]; - __pyx_v_upgrade = values[7]; - __pyx_v_chunked = values[8]; - __pyx_v_url = values[9]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 122, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage___init__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self), __pyx_v_method, __pyx_v_path, __pyx_v_version, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_compression, __pyx_v_upgrade, __pyx_v_chunked, __pyx_v_url); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage___init__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self, PyObject *__pyx_v_method, PyObject *__pyx_v_path, PyObject *__pyx_v_version, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, PyObject *__pyx_v_should_close, PyObject *__pyx_v_compression, PyObject *__pyx_v_upgrade, PyObject *__pyx_v_chunked, PyObject *__pyx_v_url) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - - /* "aiohttp/_http_parser.pyx":124 - * def __init__(self, method, path, version, headers, raw_headers, - * should_close, compression, upgrade, chunked, url): - * self.method = method # <<<<<<<<<<<<<< - * self.path = path - * self.version = version - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_method))||((__pyx_v_method) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_method)->tp_name), 0))) __PYX_ERR(0, 124, __pyx_L1_error) - __pyx_t_1 = __pyx_v_method; - __Pyx_INCREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->method); - __Pyx_DECREF(__pyx_v_self->method); - __pyx_v_self->method = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":125 - * should_close, compression, upgrade, chunked, url): - * self.method = method - * self.path = path # <<<<<<<<<<<<<< - * self.version = version - * self.headers = headers - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_path))||((__pyx_v_path) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_path)->tp_name), 0))) __PYX_ERR(0, 125, __pyx_L1_error) - __pyx_t_1 = __pyx_v_path; - __Pyx_INCREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->path); - __Pyx_DECREF(__pyx_v_self->path); - __pyx_v_self->path = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":126 - * self.method = method - * self.path = path - * self.version = version # <<<<<<<<<<<<<< - * self.headers = headers - * self.raw_headers = raw_headers - */ - __Pyx_INCREF(__pyx_v_version); - __Pyx_GIVEREF(__pyx_v_version); - __Pyx_GOTREF(__pyx_v_self->version); - __Pyx_DECREF(__pyx_v_self->version); - __pyx_v_self->version = __pyx_v_version; - - /* "aiohttp/_http_parser.pyx":127 - * self.path = path - * self.version = version - * self.headers = headers # <<<<<<<<<<<<<< - * self.raw_headers = raw_headers - * self.should_close = should_close - */ - __Pyx_INCREF(__pyx_v_headers); - __Pyx_GIVEREF(__pyx_v_headers); - __Pyx_GOTREF(__pyx_v_self->headers); - __Pyx_DECREF(__pyx_v_self->headers); - __pyx_v_self->headers = __pyx_v_headers; - - /* "aiohttp/_http_parser.pyx":128 - * self.version = version - * self.headers = headers - * self.raw_headers = raw_headers # <<<<<<<<<<<<<< - * self.should_close = should_close - * self.compression = compression - */ - __Pyx_INCREF(__pyx_v_raw_headers); - __Pyx_GIVEREF(__pyx_v_raw_headers); - __Pyx_GOTREF(__pyx_v_self->raw_headers); - __Pyx_DECREF(__pyx_v_self->raw_headers); - __pyx_v_self->raw_headers = __pyx_v_raw_headers; - - /* "aiohttp/_http_parser.pyx":129 - * self.headers = headers - * self.raw_headers = raw_headers - * self.should_close = should_close # <<<<<<<<<<<<<< - * self.compression = compression - * self.upgrade = upgrade - */ - __Pyx_INCREF(__pyx_v_should_close); - __Pyx_GIVEREF(__pyx_v_should_close); - __Pyx_GOTREF(__pyx_v_self->should_close); - __Pyx_DECREF(__pyx_v_self->should_close); - __pyx_v_self->should_close = __pyx_v_should_close; - - /* "aiohttp/_http_parser.pyx":130 - * self.raw_headers = raw_headers - * self.should_close = should_close - * self.compression = compression # <<<<<<<<<<<<<< - * self.upgrade = upgrade - * self.chunked = chunked - */ - __Pyx_INCREF(__pyx_v_compression); - __Pyx_GIVEREF(__pyx_v_compression); - __Pyx_GOTREF(__pyx_v_self->compression); - __Pyx_DECREF(__pyx_v_self->compression); - __pyx_v_self->compression = __pyx_v_compression; - - /* "aiohttp/_http_parser.pyx":131 - * self.should_close = should_close - * self.compression = compression - * self.upgrade = upgrade # <<<<<<<<<<<<<< - * self.chunked = chunked - * self.url = url - */ - __Pyx_INCREF(__pyx_v_upgrade); - __Pyx_GIVEREF(__pyx_v_upgrade); - __Pyx_GOTREF(__pyx_v_self->upgrade); - __Pyx_DECREF(__pyx_v_self->upgrade); - __pyx_v_self->upgrade = __pyx_v_upgrade; - - /* "aiohttp/_http_parser.pyx":132 - * self.compression = compression - * self.upgrade = upgrade - * self.chunked = chunked # <<<<<<<<<<<<<< - * self.url = url - * - */ - __Pyx_INCREF(__pyx_v_chunked); - __Pyx_GIVEREF(__pyx_v_chunked); - __Pyx_GOTREF(__pyx_v_self->chunked); - __Pyx_DECREF(__pyx_v_self->chunked); - __pyx_v_self->chunked = __pyx_v_chunked; - - /* "aiohttp/_http_parser.pyx":133 - * self.upgrade = upgrade - * self.chunked = chunked - * self.url = url # <<<<<<<<<<<<<< - * - * def __repr__(self): - */ - __Pyx_INCREF(__pyx_v_url); - __Pyx_GIVEREF(__pyx_v_url); - __Pyx_GOTREF(__pyx_v_self->url); - __Pyx_DECREF(__pyx_v_self->url); - __pyx_v_self->url = __pyx_v_url; - - /* "aiohttp/_http_parser.pyx":122 - * cdef readonly object url # yarl.URL - * - * def __init__(self, method, path, version, headers, raw_headers, # <<<<<<<<<<<<<< - * should_close, compression, upgrade, chunked, url): - * self.method = method - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":135 - * self.url = url - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("method", self.method)) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3__repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3__repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_2__repr__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} -static PyObject *__pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ - -/* "aiohttp/_http_parser.pyx":147 - * info.append(("chunked", self.chunked)) - * info.append(("url", self.url)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< - * return '' - * - */ - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___genexpr(PyObject *__pyx_self) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *__pyx_cur_scope; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("genexpr", 0); - __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL); - if (unlikely(!__pyx_cur_scope)) { - __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)Py_None); - __Pyx_INCREF(Py_None); - __PYX_ERR(0, 147, __pyx_L1_error) - } else { - __Pyx_GOTREF(__pyx_cur_scope); - } - __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *) __pyx_self; - __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope)); - __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope); - { - __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___2generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_repr___locals_genexpr, __pyx_n_s_aiohttp__http_parser); if (unlikely(!gen)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_DECREF(__pyx_cur_scope); - __Pyx_RefNannyFinishContext(); - return (PyObject *) gen; - } - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__repr__.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ -{ - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)__pyx_generator->closure); - PyObject *__pyx_r = NULL; - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *(*__pyx_t_7)(PyObject *); - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("genexpr", 0); - switch (__pyx_generator->resume_label) { - case 0: goto __pyx_L3_first_run; - default: /* CPython raises the right error here */ - __Pyx_RefNannyFinishContext(); - return NULL; - } - __pyx_L3_first_run:; - if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 147, __pyx_L1_error) - __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_r); - if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info)) { __Pyx_RaiseClosureNameError("info"); __PYX_ERR(0, 147, __pyx_L1_error) } - if (unlikely(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(0, 147, __pyx_L1_error) - } - __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_info; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; - for (;;) { - if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 147, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { - PyObject* sequence = __pyx_t_3; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(0, 147, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - if (likely(PyTuple_CheckExact(sequence))) { - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); - } else { - __pyx_t_4 = PyList_GET_ITEM(sequence, 0); - __pyx_t_5 = PyList_GET_ITEM(sequence, 1); - } - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - #else - __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - Py_ssize_t index = -1; - __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext; - index = 0; __pyx_t_4 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_4)) goto __pyx_L6_unpacking_failed; - __Pyx_GOTREF(__pyx_t_4); - index = 1; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; - __Pyx_GOTREF(__pyx_t_5); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 2) < 0) __PYX_ERR(0, 147, __pyx_L1_error) - __pyx_t_7 = NULL; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - goto __pyx_L7_unpacking_done; - __pyx_L6_unpacking_failed:; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_7 = NULL; - if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); - __PYX_ERR(0, 147, __pyx_L1_error) - __pyx_L7_unpacking_done:; - } - __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name); - __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - __pyx_t_4 = 0; - __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_val); - __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_val, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_name, __pyx_kp_u_); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyObject_Repr(__pyx_cur_scope->__pyx_v_val); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_r); __pyx_r = 0; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - #if !CYTHON_USE_EXC_INFO_STACK - __Pyx_Coroutine_ResetAndClearException(__pyx_generator); - #endif - __pyx_generator->resume_label = -1; - __Pyx_Coroutine_clear((PyObject*)__pyx_generator); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":135 - * self.url = url - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("method", self.method)) - */ - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_2__repr__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *__pyx_cur_scope; - PyObject *__pyx_v_sinfo = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__repr__", 0); - __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct____repr__(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct____repr__, __pyx_empty_tuple, NULL); - if (unlikely(!__pyx_cur_scope)) { - __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)Py_None); - __Pyx_INCREF(Py_None); - __PYX_ERR(0, 135, __pyx_L1_error) - } else { - __Pyx_GOTREF(__pyx_cur_scope); - } - - /* "aiohttp/_http_parser.pyx":136 - * - * def __repr__(self): - * info = [] # <<<<<<<<<<<<<< - * info.append(("method", self.method)) - * info.append(("path", self.path)) - */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_cur_scope->__pyx_v_info = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":137 - * def __repr__(self): - * info = [] - * info.append(("method", self.method)) # <<<<<<<<<<<<<< - * info.append(("path", self.path)) - * info.append(("version", self.version)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_method); - __Pyx_GIVEREF(__pyx_n_u_method); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_method); - __Pyx_INCREF(__pyx_v_self->method); - __Pyx_GIVEREF(__pyx_v_self->method); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->method); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 137, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":138 - * info = [] - * info.append(("method", self.method)) - * info.append(("path", self.path)) # <<<<<<<<<<<<<< - * info.append(("version", self.version)) - * info.append(("headers", self.headers)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_path); - __Pyx_GIVEREF(__pyx_n_u_path); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_path); - __Pyx_INCREF(__pyx_v_self->path); - __Pyx_GIVEREF(__pyx_v_self->path); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->path); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 138, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":139 - * info.append(("method", self.method)) - * info.append(("path", self.path)) - * info.append(("version", self.version)) # <<<<<<<<<<<<<< - * info.append(("headers", self.headers)) - * info.append(("raw_headers", self.raw_headers)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_version); - __Pyx_GIVEREF(__pyx_n_u_version); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_version); - __Pyx_INCREF(__pyx_v_self->version); - __Pyx_GIVEREF(__pyx_v_self->version); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->version); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 139, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":140 - * info.append(("path", self.path)) - * info.append(("version", self.version)) - * info.append(("headers", self.headers)) # <<<<<<<<<<<<<< - * info.append(("raw_headers", self.raw_headers)) - * info.append(("should_close", self.should_close)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_headers); - __Pyx_GIVEREF(__pyx_n_u_headers); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_headers); - __Pyx_INCREF(__pyx_v_self->headers); - __Pyx_GIVEREF(__pyx_v_self->headers); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->headers); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":141 - * info.append(("version", self.version)) - * info.append(("headers", self.headers)) - * info.append(("raw_headers", self.raw_headers)) # <<<<<<<<<<<<<< - * info.append(("should_close", self.should_close)) - * info.append(("compression", self.compression)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 141, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_raw_headers); - __Pyx_GIVEREF(__pyx_n_u_raw_headers); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_raw_headers); - __Pyx_INCREF(__pyx_v_self->raw_headers); - __Pyx_GIVEREF(__pyx_v_self->raw_headers); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->raw_headers); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 141, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":142 - * info.append(("headers", self.headers)) - * info.append(("raw_headers", self.raw_headers)) - * info.append(("should_close", self.should_close)) # <<<<<<<<<<<<<< - * info.append(("compression", self.compression)) - * info.append(("upgrade", self.upgrade)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_should_close); - __Pyx_GIVEREF(__pyx_n_u_should_close); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_should_close); - __Pyx_INCREF(__pyx_v_self->should_close); - __Pyx_GIVEREF(__pyx_v_self->should_close); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->should_close); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":143 - * info.append(("raw_headers", self.raw_headers)) - * info.append(("should_close", self.should_close)) - * info.append(("compression", self.compression)) # <<<<<<<<<<<<<< - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 143, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_compression); - __Pyx_GIVEREF(__pyx_n_u_compression); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_compression); - __Pyx_INCREF(__pyx_v_self->compression); - __Pyx_GIVEREF(__pyx_v_self->compression); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->compression); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 143, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":144 - * info.append(("should_close", self.should_close)) - * info.append(("compression", self.compression)) - * info.append(("upgrade", self.upgrade)) # <<<<<<<<<<<<<< - * info.append(("chunked", self.chunked)) - * info.append(("url", self.url)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 144, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_upgrade); - __Pyx_GIVEREF(__pyx_n_u_upgrade); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_upgrade); - __Pyx_INCREF(__pyx_v_self->upgrade); - __Pyx_GIVEREF(__pyx_v_self->upgrade); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->upgrade); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 144, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":145 - * info.append(("compression", self.compression)) - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) # <<<<<<<<<<<<<< - * info.append(("url", self.url)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 145, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_chunked); - __Pyx_GIVEREF(__pyx_n_u_chunked); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_chunked); - __Pyx_INCREF(__pyx_v_self->chunked); - __Pyx_GIVEREF(__pyx_v_self->chunked); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->chunked); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 145, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":146 - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) - * info.append(("url", self.url)) # <<<<<<<<<<<<<< - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) - * return '' - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 146, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_url); - __Pyx_GIVEREF(__pyx_n_u_url); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_url); - __Pyx_INCREF(__pyx_v_self->url); - __Pyx_GIVEREF(__pyx_v_self->url); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->url); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 146, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":147 - * info.append(("chunked", self.chunked)) - * info.append(("url", self.url)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< - * return '' - * - */ - __pyx_t_1 = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_Generator_Next(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyUnicode_Join(__pyx_kp_u__2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_sinfo = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":148 - * info.append(("url", self.url)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) - * return '' # <<<<<<<<<<<<<< - * - * def _replace(self, **dct): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyUnicode_ConcatSafe(__pyx_kp_u_RawRequestMessage, __pyx_v_sinfo); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_1, __pyx_kp_u__3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":135 - * self.url = url - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("method", self.method)) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_sinfo); - __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":150 - * return '' - * - * def _replace(self, **dct): # <<<<<<<<<<<<<< - * cdef RawRequestMessage ret - * ret = _new_request_message(self.method, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_dct = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_replace (wrapper)", 0); - if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) { - __Pyx_RaiseArgtupleInvalid("_replace", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return NULL;} - if (__pyx_kwds && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "_replace", 1))) return NULL; - __pyx_v_dct = (__pyx_kwds) ? PyDict_Copy(__pyx_kwds) : PyDict_New(); if (unlikely(!__pyx_v_dct)) return NULL; - __Pyx_GOTREF(__pyx_v_dct); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4_replace(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self), __pyx_v_dct); - - /* function exit code */ - __Pyx_XDECREF(__pyx_v_dct); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4_replace(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self, PyObject *__pyx_v_dct) { - struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_ret = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_replace", 0); - - /* "aiohttp/_http_parser.pyx":152 - * def _replace(self, **dct): - * cdef RawRequestMessage ret - * ret = _new_request_message(self.method, # <<<<<<<<<<<<<< - * self.path, - * self.version, - */ - __pyx_t_1 = __pyx_v_self->method; - __Pyx_INCREF(__pyx_t_1); - - /* "aiohttp/_http_parser.pyx":153 - * cdef RawRequestMessage ret - * ret = _new_request_message(self.method, - * self.path, # <<<<<<<<<<<<<< - * self.version, - * self.headers, - */ - __pyx_t_2 = __pyx_v_self->path; - __Pyx_INCREF(__pyx_t_2); - - /* "aiohttp/_http_parser.pyx":154 - * ret = _new_request_message(self.method, - * self.path, - * self.version, # <<<<<<<<<<<<<< - * self.headers, - * self.raw_headers, - */ - __pyx_t_3 = __pyx_v_self->version; - __Pyx_INCREF(__pyx_t_3); - - /* "aiohttp/_http_parser.pyx":155 - * self.path, - * self.version, - * self.headers, # <<<<<<<<<<<<<< - * self.raw_headers, - * self.should_close, - */ - __pyx_t_4 = __pyx_v_self->headers; - __Pyx_INCREF(__pyx_t_4); - - /* "aiohttp/_http_parser.pyx":156 - * self.version, - * self.headers, - * self.raw_headers, # <<<<<<<<<<<<<< - * self.should_close, - * self.compression, - */ - __pyx_t_5 = __pyx_v_self->raw_headers; - __Pyx_INCREF(__pyx_t_5); - - /* "aiohttp/_http_parser.pyx":157 - * self.headers, - * self.raw_headers, - * self.should_close, # <<<<<<<<<<<<<< - * self.compression, - * self.upgrade, - */ - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_self->should_close); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":158 - * self.raw_headers, - * self.should_close, - * self.compression, # <<<<<<<<<<<<<< - * self.upgrade, - * self.chunked, - */ - __pyx_t_7 = __pyx_v_self->compression; - __Pyx_INCREF(__pyx_t_7); - - /* "aiohttp/_http_parser.pyx":159 - * self.should_close, - * self.compression, - * self.upgrade, # <<<<<<<<<<<<<< - * self.chunked, - * self.url) - */ - __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_self->upgrade); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":160 - * self.compression, - * self.upgrade, - * self.chunked, # <<<<<<<<<<<<<< - * self.url) - * if "method" in dct: - */ - __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_self->chunked); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 160, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":161 - * self.upgrade, - * self.chunked, - * self.url) # <<<<<<<<<<<<<< - * if "method" in dct: - * ret.method = dct["method"] - */ - __pyx_t_10 = __pyx_v_self->url; - __Pyx_INCREF(__pyx_t_10); - - /* "aiohttp/_http_parser.pyx":152 - * def _replace(self, **dct): - * cdef RawRequestMessage ret - * ret = _new_request_message(self.method, # <<<<<<<<<<<<<< - * self.path, - * self.version, - */ - __pyx_t_11 = __pyx_f_7aiohttp_12_http_parser__new_request_message(((PyObject*)__pyx_t_1), ((PyObject*)__pyx_t_2), __pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 152, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - if (!(likely(((__pyx_t_11) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_11, __pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage))))) __PYX_ERR(0, 152, __pyx_L1_error) - __pyx_v_ret = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_t_11); - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":162 - * self.chunked, - * self.url) - * if "method" in dct: # <<<<<<<<<<<<<< - * ret.method = dct["method"] - * if "path" in dct: - */ - __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_method, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 162, __pyx_L1_error) - __pyx_t_8 = (__pyx_t_9 != 0); - if (__pyx_t_8) { - - /* "aiohttp/_http_parser.pyx":163 - * self.url) - * if "method" in dct: - * ret.method = dct["method"] # <<<<<<<<<<<<<< - * if "path" in dct: - * ret.path = dct["path"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_method); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 163, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - if (!(likely(PyUnicode_CheckExact(__pyx_t_11))||((__pyx_t_11) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_11)->tp_name), 0))) __PYX_ERR(0, 163, __pyx_L1_error) - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->method); - __Pyx_DECREF(__pyx_v_ret->method); - __pyx_v_ret->method = ((PyObject*)__pyx_t_11); - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":162 - * self.chunked, - * self.url) - * if "method" in dct: # <<<<<<<<<<<<<< - * ret.method = dct["method"] - * if "path" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":164 - * if "method" in dct: - * ret.method = dct["method"] - * if "path" in dct: # <<<<<<<<<<<<<< - * ret.path = dct["path"] - * if "version" in dct: - */ - __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_path, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 164, __pyx_L1_error) - __pyx_t_9 = (__pyx_t_8 != 0); - if (__pyx_t_9) { - - /* "aiohttp/_http_parser.pyx":165 - * ret.method = dct["method"] - * if "path" in dct: - * ret.path = dct["path"] # <<<<<<<<<<<<<< - * if "version" in dct: - * ret.version = dct["version"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_path); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 165, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - if (!(likely(PyUnicode_CheckExact(__pyx_t_11))||((__pyx_t_11) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_11)->tp_name), 0))) __PYX_ERR(0, 165, __pyx_L1_error) - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->path); - __Pyx_DECREF(__pyx_v_ret->path); - __pyx_v_ret->path = ((PyObject*)__pyx_t_11); - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":164 - * if "method" in dct: - * ret.method = dct["method"] - * if "path" in dct: # <<<<<<<<<<<<<< - * ret.path = dct["path"] - * if "version" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":166 - * if "path" in dct: - * ret.path = dct["path"] - * if "version" in dct: # <<<<<<<<<<<<<< - * ret.version = dct["version"] - * if "headers" in dct: - */ - __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_version, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 166, __pyx_L1_error) - __pyx_t_8 = (__pyx_t_9 != 0); - if (__pyx_t_8) { - - /* "aiohttp/_http_parser.pyx":167 - * ret.path = dct["path"] - * if "version" in dct: - * ret.version = dct["version"] # <<<<<<<<<<<<<< - * if "headers" in dct: - * ret.headers = dct["headers"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_version); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 167, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->version); - __Pyx_DECREF(__pyx_v_ret->version); - __pyx_v_ret->version = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":166 - * if "path" in dct: - * ret.path = dct["path"] - * if "version" in dct: # <<<<<<<<<<<<<< - * ret.version = dct["version"] - * if "headers" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":168 - * if "version" in dct: - * ret.version = dct["version"] - * if "headers" in dct: # <<<<<<<<<<<<<< - * ret.headers = dct["headers"] - * if "raw_headers" in dct: - */ - __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_headers, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 168, __pyx_L1_error) - __pyx_t_9 = (__pyx_t_8 != 0); - if (__pyx_t_9) { - - /* "aiohttp/_http_parser.pyx":169 - * ret.version = dct["version"] - * if "headers" in dct: - * ret.headers = dct["headers"] # <<<<<<<<<<<<<< - * if "raw_headers" in dct: - * ret.raw_headers = dct["raw_headers"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_headers); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 169, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->headers); - __Pyx_DECREF(__pyx_v_ret->headers); - __pyx_v_ret->headers = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":168 - * if "version" in dct: - * ret.version = dct["version"] - * if "headers" in dct: # <<<<<<<<<<<<<< - * ret.headers = dct["headers"] - * if "raw_headers" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":170 - * if "headers" in dct: - * ret.headers = dct["headers"] - * if "raw_headers" in dct: # <<<<<<<<<<<<<< - * ret.raw_headers = dct["raw_headers"] - * if "should_close" in dct: - */ - __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_raw_headers, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 170, __pyx_L1_error) - __pyx_t_8 = (__pyx_t_9 != 0); - if (__pyx_t_8) { - - /* "aiohttp/_http_parser.pyx":171 - * ret.headers = dct["headers"] - * if "raw_headers" in dct: - * ret.raw_headers = dct["raw_headers"] # <<<<<<<<<<<<<< - * if "should_close" in dct: - * ret.should_close = dct["should_close"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_raw_headers); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 171, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->raw_headers); - __Pyx_DECREF(__pyx_v_ret->raw_headers); - __pyx_v_ret->raw_headers = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":170 - * if "headers" in dct: - * ret.headers = dct["headers"] - * if "raw_headers" in dct: # <<<<<<<<<<<<<< - * ret.raw_headers = dct["raw_headers"] - * if "should_close" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":172 - * if "raw_headers" in dct: - * ret.raw_headers = dct["raw_headers"] - * if "should_close" in dct: # <<<<<<<<<<<<<< - * ret.should_close = dct["should_close"] - * if "compression" in dct: - */ - __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_should_close, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 172, __pyx_L1_error) - __pyx_t_9 = (__pyx_t_8 != 0); - if (__pyx_t_9) { - - /* "aiohttp/_http_parser.pyx":173 - * ret.raw_headers = dct["raw_headers"] - * if "should_close" in dct: - * ret.should_close = dct["should_close"] # <<<<<<<<<<<<<< - * if "compression" in dct: - * ret.compression = dct["compression"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_should_close); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 173, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->should_close); - __Pyx_DECREF(__pyx_v_ret->should_close); - __pyx_v_ret->should_close = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":172 - * if "raw_headers" in dct: - * ret.raw_headers = dct["raw_headers"] - * if "should_close" in dct: # <<<<<<<<<<<<<< - * ret.should_close = dct["should_close"] - * if "compression" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":174 - * if "should_close" in dct: - * ret.should_close = dct["should_close"] - * if "compression" in dct: # <<<<<<<<<<<<<< - * ret.compression = dct["compression"] - * if "upgrade" in dct: - */ - __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_compression, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 174, __pyx_L1_error) - __pyx_t_8 = (__pyx_t_9 != 0); - if (__pyx_t_8) { - - /* "aiohttp/_http_parser.pyx":175 - * ret.should_close = dct["should_close"] - * if "compression" in dct: - * ret.compression = dct["compression"] # <<<<<<<<<<<<<< - * if "upgrade" in dct: - * ret.upgrade = dct["upgrade"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_compression); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 175, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->compression); - __Pyx_DECREF(__pyx_v_ret->compression); - __pyx_v_ret->compression = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":174 - * if "should_close" in dct: - * ret.should_close = dct["should_close"] - * if "compression" in dct: # <<<<<<<<<<<<<< - * ret.compression = dct["compression"] - * if "upgrade" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":176 - * if "compression" in dct: - * ret.compression = dct["compression"] - * if "upgrade" in dct: # <<<<<<<<<<<<<< - * ret.upgrade = dct["upgrade"] - * if "chunked" in dct: - */ - __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_upgrade, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 176, __pyx_L1_error) - __pyx_t_9 = (__pyx_t_8 != 0); - if (__pyx_t_9) { - - /* "aiohttp/_http_parser.pyx":177 - * ret.compression = dct["compression"] - * if "upgrade" in dct: - * ret.upgrade = dct["upgrade"] # <<<<<<<<<<<<<< - * if "chunked" in dct: - * ret.chunked = dct["chunked"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_upgrade); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 177, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->upgrade); - __Pyx_DECREF(__pyx_v_ret->upgrade); - __pyx_v_ret->upgrade = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":176 - * if "compression" in dct: - * ret.compression = dct["compression"] - * if "upgrade" in dct: # <<<<<<<<<<<<<< - * ret.upgrade = dct["upgrade"] - * if "chunked" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":178 - * if "upgrade" in dct: - * ret.upgrade = dct["upgrade"] - * if "chunked" in dct: # <<<<<<<<<<<<<< - * ret.chunked = dct["chunked"] - * if "url" in dct: - */ - __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_chunked, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 178, __pyx_L1_error) - __pyx_t_8 = (__pyx_t_9 != 0); - if (__pyx_t_8) { - - /* "aiohttp/_http_parser.pyx":179 - * ret.upgrade = dct["upgrade"] - * if "chunked" in dct: - * ret.chunked = dct["chunked"] # <<<<<<<<<<<<<< - * if "url" in dct: - * ret.url = dct["url"] - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_chunked); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 179, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->chunked); - __Pyx_DECREF(__pyx_v_ret->chunked); - __pyx_v_ret->chunked = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":178 - * if "upgrade" in dct: - * ret.upgrade = dct["upgrade"] - * if "chunked" in dct: # <<<<<<<<<<<<<< - * ret.chunked = dct["chunked"] - * if "url" in dct: - */ - } - - /* "aiohttp/_http_parser.pyx":180 - * if "chunked" in dct: - * ret.chunked = dct["chunked"] - * if "url" in dct: # <<<<<<<<<<<<<< - * ret.url = dct["url"] - * return ret - */ - __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_url, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 180, __pyx_L1_error) - __pyx_t_9 = (__pyx_t_8 != 0); - if (__pyx_t_9) { - - /* "aiohttp/_http_parser.pyx":181 - * ret.chunked = dct["chunked"] - * if "url" in dct: - * ret.url = dct["url"] # <<<<<<<<<<<<<< - * return ret - * - */ - __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_url); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 181, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_v_ret->url); - __Pyx_DECREF(__pyx_v_ret->url); - __pyx_v_ret->url = __pyx_t_11; - __pyx_t_11 = 0; - - /* "aiohttp/_http_parser.pyx":180 - * if "chunked" in dct: - * ret.chunked = dct["chunked"] - * if "url" in dct: # <<<<<<<<<<<<<< - * ret.url = dct["url"] - * return ret - */ - } - - /* "aiohttp/_http_parser.pyx":182 - * if "url" in dct: - * ret.url = dct["url"] - * return ret # <<<<<<<<<<<<<< - * - * cdef _new_request_message(str method, - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_ret)); - __pyx_r = ((PyObject *)__pyx_v_ret); - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":150 - * return '' - * - * def _replace(self, **dct): # <<<<<<<<<<<<<< - * cdef RawRequestMessage ret - * ret = _new_request_message(self.method, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage._replace", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_ret); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":111 - * @cython.freelist(DEFAULT_FREELIST_SIZE) - * cdef class RawRequestMessage: - * cdef readonly str method # <<<<<<<<<<<<<< - * cdef readonly str path - * cdef readonly object version # HttpVersion - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_6method_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_6method_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6method___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6method___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->method); - __pyx_r = __pyx_v_self->method; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":112 - * cdef class RawRequestMessage: - * cdef readonly str method - * cdef readonly str path # <<<<<<<<<<<<<< - * cdef readonly object version # HttpVersion - * cdef readonly object headers # CIMultiDict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_4path_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_4path_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4path___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4path___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->path); - __pyx_r = __pyx_v_self->path; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":113 - * cdef readonly str method - * cdef readonly str path - * cdef readonly object version # HttpVersion # <<<<<<<<<<<<<< - * cdef readonly object headers # CIMultiDict - * cdef readonly object raw_headers # tuple - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7version_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7version_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7version___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7version___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->version); - __pyx_r = __pyx_v_self->version; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":114 - * cdef readonly str path - * cdef readonly object version # HttpVersion - * cdef readonly object headers # CIMultiDict # <<<<<<<<<<<<<< - * cdef readonly object raw_headers # tuple - * cdef readonly object should_close - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7headers_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7headers_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->headers); - __pyx_r = __pyx_v_self->headers; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":115 - * cdef readonly object version # HttpVersion - * cdef readonly object headers # CIMultiDict - * cdef readonly object raw_headers # tuple # <<<<<<<<<<<<<< - * cdef readonly object should_close - * cdef readonly object compression - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->raw_headers); - __pyx_r = __pyx_v_self->raw_headers; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":116 - * cdef readonly object headers # CIMultiDict - * cdef readonly object raw_headers # tuple - * cdef readonly object should_close # <<<<<<<<<<<<<< - * cdef readonly object compression - * cdef readonly object upgrade - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_12should_close_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_12should_close_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_12should_close___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_12should_close___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->should_close); - __pyx_r = __pyx_v_self->should_close; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":117 - * cdef readonly object raw_headers # tuple - * cdef readonly object should_close - * cdef readonly object compression # <<<<<<<<<<<<<< - * cdef readonly object upgrade - * cdef readonly object chunked - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11compression_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11compression_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11compression___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11compression___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->compression); - __pyx_r = __pyx_v_self->compression; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":118 - * cdef readonly object should_close - * cdef readonly object compression - * cdef readonly object upgrade # <<<<<<<<<<<<<< - * cdef readonly object chunked - * cdef readonly object url # yarl.URL - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->upgrade); - __pyx_r = __pyx_v_self->upgrade; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":119 - * cdef readonly object compression - * cdef readonly object upgrade - * cdef readonly object chunked # <<<<<<<<<<<<<< - * cdef readonly object url # yarl.URL - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7chunked_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7chunked_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7chunked___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7chunked___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->chunked); - __pyx_r = __pyx_v_self->chunked; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":120 - * cdef readonly object upgrade - * cdef readonly object chunked - * cdef readonly object url # yarl.URL # <<<<<<<<<<<<<< - * - * def __init__(self, method, path, version, headers, raw_headers, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3url_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3url_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_3url___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_3url___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->url); - __pyx_r = __pyx_v_self->url; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = PyTuple_New(10); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_self->chunked); - __Pyx_GIVEREF(__pyx_v_self->chunked); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->chunked); - __Pyx_INCREF(__pyx_v_self->compression); - __Pyx_GIVEREF(__pyx_v_self->compression); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->compression); - __Pyx_INCREF(__pyx_v_self->headers); - __Pyx_GIVEREF(__pyx_v_self->headers); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_self->headers); - __Pyx_INCREF(__pyx_v_self->method); - __Pyx_GIVEREF(__pyx_v_self->method); - PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_self->method); - __Pyx_INCREF(__pyx_v_self->path); - __Pyx_GIVEREF(__pyx_v_self->path); - PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_self->path); - __Pyx_INCREF(__pyx_v_self->raw_headers); - __Pyx_GIVEREF(__pyx_v_self->raw_headers); - PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_v_self->raw_headers); - __Pyx_INCREF(__pyx_v_self->should_close); - __Pyx_GIVEREF(__pyx_v_self->should_close); - PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_v_self->should_close); - __Pyx_INCREF(__pyx_v_self->upgrade); - __Pyx_GIVEREF(__pyx_v_self->upgrade); - PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_v_self->upgrade); - __Pyx_INCREF(__pyx_v_self->url); - __Pyx_GIVEREF(__pyx_v_self->url); - PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_v_self->url); - __Pyx_INCREF(__pyx_v_self->version); - __Pyx_GIVEREF(__pyx_v_self->version); - PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_v_self->version); - __pyx_v_state = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v__dict = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":7 - * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_2 = (__pyx_v__dict != Py_None); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); - __pyx_t_4 = 0; - - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None - */ - __pyx_v_use_setstate = 1; - - /* "(tree fragment)":7 - * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - goto __pyx_L3; - } - - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_self->chunked != Py_None); - __pyx_t_5 = (__pyx_t_2 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->compression != Py_None); - __pyx_t_2 = (__pyx_t_5 != 0); - if (!__pyx_t_2) { - } else { - __pyx_t_3 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->headers != Py_None); - __pyx_t_5 = (__pyx_t_2 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->method != ((PyObject*)Py_None)); - __pyx_t_2 = (__pyx_t_5 != 0); - if (!__pyx_t_2) { - } else { - __pyx_t_3 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->path != ((PyObject*)Py_None)); - __pyx_t_5 = (__pyx_t_2 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->raw_headers != Py_None); - __pyx_t_2 = (__pyx_t_5 != 0); - if (!__pyx_t_2) { - } else { - __pyx_t_3 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->should_close != Py_None); - __pyx_t_5 = (__pyx_t_2 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->upgrade != Py_None); - __pyx_t_2 = (__pyx_t_5 != 0); - if (!__pyx_t_2) { - } else { - __pyx_t_3 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->url != Py_None); - __pyx_t_5 = (__pyx_t_2 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->version != Py_None); - __pyx_t_2 = (__pyx_t_5 != 0); - __pyx_t_3 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - __pyx_v_use_setstate = __pyx_t_3; - } - __pyx_L3:; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state - * else: - */ - __pyx_t_3 = (__pyx_v_use_setstate != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":13 - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None - * if use_setstate: - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_21004882); - __Pyx_GIVEREF(__pyx_int_21004882); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_21004882); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_state); - __pyx_t_4 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L0; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state - * else: - */ - } - - /* "(tree fragment)":15 - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state - * else: - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_21004882); - __Pyx_GIVEREF(__pyx_int_21004882); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_21004882); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1); - __pyx_t_6 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - } - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__setstate_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":17 - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) # <<<<<<<<<<<<<< - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":184 - * return ret - * - * cdef _new_request_message(str method, # <<<<<<<<<<<<<< - * str path, - * object version, - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser__new_request_message(PyObject *__pyx_v_method, PyObject *__pyx_v_path, PyObject *__pyx_v_version, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, int __pyx_v_should_close, PyObject *__pyx_v_compression, int __pyx_v_upgrade, int __pyx_v_chunked, PyObject *__pyx_v_url) { - struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_ret = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_new_request_message", 0); - - /* "aiohttp/_http_parser.pyx":195 - * object url): - * cdef RawRequestMessage ret - * ret = RawRequestMessage.__new__(RawRequestMessage) # <<<<<<<<<<<<<< - * ret.method = method - * ret.path = path - */ - __pyx_t_1 = ((PyObject *)__pyx_tp_new_7aiohttp_12_http_parser_RawRequestMessage(((PyTypeObject *)__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 195, __pyx_L1_error) - __Pyx_GOTREF(((PyObject *)__pyx_t_1)); - __pyx_v_ret = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":196 - * cdef RawRequestMessage ret - * ret = RawRequestMessage.__new__(RawRequestMessage) - * ret.method = method # <<<<<<<<<<<<<< - * ret.path = path - * ret.version = version - */ - __Pyx_INCREF(__pyx_v_method); - __Pyx_GIVEREF(__pyx_v_method); - __Pyx_GOTREF(__pyx_v_ret->method); - __Pyx_DECREF(__pyx_v_ret->method); - __pyx_v_ret->method = __pyx_v_method; - - /* "aiohttp/_http_parser.pyx":197 - * ret = RawRequestMessage.__new__(RawRequestMessage) - * ret.method = method - * ret.path = path # <<<<<<<<<<<<<< - * ret.version = version - * ret.headers = headers - */ - __Pyx_INCREF(__pyx_v_path); - __Pyx_GIVEREF(__pyx_v_path); - __Pyx_GOTREF(__pyx_v_ret->path); - __Pyx_DECREF(__pyx_v_ret->path); - __pyx_v_ret->path = __pyx_v_path; - - /* "aiohttp/_http_parser.pyx":198 - * ret.method = method - * ret.path = path - * ret.version = version # <<<<<<<<<<<<<< - * ret.headers = headers - * ret.raw_headers = raw_headers - */ - __Pyx_INCREF(__pyx_v_version); - __Pyx_GIVEREF(__pyx_v_version); - __Pyx_GOTREF(__pyx_v_ret->version); - __Pyx_DECREF(__pyx_v_ret->version); - __pyx_v_ret->version = __pyx_v_version; - - /* "aiohttp/_http_parser.pyx":199 - * ret.path = path - * ret.version = version - * ret.headers = headers # <<<<<<<<<<<<<< - * ret.raw_headers = raw_headers - * ret.should_close = should_close - */ - __Pyx_INCREF(__pyx_v_headers); - __Pyx_GIVEREF(__pyx_v_headers); - __Pyx_GOTREF(__pyx_v_ret->headers); - __Pyx_DECREF(__pyx_v_ret->headers); - __pyx_v_ret->headers = __pyx_v_headers; - - /* "aiohttp/_http_parser.pyx":200 - * ret.version = version - * ret.headers = headers - * ret.raw_headers = raw_headers # <<<<<<<<<<<<<< - * ret.should_close = should_close - * ret.compression = compression - */ - __Pyx_INCREF(__pyx_v_raw_headers); - __Pyx_GIVEREF(__pyx_v_raw_headers); - __Pyx_GOTREF(__pyx_v_ret->raw_headers); - __Pyx_DECREF(__pyx_v_ret->raw_headers); - __pyx_v_ret->raw_headers = __pyx_v_raw_headers; - - /* "aiohttp/_http_parser.pyx":201 - * ret.headers = headers - * ret.raw_headers = raw_headers - * ret.should_close = should_close # <<<<<<<<<<<<<< - * ret.compression = compression - * ret.upgrade = upgrade - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_should_close); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 201, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_ret->should_close); - __Pyx_DECREF(__pyx_v_ret->should_close); - __pyx_v_ret->should_close = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":202 - * ret.raw_headers = raw_headers - * ret.should_close = should_close - * ret.compression = compression # <<<<<<<<<<<<<< - * ret.upgrade = upgrade - * ret.chunked = chunked - */ - __Pyx_INCREF(__pyx_v_compression); - __Pyx_GIVEREF(__pyx_v_compression); - __Pyx_GOTREF(__pyx_v_ret->compression); - __Pyx_DECREF(__pyx_v_ret->compression); - __pyx_v_ret->compression = __pyx_v_compression; - - /* "aiohttp/_http_parser.pyx":203 - * ret.should_close = should_close - * ret.compression = compression - * ret.upgrade = upgrade # <<<<<<<<<<<<<< - * ret.chunked = chunked - * ret.url = url - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_upgrade); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 203, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_ret->upgrade); - __Pyx_DECREF(__pyx_v_ret->upgrade); - __pyx_v_ret->upgrade = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":204 - * ret.compression = compression - * ret.upgrade = upgrade - * ret.chunked = chunked # <<<<<<<<<<<<<< - * ret.url = url - * return ret - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_chunked); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_ret->chunked); - __Pyx_DECREF(__pyx_v_ret->chunked); - __pyx_v_ret->chunked = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":205 - * ret.upgrade = upgrade - * ret.chunked = chunked - * ret.url = url # <<<<<<<<<<<<<< - * return ret - * - */ - __Pyx_INCREF(__pyx_v_url); - __Pyx_GIVEREF(__pyx_v_url); - __Pyx_GOTREF(__pyx_v_ret->url); - __Pyx_DECREF(__pyx_v_ret->url); - __pyx_v_ret->url = __pyx_v_url; - - /* "aiohttp/_http_parser.pyx":206 - * ret.chunked = chunked - * ret.url = url - * return ret # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_ret)); - __pyx_r = ((PyObject *)__pyx_v_ret); - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":184 - * return ret - * - * cdef _new_request_message(str method, # <<<<<<<<<<<<<< - * str path, - * object version, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser._new_request_message", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_ret); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":221 - * cdef readonly object chunked - * - * def __init__(self, version, code, reason, headers, raw_headers, # <<<<<<<<<<<<<< - * should_close, compression, upgrade, chunked): - * self.version = version - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_version = 0; - PyObject *__pyx_v_code = 0; - PyObject *__pyx_v_reason = 0; - PyObject *__pyx_v_headers = 0; - PyObject *__pyx_v_raw_headers = 0; - PyObject *__pyx_v_should_close = 0; - PyObject *__pyx_v_compression = 0; - PyObject *__pyx_v_upgrade = 0; - PyObject *__pyx_v_chunked = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_version,&__pyx_n_s_code,&__pyx_n_s_reason,&__pyx_n_s_headers,&__pyx_n_s_raw_headers,&__pyx_n_s_should_close,&__pyx_n_s_compression,&__pyx_n_s_upgrade,&__pyx_n_s_chunked,0}; - PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_version)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_code)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 1); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_reason)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 2); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_headers)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 3); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_raw_headers)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 4); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 5: - if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_should_close)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 5); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 6: - if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_compression)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 6); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 7: - if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_upgrade)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 7); __PYX_ERR(0, 221, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 8: - if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_chunked)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 8); __PYX_ERR(0, 221, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 221, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 9) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - } - __pyx_v_version = values[0]; - __pyx_v_code = values[1]; - __pyx_v_reason = values[2]; - __pyx_v_headers = values[3]; - __pyx_v_raw_headers = values[4]; - __pyx_v_should_close = values[5]; - __pyx_v_compression = values[6]; - __pyx_v_upgrade = values[7]; - __pyx_v_chunked = values[8]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 221, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage___init__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self), __pyx_v_version, __pyx_v_code, __pyx_v_reason, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_compression, __pyx_v_upgrade, __pyx_v_chunked); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage___init__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self, PyObject *__pyx_v_version, PyObject *__pyx_v_code, PyObject *__pyx_v_reason, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, PyObject *__pyx_v_should_close, PyObject *__pyx_v_compression, PyObject *__pyx_v_upgrade, PyObject *__pyx_v_chunked) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - - /* "aiohttp/_http_parser.pyx":223 - * def __init__(self, version, code, reason, headers, raw_headers, - * should_close, compression, upgrade, chunked): - * self.version = version # <<<<<<<<<<<<<< - * self.code = code - * self.reason = reason - */ - __Pyx_INCREF(__pyx_v_version); - __Pyx_GIVEREF(__pyx_v_version); - __Pyx_GOTREF(__pyx_v_self->version); - __Pyx_DECREF(__pyx_v_self->version); - __pyx_v_self->version = __pyx_v_version; - - /* "aiohttp/_http_parser.pyx":224 - * should_close, compression, upgrade, chunked): - * self.version = version - * self.code = code # <<<<<<<<<<<<<< - * self.reason = reason - * self.headers = headers - */ - __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_code); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 224, __pyx_L1_error) - __pyx_v_self->code = __pyx_t_1; - - /* "aiohttp/_http_parser.pyx":225 - * self.version = version - * self.code = code - * self.reason = reason # <<<<<<<<<<<<<< - * self.headers = headers - * self.raw_headers = raw_headers - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_reason))||((__pyx_v_reason) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_reason)->tp_name), 0))) __PYX_ERR(0, 225, __pyx_L1_error) - __pyx_t_2 = __pyx_v_reason; - __Pyx_INCREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->reason); - __Pyx_DECREF(__pyx_v_self->reason); - __pyx_v_self->reason = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":226 - * self.code = code - * self.reason = reason - * self.headers = headers # <<<<<<<<<<<<<< - * self.raw_headers = raw_headers - * self.should_close = should_close - */ - __Pyx_INCREF(__pyx_v_headers); - __Pyx_GIVEREF(__pyx_v_headers); - __Pyx_GOTREF(__pyx_v_self->headers); - __Pyx_DECREF(__pyx_v_self->headers); - __pyx_v_self->headers = __pyx_v_headers; - - /* "aiohttp/_http_parser.pyx":227 - * self.reason = reason - * self.headers = headers - * self.raw_headers = raw_headers # <<<<<<<<<<<<<< - * self.should_close = should_close - * self.compression = compression - */ - __Pyx_INCREF(__pyx_v_raw_headers); - __Pyx_GIVEREF(__pyx_v_raw_headers); - __Pyx_GOTREF(__pyx_v_self->raw_headers); - __Pyx_DECREF(__pyx_v_self->raw_headers); - __pyx_v_self->raw_headers = __pyx_v_raw_headers; - - /* "aiohttp/_http_parser.pyx":228 - * self.headers = headers - * self.raw_headers = raw_headers - * self.should_close = should_close # <<<<<<<<<<<<<< - * self.compression = compression - * self.upgrade = upgrade - */ - __Pyx_INCREF(__pyx_v_should_close); - __Pyx_GIVEREF(__pyx_v_should_close); - __Pyx_GOTREF(__pyx_v_self->should_close); - __Pyx_DECREF(__pyx_v_self->should_close); - __pyx_v_self->should_close = __pyx_v_should_close; - - /* "aiohttp/_http_parser.pyx":229 - * self.raw_headers = raw_headers - * self.should_close = should_close - * self.compression = compression # <<<<<<<<<<<<<< - * self.upgrade = upgrade - * self.chunked = chunked - */ - __Pyx_INCREF(__pyx_v_compression); - __Pyx_GIVEREF(__pyx_v_compression); - __Pyx_GOTREF(__pyx_v_self->compression); - __Pyx_DECREF(__pyx_v_self->compression); - __pyx_v_self->compression = __pyx_v_compression; - - /* "aiohttp/_http_parser.pyx":230 - * self.should_close = should_close - * self.compression = compression - * self.upgrade = upgrade # <<<<<<<<<<<<<< - * self.chunked = chunked - * - */ - __Pyx_INCREF(__pyx_v_upgrade); - __Pyx_GIVEREF(__pyx_v_upgrade); - __Pyx_GOTREF(__pyx_v_self->upgrade); - __Pyx_DECREF(__pyx_v_self->upgrade); - __pyx_v_self->upgrade = __pyx_v_upgrade; - - /* "aiohttp/_http_parser.pyx":231 - * self.compression = compression - * self.upgrade = upgrade - * self.chunked = chunked # <<<<<<<<<<<<<< - * - * def __repr__(self): - */ - __Pyx_INCREF(__pyx_v_chunked); - __Pyx_GIVEREF(__pyx_v_chunked); - __Pyx_GOTREF(__pyx_v_self->chunked); - __Pyx_DECREF(__pyx_v_self->chunked); - __pyx_v_self->chunked = __pyx_v_chunked; - - /* "aiohttp/_http_parser.pyx":221 - * cdef readonly object chunked - * - * def __init__(self, version, code, reason, headers, raw_headers, # <<<<<<<<<<<<<< - * should_close, compression, upgrade, chunked): - * self.version = version - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":233 - * self.chunked = chunked - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("version", self.version)) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_3__repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_3__repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_2__repr__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} -static PyObject *__pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ - -/* "aiohttp/_http_parser.pyx":244 - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< - * return '' - * - */ - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___genexpr(PyObject *__pyx_self) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *__pyx_cur_scope; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("genexpr", 0); - __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, __pyx_empty_tuple, NULL); - if (unlikely(!__pyx_cur_scope)) { - __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)Py_None); - __Pyx_INCREF(Py_None); - __PYX_ERR(0, 244, __pyx_L1_error) - } else { - __Pyx_GOTREF(__pyx_cur_scope); - } - __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *) __pyx_self; - __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope)); - __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope); - { - __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___2generator1, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_repr___locals_genexpr, __pyx_n_s_aiohttp__http_parser); if (unlikely(!gen)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_DECREF(__pyx_cur_scope); - __Pyx_RefNannyFinishContext(); - return (PyObject *) gen; - } - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__repr__.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ -{ - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)__pyx_generator->closure); - PyObject *__pyx_r = NULL; - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *(*__pyx_t_7)(PyObject *); - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("genexpr", 0); - switch (__pyx_generator->resume_label) { - case 0: goto __pyx_L3_first_run; - default: /* CPython raises the right error here */ - __Pyx_RefNannyFinishContext(); - return NULL; - } - __pyx_L3_first_run:; - if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 244, __pyx_L1_error) - __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_r); - if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info)) { __Pyx_RaiseClosureNameError("info"); __PYX_ERR(0, 244, __pyx_L1_error) } - if (unlikely(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(0, 244, __pyx_L1_error) - } - __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_info; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; - for (;;) { - if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 244, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { - PyObject* sequence = __pyx_t_3; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(0, 244, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - if (likely(PyTuple_CheckExact(sequence))) { - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); - } else { - __pyx_t_4 = PyList_GET_ITEM(sequence, 0); - __pyx_t_5 = PyList_GET_ITEM(sequence, 1); - } - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - #else - __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - Py_ssize_t index = -1; - __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext; - index = 0; __pyx_t_4 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_4)) goto __pyx_L6_unpacking_failed; - __Pyx_GOTREF(__pyx_t_4); - index = 1; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; - __Pyx_GOTREF(__pyx_t_5); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 2) < 0) __PYX_ERR(0, 244, __pyx_L1_error) - __pyx_t_7 = NULL; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - goto __pyx_L7_unpacking_done; - __pyx_L6_unpacking_failed:; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_7 = NULL; - if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); - __PYX_ERR(0, 244, __pyx_L1_error) - __pyx_L7_unpacking_done:; - } - __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name); - __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - __pyx_t_4 = 0; - __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_val); - __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_val, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_name, __pyx_kp_u_); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyObject_Repr(__pyx_cur_scope->__pyx_v_val); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_r); __pyx_r = 0; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - #if !CYTHON_USE_EXC_INFO_STACK - __Pyx_Coroutine_ResetAndClearException(__pyx_generator); - #endif - __pyx_generator->resume_label = -1; - __Pyx_Coroutine_clear((PyObject*)__pyx_generator); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":233 - * self.chunked = chunked - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("version", self.version)) - */ - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_2__repr__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *__pyx_cur_scope; - PyObject *__pyx_v_sinfo = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__repr__", 0); - __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, __pyx_empty_tuple, NULL); - if (unlikely(!__pyx_cur_scope)) { - __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)Py_None); - __Pyx_INCREF(Py_None); - __PYX_ERR(0, 233, __pyx_L1_error) - } else { - __Pyx_GOTREF(__pyx_cur_scope); - } - - /* "aiohttp/_http_parser.pyx":234 - * - * def __repr__(self): - * info = [] # <<<<<<<<<<<<<< - * info.append(("version", self.version)) - * info.append(("code", self.code)) - */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 234, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_cur_scope->__pyx_v_info = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":235 - * def __repr__(self): - * info = [] - * info.append(("version", self.version)) # <<<<<<<<<<<<<< - * info.append(("code", self.code)) - * info.append(("reason", self.reason)) - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_u_version); - __Pyx_GIVEREF(__pyx_n_u_version); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_version); - __Pyx_INCREF(__pyx_v_self->version); - __Pyx_GIVEREF(__pyx_v_self->version); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->version); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 235, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":236 - * info = [] - * info.append(("version", self.version)) - * info.append(("code", self.code)) # <<<<<<<<<<<<<< - * info.append(("reason", self.reason)) - * info.append(("headers", self.headers)) - */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 236, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 236, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_code); - __Pyx_GIVEREF(__pyx_n_u_code); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_code); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 236, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":237 - * info.append(("version", self.version)) - * info.append(("code", self.code)) - * info.append(("reason", self.reason)) # <<<<<<<<<<<<<< - * info.append(("headers", self.headers)) - * info.append(("raw_headers", self.raw_headers)) - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_reason); - __Pyx_GIVEREF(__pyx_n_u_reason); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_reason); - __Pyx_INCREF(__pyx_v_self->reason); - __Pyx_GIVEREF(__pyx_v_self->reason); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->reason); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":238 - * info.append(("code", self.code)) - * info.append(("reason", self.reason)) - * info.append(("headers", self.headers)) # <<<<<<<<<<<<<< - * info.append(("raw_headers", self.raw_headers)) - * info.append(("should_close", self.should_close)) - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_headers); - __Pyx_GIVEREF(__pyx_n_u_headers); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_headers); - __Pyx_INCREF(__pyx_v_self->headers); - __Pyx_GIVEREF(__pyx_v_self->headers); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->headers); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 238, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":239 - * info.append(("reason", self.reason)) - * info.append(("headers", self.headers)) - * info.append(("raw_headers", self.raw_headers)) # <<<<<<<<<<<<<< - * info.append(("should_close", self.should_close)) - * info.append(("compression", self.compression)) - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 239, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_raw_headers); - __Pyx_GIVEREF(__pyx_n_u_raw_headers); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_raw_headers); - __Pyx_INCREF(__pyx_v_self->raw_headers); - __Pyx_GIVEREF(__pyx_v_self->raw_headers); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->raw_headers); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 239, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":240 - * info.append(("headers", self.headers)) - * info.append(("raw_headers", self.raw_headers)) - * info.append(("should_close", self.should_close)) # <<<<<<<<<<<<<< - * info.append(("compression", self.compression)) - * info.append(("upgrade", self.upgrade)) - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 240, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_should_close); - __Pyx_GIVEREF(__pyx_n_u_should_close); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_should_close); - __Pyx_INCREF(__pyx_v_self->should_close); - __Pyx_GIVEREF(__pyx_v_self->should_close); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->should_close); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 240, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":241 - * info.append(("raw_headers", self.raw_headers)) - * info.append(("should_close", self.should_close)) - * info.append(("compression", self.compression)) # <<<<<<<<<<<<<< - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 241, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_compression); - __Pyx_GIVEREF(__pyx_n_u_compression); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_compression); - __Pyx_INCREF(__pyx_v_self->compression); - __Pyx_GIVEREF(__pyx_v_self->compression); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->compression); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 241, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":242 - * info.append(("should_close", self.should_close)) - * info.append(("compression", self.compression)) - * info.append(("upgrade", self.upgrade)) # <<<<<<<<<<<<<< - * info.append(("chunked", self.chunked)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 242, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_upgrade); - __Pyx_GIVEREF(__pyx_n_u_upgrade); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_upgrade); - __Pyx_INCREF(__pyx_v_self->upgrade); - __Pyx_GIVEREF(__pyx_v_self->upgrade); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->upgrade); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 242, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":243 - * info.append(("compression", self.compression)) - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) # <<<<<<<<<<<<<< - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) - * return '' - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 243, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_n_u_chunked); - __Pyx_GIVEREF(__pyx_n_u_chunked); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_chunked); - __Pyx_INCREF(__pyx_v_self->chunked); - __Pyx_GIVEREF(__pyx_v_self->chunked); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->chunked); - __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 243, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":244 - * info.append(("upgrade", self.upgrade)) - * info.append(("chunked", self.chunked)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< - * return '' - * - */ - __pyx_t_3 = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_Generator_Next(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyUnicode_Join(__pyx_kp_u__2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_sinfo = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":245 - * info.append(("chunked", self.chunked)) - * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) - * return '' # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = __Pyx_PyUnicode_ConcatSafe(__pyx_kp_u_RawResponseMessage, __pyx_v_sinfo); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 245, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_kp_u__3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 245, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":233 - * self.chunked = chunked - * - * def __repr__(self): # <<<<<<<<<<<<<< - * info = [] - * info.append(("version", self.version)) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_sinfo); - __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":211 - * @cython.freelist(DEFAULT_FREELIST_SIZE) - * cdef class RawResponseMessage: - * cdef readonly object version # HttpVersion # <<<<<<<<<<<<<< - * cdef readonly int code - * cdef readonly str reason - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7version_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7version_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7version___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7version___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->version); - __pyx_r = __pyx_v_self->version; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":212 - * cdef class RawResponseMessage: - * cdef readonly object version # HttpVersion - * cdef readonly int code # <<<<<<<<<<<<<< - * cdef readonly str reason - * cdef readonly object headers # CIMultiDict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_4code_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_4code_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4code___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4code___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 212, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.code.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":213 - * cdef readonly object version # HttpVersion - * cdef readonly int code - * cdef readonly str reason # <<<<<<<<<<<<<< - * cdef readonly object headers # CIMultiDict - * cdef readonly object raw_headers # tuple - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_6reason_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_6reason_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6reason___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6reason___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->reason); - __pyx_r = __pyx_v_self->reason; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":214 - * cdef readonly int code - * cdef readonly str reason - * cdef readonly object headers # CIMultiDict # <<<<<<<<<<<<<< - * cdef readonly object raw_headers # tuple - * cdef readonly object should_close - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7headers_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7headers_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->headers); - __pyx_r = __pyx_v_self->headers; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":215 - * cdef readonly str reason - * cdef readonly object headers # CIMultiDict - * cdef readonly object raw_headers # tuple # <<<<<<<<<<<<<< - * cdef readonly object should_close - * cdef readonly object compression - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->raw_headers); - __pyx_r = __pyx_v_self->raw_headers; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":216 - * cdef readonly object headers # CIMultiDict - * cdef readonly object raw_headers # tuple - * cdef readonly object should_close # <<<<<<<<<<<<<< - * cdef readonly object compression - * cdef readonly object upgrade - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_12should_close_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_12should_close_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_12should_close___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_12should_close___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->should_close); - __pyx_r = __pyx_v_self->should_close; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":217 - * cdef readonly object raw_headers # tuple - * cdef readonly object should_close - * cdef readonly object compression # <<<<<<<<<<<<<< - * cdef readonly object upgrade - * cdef readonly object chunked - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11compression_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11compression_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11compression___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11compression___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->compression); - __pyx_r = __pyx_v_self->compression; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":218 - * cdef readonly object should_close - * cdef readonly object compression - * cdef readonly object upgrade # <<<<<<<<<<<<<< - * cdef readonly object chunked - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->upgrade); - __pyx_r = __pyx_v_self->upgrade; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":219 - * cdef readonly object compression - * cdef readonly object upgrade - * cdef readonly object chunked # <<<<<<<<<<<<<< - * - * def __init__(self, version, code, reason, headers, raw_headers, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7chunked___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7chunked___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->chunked); - __pyx_r = __pyx_v_self->chunked; - goto __pyx_L0; - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(9); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_self->chunked); - __Pyx_GIVEREF(__pyx_v_self->chunked); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_self->chunked); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1); - __Pyx_INCREF(__pyx_v_self->compression); - __Pyx_GIVEREF(__pyx_v_self->compression); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_self->compression); - __Pyx_INCREF(__pyx_v_self->headers); - __Pyx_GIVEREF(__pyx_v_self->headers); - PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_self->headers); - __Pyx_INCREF(__pyx_v_self->raw_headers); - __Pyx_GIVEREF(__pyx_v_self->raw_headers); - PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_v_self->raw_headers); - __Pyx_INCREF(__pyx_v_self->reason); - __Pyx_GIVEREF(__pyx_v_self->reason); - PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_v_self->reason); - __Pyx_INCREF(__pyx_v_self->should_close); - __Pyx_GIVEREF(__pyx_v_self->should_close); - PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_self->should_close); - __Pyx_INCREF(__pyx_v_self->upgrade); - __Pyx_GIVEREF(__pyx_v_self->upgrade); - PyTuple_SET_ITEM(__pyx_t_2, 7, __pyx_v_self->upgrade); - __Pyx_INCREF(__pyx_v_self->version); - __Pyx_GIVEREF(__pyx_v_self->version); - PyTuple_SET_ITEM(__pyx_t_2, 8, __pyx_v_self->version); - __pyx_t_1 = 0; - __pyx_v_state = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v__dict = __pyx_t_2; - __pyx_t_2 = 0; - - /* "(tree fragment)":7 - * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_3 = (__pyx_v__dict != Py_None); - __pyx_t_4 = (__pyx_t_3 != 0); - if (__pyx_t_4) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: - */ - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__dict); - __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_1)); - __pyx_t_1 = 0; - - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None - */ - __pyx_v_use_setstate = 1; - - /* "(tree fragment)":7 - * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - goto __pyx_L3; - } - - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state - */ - /*else*/ { - __pyx_t_3 = (__pyx_v_self->chunked != Py_None); - __pyx_t_5 = (__pyx_t_3 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_4 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->compression != Py_None); - __pyx_t_3 = (__pyx_t_5 != 0); - if (!__pyx_t_3) { - } else { - __pyx_t_4 = __pyx_t_3; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_3 = (__pyx_v_self->headers != Py_None); - __pyx_t_5 = (__pyx_t_3 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_4 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->raw_headers != Py_None); - __pyx_t_3 = (__pyx_t_5 != 0); - if (!__pyx_t_3) { - } else { - __pyx_t_4 = __pyx_t_3; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_3 = (__pyx_v_self->reason != ((PyObject*)Py_None)); - __pyx_t_5 = (__pyx_t_3 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_4 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->should_close != Py_None); - __pyx_t_3 = (__pyx_t_5 != 0); - if (!__pyx_t_3) { - } else { - __pyx_t_4 = __pyx_t_3; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_3 = (__pyx_v_self->upgrade != Py_None); - __pyx_t_5 = (__pyx_t_3 != 0); - if (!__pyx_t_5) { - } else { - __pyx_t_4 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->version != Py_None); - __pyx_t_3 = (__pyx_t_5 != 0); - __pyx_t_4 = __pyx_t_3; - __pyx_L4_bool_binop_done:; - __pyx_v_use_setstate = __pyx_t_4; - } - __pyx_L3:; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state - * else: - */ - __pyx_t_4 = (__pyx_v_use_setstate != 0); - if (__pyx_t_4) { - - /* "(tree fragment)":13 - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None - * if use_setstate: - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_209127132); - __Pyx_GIVEREF(__pyx_int_209127132); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_209127132); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_2, 2, Py_None); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_state); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L0; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state - * else: - */ - } - - /* "(tree fragment)":15 - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state - * else: - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_209127132); - __Pyx_GIVEREF(__pyx_int_209127132); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_209127132); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_state); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2); - __pyx_t_6 = 0; - __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - } - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6__setstate_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":17 - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) # <<<<<<<<<<<<<< - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":248 - * - * - * cdef _new_response_message(object version, # <<<<<<<<<<<<<< - * int code, - * str reason, - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser__new_response_message(PyObject *__pyx_v_version, int __pyx_v_code, PyObject *__pyx_v_reason, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, int __pyx_v_should_close, PyObject *__pyx_v_compression, int __pyx_v_upgrade, int __pyx_v_chunked) { - struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_ret = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_new_response_message", 0); - - /* "aiohttp/_http_parser.pyx":258 - * bint chunked): - * cdef RawResponseMessage ret - * ret = RawResponseMessage.__new__(RawResponseMessage) # <<<<<<<<<<<<<< - * ret.version = version - * ret.code = code - */ - __pyx_t_1 = ((PyObject *)__pyx_tp_new_7aiohttp_12_http_parser_RawResponseMessage(((PyTypeObject *)__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 258, __pyx_L1_error) - __Pyx_GOTREF(((PyObject *)__pyx_t_1)); - __pyx_v_ret = ((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":259 - * cdef RawResponseMessage ret - * ret = RawResponseMessage.__new__(RawResponseMessage) - * ret.version = version # <<<<<<<<<<<<<< - * ret.code = code - * ret.reason = reason - */ - __Pyx_INCREF(__pyx_v_version); - __Pyx_GIVEREF(__pyx_v_version); - __Pyx_GOTREF(__pyx_v_ret->version); - __Pyx_DECREF(__pyx_v_ret->version); - __pyx_v_ret->version = __pyx_v_version; - - /* "aiohttp/_http_parser.pyx":260 - * ret = RawResponseMessage.__new__(RawResponseMessage) - * ret.version = version - * ret.code = code # <<<<<<<<<<<<<< - * ret.reason = reason - * ret.headers = headers - */ - __pyx_v_ret->code = __pyx_v_code; - - /* "aiohttp/_http_parser.pyx":261 - * ret.version = version - * ret.code = code - * ret.reason = reason # <<<<<<<<<<<<<< - * ret.headers = headers - * ret.raw_headers = raw_headers - */ - __Pyx_INCREF(__pyx_v_reason); - __Pyx_GIVEREF(__pyx_v_reason); - __Pyx_GOTREF(__pyx_v_ret->reason); - __Pyx_DECREF(__pyx_v_ret->reason); - __pyx_v_ret->reason = __pyx_v_reason; - - /* "aiohttp/_http_parser.pyx":262 - * ret.code = code - * ret.reason = reason - * ret.headers = headers # <<<<<<<<<<<<<< - * ret.raw_headers = raw_headers - * ret.should_close = should_close - */ - __Pyx_INCREF(__pyx_v_headers); - __Pyx_GIVEREF(__pyx_v_headers); - __Pyx_GOTREF(__pyx_v_ret->headers); - __Pyx_DECREF(__pyx_v_ret->headers); - __pyx_v_ret->headers = __pyx_v_headers; - - /* "aiohttp/_http_parser.pyx":263 - * ret.reason = reason - * ret.headers = headers - * ret.raw_headers = raw_headers # <<<<<<<<<<<<<< - * ret.should_close = should_close - * ret.compression = compression - */ - __Pyx_INCREF(__pyx_v_raw_headers); - __Pyx_GIVEREF(__pyx_v_raw_headers); - __Pyx_GOTREF(__pyx_v_ret->raw_headers); - __Pyx_DECREF(__pyx_v_ret->raw_headers); - __pyx_v_ret->raw_headers = __pyx_v_raw_headers; - - /* "aiohttp/_http_parser.pyx":264 - * ret.headers = headers - * ret.raw_headers = raw_headers - * ret.should_close = should_close # <<<<<<<<<<<<<< - * ret.compression = compression - * ret.upgrade = upgrade - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_should_close); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 264, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_ret->should_close); - __Pyx_DECREF(__pyx_v_ret->should_close); - __pyx_v_ret->should_close = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":265 - * ret.raw_headers = raw_headers - * ret.should_close = should_close - * ret.compression = compression # <<<<<<<<<<<<<< - * ret.upgrade = upgrade - * ret.chunked = chunked - */ - __Pyx_INCREF(__pyx_v_compression); - __Pyx_GIVEREF(__pyx_v_compression); - __Pyx_GOTREF(__pyx_v_ret->compression); - __Pyx_DECREF(__pyx_v_ret->compression); - __pyx_v_ret->compression = __pyx_v_compression; - - /* "aiohttp/_http_parser.pyx":266 - * ret.should_close = should_close - * ret.compression = compression - * ret.upgrade = upgrade # <<<<<<<<<<<<<< - * ret.chunked = chunked - * return ret - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_upgrade); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 266, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_ret->upgrade); - __Pyx_DECREF(__pyx_v_ret->upgrade); - __pyx_v_ret->upgrade = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":267 - * ret.compression = compression - * ret.upgrade = upgrade - * ret.chunked = chunked # <<<<<<<<<<<<<< - * return ret - * - */ - __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_chunked); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 267, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_ret->chunked); - __Pyx_DECREF(__pyx_v_ret->chunked); - __pyx_v_ret->chunked = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":268 - * ret.upgrade = upgrade - * ret.chunked = chunked - * return ret # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_ret)); - __pyx_r = ((PyObject *)__pyx_v_ret); - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":248 - * - * - * cdef _new_response_message(object version, # <<<<<<<<<<<<<< - * int code, - * str reason, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser._new_response_message", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_ret); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":312 - * Py_buffer py_buf - * - * def __cinit__(self): # <<<<<<<<<<<<<< - * self._cparser = \ - * PyMem_Malloc(sizeof(cparser.http_parser)) - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_12_http_parser_10HttpParser_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_12_http_parser_10HttpParser_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) { - __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;} - if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__cinit__", 0))) return -1; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser___cinit__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_12_http_parser_10HttpParser___cinit__(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - - /* "aiohttp/_http_parser.pyx":313 - * - * def __cinit__(self): - * self._cparser = \ # <<<<<<<<<<<<<< - * PyMem_Malloc(sizeof(cparser.http_parser)) - * if self._cparser is NULL: - */ - __pyx_v_self->_cparser = ((struct http_parser *)PyMem_Malloc((sizeof(struct http_parser)))); - - /* "aiohttp/_http_parser.pyx":315 - * self._cparser = \ - * PyMem_Malloc(sizeof(cparser.http_parser)) - * if self._cparser is NULL: # <<<<<<<<<<<<<< - * raise MemoryError() - * - */ - __pyx_t_1 = ((__pyx_v_self->_cparser == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_parser.pyx":316 - * PyMem_Malloc(sizeof(cparser.http_parser)) - * if self._cparser is NULL: - * raise MemoryError() # <<<<<<<<<<<<<< - * - * self._csettings = \ - */ - PyErr_NoMemory(); __PYX_ERR(0, 316, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":315 - * self._cparser = \ - * PyMem_Malloc(sizeof(cparser.http_parser)) - * if self._cparser is NULL: # <<<<<<<<<<<<<< - * raise MemoryError() - * - */ - } - - /* "aiohttp/_http_parser.pyx":318 - * raise MemoryError() - * - * self._csettings = \ # <<<<<<<<<<<<<< - * PyMem_Malloc(sizeof(cparser.http_parser_settings)) - * if self._csettings is NULL: - */ - __pyx_v_self->_csettings = ((struct http_parser_settings *)PyMem_Malloc((sizeof(struct http_parser_settings)))); - - /* "aiohttp/_http_parser.pyx":320 - * self._csettings = \ - * PyMem_Malloc(sizeof(cparser.http_parser_settings)) - * if self._csettings is NULL: # <<<<<<<<<<<<<< - * raise MemoryError() - * - */ - __pyx_t_1 = ((__pyx_v_self->_csettings == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_parser.pyx":321 - * PyMem_Malloc(sizeof(cparser.http_parser_settings)) - * if self._csettings is NULL: - * raise MemoryError() # <<<<<<<<<<<<<< - * - * def __dealloc__(self): - */ - PyErr_NoMemory(); __PYX_ERR(0, 321, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":320 - * self._csettings = \ - * PyMem_Malloc(sizeof(cparser.http_parser_settings)) - * if self._csettings is NULL: # <<<<<<<<<<<<<< - * raise MemoryError() - * - */ - } - - /* "aiohttp/_http_parser.pyx":312 - * Py_buffer py_buf - * - * def __cinit__(self): # <<<<<<<<<<<<<< - * self._cparser = \ - * PyMem_Malloc(sizeof(cparser.http_parser)) - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":323 - * raise MemoryError() - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * PyMem_Free(self._cparser) - * PyMem_Free(self._csettings) - */ - -/* Python wrapper */ -static void __pyx_pw_7aiohttp_12_http_parser_10HttpParser_3__dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_pw_7aiohttp_12_http_parser_10HttpParser_3__dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_pf_7aiohttp_12_http_parser_10HttpParser_2__dealloc__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_pf_7aiohttp_12_http_parser_10HttpParser_2__dealloc__(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "aiohttp/_http_parser.pyx":324 - * - * def __dealloc__(self): - * PyMem_Free(self._cparser) # <<<<<<<<<<<<<< - * PyMem_Free(self._csettings) - * - */ - PyMem_Free(__pyx_v_self->_cparser); - - /* "aiohttp/_http_parser.pyx":325 - * def __dealloc__(self): - * PyMem_Free(self._cparser) - * PyMem_Free(self._csettings) # <<<<<<<<<<<<<< - * - * cdef _init(self, cparser.http_parser_type mode, - */ - PyMem_Free(__pyx_v_self->_csettings); - - /* "aiohttp/_http_parser.pyx":323 - * raise MemoryError() - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * PyMem_Free(self._cparser) - * PyMem_Free(self._csettings) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "aiohttp/_http_parser.pyx":327 - * PyMem_Free(self._csettings) - * - * cdef _init(self, cparser.http_parser_type mode, # <<<<<<<<<<<<<< - * object protocol, object loop, int limit, - * object timer=None, - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__init(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, enum http_parser_type __pyx_v_mode, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args) { - - /* "aiohttp/_http_parser.pyx":329 - * cdef _init(self, cparser.http_parser_type mode, - * object protocol, object loop, int limit, - * object timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - PyObject *__pyx_v_timer = ((PyObject *)Py_None); - size_t __pyx_v_max_line_size = ((size_t)0x1FFE); - size_t __pyx_v_max_headers = ((size_t)0x8000); - size_t __pyx_v_max_field_size = ((size_t)0x1FFE); - - /* "aiohttp/_http_parser.pyx":331 - * object timer=None, - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, # <<<<<<<<<<<<<< - * bint response_with_body=True, bint read_until_eof=False, - * bint auto_decompress=True): - */ - PyObject *__pyx_v_payload_exception = ((PyObject *)Py_None); - - /* "aiohttp/_http_parser.pyx":332 - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - * bint response_with_body=True, bint read_until_eof=False, # <<<<<<<<<<<<<< - * bint auto_decompress=True): - * cparser.http_parser_init(self._cparser, mode) - */ - int __pyx_v_response_with_body = ((int)1); - int __pyx_v_read_until_eof = ((int)0); - - /* "aiohttp/_http_parser.pyx":333 - * size_t max_field_size=8190, payload_exception=None, - * bint response_with_body=True, bint read_until_eof=False, - * bint auto_decompress=True): # <<<<<<<<<<<<<< - * cparser.http_parser_init(self._cparser, mode) - * self._cparser.data = self - */ - int __pyx_v_auto_decompress = ((int)1); - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_init", 0); - if (__pyx_optional_args) { - if (__pyx_optional_args->__pyx_n > 0) { - __pyx_v_timer = __pyx_optional_args->timer; - if (__pyx_optional_args->__pyx_n > 1) { - __pyx_v_max_line_size = __pyx_optional_args->max_line_size; - if (__pyx_optional_args->__pyx_n > 2) { - __pyx_v_max_headers = __pyx_optional_args->max_headers; - if (__pyx_optional_args->__pyx_n > 3) { - __pyx_v_max_field_size = __pyx_optional_args->max_field_size; - if (__pyx_optional_args->__pyx_n > 4) { - __pyx_v_payload_exception = __pyx_optional_args->payload_exception; - if (__pyx_optional_args->__pyx_n > 5) { - __pyx_v_response_with_body = __pyx_optional_args->response_with_body; - if (__pyx_optional_args->__pyx_n > 6) { - __pyx_v_read_until_eof = __pyx_optional_args->read_until_eof; - if (__pyx_optional_args->__pyx_n > 7) { - __pyx_v_auto_decompress = __pyx_optional_args->auto_decompress; - } - } - } - } - } - } - } - } - } - - /* "aiohttp/_http_parser.pyx":334 - * bint response_with_body=True, bint read_until_eof=False, - * bint auto_decompress=True): - * cparser.http_parser_init(self._cparser, mode) # <<<<<<<<<<<<<< - * self._cparser.data = self - * self._cparser.content_length = 0 - */ - http_parser_init(__pyx_v_self->_cparser, __pyx_v_mode); - - /* "aiohttp/_http_parser.pyx":335 - * bint auto_decompress=True): - * cparser.http_parser_init(self._cparser, mode) - * self._cparser.data = self # <<<<<<<<<<<<<< - * self._cparser.content_length = 0 - * - */ - __pyx_v_self->_cparser->data = ((void *)__pyx_v_self); - - /* "aiohttp/_http_parser.pyx":336 - * cparser.http_parser_init(self._cparser, mode) - * self._cparser.data = self - * self._cparser.content_length = 0 # <<<<<<<<<<<<<< - * - * cparser.http_parser_settings_init(self._csettings) - */ - __pyx_v_self->_cparser->content_length = 0; - - /* "aiohttp/_http_parser.pyx":338 - * self._cparser.content_length = 0 - * - * cparser.http_parser_settings_init(self._csettings) # <<<<<<<<<<<<<< - * - * self._protocol = protocol - */ - http_parser_settings_init(__pyx_v_self->_csettings); - - /* "aiohttp/_http_parser.pyx":340 - * cparser.http_parser_settings_init(self._csettings) - * - * self._protocol = protocol # <<<<<<<<<<<<<< - * self._loop = loop - * self._timer = timer - */ - __Pyx_INCREF(__pyx_v_protocol); - __Pyx_GIVEREF(__pyx_v_protocol); - __Pyx_GOTREF(__pyx_v_self->_protocol); - __Pyx_DECREF(__pyx_v_self->_protocol); - __pyx_v_self->_protocol = __pyx_v_protocol; - - /* "aiohttp/_http_parser.pyx":341 - * - * self._protocol = protocol - * self._loop = loop # <<<<<<<<<<<<<< - * self._timer = timer - * - */ - __Pyx_INCREF(__pyx_v_loop); - __Pyx_GIVEREF(__pyx_v_loop); - __Pyx_GOTREF(__pyx_v_self->_loop); - __Pyx_DECREF(__pyx_v_self->_loop); - __pyx_v_self->_loop = __pyx_v_loop; - - /* "aiohttp/_http_parser.pyx":342 - * self._protocol = protocol - * self._loop = loop - * self._timer = timer # <<<<<<<<<<<<<< - * - * self._buf = bytearray() - */ - __Pyx_INCREF(__pyx_v_timer); - __Pyx_GIVEREF(__pyx_v_timer); - __Pyx_GOTREF(__pyx_v_self->_timer); - __Pyx_DECREF(__pyx_v_self->_timer); - __pyx_v_self->_timer = __pyx_v_timer; - - /* "aiohttp/_http_parser.pyx":344 - * self._timer = timer - * - * self._buf = bytearray() # <<<<<<<<<<<<<< - * self._payload = None - * self._payload_error = 0 - */ - __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)(&PyByteArray_Type))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 344, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->_buf); - __Pyx_DECREF(__pyx_v_self->_buf); - __pyx_v_self->_buf = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":345 - * - * self._buf = bytearray() - * self._payload = None # <<<<<<<<<<<<<< - * self._payload_error = 0 - * self._payload_exception = payload_exception - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_payload); - __Pyx_DECREF(__pyx_v_self->_payload); - __pyx_v_self->_payload = Py_None; - - /* "aiohttp/_http_parser.pyx":346 - * self._buf = bytearray() - * self._payload = None - * self._payload_error = 0 # <<<<<<<<<<<<<< - * self._payload_exception = payload_exception - * self._messages = [] - */ - __pyx_v_self->_payload_error = 0; - - /* "aiohttp/_http_parser.pyx":347 - * self._payload = None - * self._payload_error = 0 - * self._payload_exception = payload_exception # <<<<<<<<<<<<<< - * self._messages = [] - * - */ - __Pyx_INCREF(__pyx_v_payload_exception); - __Pyx_GIVEREF(__pyx_v_payload_exception); - __Pyx_GOTREF(__pyx_v_self->_payload_exception); - __Pyx_DECREF(__pyx_v_self->_payload_exception); - __pyx_v_self->_payload_exception = __pyx_v_payload_exception; - - /* "aiohttp/_http_parser.pyx":348 - * self._payload_error = 0 - * self._payload_exception = payload_exception - * self._messages = [] # <<<<<<<<<<<<<< - * - * self._raw_name = bytearray() - */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 348, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->_messages); - __Pyx_DECREF(__pyx_v_self->_messages); - __pyx_v_self->_messages = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":350 - * self._messages = [] - * - * self._raw_name = bytearray() # <<<<<<<<<<<<<< - * self._raw_value = bytearray() - * self._has_value = False - */ - __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)(&PyByteArray_Type))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 350, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->_raw_name); - __Pyx_DECREF(__pyx_v_self->_raw_name); - __pyx_v_self->_raw_name = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":351 - * - * self._raw_name = bytearray() - * self._raw_value = bytearray() # <<<<<<<<<<<<<< - * self._has_value = False - * - */ - __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)(&PyByteArray_Type))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 351, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_self->_raw_value); - __Pyx_DECREF(__pyx_v_self->_raw_value); - __pyx_v_self->_raw_value = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":352 - * self._raw_name = bytearray() - * self._raw_value = bytearray() - * self._has_value = False # <<<<<<<<<<<<<< - * - * self._max_line_size = max_line_size - */ - __pyx_v_self->_has_value = 0; - - /* "aiohttp/_http_parser.pyx":354 - * self._has_value = False - * - * self._max_line_size = max_line_size # <<<<<<<<<<<<<< - * self._max_headers = max_headers - * self._max_field_size = max_field_size - */ - __pyx_v_self->_max_line_size = __pyx_v_max_line_size; - - /* "aiohttp/_http_parser.pyx":355 - * - * self._max_line_size = max_line_size - * self._max_headers = max_headers # <<<<<<<<<<<<<< - * self._max_field_size = max_field_size - * self._response_with_body = response_with_body - */ - __pyx_v_self->_max_headers = __pyx_v_max_headers; - - /* "aiohttp/_http_parser.pyx":356 - * self._max_line_size = max_line_size - * self._max_headers = max_headers - * self._max_field_size = max_field_size # <<<<<<<<<<<<<< - * self._response_with_body = response_with_body - * self._read_until_eof = read_until_eof - */ - __pyx_v_self->_max_field_size = __pyx_v_max_field_size; - - /* "aiohttp/_http_parser.pyx":357 - * self._max_headers = max_headers - * self._max_field_size = max_field_size - * self._response_with_body = response_with_body # <<<<<<<<<<<<<< - * self._read_until_eof = read_until_eof - * self._upgraded = False - */ - __pyx_v_self->_response_with_body = __pyx_v_response_with_body; - - /* "aiohttp/_http_parser.pyx":358 - * self._max_field_size = max_field_size - * self._response_with_body = response_with_body - * self._read_until_eof = read_until_eof # <<<<<<<<<<<<<< - * self._upgraded = False - * self._auto_decompress = auto_decompress - */ - __pyx_v_self->_read_until_eof = __pyx_v_read_until_eof; - - /* "aiohttp/_http_parser.pyx":359 - * self._response_with_body = response_with_body - * self._read_until_eof = read_until_eof - * self._upgraded = False # <<<<<<<<<<<<<< - * self._auto_decompress = auto_decompress - * self._content_encoding = None - */ - __pyx_v_self->_upgraded = 0; - - /* "aiohttp/_http_parser.pyx":360 - * self._read_until_eof = read_until_eof - * self._upgraded = False - * self._auto_decompress = auto_decompress # <<<<<<<<<<<<<< - * self._content_encoding = None - * - */ - __pyx_v_self->_auto_decompress = __pyx_v_auto_decompress; - - /* "aiohttp/_http_parser.pyx":361 - * self._upgraded = False - * self._auto_decompress = auto_decompress - * self._content_encoding = None # <<<<<<<<<<<<<< - * - * self._csettings.on_url = cb_on_url - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_content_encoding); - __Pyx_DECREF(__pyx_v_self->_content_encoding); - __pyx_v_self->_content_encoding = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":363 - * self._content_encoding = None - * - * self._csettings.on_url = cb_on_url # <<<<<<<<<<<<<< - * self._csettings.on_status = cb_on_status - * self._csettings.on_header_field = cb_on_header_field - */ - __pyx_v_self->_csettings->on_url = __pyx_f_7aiohttp_12_http_parser_cb_on_url; - - /* "aiohttp/_http_parser.pyx":364 - * - * self._csettings.on_url = cb_on_url - * self._csettings.on_status = cb_on_status # <<<<<<<<<<<<<< - * self._csettings.on_header_field = cb_on_header_field - * self._csettings.on_header_value = cb_on_header_value - */ - __pyx_v_self->_csettings->on_status = __pyx_f_7aiohttp_12_http_parser_cb_on_status; - - /* "aiohttp/_http_parser.pyx":365 - * self._csettings.on_url = cb_on_url - * self._csettings.on_status = cb_on_status - * self._csettings.on_header_field = cb_on_header_field # <<<<<<<<<<<<<< - * self._csettings.on_header_value = cb_on_header_value - * self._csettings.on_headers_complete = cb_on_headers_complete - */ - __pyx_v_self->_csettings->on_header_field = __pyx_f_7aiohttp_12_http_parser_cb_on_header_field; - - /* "aiohttp/_http_parser.pyx":366 - * self._csettings.on_status = cb_on_status - * self._csettings.on_header_field = cb_on_header_field - * self._csettings.on_header_value = cb_on_header_value # <<<<<<<<<<<<<< - * self._csettings.on_headers_complete = cb_on_headers_complete - * self._csettings.on_body = cb_on_body - */ - __pyx_v_self->_csettings->on_header_value = __pyx_f_7aiohttp_12_http_parser_cb_on_header_value; - - /* "aiohttp/_http_parser.pyx":367 - * self._csettings.on_header_field = cb_on_header_field - * self._csettings.on_header_value = cb_on_header_value - * self._csettings.on_headers_complete = cb_on_headers_complete # <<<<<<<<<<<<<< - * self._csettings.on_body = cb_on_body - * self._csettings.on_message_begin = cb_on_message_begin - */ - __pyx_v_self->_csettings->on_headers_complete = __pyx_f_7aiohttp_12_http_parser_cb_on_headers_complete; - - /* "aiohttp/_http_parser.pyx":368 - * self._csettings.on_header_value = cb_on_header_value - * self._csettings.on_headers_complete = cb_on_headers_complete - * self._csettings.on_body = cb_on_body # <<<<<<<<<<<<<< - * self._csettings.on_message_begin = cb_on_message_begin - * self._csettings.on_message_complete = cb_on_message_complete - */ - __pyx_v_self->_csettings->on_body = __pyx_f_7aiohttp_12_http_parser_cb_on_body; - - /* "aiohttp/_http_parser.pyx":369 - * self._csettings.on_headers_complete = cb_on_headers_complete - * self._csettings.on_body = cb_on_body - * self._csettings.on_message_begin = cb_on_message_begin # <<<<<<<<<<<<<< - * self._csettings.on_message_complete = cb_on_message_complete - * self._csettings.on_chunk_header = cb_on_chunk_header - */ - __pyx_v_self->_csettings->on_message_begin = __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin; - - /* "aiohttp/_http_parser.pyx":370 - * self._csettings.on_body = cb_on_body - * self._csettings.on_message_begin = cb_on_message_begin - * self._csettings.on_message_complete = cb_on_message_complete # <<<<<<<<<<<<<< - * self._csettings.on_chunk_header = cb_on_chunk_header - * self._csettings.on_chunk_complete = cb_on_chunk_complete - */ - __pyx_v_self->_csettings->on_message_complete = __pyx_f_7aiohttp_12_http_parser_cb_on_message_complete; - - /* "aiohttp/_http_parser.pyx":371 - * self._csettings.on_message_begin = cb_on_message_begin - * self._csettings.on_message_complete = cb_on_message_complete - * self._csettings.on_chunk_header = cb_on_chunk_header # <<<<<<<<<<<<<< - * self._csettings.on_chunk_complete = cb_on_chunk_complete - * - */ - __pyx_v_self->_csettings->on_chunk_header = __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_header; - - /* "aiohttp/_http_parser.pyx":372 - * self._csettings.on_message_complete = cb_on_message_complete - * self._csettings.on_chunk_header = cb_on_chunk_header - * self._csettings.on_chunk_complete = cb_on_chunk_complete # <<<<<<<<<<<<<< - * - * self._last_error = None - */ - __pyx_v_self->_csettings->on_chunk_complete = __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_complete; - - /* "aiohttp/_http_parser.pyx":374 - * self._csettings.on_chunk_complete = cb_on_chunk_complete - * - * self._last_error = None # <<<<<<<<<<<<<< - * self._limit = limit - * - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_last_error); - __Pyx_DECREF(__pyx_v_self->_last_error); - __pyx_v_self->_last_error = Py_None; - - /* "aiohttp/_http_parser.pyx":375 - * - * self._last_error = None - * self._limit = limit # <<<<<<<<<<<<<< - * - * cdef _process_header(self): - */ - __pyx_v_self->_limit = __pyx_v_limit; - - /* "aiohttp/_http_parser.pyx":327 - * PyMem_Free(self._csettings) - * - * cdef _init(self, cparser.http_parser_type mode, # <<<<<<<<<<<<<< - * object protocol, object loop, int limit, - * object timer=None, - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._init", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":377 - * self._limit = limit - * - * cdef _process_header(self): # <<<<<<<<<<<<<< - * if self._raw_name: - * raw_name = bytes(self._raw_name) - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__process_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_v_raw_name = NULL; - PyObject *__pyx_v_raw_value = NULL; - PyObject *__pyx_v_name = NULL; - PyObject *__pyx_v_value = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - int __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_process_header", 0); - - /* "aiohttp/_http_parser.pyx":378 - * - * cdef _process_header(self): - * if self._raw_name: # <<<<<<<<<<<<<< - * raw_name = bytes(self._raw_name) - * raw_value = bytes(self._raw_value) - */ - __pyx_t_1 = (__pyx_v_self->_raw_name != Py_None)&&(PyByteArray_GET_SIZE(__pyx_v_self->_raw_name) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":379 - * cdef _process_header(self): - * if self._raw_name: - * raw_name = bytes(self._raw_name) # <<<<<<<<<<<<<< - * raw_value = bytes(self._raw_value) - * - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_v_self->_raw_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 379, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_raw_name = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":380 - * if self._raw_name: - * raw_name = bytes(self._raw_name) - * raw_value = bytes(self._raw_value) # <<<<<<<<<<<<<< - * - * name = find_header(raw_name) - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_v_self->_raw_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 380, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_raw_value = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":382 - * raw_value = bytes(self._raw_value) - * - * name = find_header(raw_name) # <<<<<<<<<<<<<< - * value = raw_value.decode('utf-8', 'surrogateescape') - * - */ - __pyx_t_2 = __pyx_f_7aiohttp_12_http_parser_find_header(__pyx_v_raw_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 382, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_name = __pyx_t_2; - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":383 - * - * name = find_header(raw_name) - * value = raw_value.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * - * self._headers.add(name, value) - */ - __pyx_t_2 = __Pyx_decode_bytes(__pyx_v_raw_value, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 383, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_value = __pyx_t_2; - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":385 - * value = raw_value.decode('utf-8', 'surrogateescape') - * - * self._headers.add(name, value) # <<<<<<<<<<<<<< - * - * if name is CONTENT_ENCODING: - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_headers, __pyx_n_s_add); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 385, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = NULL; - __pyx_t_5 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - __pyx_t_5 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_name, __pyx_v_value}; - __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_2); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_name, __pyx_v_value}; - __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_2); - } else - #endif - { - __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 385, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (__pyx_t_4) { - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL; - } - __Pyx_INCREF(__pyx_v_name); - __Pyx_GIVEREF(__pyx_v_name); - PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_name); - __Pyx_INCREF(__pyx_v_value); - __Pyx_GIVEREF(__pyx_v_value); - PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_value); - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":387 - * self._headers.add(name, value) - * - * if name is CONTENT_ENCODING: # <<<<<<<<<<<<<< - * self._content_encoding = value - * - */ - __pyx_t_1 = (__pyx_v_name == __pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING); - __pyx_t_7 = (__pyx_t_1 != 0); - if (__pyx_t_7) { - - /* "aiohttp/_http_parser.pyx":388 - * - * if name is CONTENT_ENCODING: - * self._content_encoding = value # <<<<<<<<<<<<<< - * - * PyByteArray_Resize(self._raw_name, 0) - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_value))||((__pyx_v_value) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_value)->tp_name), 0))) __PYX_ERR(0, 388, __pyx_L1_error) - __pyx_t_2 = __pyx_v_value; - __Pyx_INCREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->_content_encoding); - __Pyx_DECREF(__pyx_v_self->_content_encoding); - __pyx_v_self->_content_encoding = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":387 - * self._headers.add(name, value) - * - * if name is CONTENT_ENCODING: # <<<<<<<<<<<<<< - * self._content_encoding = value - * - */ - } - - /* "aiohttp/_http_parser.pyx":390 - * self._content_encoding = value - * - * PyByteArray_Resize(self._raw_name, 0) # <<<<<<<<<<<<<< - * PyByteArray_Resize(self._raw_value, 0) - * self._has_value = False - */ - __pyx_t_2 = __pyx_v_self->_raw_name; - __Pyx_INCREF(__pyx_t_2); - __pyx_t_5 = PyByteArray_Resize(__pyx_t_2, 0); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(0, 390, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":391 - * - * PyByteArray_Resize(self._raw_name, 0) - * PyByteArray_Resize(self._raw_value, 0) # <<<<<<<<<<<<<< - * self._has_value = False - * self._raw_headers.append((raw_name, raw_value)) - */ - __pyx_t_2 = __pyx_v_self->_raw_value; - __Pyx_INCREF(__pyx_t_2); - __pyx_t_5 = PyByteArray_Resize(__pyx_t_2, 0); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(0, 391, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":392 - * PyByteArray_Resize(self._raw_name, 0) - * PyByteArray_Resize(self._raw_value, 0) - * self._has_value = False # <<<<<<<<<<<<<< - * self._raw_headers.append((raw_name, raw_value)) - * - */ - __pyx_v_self->_has_value = 0; - - /* "aiohttp/_http_parser.pyx":393 - * PyByteArray_Resize(self._raw_value, 0) - * self._has_value = False - * self._raw_headers.append((raw_name, raw_value)) # <<<<<<<<<<<<<< - * - * cdef _on_header_field(self, char* at, size_t length): - */ - if (unlikely(__pyx_v_self->_raw_headers == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); - __PYX_ERR(0, 393, __pyx_L1_error) - } - __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 393, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_raw_name); - __Pyx_GIVEREF(__pyx_v_raw_name); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_raw_name); - __Pyx_INCREF(__pyx_v_raw_value); - __Pyx_GIVEREF(__pyx_v_raw_value); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_raw_value); - __pyx_t_8 = __Pyx_PyList_Append(__pyx_v_self->_raw_headers, __pyx_t_2); if (unlikely(__pyx_t_8 == ((int)-1))) __PYX_ERR(0, 393, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":378 - * - * cdef _process_header(self): - * if self._raw_name: # <<<<<<<<<<<<<< - * raw_name = bytes(self._raw_name) - * raw_value = bytes(self._raw_value) - */ - } - - /* "aiohttp/_http_parser.pyx":377 - * self._limit = limit - * - * cdef _process_header(self): # <<<<<<<<<<<<<< - * if self._raw_name: - * raw_name = bytes(self._raw_name) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._process_header", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_raw_name); - __Pyx_XDECREF(__pyx_v_raw_value); - __Pyx_XDECREF(__pyx_v_name); - __Pyx_XDECREF(__pyx_v_value); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":395 - * self._raw_headers.append((raw_name, raw_value)) - * - * cdef _on_header_field(self, char* at, size_t length): # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * cdef char *buf - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_field(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length) { - Py_ssize_t __pyx_v_size; - char *__pyx_v_buf; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_header_field", 0); - - /* "aiohttp/_http_parser.pyx":398 - * cdef Py_ssize_t size - * cdef char *buf - * if self._has_value: # <<<<<<<<<<<<<< - * self._process_header() - * - */ - __pyx_t_1 = (__pyx_v_self->_has_value != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":399 - * cdef char *buf - * if self._has_value: - * self._process_header() # <<<<<<<<<<<<<< - * - * size = PyByteArray_Size(self._raw_name) - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self->__pyx_vtab)->_process_header(__pyx_v_self); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 399, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":398 - * cdef Py_ssize_t size - * cdef char *buf - * if self._has_value: # <<<<<<<<<<<<<< - * self._process_header() - * - */ - } - - /* "aiohttp/_http_parser.pyx":401 - * self._process_header() - * - * size = PyByteArray_Size(self._raw_name) # <<<<<<<<<<<<<< - * PyByteArray_Resize(self._raw_name, size + length) - * buf = PyByteArray_AsString(self._raw_name) - */ - __pyx_t_2 = __pyx_v_self->_raw_name; - __Pyx_INCREF(__pyx_t_2); - __pyx_t_3 = PyByteArray_Size(__pyx_t_2); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1L))) __PYX_ERR(0, 401, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v_size = __pyx_t_3; - - /* "aiohttp/_http_parser.pyx":402 - * - * size = PyByteArray_Size(self._raw_name) - * PyByteArray_Resize(self._raw_name, size + length) # <<<<<<<<<<<<<< - * buf = PyByteArray_AsString(self._raw_name) - * memcpy(buf + size, at, length) - */ - __pyx_t_2 = __pyx_v_self->_raw_name; - __Pyx_INCREF(__pyx_t_2); - __pyx_t_4 = PyByteArray_Resize(__pyx_t_2, (__pyx_v_size + __pyx_v_length)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 402, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":403 - * size = PyByteArray_Size(self._raw_name) - * PyByteArray_Resize(self._raw_name, size + length) - * buf = PyByteArray_AsString(self._raw_name) # <<<<<<<<<<<<<< - * memcpy(buf + size, at, length) - * - */ - __pyx_t_2 = __pyx_v_self->_raw_name; - __Pyx_INCREF(__pyx_t_2); - __pyx_v_buf = PyByteArray_AsString(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":404 - * PyByteArray_Resize(self._raw_name, size + length) - * buf = PyByteArray_AsString(self._raw_name) - * memcpy(buf + size, at, length) # <<<<<<<<<<<<<< - * - * cdef _on_header_value(self, char* at, size_t length): - */ - (void)(memcpy((__pyx_v_buf + __pyx_v_size), __pyx_v_at, __pyx_v_length)); - - /* "aiohttp/_http_parser.pyx":395 - * self._raw_headers.append((raw_name, raw_value)) - * - * cdef _on_header_field(self, char* at, size_t length): # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * cdef char *buf - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_header_field", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":406 - * memcpy(buf + size, at, length) - * - * cdef _on_header_value(self, char* at, size_t length): # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * cdef char *buf - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_value(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length) { - Py_ssize_t __pyx_v_size; - char *__pyx_v_buf; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - int __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_header_value", 0); - - /* "aiohttp/_http_parser.pyx":410 - * cdef char *buf - * - * size = PyByteArray_Size(self._raw_value) # <<<<<<<<<<<<<< - * PyByteArray_Resize(self._raw_value, size + length) - * buf = PyByteArray_AsString(self._raw_value) - */ - __pyx_t_1 = __pyx_v_self->_raw_value; - __Pyx_INCREF(__pyx_t_1); - __pyx_t_2 = PyByteArray_Size(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1L))) __PYX_ERR(0, 410, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_size = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":411 - * - * size = PyByteArray_Size(self._raw_value) - * PyByteArray_Resize(self._raw_value, size + length) # <<<<<<<<<<<<<< - * buf = PyByteArray_AsString(self._raw_value) - * memcpy(buf + size, at, length) - */ - __pyx_t_1 = __pyx_v_self->_raw_value; - __Pyx_INCREF(__pyx_t_1); - __pyx_t_3 = PyByteArray_Resize(__pyx_t_1, (__pyx_v_size + __pyx_v_length)); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 411, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":412 - * size = PyByteArray_Size(self._raw_value) - * PyByteArray_Resize(self._raw_value, size + length) - * buf = PyByteArray_AsString(self._raw_value) # <<<<<<<<<<<<<< - * memcpy(buf + size, at, length) - * self._has_value = True - */ - __pyx_t_1 = __pyx_v_self->_raw_value; - __Pyx_INCREF(__pyx_t_1); - __pyx_v_buf = PyByteArray_AsString(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":413 - * PyByteArray_Resize(self._raw_value, size + length) - * buf = PyByteArray_AsString(self._raw_value) - * memcpy(buf + size, at, length) # <<<<<<<<<<<<<< - * self._has_value = True - * - */ - (void)(memcpy((__pyx_v_buf + __pyx_v_size), __pyx_v_at, __pyx_v_length)); - - /* "aiohttp/_http_parser.pyx":414 - * buf = PyByteArray_AsString(self._raw_value) - * memcpy(buf + size, at, length) - * self._has_value = True # <<<<<<<<<<<<<< - * - * cdef _on_headers_complete(self): - */ - __pyx_v_self->_has_value = 1; - - /* "aiohttp/_http_parser.pyx":406 - * memcpy(buf + size, at, length) - * - * cdef _on_header_value(self, char* at, size_t length): # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * cdef char *buf - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_header_value", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":416 - * self._has_value = True - * - * cdef _on_headers_complete(self): # <<<<<<<<<<<<<< - * self._process_header() - * - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_v_method = NULL; - int __pyx_v_should_close; - unsigned int __pyx_v_upgrade; - unsigned int __pyx_v_chunked; - PyObject *__pyx_v_raw_headers = NULL; - PyObject *__pyx_v_headers = NULL; - PyObject *__pyx_v_encoding = NULL; - PyObject *__pyx_v_enc = NULL; - PyObject *__pyx_v_msg = NULL; - PyObject *__pyx_v_payload = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - unsigned int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_headers_complete", 0); - - /* "aiohttp/_http_parser.pyx":417 - * - * cdef _on_headers_complete(self): - * self._process_header() # <<<<<<<<<<<<<< - * - * method = http_method_str(self._cparser.method) - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self->__pyx_vtab)->_process_header(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 417, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":419 - * self._process_header() - * - * method = http_method_str(self._cparser.method) # <<<<<<<<<<<<<< - * should_close = not cparser.http_should_keep_alive(self._cparser) - * upgrade = self._cparser.upgrade - */ - __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser_http_method_str(__pyx_v_self->_cparser->method); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 419, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_method = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":420 - * - * method = http_method_str(self._cparser.method) - * should_close = not cparser.http_should_keep_alive(self._cparser) # <<<<<<<<<<<<<< - * upgrade = self._cparser.upgrade - * chunked = self._cparser.flags & cparser.F_CHUNKED - */ - __pyx_v_should_close = (!(http_should_keep_alive(__pyx_v_self->_cparser) != 0)); - - /* "aiohttp/_http_parser.pyx":421 - * method = http_method_str(self._cparser.method) - * should_close = not cparser.http_should_keep_alive(self._cparser) - * upgrade = self._cparser.upgrade # <<<<<<<<<<<<<< - * chunked = self._cparser.flags & cparser.F_CHUNKED - * - */ - __pyx_t_2 = __pyx_v_self->_cparser->upgrade; - __pyx_v_upgrade = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":422 - * should_close = not cparser.http_should_keep_alive(self._cparser) - * upgrade = self._cparser.upgrade - * chunked = self._cparser.flags & cparser.F_CHUNKED # <<<<<<<<<<<<<< - * - * raw_headers = tuple(self._raw_headers) - */ - __pyx_v_chunked = (__pyx_v_self->_cparser->flags & F_CHUNKED); - - /* "aiohttp/_http_parser.pyx":424 - * chunked = self._cparser.flags & cparser.F_CHUNKED - * - * raw_headers = tuple(self._raw_headers) # <<<<<<<<<<<<<< - * headers = CIMultiDictProxy(self._headers) - * - */ - if (unlikely(__pyx_v_self->_raw_headers == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(0, 424, __pyx_L1_error) - } - __pyx_t_1 = PyList_AsTuple(__pyx_v_self->_raw_headers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 424, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_raw_headers = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":425 - * - * raw_headers = tuple(self._raw_headers) - * headers = CIMultiDictProxy(self._headers) # <<<<<<<<<<<<<< - * - * if upgrade or self._cparser.method == 5: # cparser.CONNECT: - */ - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy); - __pyx_t_3 = __pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy; __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_self->_headers) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_self->_headers); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 425, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_headers = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":427 - * headers = CIMultiDictProxy(self._headers) - * - * if upgrade or self._cparser.method == 5: # cparser.CONNECT: # <<<<<<<<<<<<<< - * self._upgraded = True - * - */ - __pyx_t_6 = (__pyx_v_upgrade != 0); - if (!__pyx_t_6) { - } else { - __pyx_t_5 = __pyx_t_6; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_6 = ((__pyx_v_self->_cparser->method == 5) != 0); - __pyx_t_5 = __pyx_t_6; - __pyx_L4_bool_binop_done:; - if (__pyx_t_5) { - - /* "aiohttp/_http_parser.pyx":428 - * - * if upgrade or self._cparser.method == 5: # cparser.CONNECT: - * self._upgraded = True # <<<<<<<<<<<<<< - * - * # do not support old websocket spec - */ - __pyx_v_self->_upgraded = 1; - - /* "aiohttp/_http_parser.pyx":427 - * headers = CIMultiDictProxy(self._headers) - * - * if upgrade or self._cparser.method == 5: # cparser.CONNECT: # <<<<<<<<<<<<<< - * self._upgraded = True - * - */ - } - - /* "aiohttp/_http_parser.pyx":431 - * - * # do not support old websocket spec - * if SEC_WEBSOCKET_KEY1 in headers: # <<<<<<<<<<<<<< - * raise InvalidHeader(SEC_WEBSOCKET_KEY1) - * - */ - __pyx_t_5 = (__Pyx_PySequence_ContainsTF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_v_headers, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 431, __pyx_L1_error) - __pyx_t_6 = (__pyx_t_5 != 0); - if (unlikely(__pyx_t_6)) { - - /* "aiohttp/_http_parser.pyx":432 - * # do not support old websocket spec - * if SEC_WEBSOCKET_KEY1 in headers: - * raise InvalidHeader(SEC_WEBSOCKET_KEY1) # <<<<<<<<<<<<<< - * - * encoding = None - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_InvalidHeader); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 432, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 432, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":431 - * - * # do not support old websocket spec - * if SEC_WEBSOCKET_KEY1 in headers: # <<<<<<<<<<<<<< - * raise InvalidHeader(SEC_WEBSOCKET_KEY1) - * - */ - } - - /* "aiohttp/_http_parser.pyx":434 - * raise InvalidHeader(SEC_WEBSOCKET_KEY1) - * - * encoding = None # <<<<<<<<<<<<<< - * enc = self._content_encoding - * if enc is not None: - */ - __Pyx_INCREF(Py_None); - __pyx_v_encoding = Py_None; - - /* "aiohttp/_http_parser.pyx":435 - * - * encoding = None - * enc = self._content_encoding # <<<<<<<<<<<<<< - * if enc is not None: - * self._content_encoding = None - */ - __pyx_t_1 = __pyx_v_self->_content_encoding; - __Pyx_INCREF(__pyx_t_1); - __pyx_v_enc = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":436 - * encoding = None - * enc = self._content_encoding - * if enc is not None: # <<<<<<<<<<<<<< - * self._content_encoding = None - * enc = enc.lower() - */ - __pyx_t_6 = (__pyx_v_enc != Py_None); - __pyx_t_5 = (__pyx_t_6 != 0); - if (__pyx_t_5) { - - /* "aiohttp/_http_parser.pyx":437 - * enc = self._content_encoding - * if enc is not None: - * self._content_encoding = None # <<<<<<<<<<<<<< - * enc = enc.lower() - * if enc in ('gzip', 'deflate', 'br'): - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_content_encoding); - __Pyx_DECREF(__pyx_v_self->_content_encoding); - __pyx_v_self->_content_encoding = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":438 - * if enc is not None: - * self._content_encoding = None - * enc = enc.lower() # <<<<<<<<<<<<<< - * if enc in ('gzip', 'deflate', 'br'): - * encoding = enc - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_enc, __pyx_n_s_lower); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 438, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 438, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF_SET(__pyx_v_enc, __pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":439 - * self._content_encoding = None - * enc = enc.lower() - * if enc in ('gzip', 'deflate', 'br'): # <<<<<<<<<<<<<< - * encoding = enc - * - */ - __Pyx_INCREF(__pyx_v_enc); - __pyx_t_1 = __pyx_v_enc; - __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_gzip, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 439, __pyx_L1_error) - if (!__pyx_t_6) { - } else { - __pyx_t_5 = __pyx_t_6; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_deflate, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 439, __pyx_L1_error) - if (!__pyx_t_6) { - } else { - __pyx_t_5 = __pyx_t_6; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_br, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 439, __pyx_L1_error) - __pyx_t_5 = __pyx_t_6; - __pyx_L9_bool_binop_done:; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_6 = (__pyx_t_5 != 0); - if (__pyx_t_6) { - - /* "aiohttp/_http_parser.pyx":440 - * enc = enc.lower() - * if enc in ('gzip', 'deflate', 'br'): - * encoding = enc # <<<<<<<<<<<<<< - * - * if self._cparser.type == cparser.HTTP_REQUEST: - */ - __Pyx_INCREF(__pyx_v_enc); - __Pyx_DECREF_SET(__pyx_v_encoding, __pyx_v_enc); - - /* "aiohttp/_http_parser.pyx":439 - * self._content_encoding = None - * enc = enc.lower() - * if enc in ('gzip', 'deflate', 'br'): # <<<<<<<<<<<<<< - * encoding = enc - * - */ - } - - /* "aiohttp/_http_parser.pyx":436 - * encoding = None - * enc = self._content_encoding - * if enc is not None: # <<<<<<<<<<<<<< - * self._content_encoding = None - * enc = enc.lower() - */ - } - - /* "aiohttp/_http_parser.pyx":442 - * encoding = enc - * - * if self._cparser.type == cparser.HTTP_REQUEST: # <<<<<<<<<<<<<< - * msg = _new_request_message( - * method, self._path, - */ - __pyx_t_6 = ((__pyx_v_self->_cparser->type == HTTP_REQUEST) != 0); - if (__pyx_t_6) { - - /* "aiohttp/_http_parser.pyx":444 - * if self._cparser.type == cparser.HTTP_REQUEST: - * msg = _new_request_message( - * method, self._path, # <<<<<<<<<<<<<< - * self.http_version(), headers, raw_headers, - * should_close, encoding, upgrade, chunked, self._url) - */ - __pyx_t_1 = __pyx_v_self->_path; - __Pyx_INCREF(__pyx_t_1); - - /* "aiohttp/_http_parser.pyx":445 - * msg = _new_request_message( - * method, self._path, - * self.http_version(), headers, raw_headers, # <<<<<<<<<<<<<< - * should_close, encoding, upgrade, chunked, self._url) - * else: - */ - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(__pyx_v_self); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 445, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "aiohttp/_http_parser.pyx":446 - * method, self._path, - * self.http_version(), headers, raw_headers, - * should_close, encoding, upgrade, chunked, self._url) # <<<<<<<<<<<<<< - * else: - * msg = _new_response_message( - */ - __pyx_t_4 = __pyx_v_self->_url; - __Pyx_INCREF(__pyx_t_4); - - /* "aiohttp/_http_parser.pyx":443 - * - * if self._cparser.type == cparser.HTTP_REQUEST: - * msg = _new_request_message( # <<<<<<<<<<<<<< - * method, self._path, - * self.http_version(), headers, raw_headers, - */ - __pyx_t_7 = __pyx_f_7aiohttp_12_http_parser__new_request_message(__pyx_v_method, ((PyObject*)__pyx_t_1), __pyx_t_3, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_msg = __pyx_t_7; - __pyx_t_7 = 0; - - /* "aiohttp/_http_parser.pyx":442 - * encoding = enc - * - * if self._cparser.type == cparser.HTTP_REQUEST: # <<<<<<<<<<<<<< - * msg = _new_request_message( - * method, self._path, - */ - goto __pyx_L12; - } - - /* "aiohttp/_http_parser.pyx":448 - * should_close, encoding, upgrade, chunked, self._url) - * else: - * msg = _new_response_message( # <<<<<<<<<<<<<< - * self.http_version(), self._cparser.status_code, self._reason, - * headers, raw_headers, should_close, encoding, - */ - /*else*/ { - - /* "aiohttp/_http_parser.pyx":449 - * else: - * msg = _new_response_message( - * self.http_version(), self._cparser.status_code, self._reason, # <<<<<<<<<<<<<< - * headers, raw_headers, should_close, encoding, - * upgrade, chunked) - */ - __pyx_t_7 = __pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(__pyx_v_self); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 449, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_4 = __pyx_v_self->_reason; - __Pyx_INCREF(__pyx_t_4); - - /* "aiohttp/_http_parser.pyx":448 - * should_close, encoding, upgrade, chunked, self._url) - * else: - * msg = _new_response_message( # <<<<<<<<<<<<<< - * self.http_version(), self._cparser.status_code, self._reason, - * headers, raw_headers, should_close, encoding, - */ - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser__new_response_message(__pyx_t_7, __pyx_v_self->_cparser->status_code, ((PyObject*)__pyx_t_4), __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 448, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_msg = __pyx_t_3; - __pyx_t_3 = 0; - } - __pyx_L12:; - - /* "aiohttp/_http_parser.pyx":453 - * upgrade, chunked) - * - * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or # <<<<<<<<<<<<<< - * self._cparser.method == 5 or # CONNECT: 5 - * (self._cparser.status_code >= 199 and - */ - __pyx_t_5 = (ULLONG_MAX > __pyx_v_self->_cparser->content_length); - if (__pyx_t_5) { - __pyx_t_5 = (__pyx_v_self->_cparser->content_length > 0); - } - __pyx_t_8 = (__pyx_t_5 != 0); - if (!__pyx_t_8) { - } else { - __pyx_t_6 = __pyx_t_8; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_8 = (__pyx_v_chunked != 0); - if (!__pyx_t_8) { - } else { - __pyx_t_6 = __pyx_t_8; - goto __pyx_L14_bool_binop_done; - } - - /* "aiohttp/_http_parser.pyx":454 - * - * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or - * self._cparser.method == 5 or # CONNECT: 5 # <<<<<<<<<<<<<< - * (self._cparser.status_code >= 199 and - * self._cparser.content_length == ULLONG_MAX and - */ - __pyx_t_8 = ((__pyx_v_self->_cparser->method == 5) != 0); - if (!__pyx_t_8) { - } else { - __pyx_t_6 = __pyx_t_8; - goto __pyx_L14_bool_binop_done; - } - - /* "aiohttp/_http_parser.pyx":455 - * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or - * self._cparser.method == 5 or # CONNECT: 5 - * (self._cparser.status_code >= 199 and # <<<<<<<<<<<<<< - * self._cparser.content_length == ULLONG_MAX and - * self._read_until_eof) - */ - __pyx_t_8 = ((__pyx_v_self->_cparser->status_code >= 0xC7) != 0); - if (__pyx_t_8) { - } else { - __pyx_t_6 = __pyx_t_8; - goto __pyx_L14_bool_binop_done; - } - - /* "aiohttp/_http_parser.pyx":456 - * self._cparser.method == 5 or # CONNECT: 5 - * (self._cparser.status_code >= 199 and - * self._cparser.content_length == ULLONG_MAX and # <<<<<<<<<<<<<< - * self._read_until_eof) - * ): - */ - __pyx_t_8 = ((__pyx_v_self->_cparser->content_length == ULLONG_MAX) != 0); - if (__pyx_t_8) { - } else { - __pyx_t_6 = __pyx_t_8; - goto __pyx_L14_bool_binop_done; - } - - /* "aiohttp/_http_parser.pyx":457 - * (self._cparser.status_code >= 199 and - * self._cparser.content_length == ULLONG_MAX and - * self._read_until_eof) # <<<<<<<<<<<<<< - * ): - * payload = StreamReader( - */ - __pyx_t_8 = (__pyx_v_self->_read_until_eof != 0); - __pyx_t_6 = __pyx_t_8; - __pyx_L14_bool_binop_done:; - - /* "aiohttp/_http_parser.pyx":453 - * upgrade, chunked) - * - * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or # <<<<<<<<<<<<<< - * self._cparser.method == 5 or # CONNECT: 5 - * (self._cparser.status_code >= 199 and - */ - if (__pyx_t_6) { - - /* "aiohttp/_http_parser.pyx":459 - * self._read_until_eof) - * ): - * payload = StreamReader( # <<<<<<<<<<<<<< - * self._protocol, timer=self._timer, loop=self._loop, - * limit=self._limit) - */ - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 459, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_self->_protocol); - __Pyx_GIVEREF(__pyx_v_self->_protocol); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->_protocol); - - /* "aiohttp/_http_parser.pyx":460 - * ): - * payload = StreamReader( - * self._protocol, timer=self._timer, loop=self._loop, # <<<<<<<<<<<<<< - * limit=self._limit) - * else: - */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 460, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_timer, __pyx_v_self->_timer) < 0) __PYX_ERR(0, 460, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_loop, __pyx_v_self->_loop) < 0) __PYX_ERR(0, 460, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":461 - * payload = StreamReader( - * self._protocol, timer=self._timer, loop=self._loop, - * limit=self._limit) # <<<<<<<<<<<<<< - * else: - * payload = EMPTY_PAYLOAD - */ - __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_self->_limit); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 461, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_limit, __pyx_t_7) < 0) __PYX_ERR(0, 460, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "aiohttp/_http_parser.pyx":459 - * self._read_until_eof) - * ): - * payload = StreamReader( # <<<<<<<<<<<<<< - * self._protocol, timer=self._timer, loop=self._loop, - * limit=self._limit) - */ - __pyx_t_7 = __Pyx_PyObject_Call(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 459, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_payload = __pyx_t_7; - __pyx_t_7 = 0; - - /* "aiohttp/_http_parser.pyx":453 - * upgrade, chunked) - * - * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or # <<<<<<<<<<<<<< - * self._cparser.method == 5 or # CONNECT: 5 - * (self._cparser.status_code >= 199 and - */ - goto __pyx_L13; - } - - /* "aiohttp/_http_parser.pyx":463 - * limit=self._limit) - * else: - * payload = EMPTY_PAYLOAD # <<<<<<<<<<<<<< - * - * self._payload = payload - */ - /*else*/ { - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); - __pyx_v_payload = __pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD; - } - __pyx_L13:; - - /* "aiohttp/_http_parser.pyx":465 - * payload = EMPTY_PAYLOAD - * - * self._payload = payload # <<<<<<<<<<<<<< - * if encoding is not None and self._auto_decompress: - * self._payload = DeflateBuffer(payload, encoding) - */ - __Pyx_INCREF(__pyx_v_payload); - __Pyx_GIVEREF(__pyx_v_payload); - __Pyx_GOTREF(__pyx_v_self->_payload); - __Pyx_DECREF(__pyx_v_self->_payload); - __pyx_v_self->_payload = __pyx_v_payload; - - /* "aiohttp/_http_parser.pyx":466 - * - * self._payload = payload - * if encoding is not None and self._auto_decompress: # <<<<<<<<<<<<<< - * self._payload = DeflateBuffer(payload, encoding) - * - */ - __pyx_t_8 = (__pyx_v_encoding != Py_None); - __pyx_t_5 = (__pyx_t_8 != 0); - if (__pyx_t_5) { - } else { - __pyx_t_6 = __pyx_t_5; - goto __pyx_L21_bool_binop_done; - } - __pyx_t_5 = (__pyx_v_self->_auto_decompress != 0); - __pyx_t_6 = __pyx_t_5; - __pyx_L21_bool_binop_done:; - if (__pyx_t_6) { - - /* "aiohttp/_http_parser.pyx":467 - * self._payload = payload - * if encoding is not None and self._auto_decompress: - * self._payload = DeflateBuffer(payload, encoding) # <<<<<<<<<<<<<< - * - * if not self._response_with_body: - */ - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer); - __pyx_t_4 = __pyx_v_7aiohttp_12_http_parser_DeflateBuffer; __pyx_t_3 = NULL; - __pyx_t_9 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - __pyx_t_9 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_payload, __pyx_v_encoding}; - __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 467, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_7); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_payload, __pyx_v_encoding}; - __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 467, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GOTREF(__pyx_t_7); - } else - #endif - { - __pyx_t_1 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 467, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (__pyx_t_3) { - __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3); __pyx_t_3 = NULL; - } - __Pyx_INCREF(__pyx_v_payload); - __Pyx_GIVEREF(__pyx_v_payload); - PyTuple_SET_ITEM(__pyx_t_1, 0+__pyx_t_9, __pyx_v_payload); - __Pyx_INCREF(__pyx_v_encoding); - __Pyx_GIVEREF(__pyx_v_encoding); - PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_9, __pyx_v_encoding); - __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_1, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 467, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GIVEREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_v_self->_payload); - __Pyx_DECREF(__pyx_v_self->_payload); - __pyx_v_self->_payload = __pyx_t_7; - __pyx_t_7 = 0; - - /* "aiohttp/_http_parser.pyx":466 - * - * self._payload = payload - * if encoding is not None and self._auto_decompress: # <<<<<<<<<<<<<< - * self._payload = DeflateBuffer(payload, encoding) - * - */ - } - - /* "aiohttp/_http_parser.pyx":469 - * self._payload = DeflateBuffer(payload, encoding) - * - * if not self._response_with_body: # <<<<<<<<<<<<<< - * payload = EMPTY_PAYLOAD - * - */ - __pyx_t_6 = ((!(__pyx_v_self->_response_with_body != 0)) != 0); - if (__pyx_t_6) { - - /* "aiohttp/_http_parser.pyx":470 - * - * if not self._response_with_body: - * payload = EMPTY_PAYLOAD # <<<<<<<<<<<<<< - * - * self._messages.append((msg, payload)) - */ - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); - __Pyx_DECREF_SET(__pyx_v_payload, __pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); - - /* "aiohttp/_http_parser.pyx":469 - * self._payload = DeflateBuffer(payload, encoding) - * - * if not self._response_with_body: # <<<<<<<<<<<<<< - * payload = EMPTY_PAYLOAD - * - */ - } - - /* "aiohttp/_http_parser.pyx":472 - * payload = EMPTY_PAYLOAD - * - * self._messages.append((msg, payload)) # <<<<<<<<<<<<<< - * - * cdef _on_message_complete(self): - */ - if (unlikely(__pyx_v_self->_messages == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); - __PYX_ERR(0, 472, __pyx_L1_error) - } - __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 472, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_INCREF(__pyx_v_msg); - __Pyx_GIVEREF(__pyx_v_msg); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_msg); - __Pyx_INCREF(__pyx_v_payload); - __Pyx_GIVEREF(__pyx_v_payload); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_payload); - __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_self->_messages, __pyx_t_7); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 472, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "aiohttp/_http_parser.pyx":416 - * self._has_value = True - * - * cdef _on_headers_complete(self): # <<<<<<<<<<<<<< - * self._process_header() - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_method); - __Pyx_XDECREF(__pyx_v_raw_headers); - __Pyx_XDECREF(__pyx_v_headers); - __Pyx_XDECREF(__pyx_v_encoding); - __Pyx_XDECREF(__pyx_v_enc); - __Pyx_XDECREF(__pyx_v_msg); - __Pyx_XDECREF(__pyx_v_payload); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":474 - * self._messages.append((msg, payload)) - * - * cdef _on_message_complete(self): # <<<<<<<<<<<<<< - * self._payload.feed_eof() - * self._payload = None - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_message_complete", 0); - - /* "aiohttp/_http_parser.pyx":475 - * - * cdef _on_message_complete(self): - * self._payload.feed_eof() # <<<<<<<<<<<<<< - * self._payload = None - * - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_feed_eof); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 475, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 475, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":476 - * cdef _on_message_complete(self): - * self._payload.feed_eof() - * self._payload = None # <<<<<<<<<<<<<< - * - * cdef _on_chunk_header(self): - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_payload); - __Pyx_DECREF(__pyx_v_self->_payload); - __pyx_v_self->_payload = Py_None; - - /* "aiohttp/_http_parser.pyx":474 - * self._messages.append((msg, payload)) - * - * cdef _on_message_complete(self): # <<<<<<<<<<<<<< - * self._payload.feed_eof() - * self._payload = None - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_message_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":478 - * self._payload = None - * - * cdef _on_chunk_header(self): # <<<<<<<<<<<<<< - * self._payload.begin_http_chunk_receiving() - * - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_chunk_header", 0); - - /* "aiohttp/_http_parser.pyx":479 - * - * cdef _on_chunk_header(self): - * self._payload.begin_http_chunk_receiving() # <<<<<<<<<<<<<< - * - * cdef _on_chunk_complete(self): - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_begin_http_chunk_receiving); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 479, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 479, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":478 - * self._payload = None - * - * cdef _on_chunk_header(self): # <<<<<<<<<<<<<< - * self._payload.begin_http_chunk_receiving() - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_chunk_header", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":481 - * self._payload.begin_http_chunk_receiving() - * - * cdef _on_chunk_complete(self): # <<<<<<<<<<<<<< - * self._payload.end_http_chunk_receiving() - * - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_chunk_complete", 0); - - /* "aiohttp/_http_parser.pyx":482 - * - * cdef _on_chunk_complete(self): - * self._payload.end_http_chunk_receiving() # <<<<<<<<<<<<<< - * - * cdef object _on_status_complete(self): - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_end_http_chunk_receiving); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 482, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 482, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":481 - * self._payload.begin_http_chunk_receiving() - * - * cdef _on_chunk_complete(self): # <<<<<<<<<<<<<< - * self._payload.end_http_chunk_receiving() - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_chunk_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":484 - * self._payload.end_http_chunk_receiving() - * - * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< - * pass - * - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_status_complete(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_on_status_complete", 0); - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":487 - * pass - * - * cdef inline http_version(self): # <<<<<<<<<<<<<< - * cdef cparser.http_parser* parser = self._cparser - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - struct http_parser *__pyx_v_parser; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - struct http_parser *__pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("http_version", 0); - - /* "aiohttp/_http_parser.pyx":488 - * - * cdef inline http_version(self): - * cdef cparser.http_parser* parser = self._cparser # <<<<<<<<<<<<<< - * - * if parser.http_major == 1: - */ - __pyx_t_1 = __pyx_v_self->_cparser; - __pyx_v_parser = __pyx_t_1; - - /* "aiohttp/_http_parser.pyx":490 - * cdef cparser.http_parser* parser = self._cparser - * - * if parser.http_major == 1: # <<<<<<<<<<<<<< - * if parser.http_minor == 0: - * return HttpVersion10 - */ - __pyx_t_2 = ((__pyx_v_parser->http_major == 1) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":491 - * - * if parser.http_major == 1: - * if parser.http_minor == 0: # <<<<<<<<<<<<<< - * return HttpVersion10 - * elif parser.http_minor == 1: - */ - switch (__pyx_v_parser->http_minor) { - case 0: - - /* "aiohttp/_http_parser.pyx":492 - * if parser.http_major == 1: - * if parser.http_minor == 0: - * return HttpVersion10 # <<<<<<<<<<<<<< - * elif parser.http_minor == 1: - * return HttpVersion11 - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion10); - __pyx_r = __pyx_v_7aiohttp_12_http_parser_HttpVersion10; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":491 - * - * if parser.http_major == 1: - * if parser.http_minor == 0: # <<<<<<<<<<<<<< - * return HttpVersion10 - * elif parser.http_minor == 1: - */ - break; - case 1: - - /* "aiohttp/_http_parser.pyx":494 - * return HttpVersion10 - * elif parser.http_minor == 1: - * return HttpVersion11 # <<<<<<<<<<<<<< - * - * return HttpVersion(parser.http_major, parser.http_minor) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion11); - __pyx_r = __pyx_v_7aiohttp_12_http_parser_HttpVersion11; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":493 - * if parser.http_minor == 0: - * return HttpVersion10 - * elif parser.http_minor == 1: # <<<<<<<<<<<<<< - * return HttpVersion11 - * - */ - break; - default: break; - } - - /* "aiohttp/_http_parser.pyx":490 - * cdef cparser.http_parser* parser = self._cparser - * - * if parser.http_major == 1: # <<<<<<<<<<<<<< - * if parser.http_minor == 0: - * return HttpVersion10 - */ - } - - /* "aiohttp/_http_parser.pyx":496 - * return HttpVersion11 - * - * return HttpVersion(parser.http_major, parser.http_minor) # <<<<<<<<<<<<<< - * - * ### Public API ### - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_PyInt_From_unsigned_short(__pyx_v_parser->http_major); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyInt_From_unsigned_short(__pyx_v_parser->http_minor); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion); - __pyx_t_6 = __pyx_v_7aiohttp_12_http_parser_HttpVersion; __pyx_t_7 = NULL; - __pyx_t_8 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_7)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_7); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_8 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_4, __pyx_t_5}; - __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 496, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_4, __pyx_t_5}; - __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 496, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - if (__pyx_t_7) { - __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; - } - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_5); - __pyx_t_4 = 0; - __pyx_t_5 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":487 - * pass - * - * cdef inline http_version(self): # <<<<<<<<<<<<<< - * cdef cparser.http_parser* parser = self._cparser - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.http_version", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":500 - * ### Public API ### - * - * def feed_eof(self): # <<<<<<<<<<<<<< - * cdef bytes desc - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_5feed_eof(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_5feed_eof(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("feed_eof (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_v_desc = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("feed_eof", 0); - - /* "aiohttp/_http_parser.pyx":503 - * cdef bytes desc - * - * if self._payload is not None: # <<<<<<<<<<<<<< - * if self._cparser.flags & cparser.F_CHUNKED: - * raise TransferEncodingError( - */ - __pyx_t_1 = (__pyx_v_self->_payload != Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":504 - * - * if self._payload is not None: - * if self._cparser.flags & cparser.F_CHUNKED: # <<<<<<<<<<<<<< - * raise TransferEncodingError( - * "Not enough data for satisfy transfer length header.") - */ - __pyx_t_2 = ((__pyx_v_self->_cparser->flags & F_CHUNKED) != 0); - if (unlikely(__pyx_t_2)) { - - /* "aiohttp/_http_parser.pyx":505 - * if self._payload is not None: - * if self._cparser.flags & cparser.F_CHUNKED: - * raise TransferEncodingError( # <<<<<<<<<<<<<< - * "Not enough data for satisfy transfer length header.") - * elif self._cparser.flags & cparser.F_CONTENTLENGTH: - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_TransferEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 505, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Not_enough_data_for_satisfy_tran) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Not_enough_data_for_satisfy_tran); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 505, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 505, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":504 - * - * if self._payload is not None: - * if self._cparser.flags & cparser.F_CHUNKED: # <<<<<<<<<<<<<< - * raise TransferEncodingError( - * "Not enough data for satisfy transfer length header.") - */ - } - - /* "aiohttp/_http_parser.pyx":507 - * raise TransferEncodingError( - * "Not enough data for satisfy transfer length header.") - * elif self._cparser.flags & cparser.F_CONTENTLENGTH: # <<<<<<<<<<<<<< - * raise ContentLengthError( - * "Not enough data for satisfy content length header.") - */ - __pyx_t_2 = ((__pyx_v_self->_cparser->flags & F_CONTENTLENGTH) != 0); - if (unlikely(__pyx_t_2)) { - - /* "aiohttp/_http_parser.pyx":508 - * "Not enough data for satisfy transfer length header.") - * elif self._cparser.flags & cparser.F_CONTENTLENGTH: - * raise ContentLengthError( # <<<<<<<<<<<<<< - * "Not enough data for satisfy content length header.") - * elif self._cparser.http_errno != cparser.HPE_OK: - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_ContentLengthError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 508, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Not_enough_data_for_satisfy_cont) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Not_enough_data_for_satisfy_cont); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 508, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 508, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":507 - * raise TransferEncodingError( - * "Not enough data for satisfy transfer length header.") - * elif self._cparser.flags & cparser.F_CONTENTLENGTH: # <<<<<<<<<<<<<< - * raise ContentLengthError( - * "Not enough data for satisfy content length header.") - */ - } - - /* "aiohttp/_http_parser.pyx":510 - * raise ContentLengthError( - * "Not enough data for satisfy content length header.") - * elif self._cparser.http_errno != cparser.HPE_OK: # <<<<<<<<<<<<<< - * desc = cparser.http_errno_description( - * self._cparser.http_errno) - */ - __pyx_t_2 = ((__pyx_v_self->_cparser->http_errno != HPE_OK) != 0); - if (unlikely(__pyx_t_2)) { - - /* "aiohttp/_http_parser.pyx":511 - * "Not enough data for satisfy content length header.") - * elif self._cparser.http_errno != cparser.HPE_OK: - * desc = cparser.http_errno_description( # <<<<<<<<<<<<<< - * self._cparser.http_errno) - * raise PayloadEncodingError(desc.decode('latin-1')) - */ - __pyx_t_3 = __Pyx_PyBytes_FromString(http_errno_description(((enum http_errno)__pyx_v_self->_cparser->http_errno))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 511, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_v_desc = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":513 - * desc = cparser.http_errno_description( - * self._cparser.http_errno) - * raise PayloadEncodingError(desc.decode('latin-1')) # <<<<<<<<<<<<<< - * else: - * self._payload.feed_eof() - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_PayloadEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 513, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_decode_bytes(__pyx_v_desc, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeLatin1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 513, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 513, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 513, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":510 - * raise ContentLengthError( - * "Not enough data for satisfy content length header.") - * elif self._cparser.http_errno != cparser.HPE_OK: # <<<<<<<<<<<<<< - * desc = cparser.http_errno_description( - * self._cparser.http_errno) - */ - } - - /* "aiohttp/_http_parser.pyx":515 - * raise PayloadEncodingError(desc.decode('latin-1')) - * else: - * self._payload.feed_eof() # <<<<<<<<<<<<<< - * elif self._started: - * self._on_headers_complete() - */ - /*else*/ { - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_feed_eof); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 515, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 515, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - - /* "aiohttp/_http_parser.pyx":503 - * cdef bytes desc - * - * if self._payload is not None: # <<<<<<<<<<<<<< - * if self._cparser.flags & cparser.F_CHUNKED: - * raise TransferEncodingError( - */ - goto __pyx_L3; - } - - /* "aiohttp/_http_parser.pyx":516 - * else: - * self._payload.feed_eof() - * elif self._started: # <<<<<<<<<<<<<< - * self._on_headers_complete() - * if self._messages: - */ - __pyx_t_2 = (__pyx_v_self->_started != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":517 - * self._payload.feed_eof() - * elif self._started: - * self._on_headers_complete() # <<<<<<<<<<<<<< - * if self._messages: - * return self._messages[-1][0] - */ - __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self->__pyx_vtab)->_on_headers_complete(__pyx_v_self); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 517, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":518 - * elif self._started: - * self._on_headers_complete() - * if self._messages: # <<<<<<<<<<<<<< - * return self._messages[-1][0] - * - */ - __pyx_t_2 = (__pyx_v_self->_messages != Py_None)&&(PyList_GET_SIZE(__pyx_v_self->_messages) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":519 - * self._on_headers_complete() - * if self._messages: - * return self._messages[-1][0] # <<<<<<<<<<<<<< - * - * def feed_data(self, data): - */ - __Pyx_XDECREF(__pyx_r); - if (unlikely(__pyx_v_self->_messages == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(0, 519, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_self->_messages, -1L, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 519, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 519, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":518 - * elif self._started: - * self._on_headers_complete() - * if self._messages: # <<<<<<<<<<<<<< - * return self._messages[-1][0] - * - */ - } - - /* "aiohttp/_http_parser.pyx":516 - * else: - * self._payload.feed_eof() - * elif self._started: # <<<<<<<<<<<<<< - * self._on_headers_complete() - * if self._messages: - */ - } - __pyx_L3:; - - /* "aiohttp/_http_parser.pyx":500 - * ### Public API ### - * - * def feed_eof(self): # <<<<<<<<<<<<<< - * cdef bytes desc - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.feed_eof", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_desc); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":521 - * return self._messages[-1][0] - * - * def feed_data(self, data): # <<<<<<<<<<<<<< - * cdef: - * size_t data_len - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_7feed_data(PyObject *__pyx_v_self, PyObject *__pyx_v_data); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_7feed_data(PyObject *__pyx_v_self, PyObject *__pyx_v_data) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("feed_data (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_6feed_data(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), ((PyObject *)__pyx_v_data)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_6feed_data(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, PyObject *__pyx_v_data) { - size_t __pyx_v_data_len; - size_t __pyx_v_nb; - PyObject *__pyx_v_ex = NULL; - PyObject *__pyx_v_messages = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("feed_data", 0); - - /* "aiohttp/_http_parser.pyx":526 - * size_t nb - * - * PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) # <<<<<<<<<<<<<< - * data_len = self.py_buf.len - * - */ - __pyx_t_1 = PyObject_GetBuffer(__pyx_v_data, (&__pyx_v_self->py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 526, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":527 - * - * PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) - * data_len = self.py_buf.len # <<<<<<<<<<<<<< - * - * nb = cparser.http_parser_execute( - */ - __pyx_v_data_len = ((size_t)__pyx_v_self->py_buf.len); - - /* "aiohttp/_http_parser.pyx":529 - * data_len = self.py_buf.len - * - * nb = cparser.http_parser_execute( # <<<<<<<<<<<<<< - * self._cparser, - * self._csettings, - */ - __pyx_v_nb = http_parser_execute(__pyx_v_self->_cparser, __pyx_v_self->_csettings, ((char *)__pyx_v_self->py_buf.buf), __pyx_v_data_len); - - /* "aiohttp/_http_parser.pyx":535 - * data_len) - * - * PyBuffer_Release(&self.py_buf) # <<<<<<<<<<<<<< - * - * if (self._cparser.http_errno != cparser.HPE_OK): - */ - PyBuffer_Release((&__pyx_v_self->py_buf)); - - /* "aiohttp/_http_parser.pyx":537 - * PyBuffer_Release(&self.py_buf) - * - * if (self._cparser.http_errno != cparser.HPE_OK): # <<<<<<<<<<<<<< - * if self._payload_error == 0: - * if self._last_error is not None: - */ - __pyx_t_2 = ((__pyx_v_self->_cparser->http_errno != HPE_OK) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":538 - * - * if (self._cparser.http_errno != cparser.HPE_OK): - * if self._payload_error == 0: # <<<<<<<<<<<<<< - * if self._last_error is not None: - * ex = self._last_error - */ - __pyx_t_2 = ((__pyx_v_self->_payload_error == 0) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":539 - * if (self._cparser.http_errno != cparser.HPE_OK): - * if self._payload_error == 0: - * if self._last_error is not None: # <<<<<<<<<<<<<< - * ex = self._last_error - * self._last_error = None - */ - __pyx_t_2 = (__pyx_v_self->_last_error != Py_None); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { - - /* "aiohttp/_http_parser.pyx":540 - * if self._payload_error == 0: - * if self._last_error is not None: - * ex = self._last_error # <<<<<<<<<<<<<< - * self._last_error = None - * else: - */ - __pyx_t_4 = __pyx_v_self->_last_error; - __Pyx_INCREF(__pyx_t_4); - __pyx_v_ex = __pyx_t_4; - __pyx_t_4 = 0; - - /* "aiohttp/_http_parser.pyx":541 - * if self._last_error is not None: - * ex = self._last_error - * self._last_error = None # <<<<<<<<<<<<<< - * else: - * ex = parser_error_from_errno( - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_last_error); - __Pyx_DECREF(__pyx_v_self->_last_error); - __pyx_v_self->_last_error = Py_None; - - /* "aiohttp/_http_parser.pyx":539 - * if (self._cparser.http_errno != cparser.HPE_OK): - * if self._payload_error == 0: - * if self._last_error is not None: # <<<<<<<<<<<<<< - * ex = self._last_error - * self._last_error = None - */ - goto __pyx_L5; - } - - /* "aiohttp/_http_parser.pyx":543 - * self._last_error = None - * else: - * ex = parser_error_from_errno( # <<<<<<<<<<<<<< - * self._cparser.http_errno) - * self._payload = None - */ - /*else*/ { - - /* "aiohttp/_http_parser.pyx":544 - * else: - * ex = parser_error_from_errno( - * self._cparser.http_errno) # <<<<<<<<<<<<<< - * self._payload = None - * raise ex - */ - __pyx_t_4 = __pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(((enum http_errno)__pyx_v_self->_cparser->http_errno)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 543, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_v_ex = __pyx_t_4; - __pyx_t_4 = 0; - } - __pyx_L5:; - - /* "aiohttp/_http_parser.pyx":545 - * ex = parser_error_from_errno( - * self._cparser.http_errno) - * self._payload = None # <<<<<<<<<<<<<< - * raise ex - * - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_payload); - __Pyx_DECREF(__pyx_v_self->_payload); - __pyx_v_self->_payload = Py_None; - - /* "aiohttp/_http_parser.pyx":546 - * self._cparser.http_errno) - * self._payload = None - * raise ex # <<<<<<<<<<<<<< - * - * if self._messages: - */ - __Pyx_Raise(__pyx_v_ex, 0, 0, 0); - __PYX_ERR(0, 546, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":538 - * - * if (self._cparser.http_errno != cparser.HPE_OK): - * if self._payload_error == 0: # <<<<<<<<<<<<<< - * if self._last_error is not None: - * ex = self._last_error - */ - } - - /* "aiohttp/_http_parser.pyx":537 - * PyBuffer_Release(&self.py_buf) - * - * if (self._cparser.http_errno != cparser.HPE_OK): # <<<<<<<<<<<<<< - * if self._payload_error == 0: - * if self._last_error is not None: - */ - } - - /* "aiohttp/_http_parser.pyx":548 - * raise ex - * - * if self._messages: # <<<<<<<<<<<<<< - * messages = self._messages - * self._messages = [] - */ - __pyx_t_3 = (__pyx_v_self->_messages != Py_None)&&(PyList_GET_SIZE(__pyx_v_self->_messages) != 0); - if (__pyx_t_3) { - - /* "aiohttp/_http_parser.pyx":549 - * - * if self._messages: - * messages = self._messages # <<<<<<<<<<<<<< - * self._messages = [] - * else: - */ - __pyx_t_4 = __pyx_v_self->_messages; - __Pyx_INCREF(__pyx_t_4); - __pyx_v_messages = __pyx_t_4; - __pyx_t_4 = 0; - - /* "aiohttp/_http_parser.pyx":550 - * if self._messages: - * messages = self._messages - * self._messages = [] # <<<<<<<<<<<<<< - * else: - * messages = () - */ - __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 550, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - __Pyx_GOTREF(__pyx_v_self->_messages); - __Pyx_DECREF(__pyx_v_self->_messages); - __pyx_v_self->_messages = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; - - /* "aiohttp/_http_parser.pyx":548 - * raise ex - * - * if self._messages: # <<<<<<<<<<<<<< - * messages = self._messages - * self._messages = [] - */ - goto __pyx_L6; - } - - /* "aiohttp/_http_parser.pyx":552 - * self._messages = [] - * else: - * messages = () # <<<<<<<<<<<<<< - * - * if self._upgraded: - */ - /*else*/ { - __Pyx_INCREF(__pyx_empty_tuple); - __pyx_v_messages = __pyx_empty_tuple; - } - __pyx_L6:; - - /* "aiohttp/_http_parser.pyx":554 - * messages = () - * - * if self._upgraded: # <<<<<<<<<<<<<< - * return messages, True, data[nb:] - * else: - */ - __pyx_t_3 = (__pyx_v_self->_upgraded != 0); - if (__pyx_t_3) { - - /* "aiohttp/_http_parser.pyx":555 - * - * if self._upgraded: - * return messages, True, data[nb:] # <<<<<<<<<<<<<< - * else: - * return messages, False, b'' - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_PyObject_GetSlice(__pyx_v_data, __pyx_v_nb, 0, NULL, NULL, NULL, 1, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 555, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 555, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_messages); - __Pyx_GIVEREF(__pyx_v_messages); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_messages); - __Pyx_INCREF(Py_True); - __Pyx_GIVEREF(Py_True); - PyTuple_SET_ITEM(__pyx_t_5, 1, Py_True); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":554 - * messages = () - * - * if self._upgraded: # <<<<<<<<<<<<<< - * return messages, True, data[nb:] - * else: - */ - } - - /* "aiohttp/_http_parser.pyx":557 - * return messages, True, data[nb:] - * else: - * return messages, False, b'' # <<<<<<<<<<<<<< - * - * def set_upgraded(self, val): - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 557, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_messages); - __Pyx_GIVEREF(__pyx_v_messages); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_messages); - __Pyx_INCREF(Py_False); - __Pyx_GIVEREF(Py_False); - PyTuple_SET_ITEM(__pyx_t_5, 1, Py_False); - __Pyx_INCREF(__pyx_kp_b__4); - __Pyx_GIVEREF(__pyx_kp_b__4); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_b__4); - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":521 - * return self._messages[-1][0] - * - * def feed_data(self, data): # <<<<<<<<<<<<<< - * cdef: - * size_t data_len - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.feed_data", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_ex); - __Pyx_XDECREF(__pyx_v_messages); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":559 - * return messages, False, b'' - * - * def set_upgraded(self, val): # <<<<<<<<<<<<<< - * self._upgraded = val - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_9set_upgraded(PyObject *__pyx_v_self, PyObject *__pyx_v_val); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_9set_upgraded(PyObject *__pyx_v_self, PyObject *__pyx_v_val) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("set_upgraded (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_8set_upgraded(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), ((PyObject *)__pyx_v_val)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_8set_upgraded(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, PyObject *__pyx_v_val) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("set_upgraded", 0); - - /* "aiohttp/_http_parser.pyx":560 - * - * def set_upgraded(self, val): - * self._upgraded = val # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_val); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 560, __pyx_L1_error) - __pyx_v_self->_upgraded = __pyx_t_1; - - /* "aiohttp/_http_parser.pyx":559 - * return messages, False, b'' - * - * def set_upgraded(self, val): # <<<<<<<<<<<<<< - * self._upgraded = val - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.set_upgraded", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_11__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_11__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_10__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_13__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_13__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_12__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":565 - * cdef class HttpRequestParser(HttpParser): - * - * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_protocol = 0; - PyObject *__pyx_v_loop = 0; - int __pyx_v_limit; - PyObject *__pyx_v_timer = 0; - size_t __pyx_v_max_line_size; - size_t __pyx_v_max_headers; - size_t __pyx_v_max_field_size; - PyObject *__pyx_v_payload_exception = 0; - int __pyx_v_response_with_body; - int __pyx_v_read_until_eof; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_protocol,&__pyx_n_s_loop,&__pyx_n_s_limit,&__pyx_n_s_timer,&__pyx_n_s_max_line_size,&__pyx_n_s_max_headers,&__pyx_n_s_max_field_size,&__pyx_n_s_payload_exception,&__pyx_n_s_response_with_body,&__pyx_n_s_read_until_eof,0}; - PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; - values[3] = ((PyObject *)Py_None); - - /* "aiohttp/_http_parser.pyx":567 - * def __init__(self, protocol, loop, int limit, timer=None, - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, # <<<<<<<<<<<<<< - * bint response_with_body=True, bint read_until_eof=False, - * ): - */ - values[7] = ((PyObject *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); - CYTHON_FALLTHROUGH; - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_protocol)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_loop)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 10, 1); __PYX_ERR(0, 565, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_limit)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 10, 2); __PYX_ERR(0, 565, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_timer); - if (value) { values[3] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_line_size); - if (value) { values[4] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 5: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_headers); - if (value) { values[5] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 6: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_field_size); - if (value) { values[6] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 7: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_payload_exception); - if (value) { values[7] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 8: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_response_with_body); - if (value) { values[8] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 9: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_until_eof); - if (value) { values[9] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 565, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); - CYTHON_FALLTHROUGH; - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_protocol = values[0]; - __pyx_v_loop = values[1]; - __pyx_v_limit = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_limit == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 565, __pyx_L3_error) - __pyx_v_timer = values[3]; - if (values[4]) { - __pyx_v_max_line_size = __Pyx_PyInt_As_size_t(values[4]); if (unlikely((__pyx_v_max_line_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L3_error) - } else { - __pyx_v_max_line_size = ((size_t)0x1FFE); - } - if (values[5]) { - __pyx_v_max_headers = __Pyx_PyInt_As_size_t(values[5]); if (unlikely((__pyx_v_max_headers == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L3_error) - } else { - __pyx_v_max_headers = ((size_t)0x8000); - } - if (values[6]) { - __pyx_v_max_field_size = __Pyx_PyInt_As_size_t(values[6]); if (unlikely((__pyx_v_max_field_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 567, __pyx_L3_error) - } else { - __pyx_v_max_field_size = ((size_t)0x1FFE); - } - __pyx_v_payload_exception = values[7]; - if (values[8]) { - __pyx_v_response_with_body = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_response_with_body == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 568, __pyx_L3_error) - } else { - - /* "aiohttp/_http_parser.pyx":568 - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - * bint response_with_body=True, bint read_until_eof=False, # <<<<<<<<<<<<<< - * ): - * self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, - */ - __pyx_v_response_with_body = ((int)1); - } - if (values[9]) { - __pyx_v_read_until_eof = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_read_until_eof == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 568, __pyx_L3_error) - } else { - __pyx_v_read_until_eof = ((int)0); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 565, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser___init__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self), __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, __pyx_v_timer, __pyx_v_max_line_size, __pyx_v_max_headers, __pyx_v_max_field_size, __pyx_v_payload_exception, __pyx_v_response_with_body, __pyx_v_read_until_eof); - - /* "aiohttp/_http_parser.pyx":565 - * cdef class HttpRequestParser(HttpParser): - * - * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser___init__(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, PyObject *__pyx_v_timer, size_t __pyx_v_max_line_size, size_t __pyx_v_max_headers, size_t __pyx_v_max_field_size, PyObject *__pyx_v_payload_exception, int __pyx_v_response_with_body, int __pyx_v_read_until_eof) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - - /* "aiohttp/_http_parser.pyx":570 - * bint response_with_body=True, bint read_until_eof=False, - * ): - * self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, # <<<<<<<<<<<<<< - * max_line_size, max_headers, max_field_size, - * payload_exception, response_with_body, read_until_eof) - */ - __pyx_t_2.__pyx_n = 7; - __pyx_t_2.timer = __pyx_v_timer; - __pyx_t_2.max_line_size = __pyx_v_max_line_size; - __pyx_t_2.max_headers = __pyx_v_max_headers; - __pyx_t_2.max_field_size = __pyx_v_max_field_size; - __pyx_t_2.payload_exception = __pyx_v_payload_exception; - __pyx_t_2.response_with_body = __pyx_v_response_with_body; - __pyx_t_2.read_until_eof = __pyx_v_read_until_eof; - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._init(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), HTTP_REQUEST, __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 570, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":565 - * cdef class HttpRequestParser(HttpParser): - * - * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":574 - * payload_exception, response_with_body, read_until_eof) - * - * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< - * cdef Py_buffer py_buf - * if not self._buf: - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self) { - Py_buffer __pyx_v_py_buf; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_t_7; - char const *__pyx_t_8; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_status_complete", 0); - - /* "aiohttp/_http_parser.pyx":576 - * cdef object _on_status_complete(self): - * cdef Py_buffer py_buf - * if not self._buf: # <<<<<<<<<<<<<< - * return - * self._path = self._buf.decode('utf-8', 'surrogateescape') - */ - __pyx_t_1 = (__pyx_v_self->__pyx_base._buf != Py_None)&&(PyByteArray_GET_SIZE(__pyx_v_self->__pyx_base._buf) != 0); - __pyx_t_2 = ((!__pyx_t_1) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":577 - * cdef Py_buffer py_buf - * if not self._buf: - * return # <<<<<<<<<<<<<< - * self._path = self._buf.decode('utf-8', 'surrogateescape') - * if self._cparser.method == 5: # CONNECT - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":576 - * cdef object _on_status_complete(self): - * cdef Py_buffer py_buf - * if not self._buf: # <<<<<<<<<<<<<< - * return - * self._path = self._buf.decode('utf-8', 'surrogateescape') - */ - } - - /* "aiohttp/_http_parser.pyx":578 - * if not self._buf: - * return - * self._path = self._buf.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * if self._cparser.method == 5: # CONNECT - * self._url = URL(self._path) - */ - if (unlikely(__pyx_v_self->__pyx_base._buf == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "decode"); - __PYX_ERR(0, 578, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_decode_bytearray(__pyx_v_self->__pyx_base._buf, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 578, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __Pyx_GOTREF(__pyx_v_self->__pyx_base._path); - __Pyx_DECREF(__pyx_v_self->__pyx_base._path); - __pyx_v_self->__pyx_base._path = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":579 - * return - * self._path = self._buf.decode('utf-8', 'surrogateescape') - * if self._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< - * self._url = URL(self._path) - * else: - */ - __pyx_t_2 = ((__pyx_v_self->__pyx_base._cparser->method == 5) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_parser.pyx":580 - * self._path = self._buf.decode('utf-8', 'surrogateescape') - * if self._cparser.method == 5: # CONNECT - * self._url = URL(self._path) # <<<<<<<<<<<<<< - * else: - * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) - */ - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_URL); - __pyx_t_4 = __pyx_v_7aiohttp_12_http_parser_URL; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_v_self->__pyx_base._path) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->__pyx_base._path); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 580, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GIVEREF(__pyx_t_3); - __Pyx_GOTREF(__pyx_v_self->__pyx_base._url); - __Pyx_DECREF(__pyx_v_self->__pyx_base._url); - __pyx_v_self->__pyx_base._url = __pyx_t_3; - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":579 - * return - * self._path = self._buf.decode('utf-8', 'surrogateescape') - * if self._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< - * self._url = URL(self._path) - * else: - */ - goto __pyx_L4; - } - - /* "aiohttp/_http_parser.pyx":582 - * self._url = URL(self._path) - * else: - * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) # <<<<<<<<<<<<<< - * try: - * self._url = _parse_url(py_buf.buf, - */ - /*else*/ { - __pyx_t_3 = __pyx_v_self->__pyx_base._buf; - __Pyx_INCREF(__pyx_t_3); - __pyx_t_6 = PyObject_GetBuffer(__pyx_t_3, (&__pyx_v_py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 582, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":583 - * else: - * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) - * try: # <<<<<<<<<<<<<< - * self._url = _parse_url(py_buf.buf, - * py_buf.len) - */ - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":584 - * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) - * try: - * self._url = _parse_url(py_buf.buf, # <<<<<<<<<<<<<< - * py_buf.len) - * finally: - */ - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser__parse_url(((char *)__pyx_v_py_buf.buf), __pyx_v_py_buf.len); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 584, __pyx_L6_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __Pyx_GOTREF(__pyx_v_self->__pyx_base._url); - __Pyx_DECREF(__pyx_v_self->__pyx_base._url); - __pyx_v_self->__pyx_base._url = __pyx_t_3; - __pyx_t_3 = 0; - } - - /* "aiohttp/_http_parser.pyx":587 - * py_buf.len) - * finally: - * PyBuffer_Release(&py_buf) # <<<<<<<<<<<<<< - * PyByteArray_Resize(self._buf, 0) - * - */ - /*finally:*/ { - /*normal exit:*/{ - PyBuffer_Release((&__pyx_v_py_buf)); - goto __pyx_L7; - } - __pyx_L6_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11) < 0)) __Pyx_ErrFetch(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11); - __Pyx_XGOTREF(__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_10); - __Pyx_XGOTREF(__pyx_t_11); - __Pyx_XGOTREF(__pyx_t_12); - __Pyx_XGOTREF(__pyx_t_13); - __Pyx_XGOTREF(__pyx_t_14); - __pyx_t_6 = __pyx_lineno; __pyx_t_7 = __pyx_clineno; __pyx_t_8 = __pyx_filename; - { - PyBuffer_Release((&__pyx_v_py_buf)); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_XGIVEREF(__pyx_t_13); - __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14); - } - __Pyx_XGIVEREF(__pyx_t_9); - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_ErrRestore(__pyx_t_9, __pyx_t_10, __pyx_t_11); - __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; - __pyx_lineno = __pyx_t_6; __pyx_clineno = __pyx_t_7; __pyx_filename = __pyx_t_8; - goto __pyx_L1_error; - } - __pyx_L7:; - } - } - __pyx_L4:; - - /* "aiohttp/_http_parser.pyx":588 - * finally: - * PyBuffer_Release(&py_buf) - * PyByteArray_Resize(self._buf, 0) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_v_self->__pyx_base._buf; - __Pyx_INCREF(__pyx_t_3); - __pyx_t_7 = PyByteArray_Resize(__pyx_t_3, 0); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 588, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":574 - * payload_exception, response_with_body, read_until_eof) - * - * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< - * cdef Py_buffer py_buf - * if not self._buf: - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser._on_status_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_2__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_2__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_4__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_4__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":593 - * cdef class HttpResponseParser(HttpParser): - * - * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - -/* Python wrapper */ -static int __pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_protocol = 0; - PyObject *__pyx_v_loop = 0; - int __pyx_v_limit; - PyObject *__pyx_v_timer = 0; - size_t __pyx_v_max_line_size; - size_t __pyx_v_max_headers; - size_t __pyx_v_max_field_size; - PyObject *__pyx_v_payload_exception = 0; - int __pyx_v_response_with_body; - int __pyx_v_read_until_eof; - int __pyx_v_auto_decompress; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_protocol,&__pyx_n_s_loop,&__pyx_n_s_limit,&__pyx_n_s_timer,&__pyx_n_s_max_line_size,&__pyx_n_s_max_headers,&__pyx_n_s_max_field_size,&__pyx_n_s_payload_exception,&__pyx_n_s_response_with_body,&__pyx_n_s_read_until_eof,&__pyx_n_s_auto_decompress,0}; - PyObject* values[11] = {0,0,0,0,0,0,0,0,0,0,0}; - values[3] = ((PyObject *)Py_None); - - /* "aiohttp/_http_parser.pyx":595 - * def __init__(self, protocol, loop, int limit, timer=None, - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, # <<<<<<<<<<<<<< - * bint response_with_body=True, bint read_until_eof=False, - * bint auto_decompress=True - */ - values[7] = ((PyObject *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10); - CYTHON_FALLTHROUGH; - case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); - CYTHON_FALLTHROUGH; - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_protocol)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_loop)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 11, 1); __PYX_ERR(0, 593, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_limit)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 11, 2); __PYX_ERR(0, 593, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_timer); - if (value) { values[3] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_line_size); - if (value) { values[4] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 5: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_headers); - if (value) { values[5] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 6: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_field_size); - if (value) { values[6] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 7: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_payload_exception); - if (value) { values[7] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 8: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_response_with_body); - if (value) { values[8] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 9: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_until_eof); - if (value) { values[9] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 10: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_auto_decompress); - if (value) { values[10] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 593, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10); - CYTHON_FALLTHROUGH; - case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); - CYTHON_FALLTHROUGH; - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_protocol = values[0]; - __pyx_v_loop = values[1]; - __pyx_v_limit = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_limit == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 593, __pyx_L3_error) - __pyx_v_timer = values[3]; - if (values[4]) { - __pyx_v_max_line_size = __Pyx_PyInt_As_size_t(values[4]); if (unlikely((__pyx_v_max_line_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 594, __pyx_L3_error) - } else { - __pyx_v_max_line_size = ((size_t)0x1FFE); - } - if (values[5]) { - __pyx_v_max_headers = __Pyx_PyInt_As_size_t(values[5]); if (unlikely((__pyx_v_max_headers == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 594, __pyx_L3_error) - } else { - __pyx_v_max_headers = ((size_t)0x8000); - } - if (values[6]) { - __pyx_v_max_field_size = __Pyx_PyInt_As_size_t(values[6]); if (unlikely((__pyx_v_max_field_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 595, __pyx_L3_error) - } else { - __pyx_v_max_field_size = ((size_t)0x1FFE); - } - __pyx_v_payload_exception = values[7]; - if (values[8]) { - __pyx_v_response_with_body = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_response_with_body == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 596, __pyx_L3_error) - } else { - - /* "aiohttp/_http_parser.pyx":596 - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - * bint response_with_body=True, bint read_until_eof=False, # <<<<<<<<<<<<<< - * bint auto_decompress=True - * ): - */ - __pyx_v_response_with_body = ((int)1); - } - if (values[9]) { - __pyx_v_read_until_eof = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_read_until_eof == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 596, __pyx_L3_error) - } else { - __pyx_v_read_until_eof = ((int)0); - } - if (values[10]) { - __pyx_v_auto_decompress = __Pyx_PyObject_IsTrue(values[10]); if (unlikely((__pyx_v_auto_decompress == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 597, __pyx_L3_error) - } else { - - /* "aiohttp/_http_parser.pyx":597 - * size_t max_field_size=8190, payload_exception=None, - * bint response_with_body=True, bint read_until_eof=False, - * bint auto_decompress=True # <<<<<<<<<<<<<< - * ): - * self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, - */ - __pyx_v_auto_decompress = ((int)1); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 11, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 593, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser___init__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self), __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, __pyx_v_timer, __pyx_v_max_line_size, __pyx_v_max_headers, __pyx_v_max_field_size, __pyx_v_payload_exception, __pyx_v_response_with_body, __pyx_v_read_until_eof, __pyx_v_auto_decompress); - - /* "aiohttp/_http_parser.pyx":593 - * cdef class HttpResponseParser(HttpParser): - * - * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser___init__(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, PyObject *__pyx_v_timer, size_t __pyx_v_max_line_size, size_t __pyx_v_max_headers, size_t __pyx_v_max_field_size, PyObject *__pyx_v_payload_exception, int __pyx_v_response_with_body, int __pyx_v_read_until_eof, int __pyx_v_auto_decompress) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - - /* "aiohttp/_http_parser.pyx":599 - * bint auto_decompress=True - * ): - * self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, # <<<<<<<<<<<<<< - * max_line_size, max_headers, max_field_size, - * payload_exception, response_with_body, read_until_eof, - */ - __pyx_t_2.__pyx_n = 8; - __pyx_t_2.timer = __pyx_v_timer; - __pyx_t_2.max_line_size = __pyx_v_max_line_size; - __pyx_t_2.max_headers = __pyx_v_max_headers; - __pyx_t_2.max_field_size = __pyx_v_max_field_size; - __pyx_t_2.payload_exception = __pyx_v_payload_exception; - __pyx_t_2.response_with_body = __pyx_v_response_with_body; - __pyx_t_2.read_until_eof = __pyx_v_read_until_eof; - __pyx_t_2.auto_decompress = __pyx_v_auto_decompress; - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._init(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), HTTP_RESPONSE, __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 599, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":593 - * cdef class HttpResponseParser(HttpParser): - * - * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< - * size_t max_line_size=8190, size_t max_headers=32768, - * size_t max_field_size=8190, payload_exception=None, - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":604 - * auto_decompress) - * - * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< - * if self._buf: - * self._reason = self._buf.decode('utf-8', 'surrogateescape') - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_18HttpResponseParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_on_status_complete", 0); - - /* "aiohttp/_http_parser.pyx":605 - * - * cdef object _on_status_complete(self): - * if self._buf: # <<<<<<<<<<<<<< - * self._reason = self._buf.decode('utf-8', 'surrogateescape') - * PyByteArray_Resize(self._buf, 0) - */ - __pyx_t_1 = (__pyx_v_self->__pyx_base._buf != Py_None)&&(PyByteArray_GET_SIZE(__pyx_v_self->__pyx_base._buf) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":606 - * cdef object _on_status_complete(self): - * if self._buf: - * self._reason = self._buf.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * PyByteArray_Resize(self._buf, 0) - * else: - */ - if (unlikely(__pyx_v_self->__pyx_base._buf == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "decode"); - __PYX_ERR(0, 606, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_decode_bytearray(__pyx_v_self->__pyx_base._buf, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 606, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->__pyx_base._reason); - __Pyx_DECREF(__pyx_v_self->__pyx_base._reason); - __pyx_v_self->__pyx_base._reason = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":607 - * if self._buf: - * self._reason = self._buf.decode('utf-8', 'surrogateescape') - * PyByteArray_Resize(self._buf, 0) # <<<<<<<<<<<<<< - * else: - * self._reason = self._reason or '' - */ - __pyx_t_2 = __pyx_v_self->__pyx_base._buf; - __Pyx_INCREF(__pyx_t_2); - __pyx_t_3 = PyByteArray_Resize(__pyx_t_2, 0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 607, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":605 - * - * cdef object _on_status_complete(self): - * if self._buf: # <<<<<<<<<<<<<< - * self._reason = self._buf.decode('utf-8', 'surrogateescape') - * PyByteArray_Resize(self._buf, 0) - */ - goto __pyx_L3; - } - - /* "aiohttp/_http_parser.pyx":609 - * PyByteArray_Resize(self._buf, 0) - * else: - * self._reason = self._reason or '' # <<<<<<<<<<<<<< - * - * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: - */ - /*else*/ { - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->__pyx_base._reason); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 609, __pyx_L1_error) - if (!__pyx_t_1) { - } else { - __Pyx_INCREF(__pyx_v_self->__pyx_base._reason); - __pyx_t_2 = __pyx_v_self->__pyx_base._reason; - goto __pyx_L4_bool_binop_done; - } - __Pyx_INCREF(__pyx_kp_u__4); - __pyx_t_2 = __pyx_kp_u__4; - __pyx_L4_bool_binop_done:; - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->__pyx_base._reason); - __Pyx_DECREF(__pyx_v_self->__pyx_base._reason); - __pyx_v_self->__pyx_base._reason = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - } - __pyx_L3:; - - /* "aiohttp/_http_parser.pyx":604 - * auto_decompress) - * - * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< - * if self._buf: - * self._reason = self._buf.decode('utf-8', 'surrogateescape') - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser._on_status_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_2__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_2__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_4__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_4__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":611 - * self._reason = self._reason or '' - * - * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin(struct http_parser *__pyx_v_parser) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_message_begin", 0); - - /* "aiohttp/_http_parser.pyx":612 - * - * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * - * pyparser._started = True - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":614 - * cdef HttpParser pyparser = parser.data - * - * pyparser._started = True # <<<<<<<<<<<<<< - * pyparser._headers = CIMultiDict() - * pyparser._raw_headers = [] - */ - __pyx_v_pyparser->_started = 1; - - /* "aiohttp/_http_parser.pyx":615 - * - * pyparser._started = True - * pyparser._headers = CIMultiDict() # <<<<<<<<<<<<<< - * pyparser._raw_headers = [] - * PyByteArray_Resize(pyparser._buf, 0) - */ - __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDict); - __pyx_t_2 = __pyx_v_7aiohttp_12_http_parser_CIMultiDict; __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 615, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_pyparser->_headers); - __Pyx_DECREF(__pyx_v_pyparser->_headers); - __pyx_v_pyparser->_headers = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":616 - * pyparser._started = True - * pyparser._headers = CIMultiDict() - * pyparser._raw_headers = [] # <<<<<<<<<<<<<< - * PyByteArray_Resize(pyparser._buf, 0) - * pyparser._path = None - */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 616, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v_pyparser->_raw_headers); - __Pyx_DECREF(__pyx_v_pyparser->_raw_headers); - __pyx_v_pyparser->_raw_headers = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":617 - * pyparser._headers = CIMultiDict() - * pyparser._raw_headers = [] - * PyByteArray_Resize(pyparser._buf, 0) # <<<<<<<<<<<<<< - * pyparser._path = None - * pyparser._reason = None - */ - __pyx_t_1 = __pyx_v_pyparser->_buf; - __Pyx_INCREF(__pyx_t_1); - __pyx_t_4 = PyByteArray_Resize(__pyx_t_1, 0); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 617, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":618 - * pyparser._raw_headers = [] - * PyByteArray_Resize(pyparser._buf, 0) - * pyparser._path = None # <<<<<<<<<<<<<< - * pyparser._reason = None - * return 0 - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_pyparser->_path); - __Pyx_DECREF(__pyx_v_pyparser->_path); - __pyx_v_pyparser->_path = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":619 - * PyByteArray_Resize(pyparser._buf, 0) - * pyparser._path = None - * pyparser._reason = None # <<<<<<<<<<<<<< - * return 0 - * - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_pyparser->_reason); - __Pyx_DECREF(__pyx_v_pyparser->_reason); - __pyx_v_pyparser->_reason = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":620 - * pyparser._path = None - * pyparser._reason = None - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":611 - * self._reason = self._reason or '' - * - * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_message_begin", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":623 - * - * - * cdef int cb_on_url(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_url(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_ex = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_t_10; - PyObject *__pyx_t_11 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_url", 0); - - /* "aiohttp/_http_parser.pyx":625 - * cdef int cb_on_url(cparser.http_parser* parser, - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * try: - * if length > pyparser._max_line_size: - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":626 - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * if length > pyparser._max_line_size: - * raise LineTooLong( - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":627 - * cdef HttpParser pyparser = parser.data - * try: - * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) - */ - __pyx_t_5 = ((__pyx_v_length > __pyx_v_pyparser->_max_line_size) != 0); - if (unlikely(__pyx_t_5)) { - - /* "aiohttp/_http_parser.pyx":628 - * try: - * if length > pyparser._max_line_size: - * raise LineTooLong( # <<<<<<<<<<<<<< - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) - */ - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 628, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "aiohttp/_http_parser.pyx":629 - * if length > pyparser._max_line_size: - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) # <<<<<<<<<<<<<< - * extend(pyparser._buf, at, length) - * except BaseException as ex: - */ - __pyx_t_7 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_line_size); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 629, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_length); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 629, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_9 = NULL; - __pyx_t_10 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_9)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_9); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_10 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else - #endif - { - __pyx_t_11 = PyTuple_New(3+__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 628, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_11); - if (__pyx_t_9) { - __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; - } - __Pyx_INCREF(__pyx_kp_u_Status_line_is_too_long); - __Pyx_GIVEREF(__pyx_kp_u_Status_line_is_too_long); - PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, __pyx_kp_u_Status_line_is_too_long); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_11, 2+__pyx_t_10, __pyx_t_8); - __pyx_t_7 = 0; - __pyx_t_8 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - } - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 628, __pyx_L3_error) - - /* "aiohttp/_http_parser.pyx":627 - * cdef HttpParser pyparser = parser.data - * try: - * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) - */ - } - - /* "aiohttp/_http_parser.pyx":630 - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) # <<<<<<<<<<<<<< - * except BaseException as ex: - * pyparser._last_error = ex - */ - __pyx_t_1 = __pyx_v_pyparser->_buf; - __Pyx_INCREF(__pyx_t_1); - __pyx_t_6 = __pyx_f_7aiohttp_12_http_parser_extend(__pyx_t_1, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 630, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "aiohttp/_http_parser.pyx":626 - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * if length > pyparser._max_line_size: - * raise LineTooLong( - */ - } - - /* "aiohttp/_http_parser.pyx":635 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "aiohttp/_http_parser.pyx":631 - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - __pyx_t_10 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_10) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_url", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_1, &__pyx_t_11) < 0) __PYX_ERR(0, 631, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_11); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_ex = __pyx_t_1; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":632 - * extend(pyparser._buf, at, length) - * except BaseException as ex: - * pyparser._last_error = ex # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_ex); - __Pyx_GIVEREF(__pyx_v_ex); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_ex; - - /* "aiohttp/_http_parser.pyx":633 - * except BaseException as ex: - * pyparser._last_error = ex - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - goto __pyx_L14_return; - } - - /* "aiohttp/_http_parser.pyx":631 - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - /*finally:*/ { - __pyx_L14_return: { - __pyx_t_10 = __pyx_r; - __Pyx_DECREF(__pyx_v_ex); - __pyx_v_ex = NULL; - __pyx_r = __pyx_t_10; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":626 - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * if length > pyparser._max_line_size: - * raise LineTooLong( - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":623 - * - * - * cdef int cb_on_url(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_url", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_ex); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":638 - * - * - * cdef int cb_on_status(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_status(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_ex = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_t_10; - PyObject *__pyx_t_11 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_status", 0); - - /* "aiohttp/_http_parser.pyx":640 - * cdef int cb_on_status(cparser.http_parser* parser, - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * cdef str reason - * try: - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":642 - * cdef HttpParser pyparser = parser.data - * cdef str reason - * try: # <<<<<<<<<<<<<< - * if length > pyparser._max_line_size: - * raise LineTooLong( - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":643 - * cdef str reason - * try: - * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) - */ - __pyx_t_5 = ((__pyx_v_length > __pyx_v_pyparser->_max_line_size) != 0); - if (unlikely(__pyx_t_5)) { - - /* "aiohttp/_http_parser.pyx":644 - * try: - * if length > pyparser._max_line_size: - * raise LineTooLong( # <<<<<<<<<<<<<< - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) - */ - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 644, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "aiohttp/_http_parser.pyx":645 - * if length > pyparser._max_line_size: - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) # <<<<<<<<<<<<<< - * extend(pyparser._buf, at, length) - * except BaseException as ex: - */ - __pyx_t_7 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_line_size); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 645, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_length); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 645, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_9 = NULL; - __pyx_t_10 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_9)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_9); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_10 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 644, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 644, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else - #endif - { - __pyx_t_11 = PyTuple_New(3+__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 644, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_11); - if (__pyx_t_9) { - __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; - } - __Pyx_INCREF(__pyx_kp_u_Status_line_is_too_long); - __Pyx_GIVEREF(__pyx_kp_u_Status_line_is_too_long); - PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, __pyx_kp_u_Status_line_is_too_long); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_11, 2+__pyx_t_10, __pyx_t_8); - __pyx_t_7 = 0; - __pyx_t_8 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 644, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - } - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 644, __pyx_L3_error) - - /* "aiohttp/_http_parser.pyx":643 - * cdef str reason - * try: - * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) - */ - } - - /* "aiohttp/_http_parser.pyx":646 - * raise LineTooLong( - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) # <<<<<<<<<<<<<< - * except BaseException as ex: - * pyparser._last_error = ex - */ - __pyx_t_1 = __pyx_v_pyparser->_buf; - __Pyx_INCREF(__pyx_t_1); - __pyx_t_6 = __pyx_f_7aiohttp_12_http_parser_extend(__pyx_t_1, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 646, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "aiohttp/_http_parser.pyx":642 - * cdef HttpParser pyparser = parser.data - * cdef str reason - * try: # <<<<<<<<<<<<<< - * if length > pyparser._max_line_size: - * raise LineTooLong( - */ - } - - /* "aiohttp/_http_parser.pyx":651 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "aiohttp/_http_parser.pyx":647 - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - __pyx_t_10 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_10) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_status", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_1, &__pyx_t_11) < 0) __PYX_ERR(0, 647, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_11); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_ex = __pyx_t_1; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":648 - * extend(pyparser._buf, at, length) - * except BaseException as ex: - * pyparser._last_error = ex # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_ex); - __Pyx_GIVEREF(__pyx_v_ex); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_ex; - - /* "aiohttp/_http_parser.pyx":649 - * except BaseException as ex: - * pyparser._last_error = ex - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - goto __pyx_L14_return; - } - - /* "aiohttp/_http_parser.pyx":647 - * 'Status line is too long', pyparser._max_line_size, length) - * extend(pyparser._buf, at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - /*finally:*/ { - __pyx_L14_return: { - __pyx_t_10 = __pyx_r; - __Pyx_DECREF(__pyx_v_ex); - __pyx_v_ex = NULL; - __pyx_r = __pyx_t_10; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":642 - * cdef HttpParser pyparser = parser.data - * cdef str reason - * try: # <<<<<<<<<<<<<< - * if length > pyparser._max_line_size: - * raise LineTooLong( - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":638 - * - * - * cdef int cb_on_status(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_status", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_ex); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":654 - * - * - * cdef int cb_on_header_field(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_field(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - Py_ssize_t __pyx_v_size; - PyObject *__pyx_v_ex = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - Py_ssize_t __pyx_t_5; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - int __pyx_t_11; - PyObject *__pyx_t_12 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_header_field", 0); - - /* "aiohttp/_http_parser.pyx":656 - * cdef int cb_on_header_field(cparser.http_parser* parser, - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * try: - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":658 - * cdef HttpParser pyparser = parser.data - * cdef Py_ssize_t size - * try: # <<<<<<<<<<<<<< - * pyparser._on_status_complete() - * size = len(pyparser._raw_name) + length - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":659 - * cdef Py_ssize_t size - * try: - * pyparser._on_status_complete() # <<<<<<<<<<<<<< - * size = len(pyparser._raw_name) + length - * if size > pyparser._max_field_size: - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_status_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 659, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":660 - * try: - * pyparser._on_status_complete() - * size = len(pyparser._raw_name) + length # <<<<<<<<<<<<<< - * if size > pyparser._max_field_size: - * raise LineTooLong( - */ - __pyx_t_1 = __pyx_v_pyparser->_raw_name; - __Pyx_INCREF(__pyx_t_1); - if (unlikely(__pyx_t_1 == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(0, 660, __pyx_L3_error) - } - __pyx_t_5 = PyByteArray_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(0, 660, __pyx_L3_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_size = (__pyx_t_5 + __pyx_v_length); - - /* "aiohttp/_http_parser.pyx":661 - * pyparser._on_status_complete() - * size = len(pyparser._raw_name) + length - * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Header name is too long', pyparser._max_field_size, size) - */ - __pyx_t_6 = ((__pyx_v_size > __pyx_v_pyparser->_max_field_size) != 0); - if (unlikely(__pyx_t_6)) { - - /* "aiohttp/_http_parser.pyx":662 - * size = len(pyparser._raw_name) + length - * if size > pyparser._max_field_size: - * raise LineTooLong( # <<<<<<<<<<<<<< - * 'Header name is too long', pyparser._max_field_size, size) - * pyparser._on_header_field(at, length) - */ - __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 662, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_7); - - /* "aiohttp/_http_parser.pyx":663 - * if size > pyparser._max_field_size: - * raise LineTooLong( - * 'Header name is too long', pyparser._max_field_size, size) # <<<<<<<<<<<<<< - * pyparser._on_header_field(at, length) - * except BaseException as ex: - */ - __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_field_size); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 663, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_size); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 663, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_10 = NULL; - __pyx_t_11 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_10)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_10); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - __pyx_t_11 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_name_is_too_long, __pyx_t_8, __pyx_t_9}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_name_is_too_long, __pyx_t_8, __pyx_t_9}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else - #endif - { - __pyx_t_12 = PyTuple_New(3+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 662, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_12); - if (__pyx_t_10) { - __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_10); __pyx_t_10 = NULL; - } - __Pyx_INCREF(__pyx_kp_u_Header_name_is_too_long); - __Pyx_GIVEREF(__pyx_kp_u_Header_name_is_too_long); - PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_11, __pyx_kp_u_Header_name_is_too_long); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_8); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_12, 2+__pyx_t_11, __pyx_t_9); - __pyx_t_8 = 0; - __pyx_t_9 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - } - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 662, __pyx_L3_error) - - /* "aiohttp/_http_parser.pyx":661 - * pyparser._on_status_complete() - * size = len(pyparser._raw_name) + length - * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Header name is too long', pyparser._max_field_size, size) - */ - } - - /* "aiohttp/_http_parser.pyx":664 - * raise LineTooLong( - * 'Header name is too long', pyparser._max_field_size, size) - * pyparser._on_header_field(at, length) # <<<<<<<<<<<<<< - * except BaseException as ex: - * pyparser._last_error = ex - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_header_field(__pyx_v_pyparser, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 664, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":658 - * cdef HttpParser pyparser = parser.data - * cdef Py_ssize_t size - * try: # <<<<<<<<<<<<<< - * pyparser._on_status_complete() - * size = len(pyparser._raw_name) + length - */ - } - - /* "aiohttp/_http_parser.pyx":669 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "aiohttp/_http_parser.pyx":665 - * 'Header name is too long', pyparser._max_field_size, size) - * pyparser._on_header_field(at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_11) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_field", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_7, &__pyx_t_12) < 0) __PYX_ERR(0, 665, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_12); - __Pyx_INCREF(__pyx_t_7); - __pyx_v_ex = __pyx_t_7; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":666 - * pyparser._on_header_field(at, length) - * except BaseException as ex: - * pyparser._last_error = ex # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_ex); - __Pyx_GIVEREF(__pyx_v_ex); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_ex; - - /* "aiohttp/_http_parser.pyx":667 - * except BaseException as ex: - * pyparser._last_error = ex - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - goto __pyx_L14_return; - } - - /* "aiohttp/_http_parser.pyx":665 - * 'Header name is too long', pyparser._max_field_size, size) - * pyparser._on_header_field(at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - /*finally:*/ { - __pyx_L14_return: { - __pyx_t_11 = __pyx_r; - __Pyx_DECREF(__pyx_v_ex); - __pyx_v_ex = NULL; - __pyx_r = __pyx_t_11; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":658 - * cdef HttpParser pyparser = parser.data - * cdef Py_ssize_t size - * try: # <<<<<<<<<<<<<< - * pyparser._on_status_complete() - * size = len(pyparser._raw_name) + length - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":654 - * - * - * cdef int cb_on_header_field(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_field", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_ex); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":672 - * - * - * cdef int cb_on_header_value(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_value(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - Py_ssize_t __pyx_v_size; - PyObject *__pyx_v_ex = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - Py_ssize_t __pyx_t_5; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - int __pyx_t_11; - PyObject *__pyx_t_12 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_header_value", 0); - - /* "aiohttp/_http_parser.pyx":674 - * cdef int cb_on_header_value(cparser.http_parser* parser, - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * cdef Py_ssize_t size - * try: - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":676 - * cdef HttpParser pyparser = parser.data - * cdef Py_ssize_t size - * try: # <<<<<<<<<<<<<< - * size = len(pyparser._raw_value) + length - * if size > pyparser._max_field_size: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":677 - * cdef Py_ssize_t size - * try: - * size = len(pyparser._raw_value) + length # <<<<<<<<<<<<<< - * if size > pyparser._max_field_size: - * raise LineTooLong( - */ - __pyx_t_1 = __pyx_v_pyparser->_raw_value; - __Pyx_INCREF(__pyx_t_1); - if (unlikely(__pyx_t_1 == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(0, 677, __pyx_L3_error) - } - __pyx_t_5 = PyByteArray_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(0, 677, __pyx_L3_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_size = (__pyx_t_5 + __pyx_v_length); - - /* "aiohttp/_http_parser.pyx":678 - * try: - * size = len(pyparser._raw_value) + length - * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Header value is too long', pyparser._max_field_size, size) - */ - __pyx_t_6 = ((__pyx_v_size > __pyx_v_pyparser->_max_field_size) != 0); - if (unlikely(__pyx_t_6)) { - - /* "aiohttp/_http_parser.pyx":679 - * size = len(pyparser._raw_value) + length - * if size > pyparser._max_field_size: - * raise LineTooLong( # <<<<<<<<<<<<<< - * 'Header value is too long', pyparser._max_field_size, size) - * pyparser._on_header_value(at, length) - */ - __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 679, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_7); - - /* "aiohttp/_http_parser.pyx":680 - * if size > pyparser._max_field_size: - * raise LineTooLong( - * 'Header value is too long', pyparser._max_field_size, size) # <<<<<<<<<<<<<< - * pyparser._on_header_value(at, length) - * except BaseException as ex: - */ - __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_field_size); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 680, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_size); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 680, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_10 = NULL; - __pyx_t_11 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_10)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_10); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - __pyx_t_11 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_value_is_too_long, __pyx_t_8, __pyx_t_9}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { - PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_value_is_too_long, __pyx_t_8, __pyx_t_9}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else - #endif - { - __pyx_t_12 = PyTuple_New(3+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 679, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_12); - if (__pyx_t_10) { - __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_10); __pyx_t_10 = NULL; - } - __Pyx_INCREF(__pyx_kp_u_Header_value_is_too_long); - __Pyx_GIVEREF(__pyx_kp_u_Header_value_is_too_long); - PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_11, __pyx_kp_u_Header_value_is_too_long); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_8); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_12, 2+__pyx_t_11, __pyx_t_9); - __pyx_t_8 = 0; - __pyx_t_9 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - } - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 679, __pyx_L3_error) - - /* "aiohttp/_http_parser.pyx":678 - * try: - * size = len(pyparser._raw_value) + length - * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< - * raise LineTooLong( - * 'Header value is too long', pyparser._max_field_size, size) - */ - } - - /* "aiohttp/_http_parser.pyx":681 - * raise LineTooLong( - * 'Header value is too long', pyparser._max_field_size, size) - * pyparser._on_header_value(at, length) # <<<<<<<<<<<<<< - * except BaseException as ex: - * pyparser._last_error = ex - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_header_value(__pyx_v_pyparser, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 681, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":676 - * cdef HttpParser pyparser = parser.data - * cdef Py_ssize_t size - * try: # <<<<<<<<<<<<<< - * size = len(pyparser._raw_value) + length - * if size > pyparser._max_field_size: - */ - } - - /* "aiohttp/_http_parser.pyx":686 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "aiohttp/_http_parser.pyx":682 - * 'Header value is too long', pyparser._max_field_size, size) - * pyparser._on_header_value(at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_11) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_value", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_7, &__pyx_t_12) < 0) __PYX_ERR(0, 682, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_12); - __Pyx_INCREF(__pyx_t_7); - __pyx_v_ex = __pyx_t_7; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":683 - * pyparser._on_header_value(at, length) - * except BaseException as ex: - * pyparser._last_error = ex # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_ex); - __Pyx_GIVEREF(__pyx_v_ex); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_ex; - - /* "aiohttp/_http_parser.pyx":684 - * except BaseException as ex: - * pyparser._last_error = ex - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - goto __pyx_L14_return; - } - - /* "aiohttp/_http_parser.pyx":682 - * 'Header value is too long', pyparser._max_field_size, size) - * pyparser._on_header_value(at, length) - * except BaseException as ex: # <<<<<<<<<<<<<< - * pyparser._last_error = ex - * return -1 - */ - /*finally:*/ { - __pyx_L14_return: { - __pyx_t_11 = __pyx_r; - __Pyx_DECREF(__pyx_v_ex); - __pyx_v_ex = NULL; - __pyx_r = __pyx_t_11; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":676 - * cdef HttpParser pyparser = parser.data - * cdef Py_ssize_t size - * try: # <<<<<<<<<<<<<< - * size = len(pyparser._raw_value) + length - * if size > pyparser._max_field_size: - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":672 - * - * - * cdef int cb_on_header_value(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_value", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_ex); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":689 - * - * - * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_headers_complete(struct http_parser *__pyx_v_parser) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_exc = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_t_7; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_headers_complete", 0); - - /* "aiohttp/_http_parser.pyx":690 - * - * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * try: - * pyparser._on_status_complete() - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":691 - * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_status_complete() - * pyparser._on_headers_complete() - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":692 - * cdef HttpParser pyparser = parser.data - * try: - * pyparser._on_status_complete() # <<<<<<<<<<<<<< - * pyparser._on_headers_complete() - * except BaseException as exc: - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_status_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 692, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":693 - * try: - * pyparser._on_status_complete() - * pyparser._on_headers_complete() # <<<<<<<<<<<<<< - * except BaseException as exc: - * pyparser._last_error = exc - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_headers_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":691 - * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_status_complete() - * pyparser._on_headers_complete() - */ - } - - /* "aiohttp/_http_parser.pyx":698 - * return -1 - * else: - * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< - * return 2 - * else: - */ - /*else:*/ { - __pyx_t_6 = (__pyx_v_pyparser->_cparser->upgrade != 0); - if (!__pyx_t_6) { - } else { - __pyx_t_5 = __pyx_t_6; - goto __pyx_L10_bool_binop_done; - } - __pyx_t_6 = ((__pyx_v_pyparser->_cparser->method == 5) != 0); - __pyx_t_5 = __pyx_t_6; - __pyx_L10_bool_binop_done:; - if (__pyx_t_5) { - - /* "aiohttp/_http_parser.pyx":699 - * else: - * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT - * return 2 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = 2; - goto __pyx_L6_except_return; - - /* "aiohttp/_http_parser.pyx":698 - * return -1 - * else: - * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< - * return 2 - * else: - */ - } - - /* "aiohttp/_http_parser.pyx":701 - * return 2 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":694 - * pyparser._on_status_complete() - * pyparser._on_headers_complete() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_7) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 694, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_8); - __Pyx_GOTREF(__pyx_t_9); - __Pyx_INCREF(__pyx_t_8); - __pyx_v_exc = __pyx_t_8; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":695 - * pyparser._on_headers_complete() - * except BaseException as exc: - * pyparser._last_error = exc # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_exc); - __Pyx_GIVEREF(__pyx_v_exc); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_exc; - - /* "aiohttp/_http_parser.pyx":696 - * except BaseException as exc: - * pyparser._last_error = exc - * return -1 # <<<<<<<<<<<<<< - * else: - * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L16_return; - } - - /* "aiohttp/_http_parser.pyx":694 - * pyparser._on_status_complete() - * pyparser._on_headers_complete() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - /*finally:*/ { - __pyx_L16_return: { - __pyx_t_7 = __pyx_r; - __Pyx_DECREF(__pyx_v_exc); - __pyx_v_exc = NULL; - __pyx_r = __pyx_t_7; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":691 - * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_status_complete() - * pyparser._on_headers_complete() - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":689 - * - * - * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_exc); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":704 - * - * - * cdef int cb_on_body(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_body = 0; - PyObject *__pyx_v_exc = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - int __pyx_t_10; - int __pyx_t_11; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; - int __pyx_t_16; - char const *__pyx_t_17; - PyObject *__pyx_t_18 = NULL; - PyObject *__pyx_t_19 = NULL; - PyObject *__pyx_t_20 = NULL; - PyObject *__pyx_t_21 = NULL; - PyObject *__pyx_t_22 = NULL; - PyObject *__pyx_t_23 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_body", 0); - - /* "aiohttp/_http_parser.pyx":706 - * cdef int cb_on_body(cparser.http_parser* parser, - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * cdef bytes body = at[:length] - * try: - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":707 - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - * cdef bytes body = at[:length] # <<<<<<<<<<<<<< - * try: - * pyparser._payload.feed_data(body, length) - */ - __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_at + 0, __pyx_v_length - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 707, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_body = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":708 - * cdef HttpParser pyparser = parser.data - * cdef bytes body = at[:length] - * try: # <<<<<<<<<<<<<< - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":709 - * cdef bytes body = at[:length] - * try: - * pyparser._payload.feed_data(body, length) # <<<<<<<<<<<<<< - * except BaseException as exc: - * if pyparser._payload_exception is not None: - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_feed_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 709, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyInt_FromSize_t(__pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 709, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = NULL; - __pyx_t_8 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_7)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_7); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_8 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_5)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_v_body, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_v_body, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 709, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_9); - if (__pyx_t_7) { - __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; - } - __Pyx_INCREF(__pyx_v_body); - __Pyx_GIVEREF(__pyx_v_body); - PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_v_body); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":708 - * cdef HttpParser pyparser = parser.data - * cdef bytes body = at[:length] - * try: # <<<<<<<<<<<<<< - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: - */ - } - - /* "aiohttp/_http_parser.pyx":718 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "aiohttp/_http_parser.pyx":710 - * try: - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: # <<<<<<<<<<<<<< - * if pyparser._payload_exception is not None: - * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) - */ - __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_8) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_body", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) __PYX_ERR(0, 710, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_9); - __Pyx_INCREF(__pyx_t_5); - __pyx_v_exc = __pyx_t_5; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":711 - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: - * if pyparser._payload_exception is not None: # <<<<<<<<<<<<<< - * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) - * else: - */ - __pyx_t_10 = (__pyx_v_pyparser->_payload_exception != Py_None); - __pyx_t_11 = (__pyx_t_10 != 0); - if (__pyx_t_11) { - - /* "aiohttp/_http_parser.pyx":712 - * except BaseException as exc: - * if pyparser._payload_exception is not None: - * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) # <<<<<<<<<<<<<< - * else: - * pyparser._payload.set_exception(exc) - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_set_exception); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 712, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_13 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_exc); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 712, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_13); - __Pyx_INCREF(__pyx_v_pyparser->_payload_exception); - __pyx_t_14 = __pyx_v_pyparser->_payload_exception; __pyx_t_15 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_14))) { - __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_14); - if (likely(__pyx_t_15)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14); - __Pyx_INCREF(__pyx_t_15); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_14, function); - } - } - __pyx_t_12 = (__pyx_t_15) ? __Pyx_PyObject_Call2Args(__pyx_t_14, __pyx_t_15, __pyx_t_13) : __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13); - __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 712, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; - __pyx_t_14 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_14)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_14); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_6 = (__pyx_t_14) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_14, __pyx_t_12) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_12); - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 712, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "aiohttp/_http_parser.pyx":711 - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: - * if pyparser._payload_exception is not None: # <<<<<<<<<<<<<< - * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) - * else: - */ - goto __pyx_L16; - } - - /* "aiohttp/_http_parser.pyx":714 - * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) - * else: - * pyparser._payload.set_exception(exc) # <<<<<<<<<<<<<< - * pyparser._payload_error = 1 - * return -1 - */ - /*else*/ { - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_set_exception); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 714, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_12 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_12)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_12); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_6 = (__pyx_t_12) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_12, __pyx_v_exc) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_exc); - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 714, __pyx_L14_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - __pyx_L16:; - - /* "aiohttp/_http_parser.pyx":715 - * else: - * pyparser._payload.set_exception(exc) - * pyparser._payload_error = 1 # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __pyx_v_pyparser->_payload_error = 1; - - /* "aiohttp/_http_parser.pyx":716 - * pyparser._payload.set_exception(exc) - * pyparser._payload_error = 1 - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L13_return; - } - - /* "aiohttp/_http_parser.pyx":710 - * try: - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: # <<<<<<<<<<<<<< - * if pyparser._payload_exception is not None: - * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) - */ - /*finally:*/ { - __pyx_L14_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20) < 0)) __Pyx_ErrFetch(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20); - __Pyx_XGOTREF(__pyx_t_18); - __Pyx_XGOTREF(__pyx_t_19); - __Pyx_XGOTREF(__pyx_t_20); - __Pyx_XGOTREF(__pyx_t_21); - __Pyx_XGOTREF(__pyx_t_22); - __Pyx_XGOTREF(__pyx_t_23); - __pyx_t_8 = __pyx_lineno; __pyx_t_16 = __pyx_clineno; __pyx_t_17 = __pyx_filename; - { - __Pyx_DECREF(__pyx_v_exc); - __pyx_v_exc = NULL; - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_21); - __Pyx_XGIVEREF(__pyx_t_22); - __Pyx_XGIVEREF(__pyx_t_23); - __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23); - } - __Pyx_XGIVEREF(__pyx_t_18); - __Pyx_XGIVEREF(__pyx_t_19); - __Pyx_XGIVEREF(__pyx_t_20); - __Pyx_ErrRestore(__pyx_t_18, __pyx_t_19, __pyx_t_20); - __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; - __pyx_lineno = __pyx_t_8; __pyx_clineno = __pyx_t_16; __pyx_filename = __pyx_t_17; - goto __pyx_L5_except_error; - } - __pyx_L13_return: { - __pyx_t_16 = __pyx_r; - __Pyx_DECREF(__pyx_v_exc); - __pyx_v_exc = NULL; - __pyx_r = __pyx_t_16; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":708 - * cdef HttpParser pyparser = parser.data - * cdef bytes body = at[:length] - * try: # <<<<<<<<<<<<<< - * pyparser._payload.feed_data(body, length) - * except BaseException as exc: - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":704 - * - * - * cdef int cb_on_body(cparser.http_parser* parser, # <<<<<<<<<<<<<< - * const char *at, size_t length) except -1: - * cdef HttpParser pyparser = parser.data - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_XDECREF(__pyx_t_13); - __Pyx_XDECREF(__pyx_t_14); - __Pyx_XDECREF(__pyx_t_15); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_body", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_body); - __Pyx_XDECREF(__pyx_v_exc); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":721 - * - * - * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_complete(struct http_parser *__pyx_v_parser) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_exc = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_message_complete", 0); - - /* "aiohttp/_http_parser.pyx":722 - * - * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * try: - * pyparser._started = False - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":723 - * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._started = False - * pyparser._on_message_complete() - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":724 - * cdef HttpParser pyparser = parser.data - * try: - * pyparser._started = False # <<<<<<<<<<<<<< - * pyparser._on_message_complete() - * except BaseException as exc: - */ - __pyx_v_pyparser->_started = 0; - - /* "aiohttp/_http_parser.pyx":725 - * try: - * pyparser._started = False - * pyparser._on_message_complete() # <<<<<<<<<<<<<< - * except BaseException as exc: - * pyparser._last_error = exc - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_message_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":723 - * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._started = False - * pyparser._on_message_complete() - */ - } - - /* "aiohttp/_http_parser.pyx":730 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":726 - * pyparser._started = False - * pyparser._on_message_complete() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_5) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_message_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 726, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_INCREF(__pyx_t_6); - __pyx_v_exc = __pyx_t_6; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":727 - * pyparser._on_message_complete() - * except BaseException as exc: - * pyparser._last_error = exc # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_exc); - __Pyx_GIVEREF(__pyx_v_exc); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_exc; - - /* "aiohttp/_http_parser.pyx":728 - * except BaseException as exc: - * pyparser._last_error = exc - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - goto __pyx_L13_return; - } - - /* "aiohttp/_http_parser.pyx":726 - * pyparser._started = False - * pyparser._on_message_complete() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - /*finally:*/ { - __pyx_L13_return: { - __pyx_t_5 = __pyx_r; - __Pyx_DECREF(__pyx_v_exc); - __pyx_v_exc = NULL; - __pyx_r = __pyx_t_5; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":723 - * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._started = False - * pyparser._on_message_complete() - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":721 - * - * - * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_message_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_exc); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":733 - * - * - * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_header(struct http_parser *__pyx_v_parser) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_exc = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_chunk_header", 0); - - /* "aiohttp/_http_parser.pyx":734 - * - * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * try: - * pyparser._on_chunk_header() - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":735 - * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_chunk_header() - * except BaseException as exc: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":736 - * cdef HttpParser pyparser = parser.data - * try: - * pyparser._on_chunk_header() # <<<<<<<<<<<<<< - * except BaseException as exc: - * pyparser._last_error = exc - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_chunk_header(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 736, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":735 - * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_chunk_header() - * except BaseException as exc: - */ - } - - /* "aiohttp/_http_parser.pyx":741 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":737 - * try: - * pyparser._on_chunk_header() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_5) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_header", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 737, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_INCREF(__pyx_t_6); - __pyx_v_exc = __pyx_t_6; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":738 - * pyparser._on_chunk_header() - * except BaseException as exc: - * pyparser._last_error = exc # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_exc); - __Pyx_GIVEREF(__pyx_v_exc); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_exc; - - /* "aiohttp/_http_parser.pyx":739 - * except BaseException as exc: - * pyparser._last_error = exc - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - goto __pyx_L13_return; - } - - /* "aiohttp/_http_parser.pyx":737 - * try: - * pyparser._on_chunk_header() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - /*finally:*/ { - __pyx_L13_return: { - __pyx_t_5 = __pyx_r; - __Pyx_DECREF(__pyx_v_exc); - __pyx_v_exc = NULL; - __pyx_r = __pyx_t_5; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":735 - * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_chunk_header() - * except BaseException as exc: - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":733 - * - * - * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_header", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_exc); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":744 - * - * - * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - -static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_complete(struct http_parser *__pyx_v_parser) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; - PyObject *__pyx_v_exc = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("cb_on_chunk_complete", 0); - - /* "aiohttp/_http_parser.pyx":745 - * - * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< - * try: - * pyparser._on_chunk_complete() - */ - __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); - __Pyx_INCREF(__pyx_t_1); - __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":746 - * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_chunk_complete() - * except BaseException as exc: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":747 - * cdef HttpParser pyparser = parser.data - * try: - * pyparser._on_chunk_complete() # <<<<<<<<<<<<<< - * except BaseException as exc: - * pyparser._last_error = exc - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_chunk_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":746 - * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_chunk_complete() - * except BaseException as exc: - */ - } - - /* "aiohttp/_http_parser.pyx":752 - * return -1 - * else: - * return 0 # <<<<<<<<<<<<<< - * - * - */ - /*else:*/ { - __pyx_r = 0; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":748 - * try: - * pyparser._on_chunk_complete() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); - if (__pyx_t_5) { - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 748, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_INCREF(__pyx_t_6); - __pyx_v_exc = __pyx_t_6; - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":749 - * pyparser._on_chunk_complete() - * except BaseException as exc: - * pyparser._last_error = exc # <<<<<<<<<<<<<< - * return -1 - * else: - */ - __Pyx_INCREF(__pyx_v_exc); - __Pyx_GIVEREF(__pyx_v_exc); - __Pyx_GOTREF(__pyx_v_pyparser->_last_error); - __Pyx_DECREF(__pyx_v_pyparser->_last_error); - __pyx_v_pyparser->_last_error = __pyx_v_exc; - - /* "aiohttp/_http_parser.pyx":750 - * except BaseException as exc: - * pyparser._last_error = exc - * return -1 # <<<<<<<<<<<<<< - * else: - * return 0 - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - goto __pyx_L13_return; - } - - /* "aiohttp/_http_parser.pyx":748 - * try: - * pyparser._on_chunk_complete() - * except BaseException as exc: # <<<<<<<<<<<<<< - * pyparser._last_error = exc - * return -1 - */ - /*finally:*/ { - __pyx_L13_return: { - __pyx_t_5 = __pyx_r; - __Pyx_DECREF(__pyx_v_exc); - __pyx_v_exc = NULL; - __pyx_r = __pyx_t_5; - goto __pyx_L6_except_return; - } - } - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "aiohttp/_http_parser.pyx":746 - * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: - * cdef HttpParser pyparser = parser.data - * try: # <<<<<<<<<<<<<< - * pyparser._on_chunk_complete() - * except BaseException as exc: - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "aiohttp/_http_parser.pyx":744 - * - * - * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< - * cdef HttpParser pyparser = parser.data - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); - __Pyx_XDECREF(__pyx_v_exc); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":755 - * - * - * cdef parser_error_from_errno(cparser.http_errno errno): # <<<<<<<<<<<<<< - * cdef bytes desc = cparser.http_errno_description(errno) - * - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum http_errno __pyx_v_errno) { - PyObject *__pyx_v_desc = 0; - PyObject *__pyx_v_cls = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("parser_error_from_errno", 0); - - /* "aiohttp/_http_parser.pyx":756 - * - * cdef parser_error_from_errno(cparser.http_errno errno): - * cdef bytes desc = cparser.http_errno_description(errno) # <<<<<<<<<<<<<< - * - * if errno in (cparser.HPE_CB_message_begin, - */ - __pyx_t_1 = __Pyx_PyBytes_FromString(http_errno_description(__pyx_v_errno)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 756, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_desc = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":758 - * cdef bytes desc = cparser.http_errno_description(errno) - * - * if errno in (cparser.HPE_CB_message_begin, # <<<<<<<<<<<<<< - * cparser.HPE_CB_url, - * cparser.HPE_CB_header_field, - */ - switch (__pyx_v_errno) { - case HPE_CB_message_begin: - case HPE_CB_url: - - /* "aiohttp/_http_parser.pyx":759 - * - * if errno in (cparser.HPE_CB_message_begin, - * cparser.HPE_CB_url, # <<<<<<<<<<<<<< - * cparser.HPE_CB_header_field, - * cparser.HPE_CB_header_value, - */ - case HPE_CB_header_field: - - /* "aiohttp/_http_parser.pyx":760 - * if errno in (cparser.HPE_CB_message_begin, - * cparser.HPE_CB_url, - * cparser.HPE_CB_header_field, # <<<<<<<<<<<<<< - * cparser.HPE_CB_header_value, - * cparser.HPE_CB_headers_complete, - */ - case HPE_CB_header_value: - - /* "aiohttp/_http_parser.pyx":761 - * cparser.HPE_CB_url, - * cparser.HPE_CB_header_field, - * cparser.HPE_CB_header_value, # <<<<<<<<<<<<<< - * cparser.HPE_CB_headers_complete, - * cparser.HPE_CB_body, - */ - case HPE_CB_headers_complete: - - /* "aiohttp/_http_parser.pyx":762 - * cparser.HPE_CB_header_field, - * cparser.HPE_CB_header_value, - * cparser.HPE_CB_headers_complete, # <<<<<<<<<<<<<< - * cparser.HPE_CB_body, - * cparser.HPE_CB_message_complete, - */ - case HPE_CB_body: - - /* "aiohttp/_http_parser.pyx":763 - * cparser.HPE_CB_header_value, - * cparser.HPE_CB_headers_complete, - * cparser.HPE_CB_body, # <<<<<<<<<<<<<< - * cparser.HPE_CB_message_complete, - * cparser.HPE_CB_status, - */ - case HPE_CB_message_complete: - - /* "aiohttp/_http_parser.pyx":764 - * cparser.HPE_CB_headers_complete, - * cparser.HPE_CB_body, - * cparser.HPE_CB_message_complete, # <<<<<<<<<<<<<< - * cparser.HPE_CB_status, - * cparser.HPE_CB_chunk_header, - */ - case HPE_CB_status: - - /* "aiohttp/_http_parser.pyx":765 - * cparser.HPE_CB_body, - * cparser.HPE_CB_message_complete, - * cparser.HPE_CB_status, # <<<<<<<<<<<<<< - * cparser.HPE_CB_chunk_header, - * cparser.HPE_CB_chunk_complete): - */ - case HPE_CB_chunk_header: - - /* "aiohttp/_http_parser.pyx":766 - * cparser.HPE_CB_message_complete, - * cparser.HPE_CB_status, - * cparser.HPE_CB_chunk_header, # <<<<<<<<<<<<<< - * cparser.HPE_CB_chunk_complete): - * cls = BadHttpMessage - */ - case HPE_CB_chunk_complete: - - /* "aiohttp/_http_parser.pyx":768 - * cparser.HPE_CB_chunk_header, - * cparser.HPE_CB_chunk_complete): - * cls = BadHttpMessage # <<<<<<<<<<<<<< - * - * elif errno == cparser.HPE_INVALID_STATUS: - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 768, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_cls = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":758 - * cdef bytes desc = cparser.http_errno_description(errno) - * - * if errno in (cparser.HPE_CB_message_begin, # <<<<<<<<<<<<<< - * cparser.HPE_CB_url, - * cparser.HPE_CB_header_field, - */ - break; - case HPE_INVALID_STATUS: - - /* "aiohttp/_http_parser.pyx":771 - * - * elif errno == cparser.HPE_INVALID_STATUS: - * cls = BadStatusLine # <<<<<<<<<<<<<< - * - * elif errno == cparser.HPE_INVALID_METHOD: - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 771, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_cls = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":770 - * cls = BadHttpMessage - * - * elif errno == cparser.HPE_INVALID_STATUS: # <<<<<<<<<<<<<< - * cls = BadStatusLine - * - */ - break; - case HPE_INVALID_METHOD: - - /* "aiohttp/_http_parser.pyx":774 - * - * elif errno == cparser.HPE_INVALID_METHOD: - * cls = BadStatusLine # <<<<<<<<<<<<<< - * - * elif errno == cparser.HPE_INVALID_URL: - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_cls = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":773 - * cls = BadStatusLine - * - * elif errno == cparser.HPE_INVALID_METHOD: # <<<<<<<<<<<<<< - * cls = BadStatusLine - * - */ - break; - case HPE_INVALID_URL: - - /* "aiohttp/_http_parser.pyx":777 - * - * elif errno == cparser.HPE_INVALID_URL: - * cls = InvalidURLError # <<<<<<<<<<<<<< - * - * else: - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 777, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_cls = __pyx_t_1; - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":776 - * cls = BadStatusLine - * - * elif errno == cparser.HPE_INVALID_URL: # <<<<<<<<<<<<<< - * cls = InvalidURLError - * - */ - break; - default: - - /* "aiohttp/_http_parser.pyx":780 - * - * else: - * cls = BadHttpMessage # <<<<<<<<<<<<<< - * - * return cls(desc.decode('latin-1')) - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_cls = __pyx_t_1; - __pyx_t_1 = 0; - break; - } - - /* "aiohttp/_http_parser.pyx":782 - * cls = BadHttpMessage - * - * return cls(desc.decode('latin-1')) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_decode_bytes(__pyx_v_desc, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeLatin1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_cls); - __pyx_t_3 = __pyx_v_cls; __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_parser.pyx":755 - * - * - * cdef parser_error_from_errno(cparser.http_errno errno): # <<<<<<<<<<<<<< - * cdef bytes desc = cparser.http_errno_description(errno) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("aiohttp._http_parser.parser_error_from_errno", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_desc); - __Pyx_XDECREF(__pyx_v_cls); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":785 - * - * - * def parse_url(url): # <<<<<<<<<<<<<< - * cdef: - * Py_buffer py_buf - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_1parse_url(PyObject *__pyx_self, PyObject *__pyx_v_url); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_1parse_url = {"parse_url", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_1parse_url, METH_O, 0}; -static PyObject *__pyx_pw_7aiohttp_12_http_parser_1parse_url(PyObject *__pyx_self, PyObject *__pyx_v_url) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("parse_url (wrapper)", 0); - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_parse_url(__pyx_self, ((PyObject *)__pyx_v_url)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_parse_url(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_url) { - Py_buffer __pyx_v_py_buf; - char *__pyx_v_buf_data; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - char const *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("parse_url", 0); - - /* "aiohttp/_http_parser.pyx":790 - * char* buf_data - * - * PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) # <<<<<<<<<<<<<< - * try: - * buf_data = py_buf.buf - */ - __pyx_t_1 = PyObject_GetBuffer(__pyx_v_url, (&__pyx_v_py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 790, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":791 - * - * PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) - * try: # <<<<<<<<<<<<<< - * buf_data = py_buf.buf - * return _parse_url(buf_data, py_buf.len) - */ - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":792 - * PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) - * try: - * buf_data = py_buf.buf # <<<<<<<<<<<<<< - * return _parse_url(buf_data, py_buf.len) - * finally: - */ - __pyx_v_buf_data = ((char *)__pyx_v_py_buf.buf); - - /* "aiohttp/_http_parser.pyx":793 - * try: - * buf_data = py_buf.buf - * return _parse_url(buf_data, py_buf.len) # <<<<<<<<<<<<<< - * finally: - * PyBuffer_Release(&py_buf) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_f_7aiohttp_12_http_parser__parse_url(__pyx_v_buf_data, __pyx_v_py_buf.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 793, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L3_return; - } - - /* "aiohttp/_http_parser.pyx":795 - * return _parse_url(buf_data, py_buf.len) - * finally: - * PyBuffer_Release(&py_buf) # <<<<<<<<<<<<<< - * - * - */ - /*finally:*/ { - __pyx_L4_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0)) __Pyx_ErrFetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_10); - __pyx_t_1 = __pyx_lineno; __pyx_t_3 = __pyx_clineno; __pyx_t_4 = __pyx_filename; - { - PyBuffer_Release((&__pyx_v_py_buf)); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_8); - __Pyx_XGIVEREF(__pyx_t_9); - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); - } - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_XGIVEREF(__pyx_t_7); - __Pyx_ErrRestore(__pyx_t_5, __pyx_t_6, __pyx_t_7); - __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; - __pyx_lineno = __pyx_t_1; __pyx_clineno = __pyx_t_3; __pyx_filename = __pyx_t_4; - goto __pyx_L1_error; - } - __pyx_L3_return: { - __pyx_t_10 = __pyx_r; - __pyx_r = 0; - PyBuffer_Release((&__pyx_v_py_buf)); - __pyx_r = __pyx_t_10; - __pyx_t_10 = 0; - goto __pyx_L0; - } - } - - /* "aiohttp/_http_parser.pyx":785 - * - * - * def parse_url(url): # <<<<<<<<<<<<<< - * cdef: - * Py_buffer py_buf - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("aiohttp._http_parser.parse_url", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_parser.pyx":798 - * - * - * cdef _parse_url(char* buf_data, size_t length): # <<<<<<<<<<<<<< - * cdef: - * cparser.http_parser_url* parsed - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_data, size_t __pyx_v_length) { - struct http_parser_url *__pyx_v_parsed; - int __pyx_v_res; - PyObject *__pyx_v_schema = 0; - PyObject *__pyx_v_host = 0; - PyObject *__pyx_v_port = 0; - PyObject *__pyx_v_path = 0; - PyObject *__pyx_v_query = 0; - PyObject *__pyx_v_fragment = 0; - PyObject *__pyx_v_user = 0; - PyObject *__pyx_v_password = 0; - PyObject *__pyx_v_userinfo = 0; - CYTHON_UNUSED PyObject *__pyx_v_result = 0; - int __pyx_v_off; - int __pyx_v_ln; - CYTHON_UNUSED PyObject *__pyx_v_sep = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - uint16_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *(*__pyx_t_8)(PyObject *); - PyObject *__pyx_t_9 = NULL; - int __pyx_t_10; - int __pyx_t_11; - char const *__pyx_t_12; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; - PyObject *__pyx_t_16 = NULL; - PyObject *__pyx_t_17 = NULL; - PyObject *__pyx_t_18 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_parse_url", 0); - - /* "aiohttp/_http_parser.pyx":802 - * cparser.http_parser_url* parsed - * int res - * str schema = None # <<<<<<<<<<<<<< - * str host = None - * object port = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_schema = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":803 - * int res - * str schema = None - * str host = None # <<<<<<<<<<<<<< - * object port = None - * str path = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_host = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":804 - * str schema = None - * str host = None - * object port = None # <<<<<<<<<<<<<< - * str path = None - * str query = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_port = Py_None; - - /* "aiohttp/_http_parser.pyx":805 - * str host = None - * object port = None - * str path = None # <<<<<<<<<<<<<< - * str query = None - * str fragment = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_path = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":806 - * object port = None - * str path = None - * str query = None # <<<<<<<<<<<<<< - * str fragment = None - * str user = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_query = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":807 - * str path = None - * str query = None - * str fragment = None # <<<<<<<<<<<<<< - * str user = None - * str password = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_fragment = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":808 - * str query = None - * str fragment = None - * str user = None # <<<<<<<<<<<<<< - * str password = None - * str userinfo = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_user = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":809 - * str fragment = None - * str user = None - * str password = None # <<<<<<<<<<<<<< - * str userinfo = None - * object result = None - */ - __Pyx_INCREF(Py_None); - __pyx_v_password = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":810 - * str user = None - * str password = None - * str userinfo = None # <<<<<<<<<<<<<< - * object result = None - * int off - */ - __Pyx_INCREF(Py_None); - __pyx_v_userinfo = ((PyObject*)Py_None); - - /* "aiohttp/_http_parser.pyx":811 - * str password = None - * str userinfo = None - * object result = None # <<<<<<<<<<<<<< - * int off - * int ln - */ - __Pyx_INCREF(Py_None); - __pyx_v_result = Py_None; - - /* "aiohttp/_http_parser.pyx":815 - * int ln - * - * parsed = \ # <<<<<<<<<<<<<< - * PyMem_Malloc(sizeof(cparser.http_parser_url)) - * if parsed is NULL: - */ - __pyx_v_parsed = ((struct http_parser_url *)PyMem_Malloc((sizeof(struct http_parser_url)))); - - /* "aiohttp/_http_parser.pyx":817 - * parsed = \ - * PyMem_Malloc(sizeof(cparser.http_parser_url)) - * if parsed is NULL: # <<<<<<<<<<<<<< - * raise MemoryError() - * cparser.http_parser_url_init(parsed) - */ - __pyx_t_1 = ((__pyx_v_parsed == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_parser.pyx":818 - * PyMem_Malloc(sizeof(cparser.http_parser_url)) - * if parsed is NULL: - * raise MemoryError() # <<<<<<<<<<<<<< - * cparser.http_parser_url_init(parsed) - * try: - */ - PyErr_NoMemory(); __PYX_ERR(0, 818, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":817 - * parsed = \ - * PyMem_Malloc(sizeof(cparser.http_parser_url)) - * if parsed is NULL: # <<<<<<<<<<<<<< - * raise MemoryError() - * cparser.http_parser_url_init(parsed) - */ - } - - /* "aiohttp/_http_parser.pyx":819 - * if parsed is NULL: - * raise MemoryError() - * cparser.http_parser_url_init(parsed) # <<<<<<<<<<<<<< - * try: - * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) - */ - http_parser_url_init(__pyx_v_parsed); - - /* "aiohttp/_http_parser.pyx":820 - * raise MemoryError() - * cparser.http_parser_url_init(parsed) - * try: # <<<<<<<<<<<<<< - * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) - * - */ - /*try:*/ { - - /* "aiohttp/_http_parser.pyx":821 - * cparser.http_parser_url_init(parsed) - * try: - * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) # <<<<<<<<<<<<<< - * - * if res == 0: - */ - __pyx_v_res = http_parser_parse_url(__pyx_v_buf_data, __pyx_v_length, 0, __pyx_v_parsed); - - /* "aiohttp/_http_parser.pyx":823 - * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) - * - * if res == 0: # <<<<<<<<<<<<<< - * if parsed.field_set & (1 << cparser.UF_SCHEMA): - * off = parsed.field_data[cparser.UF_SCHEMA].off - */ - __pyx_t_1 = ((__pyx_v_res == 0) != 0); - if (likely(__pyx_t_1)) { - - /* "aiohttp/_http_parser.pyx":824 - * - * if res == 0: - * if parsed.field_set & (1 << cparser.UF_SCHEMA): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_SCHEMA].off - * ln = parsed.field_data[cparser.UF_SCHEMA].len - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_SCHEMA)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":825 - * if res == 0: - * if parsed.field_set & (1 << cparser.UF_SCHEMA): - * off = parsed.field_data[cparser.UF_SCHEMA].off # <<<<<<<<<<<<<< - * ln = parsed.field_data[cparser.UF_SCHEMA].len - * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_SCHEMA)]).off; - __pyx_v_off = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":826 - * if parsed.field_set & (1 << cparser.UF_SCHEMA): - * off = parsed.field_data[cparser.UF_SCHEMA].off - * ln = parsed.field_data[cparser.UF_SCHEMA].len # <<<<<<<<<<<<<< - * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_SCHEMA)]).len; - __pyx_v_ln = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":827 - * off = parsed.field_data[cparser.UF_SCHEMA].off - * ln = parsed.field_data[cparser.UF_SCHEMA].len - * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * else: - * schema = '' - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 827, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_schema, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":824 - * - * if res == 0: - * if parsed.field_set & (1 << cparser.UF_SCHEMA): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_SCHEMA].off - * ln = parsed.field_data[cparser.UF_SCHEMA].len - */ - goto __pyx_L8; - } - - /* "aiohttp/_http_parser.pyx":829 - * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - * schema = '' # <<<<<<<<<<<<<< - * - * if parsed.field_set & (1 << cparser.UF_HOST): - */ - /*else*/ { - __Pyx_INCREF(__pyx_kp_u__4); - __Pyx_DECREF_SET(__pyx_v_schema, __pyx_kp_u__4); - } - __pyx_L8:; - - /* "aiohttp/_http_parser.pyx":831 - * schema = '' - * - * if parsed.field_set & (1 << cparser.UF_HOST): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_HOST].off - * ln = parsed.field_data[cparser.UF_HOST].len - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_HOST)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":832 - * - * if parsed.field_set & (1 << cparser.UF_HOST): - * off = parsed.field_data[cparser.UF_HOST].off # <<<<<<<<<<<<<< - * ln = parsed.field_data[cparser.UF_HOST].len - * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_HOST)]).off; - __pyx_v_off = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":833 - * if parsed.field_set & (1 << cparser.UF_HOST): - * off = parsed.field_data[cparser.UF_HOST].off - * ln = parsed.field_data[cparser.UF_HOST].len # <<<<<<<<<<<<<< - * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_HOST)]).len; - __pyx_v_ln = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":834 - * off = parsed.field_data[cparser.UF_HOST].off - * ln = parsed.field_data[cparser.UF_HOST].len - * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * else: - * host = '' - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 834, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_host, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":831 - * schema = '' - * - * if parsed.field_set & (1 << cparser.UF_HOST): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_HOST].off - * ln = parsed.field_data[cparser.UF_HOST].len - */ - goto __pyx_L9; - } - - /* "aiohttp/_http_parser.pyx":836 - * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - * host = '' # <<<<<<<<<<<<<< - * - * if parsed.field_set & (1 << cparser.UF_PORT): - */ - /*else*/ { - __Pyx_INCREF(__pyx_kp_u__4); - __Pyx_DECREF_SET(__pyx_v_host, __pyx_kp_u__4); - } - __pyx_L9:; - - /* "aiohttp/_http_parser.pyx":838 - * host = '' - * - * if parsed.field_set & (1 << cparser.UF_PORT): # <<<<<<<<<<<<<< - * port = parsed.port - * - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_PORT)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":839 - * - * if parsed.field_set & (1 << cparser.UF_PORT): - * port = parsed.port # <<<<<<<<<<<<<< - * - * if parsed.field_set & (1 << cparser.UF_PATH): - */ - __pyx_t_3 = __Pyx_PyInt_From_uint16_t(__pyx_v_parsed->port); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 839, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_port, __pyx_t_3); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":838 - * host = '' - * - * if parsed.field_set & (1 << cparser.UF_PORT): # <<<<<<<<<<<<<< - * port = parsed.port - * - */ - } - - /* "aiohttp/_http_parser.pyx":841 - * port = parsed.port - * - * if parsed.field_set & (1 << cparser.UF_PATH): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_PATH].off - * ln = parsed.field_data[cparser.UF_PATH].len - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_PATH)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":842 - * - * if parsed.field_set & (1 << cparser.UF_PATH): - * off = parsed.field_data[cparser.UF_PATH].off # <<<<<<<<<<<<<< - * ln = parsed.field_data[cparser.UF_PATH].len - * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_PATH)]).off; - __pyx_v_off = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":843 - * if parsed.field_set & (1 << cparser.UF_PATH): - * off = parsed.field_data[cparser.UF_PATH].off - * ln = parsed.field_data[cparser.UF_PATH].len # <<<<<<<<<<<<<< - * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_PATH)]).len; - __pyx_v_ln = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":844 - * off = parsed.field_data[cparser.UF_PATH].off - * ln = parsed.field_data[cparser.UF_PATH].len - * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * else: - * path = '' - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 844, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_path, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":841 - * port = parsed.port - * - * if parsed.field_set & (1 << cparser.UF_PATH): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_PATH].off - * ln = parsed.field_data[cparser.UF_PATH].len - */ - goto __pyx_L11; - } - - /* "aiohttp/_http_parser.pyx":846 - * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - * path = '' # <<<<<<<<<<<<<< - * - * if parsed.field_set & (1 << cparser.UF_QUERY): - */ - /*else*/ { - __Pyx_INCREF(__pyx_kp_u__4); - __Pyx_DECREF_SET(__pyx_v_path, __pyx_kp_u__4); - } - __pyx_L11:; - - /* "aiohttp/_http_parser.pyx":848 - * path = '' - * - * if parsed.field_set & (1 << cparser.UF_QUERY): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_QUERY].off - * ln = parsed.field_data[cparser.UF_QUERY].len - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_QUERY)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":849 - * - * if parsed.field_set & (1 << cparser.UF_QUERY): - * off = parsed.field_data[cparser.UF_QUERY].off # <<<<<<<<<<<<<< - * ln = parsed.field_data[cparser.UF_QUERY].len - * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_QUERY)]).off; - __pyx_v_off = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":850 - * if parsed.field_set & (1 << cparser.UF_QUERY): - * off = parsed.field_data[cparser.UF_QUERY].off - * ln = parsed.field_data[cparser.UF_QUERY].len # <<<<<<<<<<<<<< - * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_QUERY)]).len; - __pyx_v_ln = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":851 - * off = parsed.field_data[cparser.UF_QUERY].off - * ln = parsed.field_data[cparser.UF_QUERY].len - * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * else: - * query = '' - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 851, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_query, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":848 - * path = '' - * - * if parsed.field_set & (1 << cparser.UF_QUERY): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_QUERY].off - * ln = parsed.field_data[cparser.UF_QUERY].len - */ - goto __pyx_L12; - } - - /* "aiohttp/_http_parser.pyx":853 - * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - * query = '' # <<<<<<<<<<<<<< - * - * if parsed.field_set & (1 << cparser.UF_FRAGMENT): - */ - /*else*/ { - __Pyx_INCREF(__pyx_kp_u__4); - __Pyx_DECREF_SET(__pyx_v_query, __pyx_kp_u__4); - } - __pyx_L12:; - - /* "aiohttp/_http_parser.pyx":855 - * query = '' - * - * if parsed.field_set & (1 << cparser.UF_FRAGMENT): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_FRAGMENT].off - * ln = parsed.field_data[cparser.UF_FRAGMENT].len - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_FRAGMENT)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":856 - * - * if parsed.field_set & (1 << cparser.UF_FRAGMENT): - * off = parsed.field_data[cparser.UF_FRAGMENT].off # <<<<<<<<<<<<<< - * ln = parsed.field_data[cparser.UF_FRAGMENT].len - * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_FRAGMENT)]).off; - __pyx_v_off = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":857 - * if parsed.field_set & (1 << cparser.UF_FRAGMENT): - * off = parsed.field_data[cparser.UF_FRAGMENT].off - * ln = parsed.field_data[cparser.UF_FRAGMENT].len # <<<<<<<<<<<<<< - * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_FRAGMENT)]).len; - __pyx_v_ln = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":858 - * off = parsed.field_data[cparser.UF_FRAGMENT].off - * ln = parsed.field_data[cparser.UF_FRAGMENT].len - * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * else: - * fragment = '' - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 858, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_fragment, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":855 - * query = '' - * - * if parsed.field_set & (1 << cparser.UF_FRAGMENT): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_FRAGMENT].off - * ln = parsed.field_data[cparser.UF_FRAGMENT].len - */ - goto __pyx_L13; - } - - /* "aiohttp/_http_parser.pyx":860 - * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * else: - * fragment = '' # <<<<<<<<<<<<<< - * - * if parsed.field_set & (1 << cparser.UF_USERINFO): - */ - /*else*/ { - __Pyx_INCREF(__pyx_kp_u__4); - __Pyx_DECREF_SET(__pyx_v_fragment, __pyx_kp_u__4); - } - __pyx_L13:; - - /* "aiohttp/_http_parser.pyx":862 - * fragment = '' - * - * if parsed.field_set & (1 << cparser.UF_USERINFO): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_USERINFO].off - * ln = parsed.field_data[cparser.UF_USERINFO].len - */ - __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_USERINFO)) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_parser.pyx":863 - * - * if parsed.field_set & (1 << cparser.UF_USERINFO): - * off = parsed.field_data[cparser.UF_USERINFO].off # <<<<<<<<<<<<<< - * ln = parsed.field_data[cparser.UF_USERINFO].len - * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_USERINFO)]).off; - __pyx_v_off = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":864 - * if parsed.field_set & (1 << cparser.UF_USERINFO): - * off = parsed.field_data[cparser.UF_USERINFO].off - * ln = parsed.field_data[cparser.UF_USERINFO].len # <<<<<<<<<<<<<< - * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * - */ - __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_USERINFO)]).len; - __pyx_v_ln = __pyx_t_2; - - /* "aiohttp/_http_parser.pyx":865 - * off = parsed.field_data[cparser.UF_USERINFO].off - * ln = parsed.field_data[cparser.UF_USERINFO].len - * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< - * - * user, sep, password = userinfo.partition(':') - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 865, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF_SET(__pyx_v_userinfo, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "aiohttp/_http_parser.pyx":867 - * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - * - * user, sep, password = userinfo.partition(':') # <<<<<<<<<<<<<< - * - * return URL_build(scheme=schema, - */ - __pyx_t_3 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyUnicode_Type_partition, __pyx_v_userinfo, __pyx_kp_u__11); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 867, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { - PyObject* sequence = __pyx_t_3; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 3)) { - if (size > 3) __Pyx_RaiseTooManyValuesError(3); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(0, 867, __pyx_L5_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - if (likely(PyTuple_CheckExact(sequence))) { - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); - __pyx_t_6 = PyTuple_GET_ITEM(sequence, 2); - } else { - __pyx_t_4 = PyList_GET_ITEM(sequence, 0); - __pyx_t_5 = PyList_GET_ITEM(sequence, 1); - __pyx_t_6 = PyList_GET_ITEM(sequence, 2); - } - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(__pyx_t_6); - #else - __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 867, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 867, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 867, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_6); - #endif - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - Py_ssize_t index = -1; - __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 867, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext; - index = 0; __pyx_t_4 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_4)) goto __pyx_L15_unpacking_failed; - __Pyx_GOTREF(__pyx_t_4); - index = 1; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L15_unpacking_failed; - __Pyx_GOTREF(__pyx_t_5); - index = 2; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L15_unpacking_failed; - __Pyx_GOTREF(__pyx_t_6); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 3) < 0) __PYX_ERR(0, 867, __pyx_L5_error) - __pyx_t_8 = NULL; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - goto __pyx_L16_unpacking_done; - __pyx_L15_unpacking_failed:; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_8 = NULL; - if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); - __PYX_ERR(0, 867, __pyx_L5_error) - __pyx_L16_unpacking_done:; - } - if (!(likely(PyUnicode_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(0, 867, __pyx_L5_error) - if (!(likely(PyUnicode_CheckExact(__pyx_t_6))||((__pyx_t_6) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_6)->tp_name), 0))) __PYX_ERR(0, 867, __pyx_L5_error) - __Pyx_DECREF_SET(__pyx_v_user, ((PyObject*)__pyx_t_4)); - __pyx_t_4 = 0; - __pyx_v_sep = __pyx_t_5; - __pyx_t_5 = 0; - __Pyx_DECREF_SET(__pyx_v_password, ((PyObject*)__pyx_t_6)); - __pyx_t_6 = 0; - - /* "aiohttp/_http_parser.pyx":862 - * fragment = '' - * - * if parsed.field_set & (1 << cparser.UF_USERINFO): # <<<<<<<<<<<<<< - * off = parsed.field_data[cparser.UF_USERINFO].off - * ln = parsed.field_data[cparser.UF_USERINFO].len - */ - } - - /* "aiohttp/_http_parser.pyx":869 - * user, sep, password = userinfo.partition(':') - * - * return URL_build(scheme=schema, # <<<<<<<<<<<<<< - * user=user, password=password, host=host, port=port, - * path=path, query_string=query, fragment=fragment, encoded=True) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = __Pyx_PyDict_NewPresized(9); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 869, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_scheme, __pyx_v_schema) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - - /* "aiohttp/_http_parser.pyx":870 - * - * return URL_build(scheme=schema, - * user=user, password=password, host=host, port=port, # <<<<<<<<<<<<<< - * path=path, query_string=query, fragment=fragment, encoded=True) - * else: - */ - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_user, __pyx_v_user) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_password, __pyx_v_password) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_host, __pyx_v_host) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_port, __pyx_v_port) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - - /* "aiohttp/_http_parser.pyx":871 - * return URL_build(scheme=schema, - * user=user, password=password, host=host, port=port, - * path=path, query_string=query, fragment=fragment, encoded=True) # <<<<<<<<<<<<<< - * else: - * raise InvalidURLError("invalid url {!r}".format(buf_data)) - */ - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_path, __pyx_v_path) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_query_string, __pyx_v_query) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fragment, __pyx_v_fragment) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_encoded, Py_True) < 0) __PYX_ERR(0, 869, __pyx_L5_error) - - /* "aiohttp/_http_parser.pyx":869 - * user, sep, password = userinfo.partition(':') - * - * return URL_build(scheme=schema, # <<<<<<<<<<<<<< - * user=user, password=password, host=host, port=port, - * path=path, query_string=query, fragment=fragment, encoded=True) - */ - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_v_7aiohttp_12_http_parser_URL_build, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 869, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L4_return; - - /* "aiohttp/_http_parser.pyx":823 - * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) - * - * if res == 0: # <<<<<<<<<<<<<< - * if parsed.field_set & (1 << cparser.UF_SCHEMA): - * off = parsed.field_data[cparser.UF_SCHEMA].off - */ - } - - /* "aiohttp/_http_parser.pyx":873 - * path=path, query_string=query, fragment=fragment, encoded=True) - * else: - * raise InvalidURLError("invalid url {!r}".format(buf_data)) # <<<<<<<<<<<<<< - * finally: - * PyMem_Free(parsed) - */ - /*else*/ { - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 873, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_invalid_url_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 873, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyBytes_FromString(__pyx_v_buf_data); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 873, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_9 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_9)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_9); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_5 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_9, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 873, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_6 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 873, __pyx_L5_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(0, 873, __pyx_L5_error) - } - } - - /* "aiohttp/_http_parser.pyx":875 - * raise InvalidURLError("invalid url {!r}".format(buf_data)) - * finally: - * PyMem_Free(parsed) # <<<<<<<<<<<<<< - */ - /*finally:*/ { - __pyx_L5_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_16, &__pyx_t_17, &__pyx_t_18); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15) < 0)) __Pyx_ErrFetch(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_13); - __Pyx_XGOTREF(__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_16); - __Pyx_XGOTREF(__pyx_t_17); - __Pyx_XGOTREF(__pyx_t_18); - __pyx_t_10 = __pyx_lineno; __pyx_t_11 = __pyx_clineno; __pyx_t_12 = __pyx_filename; - { - PyMem_Free(__pyx_v_parsed); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_XGIVEREF(__pyx_t_18); - __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18); - } - __Pyx_XGIVEREF(__pyx_t_13); - __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_ErrRestore(__pyx_t_13, __pyx_t_14, __pyx_t_15); - __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; - __pyx_lineno = __pyx_t_10; __pyx_clineno = __pyx_t_11; __pyx_filename = __pyx_t_12; - goto __pyx_L1_error; - } - __pyx_L4_return: { - __pyx_t_18 = __pyx_r; - __pyx_r = 0; - PyMem_Free(__pyx_v_parsed); - __pyx_r = __pyx_t_18; - __pyx_t_18 = 0; - goto __pyx_L0; - } - } - - /* "aiohttp/_http_parser.pyx":798 - * - * - * cdef _parse_url(char* buf_data, size_t length): # <<<<<<<<<<<<<< - * cdef: - * cparser.http_parser_url* parsed - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("aiohttp._http_parser._parse_url", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_schema); - __Pyx_XDECREF(__pyx_v_host); - __Pyx_XDECREF(__pyx_v_port); - __Pyx_XDECREF(__pyx_v_path); - __Pyx_XDECREF(__pyx_v_query); - __Pyx_XDECREF(__pyx_v_fragment); - __Pyx_XDECREF(__pyx_v_user); - __Pyx_XDECREF(__pyx_v_password); - __Pyx_XDECREF(__pyx_v_userinfo); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_sep); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage = {"__pyx_unpickle_RawRequestMessage", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawRequestMessage", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawRequestMessage", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_RawRequestMessage") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawRequestMessage", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMessage(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMessage(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage", 0); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0x1408252: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) - */ - __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x1408252) != 0); - if (__pyx_t_1) { - - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum != 0x1408252: - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) - * __pyx_result = RawRequestMessage.__new__(__pyx_type) - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_2); - __pyx_v___pyx_PickleError = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":6 - * if __pyx_checksum != 0x1408252: - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) # <<<<<<<<<<<<<< - * __pyx_result = RawRequestMessage.__new__(__pyx_type) - * if __pyx_state is not None: - */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x14, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_v___pyx_PickleError); - __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 6, __pyx_L1_error) - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0x1408252: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) - */ - } - - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) - * __pyx_result = RawRequestMessage.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v___pyx_result = __pyx_t_3; - __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) - * __pyx_result = RawRequestMessage.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_6 = (__pyx_t_1 != 0); - if (__pyx_t_6) { - - /* "(tree fragment)":9 - * __pyx_result = RawRequestMessage.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) - * __pyx_result = RawRequestMessage.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - } - - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; - goto __pyx_L0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":11 - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage__set_state", 0); - - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[10]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->chunked); - __Pyx_DECREF(__pyx_v___pyx_result->chunked); - __pyx_v___pyx_result->chunked = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->compression); - __Pyx_DECREF(__pyx_v___pyx_result->compression); - __pyx_v___pyx_result->compression = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->headers); - __Pyx_DECREF(__pyx_v___pyx_result->headers); - __pyx_v___pyx_result->headers = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->method); - __Pyx_DECREF(__pyx_v___pyx_result->method); - __pyx_v___pyx_result->method = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->path); - __Pyx_DECREF(__pyx_v___pyx_result->path); - __pyx_v___pyx_result->path = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->raw_headers); - __Pyx_DECREF(__pyx_v___pyx_result->raw_headers); - __pyx_v___pyx_result->raw_headers = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->should_close); - __Pyx_DECREF(__pyx_v___pyx_result->should_close); - __pyx_v___pyx_result->should_close = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->upgrade); - __Pyx_DECREF(__pyx_v___pyx_result->upgrade); - __pyx_v___pyx_result->upgrade = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->url); - __Pyx_DECREF(__pyx_v___pyx_result->url); - __pyx_v___pyx_result->url = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->version); - __Pyx_DECREF(__pyx_v___pyx_result->version); - __pyx_v___pyx_result->version = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[10]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 13, __pyx_L1_error) - } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_4 = ((__pyx_t_3 > 10) != 0); - if (__pyx_t_4) { - } else { - __pyx_t_2 = __pyx_t_4; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_5 = (__pyx_t_4 != 0); - __pyx_t_2 = __pyx_t_5; - __pyx_L4_bool_binop_done:; - if (__pyx_t_2) { - - /* "(tree fragment)":14 - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[10]) # <<<<<<<<<<<<<< - */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 14, __pyx_L1_error) - } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 10, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_8)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_8); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[10]) - */ - } - - /* "(tree fragment)":11 - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage = {"__pyx_unpickle_RawResponseMessage", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawResponseMessage", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawResponseMessage", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_RawResponseMessage") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawResponseMessage", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMessage(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMessage(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage", 0); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0xc7706dc: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) - */ - __pyx_t_1 = ((__pyx_v___pyx_checksum != 0xc7706dc) != 0); - if (__pyx_t_1) { - - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum != 0xc7706dc: - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) - * __pyx_result = RawResponseMessage.__new__(__pyx_type) - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_2); - __pyx_v___pyx_PickleError = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":6 - * if __pyx_checksum != 0xc7706dc: - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) # <<<<<<<<<<<<<< - * __pyx_result = RawResponseMessage.__new__(__pyx_type) - * if __pyx_state is not None: - */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0xc7, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_v___pyx_PickleError); - __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 6, __pyx_L1_error) - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0xc7706dc: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) - */ - } - - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) - * __pyx_result = RawResponseMessage.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v___pyx_result = __pyx_t_3; - __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) - * __pyx_result = RawResponseMessage.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_6 = (__pyx_t_1 != 0); - if (__pyx_t_6) { - - /* "(tree fragment)":9 - * __pyx_result = RawResponseMessage.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) - * __pyx_result = RawResponseMessage.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - } - - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; - goto __pyx_L0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":11 - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] - * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): - */ - -static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - Py_ssize_t __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage__set_state", 0); - - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[9]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->chunked); - __Pyx_DECREF(__pyx_v___pyx_result->chunked); - __pyx_v___pyx_result->chunked = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v___pyx_result->code = __pyx_t_2; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->compression); - __Pyx_DECREF(__pyx_v___pyx_result->compression); - __pyx_v___pyx_result->compression = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->headers); - __Pyx_DECREF(__pyx_v___pyx_result->headers); - __pyx_v___pyx_result->headers = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->raw_headers); - __Pyx_DECREF(__pyx_v___pyx_result->raw_headers); - __pyx_v___pyx_result->raw_headers = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->reason); - __Pyx_DECREF(__pyx_v___pyx_result->reason); - __pyx_v___pyx_result->reason = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->should_close); - __Pyx_DECREF(__pyx_v___pyx_result->should_close); - __pyx_v___pyx_result->should_close = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->upgrade); - __Pyx_DECREF(__pyx_v___pyx_result->upgrade); - __pyx_v___pyx_result->upgrade = __pyx_t_1; - __pyx_t_1 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->version); - __Pyx_DECREF(__pyx_v___pyx_result->version); - __pyx_v___pyx_result->version = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] - * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[9]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 13, __pyx_L1_error) - } - __pyx_t_4 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_5 = ((__pyx_t_4 > 9) != 0); - if (__pyx_t_5) { - } else { - __pyx_t_3 = __pyx_t_5; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_5 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_6 = (__pyx_t_5 != 0); - __pyx_t_3 = __pyx_t_6; - __pyx_L4_bool_binop_done:; - if (__pyx_t_3) { - - /* "(tree fragment)":14 - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] - * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[9]) # <<<<<<<<<<<<<< - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_update); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 14, __pyx_L1_error) - } - __pyx_t_7 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_9 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_8))) { - __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8); - if (likely(__pyx_t_9)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8); - __Pyx_INCREF(__pyx_t_9); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_8, function); - } - } - __pyx_t_1 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_9, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] - * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[9]) - */ - } - - /* "(tree fragment)":11 - * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] - * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_freelist_7aiohttp_12_http_parser_RawRequestMessage[250]; -static int __pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage = 0; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_RawRequestMessage(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p; - PyObject *o; - if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage)) & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { - o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser_RawRequestMessage[--__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage]; - memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage)); - (void) PyObject_INIT(o, t); - PyObject_GC_Track(o); - } else { - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - } - p = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o); - p->method = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->path = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->version = Py_None; Py_INCREF(Py_None); - p->headers = Py_None; Py_INCREF(Py_None); - p->raw_headers = Py_None; Py_INCREF(Py_None); - p->should_close = Py_None; Py_INCREF(Py_None); - p->compression = Py_None; Py_INCREF(Py_None); - p->upgrade = Py_None; Py_INCREF(Py_None); - p->chunked = Py_None; Py_INCREF(Py_None); - p->url = Py_None; Py_INCREF(Py_None); - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser_RawRequestMessage(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->method); - Py_CLEAR(p->path); - Py_CLEAR(p->version); - Py_CLEAR(p->headers); - Py_CLEAR(p->raw_headers); - Py_CLEAR(p->should_close); - Py_CLEAR(p->compression); - Py_CLEAR(p->upgrade); - Py_CLEAR(p->chunked); - Py_CLEAR(p->url); - if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage < 250) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage)) & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { - __pyx_freelist_7aiohttp_12_http_parser_RawRequestMessage[__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage++] = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o); - } else { - (*Py_TYPE(o)->tp_free)(o); - } -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser_RawRequestMessage(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o; - if (p->version) { - e = (*v)(p->version, a); if (e) return e; - } - if (p->headers) { - e = (*v)(p->headers, a); if (e) return e; - } - if (p->raw_headers) { - e = (*v)(p->raw_headers, a); if (e) return e; - } - if (p->should_close) { - e = (*v)(p->should_close, a); if (e) return e; - } - if (p->compression) { - e = (*v)(p->compression, a); if (e) return e; - } - if (p->upgrade) { - e = (*v)(p->upgrade, a); if (e) return e; - } - if (p->chunked) { - e = (*v)(p->chunked, a); if (e) return e; - } - if (p->url) { - e = (*v)(p->url, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_12_http_parser_RawRequestMessage(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o; - tmp = ((PyObject*)p->version); - p->version = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->headers); - p->headers = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->raw_headers); - p->raw_headers = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->should_close); - p->should_close = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->compression); - p->compression = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->upgrade); - p->upgrade = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->chunked); - p->chunked = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->url); - p->url = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_method(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_6method_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_path(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_4path_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_version(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7version_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_headers(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7headers_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_raw_headers(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_should_close(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_12should_close_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_compression(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11compression_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_upgrade(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_chunked(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7chunked_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_url(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3url_1__get__(o); -} - -static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_RawRequestMessage[] = { - {"_replace", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace, METH_VARARGS|METH_KEYWORDS, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7aiohttp_12_http_parser_RawRequestMessage[] = { - {(char *)"method", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_method, 0, (char *)0, 0}, - {(char *)"path", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_path, 0, (char *)0, 0}, - {(char *)"version", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_version, 0, (char *)0, 0}, - {(char *)"headers", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_headers, 0, (char *)0, 0}, - {(char *)"raw_headers", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_raw_headers, 0, (char *)0, 0}, - {(char *)"should_close", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_should_close, 0, (char *)0, 0}, - {(char *)"compression", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_compression, 0, (char *)0, 0}, - {(char *)"upgrade", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_upgrade, 0, (char *)0, 0}, - {(char *)"chunked", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_chunked, 0, (char *)0, 0}, - {(char *)"url", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_url, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser_RawRequestMessage = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.RawRequestMessage", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser_RawRequestMessage, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3__repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser_RawRequestMessage, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser_RawRequestMessage, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_12_http_parser_RawRequestMessage, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7aiohttp_12_http_parser_RawRequestMessage, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_1__init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser_RawRequestMessage, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_freelist_7aiohttp_12_http_parser_RawResponseMessage[250]; -static int __pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage = 0; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_RawResponseMessage(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p; - PyObject *o; - if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage)) & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { - o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser_RawResponseMessage[--__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage]; - memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage)); - (void) PyObject_INIT(o, t); - PyObject_GC_Track(o); - } else { - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - } - p = ((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o); - p->version = Py_None; Py_INCREF(Py_None); - p->reason = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->headers = Py_None; Py_INCREF(Py_None); - p->raw_headers = Py_None; Py_INCREF(Py_None); - p->should_close = Py_None; Py_INCREF(Py_None); - p->compression = Py_None; Py_INCREF(Py_None); - p->upgrade = Py_None; Py_INCREF(Py_None); - p->chunked = Py_None; Py_INCREF(Py_None); - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser_RawResponseMessage(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->version); - Py_CLEAR(p->reason); - Py_CLEAR(p->headers); - Py_CLEAR(p->raw_headers); - Py_CLEAR(p->should_close); - Py_CLEAR(p->compression); - Py_CLEAR(p->upgrade); - Py_CLEAR(p->chunked); - if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage < 250) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage)) & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { - __pyx_freelist_7aiohttp_12_http_parser_RawResponseMessage[__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage++] = ((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o); - } else { - (*Py_TYPE(o)->tp_free)(o); - } -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser_RawResponseMessage(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o; - if (p->version) { - e = (*v)(p->version, a); if (e) return e; - } - if (p->headers) { - e = (*v)(p->headers, a); if (e) return e; - } - if (p->raw_headers) { - e = (*v)(p->raw_headers, a); if (e) return e; - } - if (p->should_close) { - e = (*v)(p->should_close, a); if (e) return e; - } - if (p->compression) { - e = (*v)(p->compression, a); if (e) return e; - } - if (p->upgrade) { - e = (*v)(p->upgrade, a); if (e) return e; - } - if (p->chunked) { - e = (*v)(p->chunked, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_12_http_parser_RawResponseMessage(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o; - tmp = ((PyObject*)p->version); - p->version = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->headers); - p->headers = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->raw_headers); - p->raw_headers = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->should_close); - p->should_close = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->compression); - p->compression = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->upgrade); - p->upgrade = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->chunked); - p->chunked = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_version(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7version_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_code(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_4code_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_reason(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_6reason_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_headers(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7headers_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_raw_headers(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_should_close(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_12should_close_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_compression(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11compression_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_upgrade(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade_1__get__(o); -} - -static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_chunked(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_1__get__(o); -} - -static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_RawResponseMessage[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7aiohttp_12_http_parser_RawResponseMessage[] = { - {(char *)"version", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_version, 0, (char *)0, 0}, - {(char *)"code", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_code, 0, (char *)0, 0}, - {(char *)"reason", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_reason, 0, (char *)0, 0}, - {(char *)"headers", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_headers, 0, (char *)0, 0}, - {(char *)"raw_headers", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_raw_headers, 0, (char *)0, 0}, - {(char *)"should_close", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_should_close, 0, (char *)0, 0}, - {(char *)"compression", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_compression, 0, (char *)0, 0}, - {(char *)"upgrade", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_upgrade, 0, (char *)0, 0}, - {(char *)"chunked", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_chunked, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser_RawResponseMessage = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.RawResponseMessage", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser_RawResponseMessage, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_3__repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser_RawResponseMessage, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser_RawResponseMessage, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_12_http_parser_RawResponseMessage, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7aiohttp_12_http_parser_RawResponseMessage, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_1__init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser_RawResponseMessage, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; -static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser __pyx_vtable_7aiohttp_12_http_parser_HttpParser; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_HttpParser(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o); - p->__pyx_vtab = __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; - p->_raw_name = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_raw_value = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_protocol = Py_None; Py_INCREF(Py_None); - p->_loop = Py_None; Py_INCREF(Py_None); - p->_timer = Py_None; Py_INCREF(Py_None); - p->_url = Py_None; Py_INCREF(Py_None); - p->_buf = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_path = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_reason = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_headers = Py_None; Py_INCREF(Py_None); - p->_raw_headers = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_messages = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_payload = Py_None; Py_INCREF(Py_None); - p->_payload_exception = Py_None; Py_INCREF(Py_None); - p->_last_error = Py_None; Py_INCREF(Py_None); - p->_content_encoding = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->py_buf.obj = NULL; - if (unlikely(__pyx_pw_7aiohttp_12_http_parser_10HttpParser_1__cinit__(o, __pyx_empty_tuple, NULL) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p = (struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_pw_7aiohttp_12_http_parser_10HttpParser_3__dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->_raw_name); - Py_CLEAR(p->_raw_value); - Py_CLEAR(p->_protocol); - Py_CLEAR(p->_loop); - Py_CLEAR(p->_timer); - Py_CLEAR(p->_url); - Py_CLEAR(p->_buf); - Py_CLEAR(p->_path); - Py_CLEAR(p->_reason); - Py_CLEAR(p->_headers); - Py_CLEAR(p->_raw_headers); - Py_CLEAR(p->_messages); - Py_CLEAR(p->_payload); - Py_CLEAR(p->_payload_exception); - Py_CLEAR(p->_last_error); - Py_CLEAR(p->_content_encoding); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p = (struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o; - if (p->_protocol) { - e = (*v)(p->_protocol, a); if (e) return e; - } - if (p->_loop) { - e = (*v)(p->_loop, a); if (e) return e; - } - if (p->_timer) { - e = (*v)(p->_timer, a); if (e) return e; - } - if (p->_url) { - e = (*v)(p->_url, a); if (e) return e; - } - if (p->_headers) { - e = (*v)(p->_headers, a); if (e) return e; - } - if (p->_raw_headers) { - e = (*v)(p->_raw_headers, a); if (e) return e; - } - if (p->_messages) { - e = (*v)(p->_messages, a); if (e) return e; - } - if (p->_payload) { - e = (*v)(p->_payload, a); if (e) return e; - } - if (p->_payload_exception) { - e = (*v)(p->_payload_exception, a); if (e) return e; - } - if (p->_last_error) { - e = (*v)(p->_last_error, a); if (e) return e; - } - if (p->py_buf.obj) { - e = (*v)(p->py_buf.obj, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p = (struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o; - tmp = ((PyObject*)p->_protocol); - p->_protocol = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_loop); - p->_loop = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_timer); - p->_timer = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_url); - p->_url = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_headers); - p->_headers = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_raw_headers); - p->_raw_headers = ((PyObject*)Py_None); Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_messages); - p->_messages = ((PyObject*)Py_None); Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_payload); - p->_payload = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_payload_exception); - p->_payload_exception = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_last_error); - p->_last_error = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - Py_CLEAR(p->py_buf.obj); - return 0; -} - -static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_HttpParser[] = { - {"feed_eof", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_5feed_eof, METH_NOARGS, 0}, - {"feed_data", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_7feed_data, METH_O, 0}, - {"set_upgraded", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_9set_upgraded, METH_O, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_11__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_13__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser_HttpParser = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.HttpParser", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_12_http_parser_HttpParser, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser_HttpParser, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; -static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser __pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_HttpRequestParser(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *p; - PyObject *o = __pyx_tp_new_7aiohttp_12_http_parser_HttpParser(t, a, k); - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)o); - p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser*)__pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser; - return o; -} - -static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_HttpRequestParser[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_3__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_5__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser_HttpRequestParser = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.HttpRequestParser", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_12_http_parser_HttpRequestParser, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_1__init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser_HttpRequestParser, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; -static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser __pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_HttpResponseParser(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *p; - PyObject *o = __pyx_tp_new_7aiohttp_12_http_parser_HttpParser(t, a, k); - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)o); - p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser*)__pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser; - return o; -} - -static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_HttpResponseParser[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_3__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_5__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser_HttpResponseParser = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.HttpResponseParser", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7aiohttp_12_http_parser_HttpResponseParser, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_1__init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser_HttpResponseParser, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct____repr__[8]; -static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = 0; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - PyObject *o; - if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__)))) { - o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct____repr__[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__]; - memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__)); - (void) PyObject_INIT(o, t); - PyObject_GC_Track(o); - } else { - o = (*t->tp_alloc)(t, 0); - if (unlikely(!o)) return 0; - } - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o; - PyObject_GC_UnTrack(o); - Py_CLEAR(p->__pyx_v_info); - if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__)))) { - __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct____repr__[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o); - } else { - (*Py_TYPE(o)->tp_free)(o); - } -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o; - if (p->__pyx_v_info) { - e = (*v)(p->__pyx_v_info, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o; - tmp = ((PyObject*)p->__pyx_v_info); - p->__pyx_v_info = ((PyObject*)Py_None); Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.__pyx_scope_struct____repr__", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr[8]; -static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = 0; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - PyObject *o; - if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr)))) { - o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr]; - memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr)); - (void) PyObject_INIT(o, t); - PyObject_GC_Track(o); - } else { - o = (*t->tp_alloc)(t, 0); - if (unlikely(!o)) return 0; - } - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)o; - PyObject_GC_UnTrack(o); - Py_CLEAR(p->__pyx_outer_scope); - Py_CLEAR(p->__pyx_v_name); - Py_CLEAR(p->__pyx_v_val); - if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr)))) { - __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)o); - } else { - (*Py_TYPE(o)->tp_free)(o); - } -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)o; - if (p->__pyx_outer_scope) { - e = (*v)(((PyObject *)p->__pyx_outer_scope), a); if (e) return e; - } - if (p->__pyx_v_name) { - e = (*v)(p->__pyx_v_name, a); if (e) return e; - } - if (p->__pyx_v_val) { - e = (*v)(p->__pyx_v_val, a); if (e) return e; - } - return 0; -} - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.__pyx_scope_struct_1_genexpr", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__[8]; -static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = 0; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - PyObject *o; - if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__)))) { - o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__]; - memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__)); - (void) PyObject_INIT(o, t); - PyObject_GC_Track(o); - } else { - o = (*t->tp_alloc)(t, 0); - if (unlikely(!o)) return 0; - } - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o; - PyObject_GC_UnTrack(o); - Py_CLEAR(p->__pyx_v_info); - if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__)))) { - __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o); - } else { - (*Py_TYPE(o)->tp_free)(o); - } -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o; - if (p->__pyx_v_info) { - e = (*v)(p->__pyx_v_info, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o; - tmp = ((PyObject*)p->__pyx_v_info); - p->__pyx_v_info = ((PyObject*)Py_None); Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.__pyx_scope_struct_2___repr__", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_traverse*/ - __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr[8]; -static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = 0; - -static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - PyObject *o; - if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr)))) { - o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr]; - memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr)); - (void) PyObject_INIT(o, t); - PyObject_GC_Track(o); - } else { - o = (*t->tp_alloc)(t, 0); - if (unlikely(!o)) return 0; - } - return o; -} - -static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(PyObject *o) { - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)o; - PyObject_GC_UnTrack(o); - Py_CLEAR(p->__pyx_outer_scope); - Py_CLEAR(p->__pyx_v_name); - Py_CLEAR(p->__pyx_v_val); - if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr)))) { - __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)o); - } else { - (*Py_TYPE(o)->tp_free)(o); - } -} - -static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)o; - if (p->__pyx_outer_scope) { - e = (*v)(((PyObject *)p->__pyx_outer_scope), a); if (e) return e; - } - if (p->__pyx_v_name) { - e = (*v)(p->__pyx_v_name, a); if (e) return e; - } - if (p->__pyx_v_val) { - e = (*v)(p->__pyx_v_val, a); if (e) return e; - } - return 0; -} - -static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = { - PyVarObject_HEAD_INIT(0, 0) - "aiohttp._http_parser.__pyx_scope_struct_3_genexpr", /*tp_name*/ - sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__http_parser(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__http_parser}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "_http_parser", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0}, - {&__pyx_n_s_ACCEPT, __pyx_k_ACCEPT, sizeof(__pyx_k_ACCEPT), 0, 0, 1, 1}, - {&__pyx_n_s_ACCEPT_CHARSET, __pyx_k_ACCEPT_CHARSET, sizeof(__pyx_k_ACCEPT_CHARSET), 0, 0, 1, 1}, - {&__pyx_n_s_ACCEPT_ENCODING, __pyx_k_ACCEPT_ENCODING, sizeof(__pyx_k_ACCEPT_ENCODING), 0, 0, 1, 1}, - {&__pyx_n_s_ACCEPT_LANGUAGE, __pyx_k_ACCEPT_LANGUAGE, sizeof(__pyx_k_ACCEPT_LANGUAGE), 0, 0, 1, 1}, - {&__pyx_n_s_ACCEPT_RANGES, __pyx_k_ACCEPT_RANGES, sizeof(__pyx_k_ACCEPT_RANGES), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_ALLOW_CREDENTIALS, __pyx_k_ACCESS_CONTROL_ALLOW_CREDENTIALS, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_CREDENTIALS), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_ALLOW_HEADERS, __pyx_k_ACCESS_CONTROL_ALLOW_HEADERS, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_HEADERS), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_ALLOW_METHODS, __pyx_k_ACCESS_CONTROL_ALLOW_METHODS, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_METHODS), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_ALLOW_ORIGIN, __pyx_k_ACCESS_CONTROL_ALLOW_ORIGIN, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_ORIGIN), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_EXPOSE_HEADERS, __pyx_k_ACCESS_CONTROL_EXPOSE_HEADERS, sizeof(__pyx_k_ACCESS_CONTROL_EXPOSE_HEADERS), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_MAX_AGE, __pyx_k_ACCESS_CONTROL_MAX_AGE, sizeof(__pyx_k_ACCESS_CONTROL_MAX_AGE), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_REQUEST_HEADERS, __pyx_k_ACCESS_CONTROL_REQUEST_HEADERS, sizeof(__pyx_k_ACCESS_CONTROL_REQUEST_HEADERS), 0, 0, 1, 1}, - {&__pyx_n_s_ACCESS_CONTROL_REQUEST_METHOD, __pyx_k_ACCESS_CONTROL_REQUEST_METHOD, sizeof(__pyx_k_ACCESS_CONTROL_REQUEST_METHOD), 0, 0, 1, 1}, - {&__pyx_n_s_AGE, __pyx_k_AGE, sizeof(__pyx_k_AGE), 0, 0, 1, 1}, - {&__pyx_n_s_ALLOW, __pyx_k_ALLOW, sizeof(__pyx_k_ALLOW), 0, 0, 1, 1}, - {&__pyx_n_s_AUTHORIZATION, __pyx_k_AUTHORIZATION, sizeof(__pyx_k_AUTHORIZATION), 0, 0, 1, 1}, - {&__pyx_n_s_BadHttpMessage, __pyx_k_BadHttpMessage, sizeof(__pyx_k_BadHttpMessage), 0, 0, 1, 1}, - {&__pyx_n_s_BadStatusLine, __pyx_k_BadStatusLine, sizeof(__pyx_k_BadStatusLine), 0, 0, 1, 1}, - {&__pyx_n_s_BaseException, __pyx_k_BaseException, sizeof(__pyx_k_BaseException), 0, 0, 1, 1}, - {&__pyx_n_s_CACHE_CONTROL, __pyx_k_CACHE_CONTROL, sizeof(__pyx_k_CACHE_CONTROL), 0, 0, 1, 1}, - {&__pyx_n_s_CIMultiDict, __pyx_k_CIMultiDict, sizeof(__pyx_k_CIMultiDict), 0, 0, 1, 1}, - {&__pyx_n_s_CIMultiDictProxy, __pyx_k_CIMultiDictProxy, sizeof(__pyx_k_CIMultiDictProxy), 0, 0, 1, 1}, - {&__pyx_n_s_CIMultiDictProxy_2, __pyx_k_CIMultiDictProxy_2, sizeof(__pyx_k_CIMultiDictProxy_2), 0, 0, 1, 1}, - {&__pyx_n_s_CIMultiDict_2, __pyx_k_CIMultiDict_2, sizeof(__pyx_k_CIMultiDict_2), 0, 0, 1, 1}, - {&__pyx_n_s_CONNECTION, __pyx_k_CONNECTION, sizeof(__pyx_k_CONNECTION), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_DISPOSITION, __pyx_k_CONTENT_DISPOSITION, sizeof(__pyx_k_CONTENT_DISPOSITION), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_ENCODING, __pyx_k_CONTENT_ENCODING, sizeof(__pyx_k_CONTENT_ENCODING), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_LANGUAGE, __pyx_k_CONTENT_LANGUAGE, sizeof(__pyx_k_CONTENT_LANGUAGE), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_LENGTH, __pyx_k_CONTENT_LENGTH, sizeof(__pyx_k_CONTENT_LENGTH), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_LOCATION, __pyx_k_CONTENT_LOCATION, sizeof(__pyx_k_CONTENT_LOCATION), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_MD5, __pyx_k_CONTENT_MD5, sizeof(__pyx_k_CONTENT_MD5), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_RANGE, __pyx_k_CONTENT_RANGE, sizeof(__pyx_k_CONTENT_RANGE), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_TRANSFER_ENCODING, __pyx_k_CONTENT_TRANSFER_ENCODING, sizeof(__pyx_k_CONTENT_TRANSFER_ENCODING), 0, 0, 1, 1}, - {&__pyx_n_s_CONTENT_TYPE, __pyx_k_CONTENT_TYPE, sizeof(__pyx_k_CONTENT_TYPE), 0, 0, 1, 1}, - {&__pyx_n_s_COOKIE, __pyx_k_COOKIE, sizeof(__pyx_k_COOKIE), 0, 0, 1, 1}, - {&__pyx_n_s_ContentLengthError, __pyx_k_ContentLengthError, sizeof(__pyx_k_ContentLengthError), 0, 0, 1, 1}, - {&__pyx_n_s_DATE, __pyx_k_DATE, sizeof(__pyx_k_DATE), 0, 0, 1, 1}, - {&__pyx_n_s_DESTINATION, __pyx_k_DESTINATION, sizeof(__pyx_k_DESTINATION), 0, 0, 1, 1}, - {&__pyx_n_s_DIGEST, __pyx_k_DIGEST, sizeof(__pyx_k_DIGEST), 0, 0, 1, 1}, - {&__pyx_n_s_DeflateBuffer, __pyx_k_DeflateBuffer, sizeof(__pyx_k_DeflateBuffer), 0, 0, 1, 1}, - {&__pyx_n_s_DeflateBuffer_2, __pyx_k_DeflateBuffer_2, sizeof(__pyx_k_DeflateBuffer_2), 0, 0, 1, 1}, - {&__pyx_n_s_EMPTY_PAYLOAD, __pyx_k_EMPTY_PAYLOAD, sizeof(__pyx_k_EMPTY_PAYLOAD), 0, 0, 1, 1}, - {&__pyx_n_s_EMPTY_PAYLOAD_2, __pyx_k_EMPTY_PAYLOAD_2, sizeof(__pyx_k_EMPTY_PAYLOAD_2), 0, 0, 1, 1}, - {&__pyx_n_s_ETAG, __pyx_k_ETAG, sizeof(__pyx_k_ETAG), 0, 0, 1, 1}, - {&__pyx_n_s_EXPECT, __pyx_k_EXPECT, sizeof(__pyx_k_EXPECT), 0, 0, 1, 1}, - {&__pyx_n_s_EXPIRES, __pyx_k_EXPIRES, sizeof(__pyx_k_EXPIRES), 0, 0, 1, 1}, - {&__pyx_n_s_FORWARDED, __pyx_k_FORWARDED, sizeof(__pyx_k_FORWARDED), 0, 0, 1, 1}, - {&__pyx_n_s_FROM, __pyx_k_FROM, sizeof(__pyx_k_FROM), 0, 0, 1, 1}, - {&__pyx_n_s_HOST, __pyx_k_HOST, sizeof(__pyx_k_HOST), 0, 0, 1, 1}, - {&__pyx_kp_u_Header_name_is_too_long, __pyx_k_Header_name_is_too_long, sizeof(__pyx_k_Header_name_is_too_long), 0, 1, 0, 0}, - {&__pyx_kp_u_Header_value_is_too_long, __pyx_k_Header_value_is_too_long, sizeof(__pyx_k_Header_value_is_too_long), 0, 1, 0, 0}, - {&__pyx_n_s_HttpRequestParser, __pyx_k_HttpRequestParser, sizeof(__pyx_k_HttpRequestParser), 0, 0, 1, 1}, - {&__pyx_n_u_HttpRequestParser, __pyx_k_HttpRequestParser, sizeof(__pyx_k_HttpRequestParser), 0, 1, 0, 1}, - {&__pyx_n_s_HttpResponseParser, __pyx_k_HttpResponseParser, sizeof(__pyx_k_HttpResponseParser), 0, 0, 1, 1}, - {&__pyx_n_u_HttpResponseParser, __pyx_k_HttpResponseParser, sizeof(__pyx_k_HttpResponseParser), 0, 1, 0, 1}, - {&__pyx_n_s_HttpVersion, __pyx_k_HttpVersion, sizeof(__pyx_k_HttpVersion), 0, 0, 1, 1}, - {&__pyx_n_s_HttpVersion10, __pyx_k_HttpVersion10, sizeof(__pyx_k_HttpVersion10), 0, 0, 1, 1}, - {&__pyx_n_s_HttpVersion10_2, __pyx_k_HttpVersion10_2, sizeof(__pyx_k_HttpVersion10_2), 0, 0, 1, 1}, - {&__pyx_n_s_HttpVersion11, __pyx_k_HttpVersion11, sizeof(__pyx_k_HttpVersion11), 0, 0, 1, 1}, - {&__pyx_n_s_HttpVersion11_2, __pyx_k_HttpVersion11_2, sizeof(__pyx_k_HttpVersion11_2), 0, 0, 1, 1}, - {&__pyx_n_s_HttpVersion_2, __pyx_k_HttpVersion_2, sizeof(__pyx_k_HttpVersion_2), 0, 0, 1, 1}, - {&__pyx_n_s_IF_MATCH, __pyx_k_IF_MATCH, sizeof(__pyx_k_IF_MATCH), 0, 0, 1, 1}, - {&__pyx_n_s_IF_MODIFIED_SINCE, __pyx_k_IF_MODIFIED_SINCE, sizeof(__pyx_k_IF_MODIFIED_SINCE), 0, 0, 1, 1}, - {&__pyx_n_s_IF_NONE_MATCH, __pyx_k_IF_NONE_MATCH, sizeof(__pyx_k_IF_NONE_MATCH), 0, 0, 1, 1}, - {&__pyx_n_s_IF_RANGE, __pyx_k_IF_RANGE, sizeof(__pyx_k_IF_RANGE), 0, 0, 1, 1}, - {&__pyx_n_s_IF_UNMODIFIED_SINCE, __pyx_k_IF_UNMODIFIED_SINCE, sizeof(__pyx_k_IF_UNMODIFIED_SINCE), 0, 0, 1, 1}, - {&__pyx_kp_s_Incompatible_checksums_s_vs_0x14, __pyx_k_Incompatible_checksums_s_vs_0x14, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x14), 0, 0, 1, 0}, - {&__pyx_kp_s_Incompatible_checksums_s_vs_0xc7, __pyx_k_Incompatible_checksums_s_vs_0xc7, sizeof(__pyx_k_Incompatible_checksums_s_vs_0xc7), 0, 0, 1, 0}, - {&__pyx_n_s_InvalidHeader, __pyx_k_InvalidHeader, sizeof(__pyx_k_InvalidHeader), 0, 0, 1, 1}, - {&__pyx_n_s_InvalidURLError, __pyx_k_InvalidURLError, sizeof(__pyx_k_InvalidURLError), 0, 0, 1, 1}, - {&__pyx_n_s_KEEP_ALIVE, __pyx_k_KEEP_ALIVE, sizeof(__pyx_k_KEEP_ALIVE), 0, 0, 1, 1}, - {&__pyx_n_s_LAST_EVENT_ID, __pyx_k_LAST_EVENT_ID, sizeof(__pyx_k_LAST_EVENT_ID), 0, 0, 1, 1}, - {&__pyx_n_s_LAST_MODIFIED, __pyx_k_LAST_MODIFIED, sizeof(__pyx_k_LAST_MODIFIED), 0, 0, 1, 1}, - {&__pyx_n_s_LINK, __pyx_k_LINK, sizeof(__pyx_k_LINK), 0, 0, 1, 1}, - {&__pyx_n_s_LOCATION, __pyx_k_LOCATION, sizeof(__pyx_k_LOCATION), 0, 0, 1, 1}, - {&__pyx_n_s_LineTooLong, __pyx_k_LineTooLong, sizeof(__pyx_k_LineTooLong), 0, 0, 1, 1}, - {&__pyx_n_s_MAX_FORWARDS, __pyx_k_MAX_FORWARDS, sizeof(__pyx_k_MAX_FORWARDS), 0, 0, 1, 1}, - {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, - {&__pyx_kp_u_Not_enough_data_for_satisfy_cont, __pyx_k_Not_enough_data_for_satisfy_cont, sizeof(__pyx_k_Not_enough_data_for_satisfy_cont), 0, 1, 0, 0}, - {&__pyx_kp_u_Not_enough_data_for_satisfy_tran, __pyx_k_Not_enough_data_for_satisfy_tran, sizeof(__pyx_k_Not_enough_data_for_satisfy_tran), 0, 1, 0, 0}, - {&__pyx_n_s_ORIGIN, __pyx_k_ORIGIN, sizeof(__pyx_k_ORIGIN), 0, 0, 1, 1}, - {&__pyx_n_s_PRAGMA, __pyx_k_PRAGMA, sizeof(__pyx_k_PRAGMA), 0, 0, 1, 1}, - {&__pyx_n_s_PROXY_AUTHENTICATE, __pyx_k_PROXY_AUTHENTICATE, sizeof(__pyx_k_PROXY_AUTHENTICATE), 0, 0, 1, 1}, - {&__pyx_n_s_PROXY_AUTHORIZATION, __pyx_k_PROXY_AUTHORIZATION, sizeof(__pyx_k_PROXY_AUTHORIZATION), 0, 0, 1, 1}, - {&__pyx_n_s_PayloadEncodingError, __pyx_k_PayloadEncodingError, sizeof(__pyx_k_PayloadEncodingError), 0, 0, 1, 1}, - {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_RANGE, __pyx_k_RANGE, sizeof(__pyx_k_RANGE), 0, 0, 1, 1}, - {&__pyx_n_s_REFERER, __pyx_k_REFERER, sizeof(__pyx_k_REFERER), 0, 0, 1, 1}, - {&__pyx_n_s_RETRY_AFTER, __pyx_k_RETRY_AFTER, sizeof(__pyx_k_RETRY_AFTER), 0, 0, 1, 1}, - {&__pyx_kp_u_RawRequestMessage, __pyx_k_RawRequestMessage, sizeof(__pyx_k_RawRequestMessage), 0, 1, 0, 0}, - {&__pyx_n_s_RawRequestMessage_2, __pyx_k_RawRequestMessage_2, sizeof(__pyx_k_RawRequestMessage_2), 0, 0, 1, 1}, - {&__pyx_n_u_RawRequestMessage_2, __pyx_k_RawRequestMessage_2, sizeof(__pyx_k_RawRequestMessage_2), 0, 1, 0, 1}, - {&__pyx_kp_u_RawResponseMessage, __pyx_k_RawResponseMessage, sizeof(__pyx_k_RawResponseMessage), 0, 1, 0, 0}, - {&__pyx_n_s_RawResponseMessage_2, __pyx_k_RawResponseMessage_2, sizeof(__pyx_k_RawResponseMessage_2), 0, 0, 1, 1}, - {&__pyx_n_u_RawResponseMessage_2, __pyx_k_RawResponseMessage_2, sizeof(__pyx_k_RawResponseMessage_2), 0, 1, 0, 1}, - {&__pyx_n_s_SEC_WEBSOCKET_ACCEPT, __pyx_k_SEC_WEBSOCKET_ACCEPT, sizeof(__pyx_k_SEC_WEBSOCKET_ACCEPT), 0, 0, 1, 1}, - {&__pyx_n_s_SEC_WEBSOCKET_EXTENSIONS, __pyx_k_SEC_WEBSOCKET_EXTENSIONS, sizeof(__pyx_k_SEC_WEBSOCKET_EXTENSIONS), 0, 0, 1, 1}, - {&__pyx_n_s_SEC_WEBSOCKET_KEY, __pyx_k_SEC_WEBSOCKET_KEY, sizeof(__pyx_k_SEC_WEBSOCKET_KEY), 0, 0, 1, 1}, - {&__pyx_n_s_SEC_WEBSOCKET_KEY1, __pyx_k_SEC_WEBSOCKET_KEY1, sizeof(__pyx_k_SEC_WEBSOCKET_KEY1), 0, 0, 1, 1}, - {&__pyx_n_s_SEC_WEBSOCKET_PROTOCOL, __pyx_k_SEC_WEBSOCKET_PROTOCOL, sizeof(__pyx_k_SEC_WEBSOCKET_PROTOCOL), 0, 0, 1, 1}, - {&__pyx_n_s_SEC_WEBSOCKET_VERSION, __pyx_k_SEC_WEBSOCKET_VERSION, sizeof(__pyx_k_SEC_WEBSOCKET_VERSION), 0, 0, 1, 1}, - {&__pyx_n_s_SERVER, __pyx_k_SERVER, sizeof(__pyx_k_SERVER), 0, 0, 1, 1}, - {&__pyx_n_s_SET_COOKIE, __pyx_k_SET_COOKIE, sizeof(__pyx_k_SET_COOKIE), 0, 0, 1, 1}, - {&__pyx_kp_u_Status_line_is_too_long, __pyx_k_Status_line_is_too_long, sizeof(__pyx_k_Status_line_is_too_long), 0, 1, 0, 0}, - {&__pyx_n_s_StreamReader, __pyx_k_StreamReader, sizeof(__pyx_k_StreamReader), 0, 0, 1, 1}, - {&__pyx_n_s_StreamReader_2, __pyx_k_StreamReader_2, sizeof(__pyx_k_StreamReader_2), 0, 0, 1, 1}, - {&__pyx_n_s_TE, __pyx_k_TE, sizeof(__pyx_k_TE), 0, 0, 1, 1}, - {&__pyx_n_s_TRAILER, __pyx_k_TRAILER, sizeof(__pyx_k_TRAILER), 0, 0, 1, 1}, - {&__pyx_n_s_TRANSFER_ENCODING, __pyx_k_TRANSFER_ENCODING, sizeof(__pyx_k_TRANSFER_ENCODING), 0, 0, 1, 1}, - {&__pyx_n_s_TransferEncodingError, __pyx_k_TransferEncodingError, sizeof(__pyx_k_TransferEncodingError), 0, 0, 1, 1}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_n_s_UPGRADE, __pyx_k_UPGRADE, sizeof(__pyx_k_UPGRADE), 0, 0, 1, 1}, - {&__pyx_n_s_URI, __pyx_k_URI, sizeof(__pyx_k_URI), 0, 0, 1, 1}, - {&__pyx_n_s_URL, __pyx_k_URL, sizeof(__pyx_k_URL), 0, 0, 1, 1}, - {&__pyx_n_s_URL_2, __pyx_k_URL_2, sizeof(__pyx_k_URL_2), 0, 0, 1, 1}, - {&__pyx_n_s_USER_AGENT, __pyx_k_USER_AGENT, sizeof(__pyx_k_USER_AGENT), 0, 0, 1, 1}, - {&__pyx_n_s_VARY, __pyx_k_VARY, sizeof(__pyx_k_VARY), 0, 0, 1, 1}, - {&__pyx_n_s_VIA, __pyx_k_VIA, sizeof(__pyx_k_VIA), 0, 0, 1, 1}, - {&__pyx_n_s_WANT_DIGEST, __pyx_k_WANT_DIGEST, sizeof(__pyx_k_WANT_DIGEST), 0, 0, 1, 1}, - {&__pyx_n_s_WARNING, __pyx_k_WARNING, sizeof(__pyx_k_WARNING), 0, 0, 1, 1}, - {&__pyx_n_s_WWW_AUTHENTICATE, __pyx_k_WWW_AUTHENTICATE, sizeof(__pyx_k_WWW_AUTHENTICATE), 0, 0, 1, 1}, - {&__pyx_n_s_X_FORWARDED_FOR, __pyx_k_X_FORWARDED_FOR, sizeof(__pyx_k_X_FORWARDED_FOR), 0, 0, 1, 1}, - {&__pyx_n_s_X_FORWARDED_HOST, __pyx_k_X_FORWARDED_HOST, sizeof(__pyx_k_X_FORWARDED_HOST), 0, 0, 1, 1}, - {&__pyx_n_s_X_FORWARDED_PROTO, __pyx_k_X_FORWARDED_PROTO, sizeof(__pyx_k_X_FORWARDED_PROTO), 0, 0, 1, 1}, - {&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0}, - {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, - {&__pyx_kp_u__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 1, 0, 0}, - {&__pyx_n_s__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 1, 1}, - {&__pyx_kp_b__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 0, 0}, - {&__pyx_kp_u__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 1, 0, 0}, - {&__pyx_n_s_add, __pyx_k_add, sizeof(__pyx_k_add), 0, 0, 1, 1}, - {&__pyx_n_s_aiohttp, __pyx_k_aiohttp, sizeof(__pyx_k_aiohttp), 0, 0, 1, 1}, - {&__pyx_n_s_aiohttp__http_parser, __pyx_k_aiohttp__http_parser, sizeof(__pyx_k_aiohttp__http_parser), 0, 0, 1, 1}, - {&__pyx_kp_s_aiohttp__http_parser_pyx, __pyx_k_aiohttp__http_parser_pyx, sizeof(__pyx_k_aiohttp__http_parser_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1}, - {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1}, - {&__pyx_n_s_auto_decompress, __pyx_k_auto_decompress, sizeof(__pyx_k_auto_decompress), 0, 0, 1, 1}, - {&__pyx_n_s_begin_http_chunk_receiving, __pyx_k_begin_http_chunk_receiving, sizeof(__pyx_k_begin_http_chunk_receiving), 0, 0, 1, 1}, - {&__pyx_n_u_br, __pyx_k_br, sizeof(__pyx_k_br), 0, 1, 0, 1}, - {&__pyx_n_s_buf_data, __pyx_k_buf_data, sizeof(__pyx_k_buf_data), 0, 0, 1, 1}, - {&__pyx_n_s_build, __pyx_k_build, sizeof(__pyx_k_build), 0, 0, 1, 1}, - {&__pyx_n_s_chunked, __pyx_k_chunked, sizeof(__pyx_k_chunked), 0, 0, 1, 1}, - {&__pyx_n_u_chunked, __pyx_k_chunked, sizeof(__pyx_k_chunked), 0, 1, 0, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, - {&__pyx_n_s_code, __pyx_k_code, sizeof(__pyx_k_code), 0, 0, 1, 1}, - {&__pyx_n_u_code, __pyx_k_code, sizeof(__pyx_k_code), 0, 1, 0, 1}, - {&__pyx_n_s_compression, __pyx_k_compression, sizeof(__pyx_k_compression), 0, 0, 1, 1}, - {&__pyx_n_u_compression, __pyx_k_compression, sizeof(__pyx_k_compression), 0, 1, 0, 1}, - {&__pyx_n_u_deflate, __pyx_k_deflate, sizeof(__pyx_k_deflate), 0, 1, 0, 1}, - {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, - {&__pyx_n_s_encoded, __pyx_k_encoded, sizeof(__pyx_k_encoded), 0, 0, 1, 1}, - {&__pyx_n_s_end_http_chunk_receiving, __pyx_k_end_http_chunk_receiving, sizeof(__pyx_k_end_http_chunk_receiving), 0, 0, 1, 1}, - {&__pyx_n_s_feed_data, __pyx_k_feed_data, sizeof(__pyx_k_feed_data), 0, 0, 1, 1}, - {&__pyx_n_s_feed_eof, __pyx_k_feed_eof, sizeof(__pyx_k_feed_eof), 0, 0, 1, 1}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_fragment, __pyx_k_fragment, sizeof(__pyx_k_fragment), 0, 0, 1, 1}, - {&__pyx_n_s_genexpr, __pyx_k_genexpr, sizeof(__pyx_k_genexpr), 0, 0, 1, 1}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_n_u_gzip, __pyx_k_gzip, sizeof(__pyx_k_gzip), 0, 1, 0, 1}, - {&__pyx_n_s_hdrs, __pyx_k_hdrs, sizeof(__pyx_k_hdrs), 0, 0, 1, 1}, - {&__pyx_n_s_headers, __pyx_k_headers, sizeof(__pyx_k_headers), 0, 0, 1, 1}, - {&__pyx_n_u_headers, __pyx_k_headers, sizeof(__pyx_k_headers), 0, 1, 0, 1}, - {&__pyx_n_s_host, __pyx_k_host, sizeof(__pyx_k_host), 0, 0, 1, 1}, - {&__pyx_n_s_http_exceptions, __pyx_k_http_exceptions, sizeof(__pyx_k_http_exceptions), 0, 0, 1, 1}, - {&__pyx_n_s_http_parser, __pyx_k_http_parser, sizeof(__pyx_k_http_parser), 0, 0, 1, 1}, - {&__pyx_n_s_http_writer, __pyx_k_http_writer, sizeof(__pyx_k_http_writer), 0, 0, 1, 1}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_kp_u_invalid_url_r, __pyx_k_invalid_url_r, sizeof(__pyx_k_invalid_url_r), 0, 1, 0, 0}, - {&__pyx_n_s_limit, __pyx_k_limit, sizeof(__pyx_k_limit), 0, 0, 1, 1}, - {&__pyx_n_s_loop, __pyx_k_loop, sizeof(__pyx_k_loop), 0, 0, 1, 1}, - {&__pyx_n_s_lower, __pyx_k_lower, sizeof(__pyx_k_lower), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_max_field_size, __pyx_k_max_field_size, sizeof(__pyx_k_max_field_size), 0, 0, 1, 1}, - {&__pyx_n_s_max_headers, __pyx_k_max_headers, sizeof(__pyx_k_max_headers), 0, 0, 1, 1}, - {&__pyx_n_s_max_line_size, __pyx_k_max_line_size, sizeof(__pyx_k_max_line_size), 0, 0, 1, 1}, - {&__pyx_n_s_method, __pyx_k_method, sizeof(__pyx_k_method), 0, 0, 1, 1}, - {&__pyx_n_u_method, __pyx_k_method, sizeof(__pyx_k_method), 0, 1, 0, 1}, - {&__pyx_n_s_multidict, __pyx_k_multidict, sizeof(__pyx_k_multidict), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, - {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, - {&__pyx_n_s_parse_url, __pyx_k_parse_url, sizeof(__pyx_k_parse_url), 0, 0, 1, 1}, - {&__pyx_n_s_partition, __pyx_k_partition, sizeof(__pyx_k_partition), 0, 0, 1, 1}, - {&__pyx_n_s_password, __pyx_k_password, sizeof(__pyx_k_password), 0, 0, 1, 1}, - {&__pyx_n_s_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 0, 1, 1}, - {&__pyx_n_u_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 1, 0, 1}, - {&__pyx_n_s_payload_exception, __pyx_k_payload_exception, sizeof(__pyx_k_payload_exception), 0, 0, 1, 1}, - {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, - {&__pyx_n_s_port, __pyx_k_port, sizeof(__pyx_k_port), 0, 0, 1, 1}, - {&__pyx_n_s_protocol, __pyx_k_protocol, sizeof(__pyx_k_protocol), 0, 0, 1, 1}, - {&__pyx_n_s_py_buf, __pyx_k_py_buf, sizeof(__pyx_k_py_buf), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_RawRequestMessage, __pyx_k_pyx_unpickle_RawRequestMessage, sizeof(__pyx_k_pyx_unpickle_RawRequestMessage), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_RawResponseMessag, __pyx_k_pyx_unpickle_RawResponseMessag, sizeof(__pyx_k_pyx_unpickle_RawResponseMessag), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_query_string, __pyx_k_query_string, sizeof(__pyx_k_query_string), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_raw_headers, __pyx_k_raw_headers, sizeof(__pyx_k_raw_headers), 0, 0, 1, 1}, - {&__pyx_n_u_raw_headers, __pyx_k_raw_headers, sizeof(__pyx_k_raw_headers), 0, 1, 0, 1}, - {&__pyx_n_s_read_until_eof, __pyx_k_read_until_eof, sizeof(__pyx_k_read_until_eof), 0, 0, 1, 1}, - {&__pyx_n_s_reason, __pyx_k_reason, sizeof(__pyx_k_reason), 0, 0, 1, 1}, - {&__pyx_n_u_reason, __pyx_k_reason, sizeof(__pyx_k_reason), 0, 1, 0, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_repr___locals_genexpr, __pyx_k_repr___locals_genexpr, sizeof(__pyx_k_repr___locals_genexpr), 0, 0, 1, 1}, - {&__pyx_n_s_response_with_body, __pyx_k_response_with_body, sizeof(__pyx_k_response_with_body), 0, 0, 1, 1}, - {&__pyx_n_s_scheme, __pyx_k_scheme, sizeof(__pyx_k_scheme), 0, 0, 1, 1}, - {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1}, - {&__pyx_n_s_set_exception, __pyx_k_set_exception, sizeof(__pyx_k_set_exception), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_should_close, __pyx_k_should_close, sizeof(__pyx_k_should_close), 0, 0, 1, 1}, - {&__pyx_n_u_should_close, __pyx_k_should_close, sizeof(__pyx_k_should_close), 0, 1, 0, 1}, - {&__pyx_n_s_streams, __pyx_k_streams, sizeof(__pyx_k_streams), 0, 0, 1, 1}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1}, - {&__pyx_n_s_timer, __pyx_k_timer, sizeof(__pyx_k_timer), 0, 0, 1, 1}, - {&__pyx_kp_u_unknown, __pyx_k_unknown, sizeof(__pyx_k_unknown), 0, 1, 0, 0}, - {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, - {&__pyx_n_s_upgrade, __pyx_k_upgrade, sizeof(__pyx_k_upgrade), 0, 0, 1, 1}, - {&__pyx_n_u_upgrade, __pyx_k_upgrade, sizeof(__pyx_k_upgrade), 0, 1, 0, 1}, - {&__pyx_n_s_url, __pyx_k_url, sizeof(__pyx_k_url), 0, 0, 1, 1}, - {&__pyx_n_u_url, __pyx_k_url, sizeof(__pyx_k_url), 0, 1, 0, 1}, - {&__pyx_n_s_user, __pyx_k_user, sizeof(__pyx_k_user), 0, 0, 1, 1}, - {&__pyx_n_s_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 0, 1, 1}, - {&__pyx_n_u_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 1, 0, 1}, - {&__pyx_n_s_yarl, __pyx_k_yarl, sizeof(__pyx_k_yarl), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 87, __pyx_L1_error) - __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(0, 316, __pyx_L1_error) - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error) - __pyx_builtin_BaseException = __Pyx_GetBuiltinName(__pyx_n_s_BaseException); if (!__pyx_builtin_BaseException) __PYX_ERR(0, 631, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__5); - __Pyx_GIVEREF(__pyx_tuple__5); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__6); - __Pyx_GIVEREF(__pyx_tuple__6); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__9); - __Pyx_GIVEREF(__pyx_tuple__9); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__10); - __Pyx_GIVEREF(__pyx_tuple__10); - - /* "aiohttp/_http_parser.pyx":57 - * char* PyByteArray_AsString(object) - * - * __all__ = ('HttpRequestParser', 'HttpResponseParser', # <<<<<<<<<<<<<< - * 'RawRequestMessage', 'RawResponseMessage') - * - */ - __pyx_tuple__12 = PyTuple_Pack(4, __pyx_n_u_HttpRequestParser, __pyx_n_u_HttpResponseParser, __pyx_n_u_RawRequestMessage_2, __pyx_n_u_RawResponseMessage_2); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); - - /* "aiohttp/_http_parser.pyx":785 - * - * - * def parse_url(url): # <<<<<<<<<<<<<< - * cdef: - * Py_buffer py_buf - */ - __pyx_tuple__13 = PyTuple_Pack(3, __pyx_n_s_url, __pyx_n_s_py_buf, __pyx_n_s_buf_data); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 785, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__13); - __Pyx_GIVEREF(__pyx_tuple__13); - __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__http_parser_pyx, __pyx_n_s_parse_url, 785, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 785, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_tuple__15 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__15); - __Pyx_GIVEREF(__pyx_tuple__15); - __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawRequestMessage, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(1, 1, __pyx_L1_error) - __pyx_tuple__17 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__17); - __Pyx_GIVEREF(__pyx_tuple__17); - __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawResponseMessag, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - __pyx_umethod_PyUnicode_Type_partition.type = (PyObject*)&PyUnicode_Type; - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_21004882 = PyInt_FromLong(21004882L); if (unlikely(!__pyx_int_21004882)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_209127132 = PyInt_FromLong(209127132L); if (unlikely(!__pyx_int_209127132)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __pyx_v_7aiohttp_12_http_parser_headers = ((PyObject*)Py_None); Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_URL = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_URL_build = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_CIMultiDict = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_HttpVersion = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_HttpVersion10 = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_HttpVersion11 = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1 = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_StreamReader = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser_DeflateBuffer = Py_None; Py_INCREF(Py_None); - __pyx_v_7aiohttp_12_http_parser__http_method = ((PyObject*)Py_None); Py_INCREF(Py_None); - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 110, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_RawRequestMessage_2, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 110, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 110, __pyx_L1_error) - __pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage = &__pyx_type_7aiohttp_12_http_parser_RawRequestMessage; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 210, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_RawResponseMessage_2, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 210, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 210, __pyx_L1_error) - __pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage = &__pyx_type_7aiohttp_12_http_parser_RawResponseMessage; - __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpParser; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._init = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, enum http_parser_type, PyObject *, PyObject *, int, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args))__pyx_f_7aiohttp_12_http_parser_10HttpParser__init; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._process_header = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__process_header; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_header_field = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_field; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_header_value = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_value; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_headers_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_complete; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_message_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_complete; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_chunk_header = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_chunk_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_status_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_status_complete; - __pyx_vtable_7aiohttp_12_http_parser_HttpParser.http_version = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_HttpParser) < 0) __PYX_ERR(0, 272, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser_HttpParser.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_HttpParser.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_HttpParser.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser_HttpParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser) < 0) __PYX_ERR(0, 272, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpParser) < 0) __PYX_ERR(0, 272, __pyx_L1_error) - __pyx_ptype_7aiohttp_12_http_parser_HttpParser = &__pyx_type_7aiohttp_12_http_parser_HttpParser; - __pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser; - __pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser.__pyx_base = *__pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; - __pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser.__pyx_base._on_status_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_complete; - __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_base = __pyx_ptype_7aiohttp_12_http_parser_HttpParser; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_HttpRequestParser, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) - __pyx_ptype_7aiohttp_12_http_parser_HttpRequestParser = &__pyx_type_7aiohttp_12_http_parser_HttpRequestParser; - __pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser; - __pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser.__pyx_base = *__pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; - __pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser.__pyx_base._on_status_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_18HttpResponseParser__on_status_complete; - __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_base = __pyx_ptype_7aiohttp_12_http_parser_HttpParser; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_HttpResponseParser, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) - __pyx_ptype_7aiohttp_12_http_parser_HttpResponseParser = &__pyx_type_7aiohttp_12_http_parser_HttpResponseParser; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__) < 0) __PYX_ERR(0, 135, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - } - __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 147, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - } - __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__) < 0) __PYX_ERR(0, 233, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - } - __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__; - if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr) < 0) __PYX_ERR(0, 244, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - } - __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(2, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(3, 8, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_7complex_complex) __PYX_ERR(4, 15, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_http_parser(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_http_parser(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__http_parser(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__http_parser(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__http_parser(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; - PyObject *__pyx_t_16 = NULL; - PyObject *__pyx_t_17 = NULL; - PyObject *__pyx_t_18 = NULL; - PyObject *__pyx_t_19 = NULL; - PyObject *__pyx_t_20 = NULL; - PyObject *__pyx_t_21 = NULL; - PyObject *__pyx_t_22 = NULL; - PyObject *__pyx_t_23 = NULL; - PyObject *__pyx_t_24 = NULL; - PyObject *__pyx_t_25 = NULL; - PyObject *__pyx_t_26 = NULL; - PyObject *__pyx_t_27 = NULL; - PyObject *__pyx_t_28 = NULL; - PyObject *__pyx_t_29 = NULL; - PyObject *__pyx_t_30 = NULL; - PyObject *__pyx_t_31 = NULL; - PyObject *__pyx_t_32 = NULL; - PyObject *__pyx_t_33 = NULL; - PyObject *__pyx_t_34 = NULL; - PyObject *__pyx_t_35 = NULL; - PyObject *__pyx_t_36 = NULL; - PyObject *__pyx_t_37 = NULL; - PyObject *__pyx_t_38 = NULL; - PyObject *__pyx_t_39 = NULL; - PyObject *__pyx_t_40 = NULL; - PyObject *__pyx_t_41 = NULL; - PyObject *__pyx_t_42 = NULL; - PyObject *__pyx_t_43 = NULL; - PyObject *__pyx_t_44 = NULL; - PyObject *__pyx_t_45 = NULL; - PyObject *__pyx_t_46 = NULL; - PyObject *__pyx_t_47 = NULL; - PyObject *__pyx_t_48 = NULL; - PyObject *__pyx_t_49 = NULL; - PyObject *__pyx_t_50 = NULL; - PyObject *__pyx_t_51 = NULL; - PyObject *__pyx_t_52 = NULL; - PyObject *__pyx_t_53 = NULL; - PyObject *__pyx_t_54 = NULL; - PyObject *__pyx_t_55 = NULL; - PyObject *__pyx_t_56 = NULL; - PyObject *__pyx_t_57 = NULL; - PyObject *__pyx_t_58 = NULL; - PyObject *__pyx_t_59 = NULL; - PyObject *__pyx_t_60 = NULL; - PyObject *__pyx_t_61 = NULL; - PyObject *__pyx_t_62 = NULL; - PyObject *__pyx_t_63 = NULL; - PyObject *__pyx_t_64 = NULL; - PyObject *__pyx_t_65 = NULL; - PyObject *__pyx_t_66 = NULL; - PyObject *__pyx_t_67 = NULL; - PyObject *__pyx_t_68 = NULL; - PyObject *__pyx_t_69 = NULL; - PyObject *__pyx_t_70 = NULL; - PyObject *__pyx_t_71 = NULL; - PyObject *__pyx_t_72 = NULL; - PyObject *__pyx_t_73 = NULL; - PyObject *__pyx_t_74 = NULL; - PyObject *__pyx_t_75 = NULL; - PyObject *__pyx_t_76 = NULL; - PyObject *__pyx_t_77 = NULL; - PyObject *__pyx_t_78 = NULL; - long __pyx_t_79; - enum http_method __pyx_t_80; - char const *__pyx_t_81; - int __pyx_t_82; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_http_parser' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__http_parser(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_http_parser", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_aiohttp___http_parser) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "aiohttp._http_parser")) { - if (unlikely(PyDict_SetItemString(modules, "aiohttp._http_parser", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "aiohttp/_http_parser.pyx":19 - * from libc.string cimport memcpy - * - * from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy # <<<<<<<<<<<<<< - * from yarl import URL as _URL - * - */ - __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_CIMultiDict); - __Pyx_GIVEREF(__pyx_n_s_CIMultiDict); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_CIMultiDict); - __Pyx_INCREF(__pyx_n_s_CIMultiDictProxy); - __Pyx_GIVEREF(__pyx_n_s_CIMultiDictProxy); - PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_CIMultiDictProxy); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_multidict, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_CIMultiDict); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_CIMultiDict_2, __pyx_t_1) < 0) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_CIMultiDictProxy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_CIMultiDictProxy_2, __pyx_t_1) < 0) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":20 - * - * from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy - * from yarl import URL as _URL # <<<<<<<<<<<<<< - * - * from aiohttp import hdrs - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_URL); - __Pyx_GIVEREF(__pyx_n_s_URL); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_URL); - __pyx_t_1 = __Pyx_Import(__pyx_n_s_yarl, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_URL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_URL_2, __pyx_t_2) < 0) __PYX_ERR(0, 20, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":22 - * from yarl import URL as _URL - * - * from aiohttp import hdrs # <<<<<<<<<<<<<< - * - * from .http_exceptions import ( - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_hdrs); - __Pyx_GIVEREF(__pyx_n_s_hdrs); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_hdrs); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_aiohttp, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_hdrs, __pyx_t_1) < 0) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":25 - * - * from .http_exceptions import ( - * BadHttpMessage, # <<<<<<<<<<<<<< - * BadStatusLine, - * ContentLengthError, - */ - __pyx_t_2 = PyList_New(8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_BadHttpMessage); - __Pyx_GIVEREF(__pyx_n_s_BadHttpMessage); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_BadHttpMessage); - __Pyx_INCREF(__pyx_n_s_BadStatusLine); - __Pyx_GIVEREF(__pyx_n_s_BadStatusLine); - PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_BadStatusLine); - __Pyx_INCREF(__pyx_n_s_ContentLengthError); - __Pyx_GIVEREF(__pyx_n_s_ContentLengthError); - PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_ContentLengthError); - __Pyx_INCREF(__pyx_n_s_InvalidHeader); - __Pyx_GIVEREF(__pyx_n_s_InvalidHeader); - PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_InvalidHeader); - __Pyx_INCREF(__pyx_n_s_InvalidURLError); - __Pyx_GIVEREF(__pyx_n_s_InvalidURLError); - PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_s_InvalidURLError); - __Pyx_INCREF(__pyx_n_s_LineTooLong); - __Pyx_GIVEREF(__pyx_n_s_LineTooLong); - PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_s_LineTooLong); - __Pyx_INCREF(__pyx_n_s_PayloadEncodingError); - __Pyx_GIVEREF(__pyx_n_s_PayloadEncodingError); - PyList_SET_ITEM(__pyx_t_2, 6, __pyx_n_s_PayloadEncodingError); - __Pyx_INCREF(__pyx_n_s_TransferEncodingError); - __Pyx_GIVEREF(__pyx_n_s_TransferEncodingError); - PyList_SET_ITEM(__pyx_t_2, 7, __pyx_n_s_TransferEncodingError); - - /* "aiohttp/_http_parser.pyx":24 - * from aiohttp import hdrs - * - * from .http_exceptions import ( # <<<<<<<<<<<<<< - * BadHttpMessage, - * BadStatusLine, - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_http_exceptions, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_BadHttpMessage, __pyx_t_2) < 0) __PYX_ERR(0, 25, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_BadStatusLine, __pyx_t_2) < 0) __PYX_ERR(0, 26, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_ContentLengthError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_ContentLengthError, __pyx_t_2) < 0) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_InvalidHeader); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_InvalidHeader, __pyx_t_2) < 0) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_InvalidURLError, __pyx_t_2) < 0) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_LineTooLong, __pyx_t_2) < 0) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_PayloadEncodingError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_PayloadEncodingError, __pyx_t_2) < 0) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_TransferEncodingError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_TransferEncodingError, __pyx_t_2) < 0) __PYX_ERR(0, 32, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":34 - * TransferEncodingError, - * ) - * from .http_parser import DeflateBuffer as _DeflateBuffer # <<<<<<<<<<<<<< - * from .http_writer import ( - * HttpVersion as _HttpVersion, - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_DeflateBuffer); - __Pyx_GIVEREF(__pyx_n_s_DeflateBuffer); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_DeflateBuffer); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_http_parser, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_DeflateBuffer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_DeflateBuffer_2, __pyx_t_1) < 0) __PYX_ERR(0, 34, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_parser.pyx":36 - * from .http_parser import DeflateBuffer as _DeflateBuffer - * from .http_writer import ( - * HttpVersion as _HttpVersion, # <<<<<<<<<<<<<< - * HttpVersion10 as _HttpVersion10, - * HttpVersion11 as _HttpVersion11, - */ - __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_HttpVersion); - __Pyx_GIVEREF(__pyx_n_s_HttpVersion); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_HttpVersion); - __Pyx_INCREF(__pyx_n_s_HttpVersion10); - __Pyx_GIVEREF(__pyx_n_s_HttpVersion10); - PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_HttpVersion10); - __Pyx_INCREF(__pyx_n_s_HttpVersion11); - __Pyx_GIVEREF(__pyx_n_s_HttpVersion11); - PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_HttpVersion11); - - /* "aiohttp/_http_parser.pyx":35 - * ) - * from .http_parser import DeflateBuffer as _DeflateBuffer - * from .http_writer import ( # <<<<<<<<<<<<<< - * HttpVersion as _HttpVersion, - * HttpVersion10 as _HttpVersion10, - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_http_writer, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_HttpVersion); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_HttpVersion_2, __pyx_t_2) < 0) __PYX_ERR(0, 36, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_HttpVersion10); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_HttpVersion10_2, __pyx_t_2) < 0) __PYX_ERR(0, 37, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_HttpVersion11); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_HttpVersion11_2, __pyx_t_2) < 0) __PYX_ERR(0, 38, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":40 - * HttpVersion11 as _HttpVersion11, - * ) - * from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader # <<<<<<<<<<<<<< - * - * cimport cython - */ - __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_EMPTY_PAYLOAD); - __Pyx_GIVEREF(__pyx_n_s_EMPTY_PAYLOAD); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_EMPTY_PAYLOAD); - __Pyx_INCREF(__pyx_n_s_StreamReader); - __Pyx_GIVEREF(__pyx_n_s_StreamReader); - PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_StreamReader); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_streams, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_EMPTY_PAYLOAD); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_EMPTY_PAYLOAD_2, __pyx_t_1) < 0) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_StreamReader); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_StreamReader_2, __pyx_t_1) < 0) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_headers.pxi":4 - * # Run ./tools/gen.py to update it after the origin changing. - * - * from . import hdrs # <<<<<<<<<<<<<< - * cdef tuple headers = ( - * hdrs.ACCEPT, - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_hdrs); - __Pyx_GIVEREF(__pyx_n_s_hdrs); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_hdrs); - __pyx_t_1 = __Pyx_Import(__pyx_n_s__4, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_hdrs, __pyx_t_2) < 0) __PYX_ERR(5, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":6 - * from . import hdrs - * cdef tuple headers = ( - * hdrs.ACCEPT, # <<<<<<<<<<<<<< - * hdrs.ACCEPT_CHARSET, - * hdrs.ACCEPT_ENCODING, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":7 - * cdef tuple headers = ( - * hdrs.ACCEPT, - * hdrs.ACCEPT_CHARSET, # <<<<<<<<<<<<<< - * hdrs.ACCEPT_ENCODING, - * hdrs.ACCEPT_LANGUAGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_CHARSET); if (unlikely(!__pyx_t_3)) __PYX_ERR(5, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":8 - * hdrs.ACCEPT, - * hdrs.ACCEPT_CHARSET, - * hdrs.ACCEPT_ENCODING, # <<<<<<<<<<<<<< - * hdrs.ACCEPT_LANGUAGE, - * hdrs.ACCEPT_RANGES, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_ENCODING); if (unlikely(!__pyx_t_4)) __PYX_ERR(5, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":9 - * hdrs.ACCEPT_CHARSET, - * hdrs.ACCEPT_ENCODING, - * hdrs.ACCEPT_LANGUAGE, # <<<<<<<<<<<<<< - * hdrs.ACCEPT_RANGES, - * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_LANGUAGE); if (unlikely(!__pyx_t_5)) __PYX_ERR(5, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":10 - * hdrs.ACCEPT_ENCODING, - * hdrs.ACCEPT_LANGUAGE, - * hdrs.ACCEPT_RANGES, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, - * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 10, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_RANGES); if (unlikely(!__pyx_t_6)) __PYX_ERR(5, 10, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":11 - * hdrs.ACCEPT_LANGUAGE, - * hdrs.ACCEPT_RANGES, - * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, - * hdrs.ACCESS_CONTROL_ALLOW_METHODS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_CREDENTIALS); if (unlikely(!__pyx_t_7)) __PYX_ERR(5, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":12 - * hdrs.ACCEPT_RANGES, - * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, - * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_ALLOW_METHODS, - * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_HEADERS); if (unlikely(!__pyx_t_8)) __PYX_ERR(5, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":13 - * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, - * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, - * hdrs.ACCESS_CONTROL_ALLOW_METHODS, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, - * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_METHODS); if (unlikely(!__pyx_t_9)) __PYX_ERR(5, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":14 - * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, - * hdrs.ACCESS_CONTROL_ALLOW_METHODS, - * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, - * hdrs.ACCESS_CONTROL_MAX_AGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_ORIGIN); if (unlikely(!__pyx_t_10)) __PYX_ERR(5, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":15 - * hdrs.ACCESS_CONTROL_ALLOW_METHODS, - * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, - * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_MAX_AGE, - * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_EXPOSE_HEADERS); if (unlikely(!__pyx_t_11)) __PYX_ERR(5, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":16 - * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, - * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, - * hdrs.ACCESS_CONTROL_MAX_AGE, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, - * hdrs.ACCESS_CONTROL_REQUEST_METHOD, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_MAX_AGE); if (unlikely(!__pyx_t_12)) __PYX_ERR(5, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":17 - * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, - * hdrs.ACCESS_CONTROL_MAX_AGE, - * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, # <<<<<<<<<<<<<< - * hdrs.ACCESS_CONTROL_REQUEST_METHOD, - * hdrs.AGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_REQUEST_HEADERS); if (unlikely(!__pyx_t_13)) __PYX_ERR(5, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_13); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":18 - * hdrs.ACCESS_CONTROL_MAX_AGE, - * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, - * hdrs.ACCESS_CONTROL_REQUEST_METHOD, # <<<<<<<<<<<<<< - * hdrs.AGE, - * hdrs.ALLOW, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 18, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_REQUEST_METHOD); if (unlikely(!__pyx_t_14)) __PYX_ERR(5, 18, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_14); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":19 - * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, - * hdrs.ACCESS_CONTROL_REQUEST_METHOD, - * hdrs.AGE, # <<<<<<<<<<<<<< - * hdrs.ALLOW, - * hdrs.AUTHORIZATION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AGE); if (unlikely(!__pyx_t_15)) __PYX_ERR(5, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_15); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":20 - * hdrs.ACCESS_CONTROL_REQUEST_METHOD, - * hdrs.AGE, - * hdrs.ALLOW, # <<<<<<<<<<<<<< - * hdrs.AUTHORIZATION, - * hdrs.CACHE_CONTROL, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ALLOW); if (unlikely(!__pyx_t_16)) __PYX_ERR(5, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_16); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":21 - * hdrs.AGE, - * hdrs.ALLOW, - * hdrs.AUTHORIZATION, # <<<<<<<<<<<<<< - * hdrs.CACHE_CONTROL, - * hdrs.CONNECTION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AUTHORIZATION); if (unlikely(!__pyx_t_17)) __PYX_ERR(5, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_17); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":22 - * hdrs.ALLOW, - * hdrs.AUTHORIZATION, - * hdrs.CACHE_CONTROL, # <<<<<<<<<<<<<< - * hdrs.CONNECTION, - * hdrs.CONTENT_DISPOSITION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_18 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CACHE_CONTROL); if (unlikely(!__pyx_t_18)) __PYX_ERR(5, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_18); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":23 - * hdrs.AUTHORIZATION, - * hdrs.CACHE_CONTROL, - * hdrs.CONNECTION, # <<<<<<<<<<<<<< - * hdrs.CONTENT_DISPOSITION, - * hdrs.CONTENT_ENCODING, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 23, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_19 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONNECTION); if (unlikely(!__pyx_t_19)) __PYX_ERR(5, 23, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_19); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":24 - * hdrs.CACHE_CONTROL, - * hdrs.CONNECTION, - * hdrs.CONTENT_DISPOSITION, # <<<<<<<<<<<<<< - * hdrs.CONTENT_ENCODING, - * hdrs.CONTENT_LANGUAGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_20 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_DISPOSITION); if (unlikely(!__pyx_t_20)) __PYX_ERR(5, 24, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_20); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":25 - * hdrs.CONNECTION, - * hdrs.CONTENT_DISPOSITION, - * hdrs.CONTENT_ENCODING, # <<<<<<<<<<<<<< - * hdrs.CONTENT_LANGUAGE, - * hdrs.CONTENT_LENGTH, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_21 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_21)) __PYX_ERR(5, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_21); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":26 - * hdrs.CONTENT_DISPOSITION, - * hdrs.CONTENT_ENCODING, - * hdrs.CONTENT_LANGUAGE, # <<<<<<<<<<<<<< - * hdrs.CONTENT_LENGTH, - * hdrs.CONTENT_LOCATION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 26, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_22 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LANGUAGE); if (unlikely(!__pyx_t_22)) __PYX_ERR(5, 26, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_22); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":27 - * hdrs.CONTENT_ENCODING, - * hdrs.CONTENT_LANGUAGE, - * hdrs.CONTENT_LENGTH, # <<<<<<<<<<<<<< - * hdrs.CONTENT_LOCATION, - * hdrs.CONTENT_MD5, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_23 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LENGTH); if (unlikely(!__pyx_t_23)) __PYX_ERR(5, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_23); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":28 - * hdrs.CONTENT_LANGUAGE, - * hdrs.CONTENT_LENGTH, - * hdrs.CONTENT_LOCATION, # <<<<<<<<<<<<<< - * hdrs.CONTENT_MD5, - * hdrs.CONTENT_RANGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_24 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LOCATION); if (unlikely(!__pyx_t_24)) __PYX_ERR(5, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_24); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":29 - * hdrs.CONTENT_LENGTH, - * hdrs.CONTENT_LOCATION, - * hdrs.CONTENT_MD5, # <<<<<<<<<<<<<< - * hdrs.CONTENT_RANGE, - * hdrs.CONTENT_TRANSFER_ENCODING, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_25 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_MD5); if (unlikely(!__pyx_t_25)) __PYX_ERR(5, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_25); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":30 - * hdrs.CONTENT_LOCATION, - * hdrs.CONTENT_MD5, - * hdrs.CONTENT_RANGE, # <<<<<<<<<<<<<< - * hdrs.CONTENT_TRANSFER_ENCODING, - * hdrs.CONTENT_TYPE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_26 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_RANGE); if (unlikely(!__pyx_t_26)) __PYX_ERR(5, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_26); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":31 - * hdrs.CONTENT_MD5, - * hdrs.CONTENT_RANGE, - * hdrs.CONTENT_TRANSFER_ENCODING, # <<<<<<<<<<<<<< - * hdrs.CONTENT_TYPE, - * hdrs.COOKIE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_27 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_TRANSFER_ENCODING); if (unlikely(!__pyx_t_27)) __PYX_ERR(5, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_27); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":32 - * hdrs.CONTENT_RANGE, - * hdrs.CONTENT_TRANSFER_ENCODING, - * hdrs.CONTENT_TYPE, # <<<<<<<<<<<<<< - * hdrs.COOKIE, - * hdrs.DATE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_28 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_TYPE); if (unlikely(!__pyx_t_28)) __PYX_ERR(5, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_28); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":33 - * hdrs.CONTENT_TRANSFER_ENCODING, - * hdrs.CONTENT_TYPE, - * hdrs.COOKIE, # <<<<<<<<<<<<<< - * hdrs.DATE, - * hdrs.DESTINATION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_29 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_COOKIE); if (unlikely(!__pyx_t_29)) __PYX_ERR(5, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_29); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":34 - * hdrs.CONTENT_TYPE, - * hdrs.COOKIE, - * hdrs.DATE, # <<<<<<<<<<<<<< - * hdrs.DESTINATION, - * hdrs.DIGEST, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 34, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_30 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DATE); if (unlikely(!__pyx_t_30)) __PYX_ERR(5, 34, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_30); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":35 - * hdrs.COOKIE, - * hdrs.DATE, - * hdrs.DESTINATION, # <<<<<<<<<<<<<< - * hdrs.DIGEST, - * hdrs.ETAG, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_31 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DESTINATION); if (unlikely(!__pyx_t_31)) __PYX_ERR(5, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_31); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":36 - * hdrs.DATE, - * hdrs.DESTINATION, - * hdrs.DIGEST, # <<<<<<<<<<<<<< - * hdrs.ETAG, - * hdrs.EXPECT, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 36, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_32 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DIGEST); if (unlikely(!__pyx_t_32)) __PYX_ERR(5, 36, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_32); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":37 - * hdrs.DESTINATION, - * hdrs.DIGEST, - * hdrs.ETAG, # <<<<<<<<<<<<<< - * hdrs.EXPECT, - * hdrs.EXPIRES, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_33 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ETAG); if (unlikely(!__pyx_t_33)) __PYX_ERR(5, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_33); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":38 - * hdrs.DIGEST, - * hdrs.ETAG, - * hdrs.EXPECT, # <<<<<<<<<<<<<< - * hdrs.EXPIRES, - * hdrs.FORWARDED, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 38, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_34 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_EXPECT); if (unlikely(!__pyx_t_34)) __PYX_ERR(5, 38, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_34); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":39 - * hdrs.ETAG, - * hdrs.EXPECT, - * hdrs.EXPIRES, # <<<<<<<<<<<<<< - * hdrs.FORWARDED, - * hdrs.FROM, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_35 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_EXPIRES); if (unlikely(!__pyx_t_35)) __PYX_ERR(5, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_35); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":40 - * hdrs.EXPECT, - * hdrs.EXPIRES, - * hdrs.FORWARDED, # <<<<<<<<<<<<<< - * hdrs.FROM, - * hdrs.HOST, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_36 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_FORWARDED); if (unlikely(!__pyx_t_36)) __PYX_ERR(5, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_36); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":41 - * hdrs.EXPIRES, - * hdrs.FORWARDED, - * hdrs.FROM, # <<<<<<<<<<<<<< - * hdrs.HOST, - * hdrs.IF_MATCH, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 41, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_37 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_FROM); if (unlikely(!__pyx_t_37)) __PYX_ERR(5, 41, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_37); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":42 - * hdrs.FORWARDED, - * hdrs.FROM, - * hdrs.HOST, # <<<<<<<<<<<<<< - * hdrs.IF_MATCH, - * hdrs.IF_MODIFIED_SINCE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 42, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_38 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_HOST); if (unlikely(!__pyx_t_38)) __PYX_ERR(5, 42, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_38); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":43 - * hdrs.FROM, - * hdrs.HOST, - * hdrs.IF_MATCH, # <<<<<<<<<<<<<< - * hdrs.IF_MODIFIED_SINCE, - * hdrs.IF_NONE_MATCH, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 43, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_39 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_MATCH); if (unlikely(!__pyx_t_39)) __PYX_ERR(5, 43, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_39); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":44 - * hdrs.HOST, - * hdrs.IF_MATCH, - * hdrs.IF_MODIFIED_SINCE, # <<<<<<<<<<<<<< - * hdrs.IF_NONE_MATCH, - * hdrs.IF_RANGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_40 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_MODIFIED_SINCE); if (unlikely(!__pyx_t_40)) __PYX_ERR(5, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_40); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":45 - * hdrs.IF_MATCH, - * hdrs.IF_MODIFIED_SINCE, - * hdrs.IF_NONE_MATCH, # <<<<<<<<<<<<<< - * hdrs.IF_RANGE, - * hdrs.IF_UNMODIFIED_SINCE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_41 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_NONE_MATCH); if (unlikely(!__pyx_t_41)) __PYX_ERR(5, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_41); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":46 - * hdrs.IF_MODIFIED_SINCE, - * hdrs.IF_NONE_MATCH, - * hdrs.IF_RANGE, # <<<<<<<<<<<<<< - * hdrs.IF_UNMODIFIED_SINCE, - * hdrs.KEEP_ALIVE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_42 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_RANGE); if (unlikely(!__pyx_t_42)) __PYX_ERR(5, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_42); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":47 - * hdrs.IF_NONE_MATCH, - * hdrs.IF_RANGE, - * hdrs.IF_UNMODIFIED_SINCE, # <<<<<<<<<<<<<< - * hdrs.KEEP_ALIVE, - * hdrs.LAST_EVENT_ID, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_43 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_UNMODIFIED_SINCE); if (unlikely(!__pyx_t_43)) __PYX_ERR(5, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_43); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":48 - * hdrs.IF_RANGE, - * hdrs.IF_UNMODIFIED_SINCE, - * hdrs.KEEP_ALIVE, # <<<<<<<<<<<<<< - * hdrs.LAST_EVENT_ID, - * hdrs.LAST_MODIFIED, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 48, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_44 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_KEEP_ALIVE); if (unlikely(!__pyx_t_44)) __PYX_ERR(5, 48, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_44); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":49 - * hdrs.IF_UNMODIFIED_SINCE, - * hdrs.KEEP_ALIVE, - * hdrs.LAST_EVENT_ID, # <<<<<<<<<<<<<< - * hdrs.LAST_MODIFIED, - * hdrs.LINK, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 49, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_45 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LAST_EVENT_ID); if (unlikely(!__pyx_t_45)) __PYX_ERR(5, 49, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_45); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":50 - * hdrs.KEEP_ALIVE, - * hdrs.LAST_EVENT_ID, - * hdrs.LAST_MODIFIED, # <<<<<<<<<<<<<< - * hdrs.LINK, - * hdrs.LOCATION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_46 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LAST_MODIFIED); if (unlikely(!__pyx_t_46)) __PYX_ERR(5, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_46); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":51 - * hdrs.LAST_EVENT_ID, - * hdrs.LAST_MODIFIED, - * hdrs.LINK, # <<<<<<<<<<<<<< - * hdrs.LOCATION, - * hdrs.MAX_FORWARDS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_47 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LINK); if (unlikely(!__pyx_t_47)) __PYX_ERR(5, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_47); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":52 - * hdrs.LAST_MODIFIED, - * hdrs.LINK, - * hdrs.LOCATION, # <<<<<<<<<<<<<< - * hdrs.MAX_FORWARDS, - * hdrs.ORIGIN, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 52, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_48 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LOCATION); if (unlikely(!__pyx_t_48)) __PYX_ERR(5, 52, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_48); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":53 - * hdrs.LINK, - * hdrs.LOCATION, - * hdrs.MAX_FORWARDS, # <<<<<<<<<<<<<< - * hdrs.ORIGIN, - * hdrs.PRAGMA, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_49 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_MAX_FORWARDS); if (unlikely(!__pyx_t_49)) __PYX_ERR(5, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_49); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":54 - * hdrs.LOCATION, - * hdrs.MAX_FORWARDS, - * hdrs.ORIGIN, # <<<<<<<<<<<<<< - * hdrs.PRAGMA, - * hdrs.PROXY_AUTHENTICATE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_50 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ORIGIN); if (unlikely(!__pyx_t_50)) __PYX_ERR(5, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_50); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":55 - * hdrs.MAX_FORWARDS, - * hdrs.ORIGIN, - * hdrs.PRAGMA, # <<<<<<<<<<<<<< - * hdrs.PROXY_AUTHENTICATE, - * hdrs.PROXY_AUTHORIZATION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 55, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_51 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PRAGMA); if (unlikely(!__pyx_t_51)) __PYX_ERR(5, 55, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_51); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":56 - * hdrs.ORIGIN, - * hdrs.PRAGMA, - * hdrs.PROXY_AUTHENTICATE, # <<<<<<<<<<<<<< - * hdrs.PROXY_AUTHORIZATION, - * hdrs.RANGE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_52 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PROXY_AUTHENTICATE); if (unlikely(!__pyx_t_52)) __PYX_ERR(5, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_52); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":57 - * hdrs.PRAGMA, - * hdrs.PROXY_AUTHENTICATE, - * hdrs.PROXY_AUTHORIZATION, # <<<<<<<<<<<<<< - * hdrs.RANGE, - * hdrs.REFERER, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_53 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PROXY_AUTHORIZATION); if (unlikely(!__pyx_t_53)) __PYX_ERR(5, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_53); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":58 - * hdrs.PROXY_AUTHENTICATE, - * hdrs.PROXY_AUTHORIZATION, - * hdrs.RANGE, # <<<<<<<<<<<<<< - * hdrs.REFERER, - * hdrs.RETRY_AFTER, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_54 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_RANGE); if (unlikely(!__pyx_t_54)) __PYX_ERR(5, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_54); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":59 - * hdrs.PROXY_AUTHORIZATION, - * hdrs.RANGE, - * hdrs.REFERER, # <<<<<<<<<<<<<< - * hdrs.RETRY_AFTER, - * hdrs.SEC_WEBSOCKET_ACCEPT, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_55 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_REFERER); if (unlikely(!__pyx_t_55)) __PYX_ERR(5, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_55); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":60 - * hdrs.RANGE, - * hdrs.REFERER, - * hdrs.RETRY_AFTER, # <<<<<<<<<<<<<< - * hdrs.SEC_WEBSOCKET_ACCEPT, - * hdrs.SEC_WEBSOCKET_EXTENSIONS, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_56 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_RETRY_AFTER); if (unlikely(!__pyx_t_56)) __PYX_ERR(5, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_56); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":61 - * hdrs.REFERER, - * hdrs.RETRY_AFTER, - * hdrs.SEC_WEBSOCKET_ACCEPT, # <<<<<<<<<<<<<< - * hdrs.SEC_WEBSOCKET_EXTENSIONS, - * hdrs.SEC_WEBSOCKET_KEY, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_57 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_ACCEPT); if (unlikely(!__pyx_t_57)) __PYX_ERR(5, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_57); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":62 - * hdrs.RETRY_AFTER, - * hdrs.SEC_WEBSOCKET_ACCEPT, - * hdrs.SEC_WEBSOCKET_EXTENSIONS, # <<<<<<<<<<<<<< - * hdrs.SEC_WEBSOCKET_KEY, - * hdrs.SEC_WEBSOCKET_KEY1, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_58 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_EXTENSIONS); if (unlikely(!__pyx_t_58)) __PYX_ERR(5, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_58); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":63 - * hdrs.SEC_WEBSOCKET_ACCEPT, - * hdrs.SEC_WEBSOCKET_EXTENSIONS, - * hdrs.SEC_WEBSOCKET_KEY, # <<<<<<<<<<<<<< - * hdrs.SEC_WEBSOCKET_KEY1, - * hdrs.SEC_WEBSOCKET_PROTOCOL, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_59 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY); if (unlikely(!__pyx_t_59)) __PYX_ERR(5, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_59); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":64 - * hdrs.SEC_WEBSOCKET_EXTENSIONS, - * hdrs.SEC_WEBSOCKET_KEY, - * hdrs.SEC_WEBSOCKET_KEY1, # <<<<<<<<<<<<<< - * hdrs.SEC_WEBSOCKET_PROTOCOL, - * hdrs.SEC_WEBSOCKET_VERSION, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 64, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_60 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_60)) __PYX_ERR(5, 64, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_60); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":65 - * hdrs.SEC_WEBSOCKET_KEY, - * hdrs.SEC_WEBSOCKET_KEY1, - * hdrs.SEC_WEBSOCKET_PROTOCOL, # <<<<<<<<<<<<<< - * hdrs.SEC_WEBSOCKET_VERSION, - * hdrs.SERVER, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 65, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_61 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_PROTOCOL); if (unlikely(!__pyx_t_61)) __PYX_ERR(5, 65, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_61); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":66 - * hdrs.SEC_WEBSOCKET_KEY1, - * hdrs.SEC_WEBSOCKET_PROTOCOL, - * hdrs.SEC_WEBSOCKET_VERSION, # <<<<<<<<<<<<<< - * hdrs.SERVER, - * hdrs.SET_COOKIE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_62 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_VERSION); if (unlikely(!__pyx_t_62)) __PYX_ERR(5, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_62); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":67 - * hdrs.SEC_WEBSOCKET_PROTOCOL, - * hdrs.SEC_WEBSOCKET_VERSION, - * hdrs.SERVER, # <<<<<<<<<<<<<< - * hdrs.SET_COOKIE, - * hdrs.TE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_63 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SERVER); if (unlikely(!__pyx_t_63)) __PYX_ERR(5, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_63); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":68 - * hdrs.SEC_WEBSOCKET_VERSION, - * hdrs.SERVER, - * hdrs.SET_COOKIE, # <<<<<<<<<<<<<< - * hdrs.TE, - * hdrs.TRAILER, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_64 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SET_COOKIE); if (unlikely(!__pyx_t_64)) __PYX_ERR(5, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_64); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":69 - * hdrs.SERVER, - * hdrs.SET_COOKIE, - * hdrs.TE, # <<<<<<<<<<<<<< - * hdrs.TRAILER, - * hdrs.TRANSFER_ENCODING, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TE); if (unlikely(!__pyx_t_65)) __PYX_ERR(5, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_65); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":70 - * hdrs.SET_COOKIE, - * hdrs.TE, - * hdrs.TRAILER, # <<<<<<<<<<<<<< - * hdrs.TRANSFER_ENCODING, - * hdrs.URI, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TRAILER); if (unlikely(!__pyx_t_66)) __PYX_ERR(5, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_66); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":71 - * hdrs.TE, - * hdrs.TRAILER, - * hdrs.TRANSFER_ENCODING, # <<<<<<<<<<<<<< - * hdrs.URI, - * hdrs.UPGRADE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TRANSFER_ENCODING); if (unlikely(!__pyx_t_67)) __PYX_ERR(5, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_67); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":72 - * hdrs.TRAILER, - * hdrs.TRANSFER_ENCODING, - * hdrs.URI, # <<<<<<<<<<<<<< - * hdrs.UPGRADE, - * hdrs.USER_AGENT, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 72, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_68 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_URI); if (unlikely(!__pyx_t_68)) __PYX_ERR(5, 72, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_68); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":73 - * hdrs.TRANSFER_ENCODING, - * hdrs.URI, - * hdrs.UPGRADE, # <<<<<<<<<<<<<< - * hdrs.USER_AGENT, - * hdrs.VARY, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_69 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_UPGRADE); if (unlikely(!__pyx_t_69)) __PYX_ERR(5, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_69); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":74 - * hdrs.URI, - * hdrs.UPGRADE, - * hdrs.USER_AGENT, # <<<<<<<<<<<<<< - * hdrs.VARY, - * hdrs.VIA, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_70 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_USER_AGENT); if (unlikely(!__pyx_t_70)) __PYX_ERR(5, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_70); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":75 - * hdrs.UPGRADE, - * hdrs.USER_AGENT, - * hdrs.VARY, # <<<<<<<<<<<<<< - * hdrs.VIA, - * hdrs.WWW_AUTHENTICATE, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 75, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_71 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_VARY); if (unlikely(!__pyx_t_71)) __PYX_ERR(5, 75, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_71); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":76 - * hdrs.USER_AGENT, - * hdrs.VARY, - * hdrs.VIA, # <<<<<<<<<<<<<< - * hdrs.WWW_AUTHENTICATE, - * hdrs.WANT_DIGEST, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 76, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_72 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_VIA); if (unlikely(!__pyx_t_72)) __PYX_ERR(5, 76, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_72); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":77 - * hdrs.VARY, - * hdrs.VIA, - * hdrs.WWW_AUTHENTICATE, # <<<<<<<<<<<<<< - * hdrs.WANT_DIGEST, - * hdrs.WARNING, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_73 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WWW_AUTHENTICATE); if (unlikely(!__pyx_t_73)) __PYX_ERR(5, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_73); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":78 - * hdrs.VIA, - * hdrs.WWW_AUTHENTICATE, - * hdrs.WANT_DIGEST, # <<<<<<<<<<<<<< - * hdrs.WARNING, - * hdrs.X_FORWARDED_FOR, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_74 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WANT_DIGEST); if (unlikely(!__pyx_t_74)) __PYX_ERR(5, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_74); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":79 - * hdrs.WWW_AUTHENTICATE, - * hdrs.WANT_DIGEST, - * hdrs.WARNING, # <<<<<<<<<<<<<< - * hdrs.X_FORWARDED_FOR, - * hdrs.X_FORWARDED_HOST, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 79, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_75 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WARNING); if (unlikely(!__pyx_t_75)) __PYX_ERR(5, 79, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_75); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":80 - * hdrs.WANT_DIGEST, - * hdrs.WARNING, - * hdrs.X_FORWARDED_FOR, # <<<<<<<<<<<<<< - * hdrs.X_FORWARDED_HOST, - * hdrs.X_FORWARDED_PROTO, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_76 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_FOR); if (unlikely(!__pyx_t_76)) __PYX_ERR(5, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_76); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":81 - * hdrs.WARNING, - * hdrs.X_FORWARDED_FOR, - * hdrs.X_FORWARDED_HOST, # <<<<<<<<<<<<<< - * hdrs.X_FORWARDED_PROTO, - * ) - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_77 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_HOST); if (unlikely(!__pyx_t_77)) __PYX_ERR(5, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_77); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":82 - * hdrs.X_FORWARDED_FOR, - * hdrs.X_FORWARDED_HOST, - * hdrs.X_FORWARDED_PROTO, # <<<<<<<<<<<<<< - * ) - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_78 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_PROTO); if (unlikely(!__pyx_t_78)) __PYX_ERR(5, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_78); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_headers.pxi":6 - * from . import hdrs - * cdef tuple headers = ( - * hdrs.ACCEPT, # <<<<<<<<<<<<<< - * hdrs.ACCEPT_CHARSET, - * hdrs.ACCEPT_ENCODING, - */ - __pyx_t_1 = PyTuple_New(77); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_t_8); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_t_9); - __Pyx_GIVEREF(__pyx_t_10); - PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_t_10); - __Pyx_GIVEREF(__pyx_t_11); - PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_t_11); - __Pyx_GIVEREF(__pyx_t_12); - PyTuple_SET_ITEM(__pyx_t_1, 10, __pyx_t_12); - __Pyx_GIVEREF(__pyx_t_13); - PyTuple_SET_ITEM(__pyx_t_1, 11, __pyx_t_13); - __Pyx_GIVEREF(__pyx_t_14); - PyTuple_SET_ITEM(__pyx_t_1, 12, __pyx_t_14); - __Pyx_GIVEREF(__pyx_t_15); - PyTuple_SET_ITEM(__pyx_t_1, 13, __pyx_t_15); - __Pyx_GIVEREF(__pyx_t_16); - PyTuple_SET_ITEM(__pyx_t_1, 14, __pyx_t_16); - __Pyx_GIVEREF(__pyx_t_17); - PyTuple_SET_ITEM(__pyx_t_1, 15, __pyx_t_17); - __Pyx_GIVEREF(__pyx_t_18); - PyTuple_SET_ITEM(__pyx_t_1, 16, __pyx_t_18); - __Pyx_GIVEREF(__pyx_t_19); - PyTuple_SET_ITEM(__pyx_t_1, 17, __pyx_t_19); - __Pyx_GIVEREF(__pyx_t_20); - PyTuple_SET_ITEM(__pyx_t_1, 18, __pyx_t_20); - __Pyx_GIVEREF(__pyx_t_21); - PyTuple_SET_ITEM(__pyx_t_1, 19, __pyx_t_21); - __Pyx_GIVEREF(__pyx_t_22); - PyTuple_SET_ITEM(__pyx_t_1, 20, __pyx_t_22); - __Pyx_GIVEREF(__pyx_t_23); - PyTuple_SET_ITEM(__pyx_t_1, 21, __pyx_t_23); - __Pyx_GIVEREF(__pyx_t_24); - PyTuple_SET_ITEM(__pyx_t_1, 22, __pyx_t_24); - __Pyx_GIVEREF(__pyx_t_25); - PyTuple_SET_ITEM(__pyx_t_1, 23, __pyx_t_25); - __Pyx_GIVEREF(__pyx_t_26); - PyTuple_SET_ITEM(__pyx_t_1, 24, __pyx_t_26); - __Pyx_GIVEREF(__pyx_t_27); - PyTuple_SET_ITEM(__pyx_t_1, 25, __pyx_t_27); - __Pyx_GIVEREF(__pyx_t_28); - PyTuple_SET_ITEM(__pyx_t_1, 26, __pyx_t_28); - __Pyx_GIVEREF(__pyx_t_29); - PyTuple_SET_ITEM(__pyx_t_1, 27, __pyx_t_29); - __Pyx_GIVEREF(__pyx_t_30); - PyTuple_SET_ITEM(__pyx_t_1, 28, __pyx_t_30); - __Pyx_GIVEREF(__pyx_t_31); - PyTuple_SET_ITEM(__pyx_t_1, 29, __pyx_t_31); - __Pyx_GIVEREF(__pyx_t_32); - PyTuple_SET_ITEM(__pyx_t_1, 30, __pyx_t_32); - __Pyx_GIVEREF(__pyx_t_33); - PyTuple_SET_ITEM(__pyx_t_1, 31, __pyx_t_33); - __Pyx_GIVEREF(__pyx_t_34); - PyTuple_SET_ITEM(__pyx_t_1, 32, __pyx_t_34); - __Pyx_GIVEREF(__pyx_t_35); - PyTuple_SET_ITEM(__pyx_t_1, 33, __pyx_t_35); - __Pyx_GIVEREF(__pyx_t_36); - PyTuple_SET_ITEM(__pyx_t_1, 34, __pyx_t_36); - __Pyx_GIVEREF(__pyx_t_37); - PyTuple_SET_ITEM(__pyx_t_1, 35, __pyx_t_37); - __Pyx_GIVEREF(__pyx_t_38); - PyTuple_SET_ITEM(__pyx_t_1, 36, __pyx_t_38); - __Pyx_GIVEREF(__pyx_t_39); - PyTuple_SET_ITEM(__pyx_t_1, 37, __pyx_t_39); - __Pyx_GIVEREF(__pyx_t_40); - PyTuple_SET_ITEM(__pyx_t_1, 38, __pyx_t_40); - __Pyx_GIVEREF(__pyx_t_41); - PyTuple_SET_ITEM(__pyx_t_1, 39, __pyx_t_41); - __Pyx_GIVEREF(__pyx_t_42); - PyTuple_SET_ITEM(__pyx_t_1, 40, __pyx_t_42); - __Pyx_GIVEREF(__pyx_t_43); - PyTuple_SET_ITEM(__pyx_t_1, 41, __pyx_t_43); - __Pyx_GIVEREF(__pyx_t_44); - PyTuple_SET_ITEM(__pyx_t_1, 42, __pyx_t_44); - __Pyx_GIVEREF(__pyx_t_45); - PyTuple_SET_ITEM(__pyx_t_1, 43, __pyx_t_45); - __Pyx_GIVEREF(__pyx_t_46); - PyTuple_SET_ITEM(__pyx_t_1, 44, __pyx_t_46); - __Pyx_GIVEREF(__pyx_t_47); - PyTuple_SET_ITEM(__pyx_t_1, 45, __pyx_t_47); - __Pyx_GIVEREF(__pyx_t_48); - PyTuple_SET_ITEM(__pyx_t_1, 46, __pyx_t_48); - __Pyx_GIVEREF(__pyx_t_49); - PyTuple_SET_ITEM(__pyx_t_1, 47, __pyx_t_49); - __Pyx_GIVEREF(__pyx_t_50); - PyTuple_SET_ITEM(__pyx_t_1, 48, __pyx_t_50); - __Pyx_GIVEREF(__pyx_t_51); - PyTuple_SET_ITEM(__pyx_t_1, 49, __pyx_t_51); - __Pyx_GIVEREF(__pyx_t_52); - PyTuple_SET_ITEM(__pyx_t_1, 50, __pyx_t_52); - __Pyx_GIVEREF(__pyx_t_53); - PyTuple_SET_ITEM(__pyx_t_1, 51, __pyx_t_53); - __Pyx_GIVEREF(__pyx_t_54); - PyTuple_SET_ITEM(__pyx_t_1, 52, __pyx_t_54); - __Pyx_GIVEREF(__pyx_t_55); - PyTuple_SET_ITEM(__pyx_t_1, 53, __pyx_t_55); - __Pyx_GIVEREF(__pyx_t_56); - PyTuple_SET_ITEM(__pyx_t_1, 54, __pyx_t_56); - __Pyx_GIVEREF(__pyx_t_57); - PyTuple_SET_ITEM(__pyx_t_1, 55, __pyx_t_57); - __Pyx_GIVEREF(__pyx_t_58); - PyTuple_SET_ITEM(__pyx_t_1, 56, __pyx_t_58); - __Pyx_GIVEREF(__pyx_t_59); - PyTuple_SET_ITEM(__pyx_t_1, 57, __pyx_t_59); - __Pyx_GIVEREF(__pyx_t_60); - PyTuple_SET_ITEM(__pyx_t_1, 58, __pyx_t_60); - __Pyx_GIVEREF(__pyx_t_61); - PyTuple_SET_ITEM(__pyx_t_1, 59, __pyx_t_61); - __Pyx_GIVEREF(__pyx_t_62); - PyTuple_SET_ITEM(__pyx_t_1, 60, __pyx_t_62); - __Pyx_GIVEREF(__pyx_t_63); - PyTuple_SET_ITEM(__pyx_t_1, 61, __pyx_t_63); - __Pyx_GIVEREF(__pyx_t_64); - PyTuple_SET_ITEM(__pyx_t_1, 62, __pyx_t_64); - __Pyx_GIVEREF(__pyx_t_65); - PyTuple_SET_ITEM(__pyx_t_1, 63, __pyx_t_65); - __Pyx_GIVEREF(__pyx_t_66); - PyTuple_SET_ITEM(__pyx_t_1, 64, __pyx_t_66); - __Pyx_GIVEREF(__pyx_t_67); - PyTuple_SET_ITEM(__pyx_t_1, 65, __pyx_t_67); - __Pyx_GIVEREF(__pyx_t_68); - PyTuple_SET_ITEM(__pyx_t_1, 66, __pyx_t_68); - __Pyx_GIVEREF(__pyx_t_69); - PyTuple_SET_ITEM(__pyx_t_1, 67, __pyx_t_69); - __Pyx_GIVEREF(__pyx_t_70); - PyTuple_SET_ITEM(__pyx_t_1, 68, __pyx_t_70); - __Pyx_GIVEREF(__pyx_t_71); - PyTuple_SET_ITEM(__pyx_t_1, 69, __pyx_t_71); - __Pyx_GIVEREF(__pyx_t_72); - PyTuple_SET_ITEM(__pyx_t_1, 70, __pyx_t_72); - __Pyx_GIVEREF(__pyx_t_73); - PyTuple_SET_ITEM(__pyx_t_1, 71, __pyx_t_73); - __Pyx_GIVEREF(__pyx_t_74); - PyTuple_SET_ITEM(__pyx_t_1, 72, __pyx_t_74); - __Pyx_GIVEREF(__pyx_t_75); - PyTuple_SET_ITEM(__pyx_t_1, 73, __pyx_t_75); - __Pyx_GIVEREF(__pyx_t_76); - PyTuple_SET_ITEM(__pyx_t_1, 74, __pyx_t_76); - __Pyx_GIVEREF(__pyx_t_77); - PyTuple_SET_ITEM(__pyx_t_1, 75, __pyx_t_77); - __Pyx_GIVEREF(__pyx_t_78); - PyTuple_SET_ITEM(__pyx_t_1, 76, __pyx_t_78); - __pyx_t_2 = 0; - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_t_5 = 0; - __pyx_t_6 = 0; - __pyx_t_7 = 0; - __pyx_t_8 = 0; - __pyx_t_9 = 0; - __pyx_t_10 = 0; - __pyx_t_11 = 0; - __pyx_t_12 = 0; - __pyx_t_13 = 0; - __pyx_t_14 = 0; - __pyx_t_15 = 0; - __pyx_t_16 = 0; - __pyx_t_17 = 0; - __pyx_t_18 = 0; - __pyx_t_19 = 0; - __pyx_t_20 = 0; - __pyx_t_21 = 0; - __pyx_t_22 = 0; - __pyx_t_23 = 0; - __pyx_t_24 = 0; - __pyx_t_25 = 0; - __pyx_t_26 = 0; - __pyx_t_27 = 0; - __pyx_t_28 = 0; - __pyx_t_29 = 0; - __pyx_t_30 = 0; - __pyx_t_31 = 0; - __pyx_t_32 = 0; - __pyx_t_33 = 0; - __pyx_t_34 = 0; - __pyx_t_35 = 0; - __pyx_t_36 = 0; - __pyx_t_37 = 0; - __pyx_t_38 = 0; - __pyx_t_39 = 0; - __pyx_t_40 = 0; - __pyx_t_41 = 0; - __pyx_t_42 = 0; - __pyx_t_43 = 0; - __pyx_t_44 = 0; - __pyx_t_45 = 0; - __pyx_t_46 = 0; - __pyx_t_47 = 0; - __pyx_t_48 = 0; - __pyx_t_49 = 0; - __pyx_t_50 = 0; - __pyx_t_51 = 0; - __pyx_t_52 = 0; - __pyx_t_53 = 0; - __pyx_t_54 = 0; - __pyx_t_55 = 0; - __pyx_t_56 = 0; - __pyx_t_57 = 0; - __pyx_t_58 = 0; - __pyx_t_59 = 0; - __pyx_t_60 = 0; - __pyx_t_61 = 0; - __pyx_t_62 = 0; - __pyx_t_63 = 0; - __pyx_t_64 = 0; - __pyx_t_65 = 0; - __pyx_t_66 = 0; - __pyx_t_67 = 0; - __pyx_t_68 = 0; - __pyx_t_69 = 0; - __pyx_t_70 = 0; - __pyx_t_71 = 0; - __pyx_t_72 = 0; - __pyx_t_73 = 0; - __pyx_t_74 = 0; - __pyx_t_75 = 0; - __pyx_t_76 = 0; - __pyx_t_77 = 0; - __pyx_t_78 = 0; - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_headers); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_headers, ((PyObject*)__pyx_t_1)); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":57 - * char* PyByteArray_AsString(object) - * - * __all__ = ('HttpRequestParser', 'HttpResponseParser', # <<<<<<<<<<<<<< - * 'RawRequestMessage', 'RawResponseMessage') - * - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_tuple__12) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - - /* "aiohttp/_http_parser.pyx":60 - * 'RawRequestMessage', 'RawResponseMessage') - * - * cdef object URL = _URL # <<<<<<<<<<<<<< - * cdef object URL_build = URL.build - * cdef object CIMultiDict = _CIMultiDict - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_URL_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_URL); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":61 - * - * cdef object URL = _URL - * cdef object URL_build = URL.build # <<<<<<<<<<<<<< - * cdef object CIMultiDict = _CIMultiDict - * cdef object CIMultiDictProxy = _CIMultiDictProxy - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_n_s_build); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_URL_build); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL_build, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":62 - * cdef object URL = _URL - * cdef object URL_build = URL.build - * cdef object CIMultiDict = _CIMultiDict # <<<<<<<<<<<<<< - * cdef object CIMultiDictProxy = _CIMultiDictProxy - * cdef object HttpVersion = _HttpVersion - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_CIMultiDict_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDict); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDict, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":63 - * cdef object URL_build = URL.build - * cdef object CIMultiDict = _CIMultiDict - * cdef object CIMultiDictProxy = _CIMultiDictProxy # <<<<<<<<<<<<<< - * cdef object HttpVersion = _HttpVersion - * cdef object HttpVersion10 = _HttpVersion10 - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_CIMultiDictProxy_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":64 - * cdef object CIMultiDict = _CIMultiDict - * cdef object CIMultiDictProxy = _CIMultiDictProxy - * cdef object HttpVersion = _HttpVersion # <<<<<<<<<<<<<< - * cdef object HttpVersion10 = _HttpVersion10 - * cdef object HttpVersion11 = _HttpVersion11 - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":65 - * cdef object CIMultiDictProxy = _CIMultiDictProxy - * cdef object HttpVersion = _HttpVersion - * cdef object HttpVersion10 = _HttpVersion10 # <<<<<<<<<<<<<< - * cdef object HttpVersion11 = _HttpVersion11 - * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion10_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion10); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion10, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":66 - * cdef object HttpVersion = _HttpVersion - * cdef object HttpVersion10 = _HttpVersion10 - * cdef object HttpVersion11 = _HttpVersion11 # <<<<<<<<<<<<<< - * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 - * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion11_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion11); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion11, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":67 - * cdef object HttpVersion10 = _HttpVersion10 - * cdef object HttpVersion11 = _HttpVersion11 - * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 # <<<<<<<<<<<<<< - * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING - * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_78 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_78)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_78); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_t_78); - __Pyx_GIVEREF(__pyx_t_78); - __pyx_t_78 = 0; - - /* "aiohttp/_http_parser.pyx":68 - * cdef object HttpVersion11 = _HttpVersion11 - * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 - * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING # <<<<<<<<<<<<<< - * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD - * cdef object StreamReader = _StreamReader - */ - __Pyx_GetModuleGlobalName(__pyx_t_78, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_78)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_78); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_78, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_78); __pyx_t_78 = 0; - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":69 - * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 - * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING - * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD # <<<<<<<<<<<<<< - * cdef object StreamReader = _StreamReader - * cdef object DeflateBuffer = _DeflateBuffer - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_EMPTY_PAYLOAD_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":70 - * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING - * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD - * cdef object StreamReader = _StreamReader # <<<<<<<<<<<<<< - * cdef object DeflateBuffer = _DeflateBuffer - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_StreamReader_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_StreamReader); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":71 - * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD - * cdef object StreamReader = _StreamReader - * cdef object DeflateBuffer = _DeflateBuffer # <<<<<<<<<<<<<< - * - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DeflateBuffer_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":85 - * DEF METHODS_COUNT = 34; - * - * cdef list _http_method = [] # <<<<<<<<<<<<<< - * - * for i in range(METHODS_COUNT): - */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser__http_method); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser__http_method, ((PyObject*)__pyx_t_1)); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":87 - * cdef list _http_method = [] - * - * for i in range(METHODS_COUNT): # <<<<<<<<<<<<<< - * _http_method.append( - * cparser.http_method_str( i).decode('ascii')) - */ - for (__pyx_t_79 = 0; __pyx_t_79 < 34; __pyx_t_79+=1) { - __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_t_79); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_i, __pyx_t_1) < 0) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":88 - * - * for i in range(METHODS_COUNT): - * _http_method.append( # <<<<<<<<<<<<<< - * cparser.http_method_str( i).decode('ascii')) - * - */ - if (unlikely(__pyx_v_7aiohttp_12_http_parser__http_method == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); - __PYX_ERR(0, 88, __pyx_L1_error) - } - - /* "aiohttp/_http_parser.pyx":89 - * for i in range(METHODS_COUNT): - * _http_method.append( - * cparser.http_method_str( i).decode('ascii')) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_80 = ((enum http_method)__Pyx_PyInt_As_enum__http_method(__pyx_t_1)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_81 = http_method_str(((enum http_method)__pyx_t_80)); - __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_81, 0, strlen(__pyx_t_81), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - - /* "aiohttp/_http_parser.pyx":88 - * - * for i in range(METHODS_COUNT): - * _http_method.append( # <<<<<<<<<<<<<< - * cparser.http_method_str( i).decode('ascii')) - * - */ - __pyx_t_82 = __Pyx_PyList_Append(__pyx_v_7aiohttp_12_http_parser__http_method, __pyx_t_1); if (unlikely(__pyx_t_82 == ((int)-1))) __PYX_ERR(0, 88, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } - - /* "aiohttp/_http_parser.pyx":785 - * - * - * def parse_url(url): # <<<<<<<<<<<<<< - * cdef: - * Py_buffer py_buf - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_1parse_url, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 785, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_parse_url, __pyx_t_1) < 0) __PYX_ERR(0, 785, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawRequestMessage, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":11 - * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] - * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawResponseMessag, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_parser.pyx":1 - * #cython: language_level=3 # <<<<<<<<<<<<<< - * # - * # Based on https://github.com/MagicStack/httptools - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_XDECREF(__pyx_t_13); - __Pyx_XDECREF(__pyx_t_14); - __Pyx_XDECREF(__pyx_t_15); - __Pyx_XDECREF(__pyx_t_16); - __Pyx_XDECREF(__pyx_t_17); - __Pyx_XDECREF(__pyx_t_18); - __Pyx_XDECREF(__pyx_t_19); - __Pyx_XDECREF(__pyx_t_20); - __Pyx_XDECREF(__pyx_t_21); - __Pyx_XDECREF(__pyx_t_22); - __Pyx_XDECREF(__pyx_t_23); - __Pyx_XDECREF(__pyx_t_24); - __Pyx_XDECREF(__pyx_t_25); - __Pyx_XDECREF(__pyx_t_26); - __Pyx_XDECREF(__pyx_t_27); - __Pyx_XDECREF(__pyx_t_28); - __Pyx_XDECREF(__pyx_t_29); - __Pyx_XDECREF(__pyx_t_30); - __Pyx_XDECREF(__pyx_t_31); - __Pyx_XDECREF(__pyx_t_32); - __Pyx_XDECREF(__pyx_t_33); - __Pyx_XDECREF(__pyx_t_34); - __Pyx_XDECREF(__pyx_t_35); - __Pyx_XDECREF(__pyx_t_36); - __Pyx_XDECREF(__pyx_t_37); - __Pyx_XDECREF(__pyx_t_38); - __Pyx_XDECREF(__pyx_t_39); - __Pyx_XDECREF(__pyx_t_40); - __Pyx_XDECREF(__pyx_t_41); - __Pyx_XDECREF(__pyx_t_42); - __Pyx_XDECREF(__pyx_t_43); - __Pyx_XDECREF(__pyx_t_44); - __Pyx_XDECREF(__pyx_t_45); - __Pyx_XDECREF(__pyx_t_46); - __Pyx_XDECREF(__pyx_t_47); - __Pyx_XDECREF(__pyx_t_48); - __Pyx_XDECREF(__pyx_t_49); - __Pyx_XDECREF(__pyx_t_50); - __Pyx_XDECREF(__pyx_t_51); - __Pyx_XDECREF(__pyx_t_52); - __Pyx_XDECREF(__pyx_t_53); - __Pyx_XDECREF(__pyx_t_54); - __Pyx_XDECREF(__pyx_t_55); - __Pyx_XDECREF(__pyx_t_56); - __Pyx_XDECREF(__pyx_t_57); - __Pyx_XDECREF(__pyx_t_58); - __Pyx_XDECREF(__pyx_t_59); - __Pyx_XDECREF(__pyx_t_60); - __Pyx_XDECREF(__pyx_t_61); - __Pyx_XDECREF(__pyx_t_62); - __Pyx_XDECREF(__pyx_t_63); - __Pyx_XDECREF(__pyx_t_64); - __Pyx_XDECREF(__pyx_t_65); - __Pyx_XDECREF(__pyx_t_66); - __Pyx_XDECREF(__pyx_t_67); - __Pyx_XDECREF(__pyx_t_68); - __Pyx_XDECREF(__pyx_t_69); - __Pyx_XDECREF(__pyx_t_70); - __Pyx_XDECREF(__pyx_t_71); - __Pyx_XDECREF(__pyx_t_72); - __Pyx_XDECREF(__pyx_t_73); - __Pyx_XDECREF(__pyx_t_74); - __Pyx_XDECREF(__pyx_t_75); - __Pyx_XDECREF(__pyx_t_76); - __Pyx_XDECREF(__pyx_t_77); - __Pyx_XDECREF(__pyx_t_78); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._http_parser", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init aiohttp._http_parser"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* decode_c_bytes */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( - const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - if (unlikely((start < 0) | (stop < 0))) { - if (start < 0) { - start += length; - if (start < 0) - start = 0; - } - if (stop < 0) - stop += length; - } - if (stop > length) - stop = length; - if (unlikely(stop <= start)) - return __Pyx_NewRef(__pyx_empty_unicode); - length = stop - start; - cstring += start; - if (decode_func) { - return decode_func(cstring, length, errors); - } else { - return PyUnicode_Decode(cstring, length, encoding, errors); - } -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* None */ -static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) { - PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname); -} - -/* RaiseTooManyValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* IterFinish */ -static CYTHON_INLINE int __Pyx_IterFinish(void) { -#if CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* exc_type = tstate->curexc_type; - if (unlikely(exc_type)) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { - PyObject *exc_value, *exc_tb; - exc_value = tstate->curexc_value; - exc_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; - Py_DECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - return 0; - } else { - return -1; - } - } - return 0; -#else - if (unlikely(PyErr_Occurred())) { - if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { - PyErr_Clear(); - return 0; - } else { - return -1; - } - } - return 0; -#endif -} - -/* UnpackItemEndCheck */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { - if (unlikely(retval)) { - Py_DECREF(retval); - __Pyx_RaiseTooManyValuesError(expected); - return -1; - } else { - return __Pyx_IterFinish(); - } - return 0; -} - -/* KeywordStringCheck */ -static int __Pyx_CheckKeywordStrings( - PyObject *kwdict, - const char* function_name, - int kw_allowed) -{ - PyObject* key = 0; - Py_ssize_t pos = 0; -#if CYTHON_COMPILING_IN_PYPY - if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0)) - goto invalid_keyword; - return 1; -#else - while (PyDict_Next(kwdict, &pos, &key, 0)) { - #if PY_MAJOR_VERSION < 3 - if (unlikely(!PyString_Check(key))) - #endif - if (unlikely(!PyUnicode_Check(key))) - goto invalid_keyword_type; - } - if ((!kw_allowed) && unlikely(key)) - goto invalid_keyword; - return 1; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - return 0; -#endif -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif - return 0; -} - -/* ExtTypeTest */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", - Py_TYPE(obj)->tp_name, type->tp_name); - return 0; -} - -/* DictGetItem */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { - PyObject *value; - value = PyDict_GetItemWithError(d, key); - if (unlikely(!value)) { - if (!PyErr_Occurred()) { - if (unlikely(PyTuple_Check(key))) { - PyObject* args = PyTuple_Pack(1, key); - if (likely(args)) { - PyErr_SetObject(PyExc_KeyError, args); - Py_DECREF(args); - } - } else { - PyErr_SetObject(PyExc_KeyError, key); - } - } - return NULL; - } - Py_INCREF(value); - return value; -} -#endif - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* GetAttr */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) -#else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); -#endif - return PyObject_GetAttr(o, n); -} - -/* GetAttr3 */ -static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r = __Pyx_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallNoArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, NULL, 0); - } -#endif -#ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) -#else - if (likely(PyCFunction_Check(func))) -#endif - { - if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { - return __Pyx_PyObject_CallMethO(func, NULL); - } - } - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); -} -#endif - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* PyObjectCall2Args */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* BytesEquals */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -#endif -} - -/* UnicodeEquals */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; -#endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); -#if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) - return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } -#endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) - return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; - } -#if CYTHON_USE_UNICODE_INTERNALS - { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; - } - } -#endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_NE); -#endif -} - -/* SliceObject */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, - Py_ssize_t cstart, Py_ssize_t cstop, - PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, - int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { -#if CYTHON_USE_TYPE_SLOTS - PyMappingMethods* mp; -#if PY_MAJOR_VERSION < 3 - PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence; - if (likely(ms && ms->sq_slice)) { - if (!has_cstart) { - if (_py_start && (*_py_start != Py_None)) { - cstart = __Pyx_PyIndex_AsSsize_t(*_py_start); - if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; - } else - cstart = 0; - } - if (!has_cstop) { - if (_py_stop && (*_py_stop != Py_None)) { - cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop); - if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; - } else - cstop = PY_SSIZE_T_MAX; - } - if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) { - Py_ssize_t l = ms->sq_length(obj); - if (likely(l >= 0)) { - if (cstop < 0) { - cstop += l; - if (cstop < 0) cstop = 0; - } - if (cstart < 0) { - cstart += l; - if (cstart < 0) cstart = 0; - } - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - goto bad; - PyErr_Clear(); - } - } - return ms->sq_slice(obj, cstart, cstop); - } -#endif - mp = Py_TYPE(obj)->tp_as_mapping; - if (likely(mp && mp->mp_subscript)) -#endif - { - PyObject* result; - PyObject *py_slice, *py_start, *py_stop; - if (_py_slice) { - py_slice = *_py_slice; - } else { - PyObject* owned_start = NULL; - PyObject* owned_stop = NULL; - if (_py_start) { - py_start = *_py_start; - } else { - if (has_cstart) { - owned_start = py_start = PyInt_FromSsize_t(cstart); - if (unlikely(!py_start)) goto bad; - } else - py_start = Py_None; - } - if (_py_stop) { - py_stop = *_py_stop; - } else { - if (has_cstop) { - owned_stop = py_stop = PyInt_FromSsize_t(cstop); - if (unlikely(!py_stop)) { - Py_XDECREF(owned_start); - goto bad; - } - } else - py_stop = Py_None; - } - py_slice = PySlice_New(py_start, py_stop, Py_None); - Py_XDECREF(owned_start); - Py_XDECREF(owned_stop); - if (unlikely(!py_slice)) goto bad; - } -#if CYTHON_USE_TYPE_SLOTS - result = mp->mp_subscript(obj, py_slice); -#else - result = PyObject_GetItem(obj, py_slice); -#endif - if (!_py_slice) { - Py_DECREF(py_slice); - } - return result; - } - PyErr_Format(PyExc_TypeError, - "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name); -bad: - return NULL; -} - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* SwapException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = *type; - exc_info->exc_value = *value; - exc_info->exc_traceback = *tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = *type; - tstate->exc_value = *value; - tstate->exc_traceback = *tb; - #endif - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); - PyErr_SetExcInfo(*type, *value, *tb); - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#endif - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* decode_c_string */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_string( - const char* cstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - Py_ssize_t length; - if (unlikely((start < 0) | (stop < 0))) { - size_t slen = strlen(cstring); - if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) { - PyErr_SetString(PyExc_OverflowError, - "c-string too long to convert to Python"); - return NULL; - } - length = (Py_ssize_t) slen; - if (start < 0) { - start += length; - if (start < 0) - start = 0; - } - if (stop < 0) - stop += length; - } - if (unlikely(stop <= start)) - return __Pyx_NewRef(__pyx_empty_unicode); - length = stop - start; - cstring += start; - if (decode_func) { - return decode_func(cstring, length, errors); - } else { - return PyUnicode_Decode(cstring, length, encoding, errors); - } -} - -/* UnpackUnboundCMethod */ -static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { - PyObject *method; - method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); - if (unlikely(!method)) - return -1; - target->method = method; -#if CYTHON_COMPILING_IN_CPYTHON - #if PY_MAJOR_VERSION >= 3 - if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) - #endif - { - PyMethodDescrObject *descr = (PyMethodDescrObject*) method; - target->func = descr->d_method->ml_meth; - target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); - } -#endif - return 0; -} - -/* CallUnboundCMethod1 */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg) { - if (likely(cfunc->func)) { - int flag = cfunc->flag; - if (flag == METH_O) { - return (*(cfunc->func))(self, arg); - } else if (PY_VERSION_HEX >= 0x030600B1 && flag == METH_FASTCALL) { - if (PY_VERSION_HEX >= 0x030700A0) { - return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, &arg, 1); - } else { - return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); - } - } else if (PY_VERSION_HEX >= 0x030700A0 && flag == (METH_FASTCALL | METH_KEYWORDS)) { - return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); - } - } - return __Pyx__CallUnboundCMethod1(cfunc, self, arg); -} -#endif -static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg){ - PyObject *args, *result = NULL; - if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; -#if CYTHON_COMPILING_IN_CPYTHON - if (cfunc->func && (cfunc->flag & METH_VARARGS)) { - args = PyTuple_New(1); - if (unlikely(!args)) goto bad; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - if (cfunc->flag & METH_KEYWORDS) - result = (*(PyCFunctionWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, NULL); - else - result = (*cfunc->func)(self, args); - } else { - args = PyTuple_New(2); - if (unlikely(!args)) goto bad; - Py_INCREF(self); - PyTuple_SET_ITEM(args, 0, self); - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 1, arg); - result = __Pyx_PyObject_Call(cfunc->method, args, NULL); - } -#else - args = PyTuple_Pack(2, self, arg); - if (unlikely(!args)) goto bad; - result = __Pyx_PyObject_Call(cfunc->method, args, NULL); -#endif -bad: - Py_XDECREF(args); - return result; -} - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* HasAttr */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { - PyObject *r; - if (unlikely(!__Pyx_PyBaseString_Check(n))) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return -1; - } - r = __Pyx_GetAttr(o, n); - if (unlikely(!r)) { - PyErr_Clear(); - return 0; - } else { - Py_DECREF(r); - return 1; - } -} - -/* PyObject_GenericGetAttrNoDict */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, attr_name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(attr_name)); -#endif - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* PyObjectGetAttrStrNoError */ -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -} - -/* SetupReduce */ -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#else - if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#endif -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} - -/* SetVTable */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable) { -#if PY_VERSION_HEX >= 0x02070000 - PyObject *ob = PyCapsule_New(vtable, 0, 0); -#else - PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); -#endif - if (!ob) - goto bad; - if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; -} - -/* TypeImport */ -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); - } -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) { - const unsigned int neg_one = (unsigned int) ((unsigned int) 0 - (unsigned int) 1), const_zero = (unsigned int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(unsigned int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(unsigned int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(unsigned int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(unsigned int), - little, !is_unsigned); - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) { - const unsigned short neg_one = (unsigned short) ((unsigned short) 0 - (unsigned short) 1), const_zero = (unsigned short) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(unsigned short) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(unsigned short) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned short) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(unsigned short) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned short) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(unsigned short), - little, !is_unsigned); - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint16_t(uint16_t value) { - const uint16_t neg_one = (uint16_t) ((uint16_t) 0 - (uint16_t) 1), const_zero = (uint16_t) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(uint16_t) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(uint16_t) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint16_t) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(uint16_t) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint16_t) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(uint16_t), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE enum http_method __Pyx_PyInt_As_enum__http_method(PyObject *x) { - const enum http_method neg_one = (enum http_method) ((enum http_method) 0 - (enum http_method) 1), const_zero = (enum http_method) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(enum http_method) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(enum http_method, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (enum http_method) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (enum http_method) 0; - case 1: __PYX_VERIFY_RETURN_INT(enum http_method, digit, digits[0]) - case 2: - if (8 * sizeof(enum http_method) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) >= 2 * PyLong_SHIFT) { - return (enum http_method) (((((enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(enum http_method) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) >= 3 * PyLong_SHIFT) { - return (enum http_method) (((((((enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(enum http_method) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) >= 4 * PyLong_SHIFT) { - return (enum http_method) (((((((((enum http_method)digits[3]) << PyLong_SHIFT) | (enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (enum http_method) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(enum http_method) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(enum http_method, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum http_method) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(enum http_method, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (enum http_method) 0; - case -1: __PYX_VERIFY_RETURN_INT(enum http_method, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(enum http_method, digit, +digits[0]) - case -2: - if (8 * sizeof(enum http_method) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) - 1 > 2 * PyLong_SHIFT) { - return (enum http_method) (((enum http_method)-1)*(((((enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(enum http_method) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) - 1 > 2 * PyLong_SHIFT) { - return (enum http_method) ((((((enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(enum http_method) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) - 1 > 3 * PyLong_SHIFT) { - return (enum http_method) (((enum http_method)-1)*(((((((enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(enum http_method) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) - 1 > 3 * PyLong_SHIFT) { - return (enum http_method) ((((((((enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(enum http_method) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) - 1 > 4 * PyLong_SHIFT) { - return (enum http_method) (((enum http_method)-1)*(((((((((enum http_method)digits[3]) << PyLong_SHIFT) | (enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(enum http_method) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(enum http_method) - 1 > 4 * PyLong_SHIFT) { - return (enum http_method) ((((((((((enum http_method)digits[3]) << PyLong_SHIFT) | (enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); - } - } - break; - } -#endif - if (sizeof(enum http_method) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(enum http_method, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum http_method) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(enum http_method, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - enum http_method val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (enum http_method) -1; - } - } else { - enum http_method val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (enum http_method) -1; - val = __Pyx_PyInt_As_enum__http_method(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to enum http_method"); - return (enum http_method) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to enum http_method"); - return (enum http_method) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { - const size_t neg_one = (size_t) ((size_t) 0 - (size_t) 1), const_zero = (size_t) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(size_t) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (size_t) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (size_t) 0; - case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, digits[0]) - case 2: - if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) >= 2 * PyLong_SHIFT) { - return (size_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) >= 3 * PyLong_SHIFT) { - return (size_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) >= 4 * PyLong_SHIFT) { - return (size_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (size_t) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(size_t) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(size_t) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (size_t) 0; - case -1: __PYX_VERIFY_RETURN_INT(size_t, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, +digits[0]) - case -2: - if (8 * sizeof(size_t) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { - return (size_t) (((size_t)-1)*(((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { - return (size_t) ((((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { - return (size_t) (((size_t)-1)*(((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { - return (size_t) ((((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { - return (size_t) (((size_t)-1)*(((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { - return (size_t) ((((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - } -#endif - if (sizeof(size_t) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(size_t) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - size_t val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (size_t) -1; - } - } else { - size_t val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (size_t) -1; - val = __Pyx_PyInt_As_size_t(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to size_t"); - return (size_t) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to size_t"); - return (size_t) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; itp_name); - if (cached_type) { - if (!PyType_Check((PyObject*)cached_type)) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s is not a type object", - type->tp_name); - goto bad; - } - if (cached_type->tp_basicsize != type->tp_basicsize) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s has the wrong size, try recompiling", - type->tp_name); - goto bad; - } - } else { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; - PyErr_Clear(); - if (PyType_Ready(type) < 0) goto bad; - if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0) - goto bad; - Py_INCREF(type); - cached_type = type; - } -done: - Py_DECREF(fake_module); - return cached_type; -bad: - Py_XDECREF(cached_type); - cached_type = NULL; - goto done; -} - -/* PyObjectGetMethod */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { - PyObject *attr; -#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrgetfunc f = NULL; - PyObject **dictptr, *dict; - int meth_found = 0; - assert (*method == NULL); - if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; - } - if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { - return 0; - } - descr = _PyType_Lookup(tp, name); - if (likely(descr != NULL)) { - Py_INCREF(descr); -#if PY_MAJOR_VERSION >= 3 - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) - #endif -#else - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr))) - #endif -#endif - { - meth_found = 1; - } else { - f = Py_TYPE(descr)->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - } - } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - attr = __Pyx_PyDict_GetItemStr(dict, name); - if (attr != NULL) { - Py_INCREF(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - goto try_unpack; - } - Py_DECREF(dict); - } - if (meth_found) { - *method = descr; - return 1; - } - if (f != NULL) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - if (descr != NULL) { - *method = descr; - return 0; - } - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(name)); -#endif - return 0; -#else - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; -#endif -try_unpack: -#if CYTHON_UNPACK_METHODS - if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { - PyObject *function = PyMethod_GET_FUNCTION(attr); - Py_INCREF(function); - Py_DECREF(attr); - *method = function; - return 1; - } -#endif - *method = attr; - return 0; -} - -/* PyObjectCallMethod1 */ -static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { - PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); - Py_DECREF(method); - return result; -} -static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { - PyObject *method = NULL, *result; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_Call2Args(method, obj, arg); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) return NULL; - return __Pyx__PyObject_CallMethod1(method, arg); -} - -/* CoroutineBase */ -#include -#include -#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) -static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject **pvalue) { - PyObject *et, *ev, *tb; - PyObject *value = NULL; - __Pyx_ErrFetch(&et, &ev, &tb); - if (!et) { - Py_XDECREF(tb); - Py_XDECREF(ev); - Py_INCREF(Py_None); - *pvalue = Py_None; - return 0; - } - if (likely(et == PyExc_StopIteration)) { - if (!ev) { - Py_INCREF(Py_None); - value = Py_None; - } -#if PY_VERSION_HEX >= 0x030300A0 - else if (Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); - } -#endif - else if (unlikely(PyTuple_Check(ev))) { - if (PyTuple_GET_SIZE(ev) >= 1) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - value = PyTuple_GET_ITEM(ev, 0); - Py_INCREF(value); -#else - value = PySequence_ITEM(ev, 0); -#endif - } else { - Py_INCREF(Py_None); - value = Py_None; - } - Py_DECREF(ev); - } - else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { - value = ev; - } - if (likely(value)) { - Py_XDECREF(tb); - Py_DECREF(et); - *pvalue = value; - return 0; - } - } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { - __Pyx_ErrRestore(et, ev, tb); - return -1; - } - PyErr_NormalizeException(&et, &ev, &tb); - if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { - __Pyx_ErrRestore(et, ev, tb); - return -1; - } - Py_XDECREF(tb); - Py_DECREF(et); -#if PY_VERSION_HEX >= 0x030300A0 - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); -#else - { - PyObject* args = __Pyx_PyObject_GetAttrStr(ev, __pyx_n_s_args); - Py_DECREF(ev); - if (likely(args)) { - value = PySequence_GetItem(args, 0); - Py_DECREF(args); - } - if (unlikely(!value)) { - __Pyx_ErrRestore(NULL, NULL, NULL); - Py_INCREF(Py_None); - value = Py_None; - } - } -#endif - *pvalue = value; - return 0; -} -static CYTHON_INLINE -void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { - PyObject *t, *v, *tb; - t = exc_state->exc_type; - v = exc_state->exc_value; - tb = exc_state->exc_traceback; - exc_state->exc_type = NULL; - exc_state->exc_value = NULL; - exc_state->exc_traceback = NULL; - Py_XDECREF(t); - Py_XDECREF(v); - Py_XDECREF(tb); -} -#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) -static void __Pyx__Coroutine_AlreadyRunningError(CYTHON_UNUSED __pyx_CoroutineObject *gen) { - const char *msg; - if ((0)) { - #ifdef __Pyx_Coroutine_USED - } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { - msg = "coroutine already executing"; - #endif - #ifdef __Pyx_AsyncGen_USED - } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) { - msg = "async generator already executing"; - #endif - } else { - msg = "generator already executing"; - } - PyErr_SetString(PyExc_ValueError, msg); -} -#define __Pyx_Coroutine_NotStartedError(gen) (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL) -static void __Pyx__Coroutine_NotStartedError(CYTHON_UNUSED PyObject *gen) { - const char *msg; - if ((0)) { - #ifdef __Pyx_Coroutine_USED - } else if (__Pyx_Coroutine_Check(gen)) { - msg = "can't send non-None value to a just-started coroutine"; - #endif - #ifdef __Pyx_AsyncGen_USED - } else if (__Pyx_AsyncGen_CheckExact(gen)) { - msg = "can't send non-None value to a just-started async generator"; - #endif - } else { - msg = "can't send non-None value to a just-started generator"; - } - PyErr_SetString(PyExc_TypeError, msg); -} -#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing) (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL) -static void __Pyx__Coroutine_AlreadyTerminatedError(CYTHON_UNUSED PyObject *gen, PyObject *value, CYTHON_UNUSED int closing) { - #ifdef __Pyx_Coroutine_USED - if (!closing && __Pyx_Coroutine_Check(gen)) { - PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine"); - } else - #endif - if (value) { - #ifdef __Pyx_AsyncGen_USED - if (__Pyx_AsyncGen_CheckExact(gen)) - PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration); - else - #endif - PyErr_SetNone(PyExc_StopIteration); - } -} -static -PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) { - __Pyx_PyThreadState_declare - PyThreadState *tstate; - __Pyx_ExcInfoStruct *exc_state; - PyObject *retval; - assert(!self->is_running); - if (unlikely(self->resume_label == 0)) { - if (unlikely(value && value != Py_None)) { - return __Pyx_Coroutine_NotStartedError((PyObject*)self); - } - } - if (unlikely(self->resume_label == -1)) { - return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing); - } -#if CYTHON_FAST_THREAD_STATE - __Pyx_PyThreadState_assign - tstate = __pyx_tstate; -#else - tstate = __Pyx_PyThreadState_Current; -#endif - exc_state = &self->gi_exc_state; - if (exc_state->exc_type) { - #if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON - #else - if (exc_state->exc_traceback) { - PyTracebackObject *tb = (PyTracebackObject *) exc_state->exc_traceback; - PyFrameObject *f = tb->tb_frame; - Py_XINCREF(tstate->frame); - assert(f->f_back == NULL); - f->f_back = tstate->frame; - } - #endif - } -#if CYTHON_USE_EXC_INFO_STACK - exc_state->previous_item = tstate->exc_info; - tstate->exc_info = exc_state; -#else - if (exc_state->exc_type) { - __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); - } else { - __Pyx_Coroutine_ExceptionClear(exc_state); - __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); - } -#endif - self->is_running = 1; - retval = self->body((PyObject *) self, tstate, value); - self->is_running = 0; -#if CYTHON_USE_EXC_INFO_STACK - exc_state = &self->gi_exc_state; - tstate->exc_info = exc_state->previous_item; - exc_state->previous_item = NULL; - __Pyx_Coroutine_ResetFrameBackpointer(exc_state); -#endif - return retval; -} -static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { - PyObject *exc_tb = exc_state->exc_traceback; - if (likely(exc_tb)) { -#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON -#else - PyTracebackObject *tb = (PyTracebackObject *) exc_tb; - PyFrameObject *f = tb->tb_frame; - Py_CLEAR(f->f_back); -#endif - } -} -static CYTHON_INLINE -PyObject *__Pyx_Coroutine_MethodReturn(CYTHON_UNUSED PyObject* gen, PyObject *retval) { - if (unlikely(!retval)) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (!__Pyx_PyErr_Occurred()) { - PyObject *exc = PyExc_StopIteration; - #ifdef __Pyx_AsyncGen_USED - if (__Pyx_AsyncGen_CheckExact(gen)) - exc = __Pyx_PyExc_StopAsyncIteration; - #endif - __Pyx_PyErr_SetNone(exc); - } - } - return retval; -} -static CYTHON_INLINE -PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) { - PyObject *ret; - PyObject *val = NULL; - __Pyx_Coroutine_Undelegate(gen); - __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val); - ret = __Pyx_Coroutine_SendEx(gen, val, 0); - Py_XDECREF(val); - return ret; -} -static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { - PyObject *retval; - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; - PyObject *yf = gen->yieldfrom; - if (unlikely(gen->is_running)) - return __Pyx_Coroutine_AlreadyRunningError(gen); - if (yf) { - PyObject *ret; - gen->is_running = 1; - #ifdef __Pyx_Generator_USED - if (__Pyx_Generator_CheckExact(yf)) { - ret = __Pyx_Coroutine_Send(yf, value); - } else - #endif - #ifdef __Pyx_Coroutine_USED - if (__Pyx_Coroutine_Check(yf)) { - ret = __Pyx_Coroutine_Send(yf, value); - } else - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_PyAsyncGenASend_CheckExact(yf)) { - ret = __Pyx_async_gen_asend_send(yf, value); - } else - #endif - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) - if (PyGen_CheckExact(yf)) { - ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); - } else - #endif - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) - if (PyCoro_CheckExact(yf)) { - ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); - } else - #endif - { - if (value == Py_None) - ret = Py_TYPE(yf)->tp_iternext(yf); - else - ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value); - } - gen->is_running = 0; - if (likely(ret)) { - return ret; - } - retval = __Pyx_Coroutine_FinishDelegation(gen); - } else { - retval = __Pyx_Coroutine_SendEx(gen, value, 0); - } - return __Pyx_Coroutine_MethodReturn(self, retval); -} -static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { - PyObject *retval = NULL; - int err = 0; - #ifdef __Pyx_Generator_USED - if (__Pyx_Generator_CheckExact(yf)) { - retval = __Pyx_Coroutine_Close(yf); - if (!retval) - return -1; - } else - #endif - #ifdef __Pyx_Coroutine_USED - if (__Pyx_Coroutine_Check(yf)) { - retval = __Pyx_Coroutine_Close(yf); - if (!retval) - return -1; - } else - if (__Pyx_CoroutineAwait_CheckExact(yf)) { - retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL); - if (!retval) - return -1; - } else - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_PyAsyncGenASend_CheckExact(yf)) { - retval = __Pyx_async_gen_asend_close(yf, NULL); - } else - if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) { - retval = __Pyx_async_gen_athrow_close(yf, NULL); - } else - #endif - { - PyObject *meth; - gen->is_running = 1; - meth = __Pyx_PyObject_GetAttrStr(yf, __pyx_n_s_close); - if (unlikely(!meth)) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_WriteUnraisable(yf); - } - PyErr_Clear(); - } else { - retval = PyObject_CallFunction(meth, NULL); - Py_DECREF(meth); - if (!retval) - err = -1; - } - gen->is_running = 0; - } - Py_XDECREF(retval); - return err; -} -static PyObject *__Pyx_Generator_Next(PyObject *self) { - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; - PyObject *yf = gen->yieldfrom; - if (unlikely(gen->is_running)) - return __Pyx_Coroutine_AlreadyRunningError(gen); - if (yf) { - PyObject *ret; - gen->is_running = 1; - #ifdef __Pyx_Generator_USED - if (__Pyx_Generator_CheckExact(yf)) { - ret = __Pyx_Generator_Next(yf); - } else - #endif - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) - if (PyGen_CheckExact(yf)) { - ret = _PyGen_Send((PyGenObject*)yf, NULL); - } else - #endif - #ifdef __Pyx_Coroutine_USED - if (__Pyx_Coroutine_Check(yf)) { - ret = __Pyx_Coroutine_Send(yf, Py_None); - } else - #endif - ret = Py_TYPE(yf)->tp_iternext(yf); - gen->is_running = 0; - if (likely(ret)) { - return ret; - } - return __Pyx_Coroutine_FinishDelegation(gen); - } - return __Pyx_Coroutine_SendEx(gen, Py_None, 0); -} -static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, CYTHON_UNUSED PyObject *arg) { - return __Pyx_Coroutine_Close(self); -} -static PyObject *__Pyx_Coroutine_Close(PyObject *self) { - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; - PyObject *retval, *raised_exception; - PyObject *yf = gen->yieldfrom; - int err = 0; - if (unlikely(gen->is_running)) - return __Pyx_Coroutine_AlreadyRunningError(gen); - if (yf) { - Py_INCREF(yf); - err = __Pyx_Coroutine_CloseIter(gen, yf); - __Pyx_Coroutine_Undelegate(gen); - Py_DECREF(yf); - } - if (err == 0) - PyErr_SetNone(PyExc_GeneratorExit); - retval = __Pyx_Coroutine_SendEx(gen, NULL, 1); - if (unlikely(retval)) { - const char *msg; - Py_DECREF(retval); - if ((0)) { - #ifdef __Pyx_Coroutine_USED - } else if (__Pyx_Coroutine_Check(self)) { - msg = "coroutine ignored GeneratorExit"; - #endif - #ifdef __Pyx_AsyncGen_USED - } else if (__Pyx_AsyncGen_CheckExact(self)) { -#if PY_VERSION_HEX < 0x03060000 - msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)"; -#else - msg = "async generator ignored GeneratorExit"; -#endif - #endif - } else { - msg = "generator ignored GeneratorExit"; - } - PyErr_SetString(PyExc_RuntimeError, msg); - return NULL; - } - raised_exception = PyErr_Occurred(); - if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) { - if (raised_exception) PyErr_Clear(); - Py_INCREF(Py_None); - return Py_None; - } - return NULL; -} -static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb, - PyObject *args, int close_on_genexit) { - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; - PyObject *yf = gen->yieldfrom; - if (unlikely(gen->is_running)) - return __Pyx_Coroutine_AlreadyRunningError(gen); - if (yf) { - PyObject *ret; - Py_INCREF(yf); - if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) { - int err = __Pyx_Coroutine_CloseIter(gen, yf); - Py_DECREF(yf); - __Pyx_Coroutine_Undelegate(gen); - if (err < 0) - return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); - goto throw_here; - } - gen->is_running = 1; - if (0 - #ifdef __Pyx_Generator_USED - || __Pyx_Generator_CheckExact(yf) - #endif - #ifdef __Pyx_Coroutine_USED - || __Pyx_Coroutine_Check(yf) - #endif - ) { - ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit); - #ifdef __Pyx_Coroutine_USED - } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { - ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit); - #endif - } else { - PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, __pyx_n_s_throw); - if (unlikely(!meth)) { - Py_DECREF(yf); - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - gen->is_running = 0; - return NULL; - } - PyErr_Clear(); - __Pyx_Coroutine_Undelegate(gen); - gen->is_running = 0; - goto throw_here; - } - if (likely(args)) { - ret = PyObject_CallObject(meth, args); - } else { - ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); - } - Py_DECREF(meth); - } - gen->is_running = 0; - Py_DECREF(yf); - if (!ret) { - ret = __Pyx_Coroutine_FinishDelegation(gen); - } - return __Pyx_Coroutine_MethodReturn(self, ret); - } -throw_here: - __Pyx_Raise(typ, val, tb, NULL); - return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); -} -static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { - PyObject *typ; - PyObject *val = NULL; - PyObject *tb = NULL; - if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)) - return NULL; - return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); -} -static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { - Py_VISIT(exc_state->exc_type); - Py_VISIT(exc_state->exc_value); - Py_VISIT(exc_state->exc_traceback); - return 0; -} -static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { - Py_VISIT(gen->closure); - Py_VISIT(gen->classobj); - Py_VISIT(gen->yieldfrom); - return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); -} -static int __Pyx_Coroutine_clear(PyObject *self) { - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; - Py_CLEAR(gen->closure); - Py_CLEAR(gen->classobj); - Py_CLEAR(gen->yieldfrom); - __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); -#ifdef __Pyx_AsyncGen_USED - if (__Pyx_AsyncGen_CheckExact(self)) { - Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); - } -#endif - Py_CLEAR(gen->gi_code); - Py_CLEAR(gen->gi_name); - Py_CLEAR(gen->gi_qualname); - Py_CLEAR(gen->gi_modulename); - return 0; -} -static void __Pyx_Coroutine_dealloc(PyObject *self) { - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; - PyObject_GC_UnTrack(gen); - if (gen->gi_weakreflist != NULL) - PyObject_ClearWeakRefs(self); - if (gen->resume_label >= 0) { - PyObject_GC_Track(self); -#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE - if (PyObject_CallFinalizerFromDealloc(self)) -#else - Py_TYPE(gen)->tp_del(self); - if (self->ob_refcnt > 0) -#endif - { - return; - } - PyObject_GC_UnTrack(self); - } -#ifdef __Pyx_AsyncGen_USED - if (__Pyx_AsyncGen_CheckExact(self)) { - /* We have to handle this case for asynchronous generators - right here, because this code has to be between UNTRACK - and GC_Del. */ - Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer); - } -#endif - __Pyx_Coroutine_clear(self); - PyObject_GC_Del(gen); -} -static void __Pyx_Coroutine_del(PyObject *self) { - PyObject *error_type, *error_value, *error_traceback; - __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; - __Pyx_PyThreadState_declare - if (gen->resume_label < 0) { - return; - } -#if !CYTHON_USE_TP_FINALIZE - assert(self->ob_refcnt == 0); - self->ob_refcnt = 1; -#endif - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); -#ifdef __Pyx_AsyncGen_USED - if (__Pyx_AsyncGen_CheckExact(self)) { - __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; - PyObject *finalizer = agen->ag_finalizer; - if (finalizer && !agen->ag_closed) { - PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self); - if (unlikely(!res)) { - PyErr_WriteUnraisable(self); - } else { - Py_DECREF(res); - } - __Pyx_ErrRestore(error_type, error_value, error_traceback); - return; - } - } -#endif - if (unlikely(gen->resume_label == 0 && !error_value)) { -#ifdef __Pyx_Coroutine_USED -#ifdef __Pyx_Generator_USED - if (!__Pyx_Generator_CheckExact(self)) -#endif - { - PyObject_GC_UnTrack(self); -#if PY_MAJOR_VERSION >= 3 || defined(PyErr_WarnFormat) - if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0)) - PyErr_WriteUnraisable(self); -#else - {PyObject *msg; - char *cmsg; - #if CYTHON_COMPILING_IN_PYPY - msg = NULL; - cmsg = (char*) "coroutine was never awaited"; - #else - char *cname; - PyObject *qualname; - qualname = gen->gi_qualname; - cname = PyString_AS_STRING(qualname); - msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname); - if (unlikely(!msg)) { - PyErr_Clear(); - cmsg = (char*) "coroutine was never awaited"; - } else { - cmsg = PyString_AS_STRING(msg); - } - #endif - if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0)) - PyErr_WriteUnraisable(self); - Py_XDECREF(msg);} -#endif - PyObject_GC_Track(self); - } -#endif - } else { - PyObject *res = __Pyx_Coroutine_Close(self); - if (unlikely(!res)) { - if (PyErr_Occurred()) - PyErr_WriteUnraisable(self); - } else { - Py_DECREF(res); - } - } - __Pyx_ErrRestore(error_type, error_value, error_traceback); -#if !CYTHON_USE_TP_FINALIZE - assert(self->ob_refcnt > 0); - if (--self->ob_refcnt == 0) { - return; - } - { - Py_ssize_t refcnt = self->ob_refcnt; - _Py_NewReference(self); - self->ob_refcnt = refcnt; - } -#if CYTHON_COMPILING_IN_CPYTHON - assert(PyType_IS_GC(self->ob_type) && - _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); - _Py_DEC_REFTOTAL; -#endif -#ifdef COUNT_ALLOCS - --Py_TYPE(self)->tp_frees; - --Py_TYPE(self)->tp_allocs; -#endif -#endif -} -static PyObject * -__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context) -{ - PyObject *name = self->gi_name; - if (unlikely(!name)) name = Py_None; - Py_INCREF(name); - return name; -} -static int -__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context) -{ - PyObject *tmp; -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__name__ must be set to a string object"); - return -1; - } - tmp = self->gi_name; - Py_INCREF(value); - self->gi_name = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context) -{ - PyObject *name = self->gi_qualname; - if (unlikely(!name)) name = Py_None; - Py_INCREF(name); - return name; -} -static int -__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context) -{ - PyObject *tmp; -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__qualname__ must be set to a string object"); - return -1; - } - tmp = self->gi_qualname; - Py_INCREF(value); - self->gi_qualname = value; - Py_XDECREF(tmp); - return 0; -} -static __pyx_CoroutineObject *__Pyx__Coroutine_New( - PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, - PyObject *name, PyObject *qualname, PyObject *module_name) { - __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); - if (unlikely(!gen)) - return NULL; - return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name); -} -static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( - __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, - PyObject *name, PyObject *qualname, PyObject *module_name) { - gen->body = body; - gen->closure = closure; - Py_XINCREF(closure); - gen->is_running = 0; - gen->resume_label = 0; - gen->classobj = NULL; - gen->yieldfrom = NULL; - gen->gi_exc_state.exc_type = NULL; - gen->gi_exc_state.exc_value = NULL; - gen->gi_exc_state.exc_traceback = NULL; -#if CYTHON_USE_EXC_INFO_STACK - gen->gi_exc_state.previous_item = NULL; -#endif - gen->gi_weakreflist = NULL; - Py_XINCREF(qualname); - gen->gi_qualname = qualname; - Py_XINCREF(name); - gen->gi_name = name; - Py_XINCREF(module_name); - gen->gi_modulename = module_name; - Py_XINCREF(code); - gen->gi_code = code; - PyObject_GC_Track(gen); - return gen; -} - -/* PatchModuleWithCoroutine */ -static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { -#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - int result; - PyObject *globals, *result_obj; - globals = PyDict_New(); if (unlikely(!globals)) goto ignore; - result = PyDict_SetItemString(globals, "_cython_coroutine_type", - #ifdef __Pyx_Coroutine_USED - (PyObject*)__pyx_CoroutineType); - #else - Py_None); - #endif - if (unlikely(result < 0)) goto ignore; - result = PyDict_SetItemString(globals, "_cython_generator_type", - #ifdef __Pyx_Generator_USED - (PyObject*)__pyx_GeneratorType); - #else - Py_None); - #endif - if (unlikely(result < 0)) goto ignore; - if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; - if (unlikely(PyDict_SetItemString(globals, "__builtins__", __pyx_b) < 0)) goto ignore; - result_obj = PyRun_String(py_code, Py_file_input, globals, globals); - if (unlikely(!result_obj)) goto ignore; - Py_DECREF(result_obj); - Py_DECREF(globals); - return module; -ignore: - Py_XDECREF(globals); - PyErr_WriteUnraisable(module); - if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) { - Py_DECREF(module); - module = NULL; - } -#else - py_code++; -#endif - return module; -} - -/* PatchGeneratorABC */ -#ifndef CYTHON_REGISTER_ABCS -#define CYTHON_REGISTER_ABCS 1 -#endif -#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) -static PyObject* __Pyx_patch_abc_module(PyObject *module); -static PyObject* __Pyx_patch_abc_module(PyObject *module) { - module = __Pyx_Coroutine_patch_module( - module, "" -"if _cython_generator_type is not None:\n" -" try: Generator = _module.Generator\n" -" except AttributeError: pass\n" -" else: Generator.register(_cython_generator_type)\n" -"if _cython_coroutine_type is not None:\n" -" try: Coroutine = _module.Coroutine\n" -" except AttributeError: pass\n" -" else: Coroutine.register(_cython_coroutine_type)\n" - ); - return module; -} -#endif -static int __Pyx_patch_abc(void) { -#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - static int abc_patched = 0; - if (CYTHON_REGISTER_ABCS && !abc_patched) { - PyObject *module; - module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections"); - if (!module) { - PyErr_WriteUnraisable(NULL); - if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, - ((PY_MAJOR_VERSION >= 3) ? - "Cython module failed to register with collections.abc module" : - "Cython module failed to register with collections module"), 1) < 0)) { - return -1; - } - } else { - module = __Pyx_patch_abc_module(module); - abc_patched = 1; - if (unlikely(!module)) - return -1; - Py_DECREF(module); - } - module = PyImport_ImportModule("backports_abc"); - if (module) { - module = __Pyx_patch_abc_module(module); - Py_XDECREF(module); - } - if (!module) { - PyErr_Clear(); - } - } -#else - if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL); -#endif - return 0; -} - -/* Generator */ -static PyMethodDef __pyx_Generator_methods[] = { - {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, - (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, - {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, - (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, - {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, - (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, - {0, 0, 0, 0} -}; -static PyMemberDef __pyx_Generator_memberlist[] = { - {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, - {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, - (char*) PyDoc_STR("object being iterated by 'yield from', or None")}, - {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL}, - {0, 0, 0, 0, 0} -}; -static PyGetSetDef __pyx_Generator_getsets[] = { - {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, - (char*) PyDoc_STR("name of the generator"), 0}, - {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, - (char*) PyDoc_STR("qualified name of the generator"), 0}, - {0, 0, 0, 0, 0} -}; -static PyTypeObject __pyx_GeneratorType_type = { - PyVarObject_HEAD_INIT(0, 0) - "generator", - sizeof(__pyx_CoroutineObject), - 0, - (destructor) __Pyx_Coroutine_dealloc, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, - 0, - (traverseproc) __Pyx_Coroutine_traverse, - 0, - 0, - offsetof(__pyx_CoroutineObject, gi_weakreflist), - 0, - (iternextfunc) __Pyx_Generator_Next, - __pyx_Generator_methods, - __pyx_Generator_memberlist, - __pyx_Generator_getsets, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -#if CYTHON_USE_TP_FINALIZE - 0, -#else - __Pyx_Coroutine_del, -#endif - 0, -#if CYTHON_USE_TP_FINALIZE - __Pyx_Coroutine_del, -#elif PY_VERSION_HEX >= 0x030400a1 - 0, -#endif -#if PY_VERSION_HEX >= 0x030800b1 - 0, -#endif -#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, -#endif -}; -static int __pyx_Generator_init(void) { - __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; - __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); - if (unlikely(!__pyx_GeneratorType)) { - return -1; - } - return 0; -} - -/* CheckBinaryVersion */ -static int __Pyx_check_binary_version(void) { - char ctversion[4], rtversion[4]; - PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); - PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); - if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { - char message[200]; - PyOS_snprintf(message, sizeof(message), - "compiletime version %s of module '%.100s' " - "does not match runtime version %s", - ctversion, __Pyx_MODULE_NAME, rtversion); - return PyErr_WarnEx(NULL, message, 1); - } - return 0; -} - -/* InitStrings */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_http_parser.cp39-win_amd64.pyd deleted file mode 100644 index 61fc6025..00000000 Binary files a/dist/ba_data/python-site-packages/aiohttp/_http_parser.cp39-win_amd64.pyd and /dev/null differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/aiohttp/_http_parser.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..6a0db3d4 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_http_parser.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx b/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx index c24e3105..7ea9b32c 100644 --- a/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx +++ b/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx @@ -2,7 +2,6 @@ # # Based on https://github.com/MagicStack/httptools # -from __future__ import absolute_import, print_function from cpython cimport ( Py_buffer, @@ -20,6 +19,7 @@ from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiD from yarl import URL as _URL from aiohttp import hdrs +from aiohttp.helpers import DEBUG, set_exception from .http_exceptions import ( BadHttpMessage, @@ -80,13 +80,13 @@ cdef inline object extend(object buf, const char* at, size_t length): memcpy(ptr + s, at, length) -DEF METHODS_COUNT = 34; +DEF METHODS_COUNT = 46; cdef list _http_method = [] for i in range(METHODS_COUNT): _http_method.append( - cparser.http_method_str( i).decode('ascii')) + cparser.llhttp_method_name( i).decode('ascii')) cdef inline str http_method_str(int i): @@ -272,8 +272,8 @@ cdef _new_response_message(object version, cdef class HttpParser: cdef: - cparser.http_parser* _cparser - cparser.http_parser_settings* _csettings + cparser.llhttp_t* _cparser + cparser.llhttp_settings_t* _csettings bytearray _raw_name bytearray _raw_value @@ -310,13 +310,13 @@ cdef class HttpParser: Py_buffer py_buf def __cinit__(self): - self._cparser = \ - PyMem_Malloc(sizeof(cparser.http_parser)) + self._cparser = \ + PyMem_Malloc(sizeof(cparser.llhttp_t)) if self._cparser is NULL: raise MemoryError() - self._csettings = \ - PyMem_Malloc(sizeof(cparser.http_parser_settings)) + self._csettings = \ + PyMem_Malloc(sizeof(cparser.llhttp_settings_t)) if self._csettings is NULL: raise MemoryError() @@ -324,19 +324,20 @@ cdef class HttpParser: PyMem_Free(self._cparser) PyMem_Free(self._csettings) - cdef _init(self, cparser.http_parser_type mode, - object protocol, object loop, int limit, - object timer=None, - size_t max_line_size=8190, size_t max_headers=32768, - size_t max_field_size=8190, payload_exception=None, - bint response_with_body=True, bint read_until_eof=False, - bint auto_decompress=True): - cparser.http_parser_init(self._cparser, mode) + cdef _init( + self, cparser.llhttp_type mode, + object protocol, object loop, int limit, + object timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True, + ): + cparser.llhttp_settings_init(self._csettings) + cparser.llhttp_init(self._cparser, mode, self._csettings) self._cparser.data = self self._cparser.content_length = 0 - cparser.http_parser_settings_init(self._csettings) - self._protocol = protocol self._loop = loop self._timer = timer @@ -417,14 +418,14 @@ cdef class HttpParser: self._process_header() method = http_method_str(self._cparser.method) - should_close = not cparser.http_should_keep_alive(self._cparser) + should_close = not cparser.llhttp_should_keep_alive(self._cparser) upgrade = self._cparser.upgrade chunked = self._cparser.flags & cparser.F_CHUNKED raw_headers = tuple(self._raw_headers) headers = CIMultiDictProxy(self._headers) - if upgrade or self._cparser.method == 5: # cparser.CONNECT: + if upgrade or self._cparser.method == cparser.HTTP_CONNECT: self._upgraded = True # do not support old websocket spec @@ -450,11 +451,12 @@ cdef class HttpParser: headers, raw_headers, should_close, encoding, upgrade, chunked) - if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or - self._cparser.method == 5 or # CONNECT: 5 - (self._cparser.status_code >= 199 and - self._cparser.content_length == ULLONG_MAX and - self._read_until_eof) + if ( + ULLONG_MAX > self._cparser.content_length > 0 or chunked or + self._cparser.method == cparser.HTTP_CONNECT or + (self._cparser.status_code >= 199 and + self._cparser.content_length == 0 and + self._read_until_eof) ): payload = StreamReader( self._protocol, timer=self._timer, loop=self._loop, @@ -485,7 +487,7 @@ cdef class HttpParser: pass cdef inline http_version(self): - cdef cparser.http_parser* parser = self._cparser + cdef cparser.llhttp_t* parser = self._cparser if parser.http_major == 1: if parser.http_minor == 0: @@ -504,12 +506,11 @@ cdef class HttpParser: if self._cparser.flags & cparser.F_CHUNKED: raise TransferEncodingError( "Not enough data for satisfy transfer length header.") - elif self._cparser.flags & cparser.F_CONTENTLENGTH: + elif self._cparser.flags & cparser.F_CONTENT_LENGTH: raise ContentLengthError( "Not enough data for satisfy content length header.") - elif self._cparser.http_errno != cparser.HPE_OK: - desc = cparser.http_errno_description( - self._cparser.http_errno) + elif cparser.llhttp_get_errno(self._cparser) != cparser.HPE_OK: + desc = cparser.llhttp_get_error_reason(self._cparser) raise PayloadEncodingError(desc.decode('latin-1')) else: self._payload.feed_eof() @@ -522,26 +523,36 @@ cdef class HttpParser: cdef: size_t data_len size_t nb + cdef cparser.llhttp_errno_t errno PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) data_len = self.py_buf.len - nb = cparser.http_parser_execute( + errno = cparser.llhttp_execute( self._cparser, - self._csettings, self.py_buf.buf, data_len) + if errno is cparser.HPE_PAUSED_UPGRADE: + cparser.llhttp_resume_after_upgrade(self._cparser) + + nb = cparser.llhttp_get_error_pos(self._cparser) - self.py_buf.buf + PyBuffer_Release(&self.py_buf) - if (self._cparser.http_errno != cparser.HPE_OK): + if errno not in (cparser.HPE_OK, cparser.HPE_PAUSED_UPGRADE): if self._payload_error == 0: if self._last_error is not None: ex = self._last_error self._last_error = None else: - ex = parser_error_from_errno( - self._cparser.http_errno) + after = cparser.llhttp_get_error_pos(self._cparser) + before = data[:after - self.py_buf.buf] + after_b = after.split(b"\r\n", 1)[0] + before = before.rsplit(b"\r\n", 1)[-1] + data = before + after_b + pointer = " " * (len(repr(before))-1) + "^" + ex = parser_error_from_errno(self._cparser, data, pointer) self._payload = None raise ex @@ -562,44 +573,86 @@ cdef class HttpParser: cdef class HttpRequestParser(HttpParser): - def __init__(self, protocol, loop, int limit, timer=None, - size_t max_line_size=8190, size_t max_headers=32768, - size_t max_field_size=8190, payload_exception=None, - bint response_with_body=True, bint read_until_eof=False, + def __init__( + self, protocol, loop, int limit, timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True, ): - self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, - max_line_size, max_headers, max_field_size, - payload_exception, response_with_body, read_until_eof) + self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, + max_line_size, max_headers, max_field_size, + payload_exception, response_with_body, read_until_eof, + auto_decompress) cdef object _on_status_complete(self): - cdef Py_buffer py_buf - if not self._buf: - return - self._path = self._buf.decode('utf-8', 'surrogateescape') - if self._cparser.method == 5: # CONNECT - self._url = URL(self._path) - else: - PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) - try: - self._url = _parse_url(py_buf.buf, - py_buf.len) - finally: - PyBuffer_Release(&py_buf) - PyByteArray_Resize(self._buf, 0) + cdef int idx1, idx2 + if not self._buf: + return + self._path = self._buf.decode('utf-8', 'surrogateescape') + try: + idx3 = len(self._path) + if self._cparser.method == cparser.HTTP_CONNECT: + # authority-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.3 + self._url = URL.build(authority=self._path, encoded=True) + elif idx3 > 1 and self._path[0] == '/': + # origin-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.1 + idx1 = self._path.find("?") + if idx1 == -1: + query = "" + idx2 = self._path.find("#") + if idx2 == -1: + path = self._path + fragment = "" + else: + path = self._path[0: idx2] + fragment = self._path[idx2+1:] + + else: + path = self._path[0:idx1] + idx1 += 1 + idx2 = self._path.find("#", idx1+1) + if idx2 == -1: + query = self._path[idx1:] + fragment = "" + else: + query = self._path[idx1: idx2] + fragment = self._path[idx2+1:] + + self._url = URL.build( + path=path, + query_string=query, + fragment=fragment, + encoded=True, + ) + else: + # absolute-form for proxy maybe, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.2 + self._url = URL(self._path, encoded=True) + finally: + PyByteArray_Resize(self._buf, 0) cdef class HttpResponseParser(HttpParser): - def __init__(self, protocol, loop, int limit, timer=None, - size_t max_line_size=8190, size_t max_headers=32768, - size_t max_field_size=8190, payload_exception=None, - bint response_with_body=True, bint read_until_eof=False, - bint auto_decompress=True + def __init__( + self, protocol, loop, int limit, timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True ): self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, max_line_size, max_headers, max_field_size, payload_exception, response_with_body, read_until_eof, auto_decompress) + # Use strict parsing on dev mode, so users are warned about broken servers. + if not DEBUG: + cparser.llhttp_set_lenient_headers(self._cparser, 1) + cparser.llhttp_set_lenient_optional_cr_before_lf(self._cparser, 1) + cparser.llhttp_set_lenient_spaces_after_chunk_size(self._cparser, 1) cdef object _on_status_complete(self): if self._buf: @@ -608,7 +661,7 @@ cdef class HttpResponseParser(HttpParser): else: self._reason = self._reason or '' -cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: +cdef int cb_on_message_begin(cparser.llhttp_t* parser) except -1: cdef HttpParser pyparser = parser.data pyparser._started = True @@ -620,7 +673,7 @@ cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: return 0 -cdef int cb_on_url(cparser.http_parser* parser, +cdef int cb_on_url(cparser.llhttp_t* parser, const char *at, size_t length) except -1: cdef HttpParser pyparser = parser.data try: @@ -635,7 +688,7 @@ cdef int cb_on_url(cparser.http_parser* parser, return 0 -cdef int cb_on_status(cparser.http_parser* parser, +cdef int cb_on_status(cparser.llhttp_t* parser, const char *at, size_t length) except -1: cdef HttpParser pyparser = parser.data cdef str reason @@ -651,7 +704,7 @@ cdef int cb_on_status(cparser.http_parser* parser, return 0 -cdef int cb_on_header_field(cparser.http_parser* parser, +cdef int cb_on_header_field(cparser.llhttp_t* parser, const char *at, size_t length) except -1: cdef HttpParser pyparser = parser.data cdef Py_ssize_t size @@ -669,7 +722,7 @@ cdef int cb_on_header_field(cparser.http_parser* parser, return 0 -cdef int cb_on_header_value(cparser.http_parser* parser, +cdef int cb_on_header_value(cparser.llhttp_t* parser, const char *at, size_t length) except -1: cdef HttpParser pyparser = parser.data cdef Py_ssize_t size @@ -686,7 +739,7 @@ cdef int cb_on_header_value(cparser.http_parser* parser, return 0 -cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: +cdef int cb_on_headers_complete(cparser.llhttp_t* parser) except -1: cdef HttpParser pyparser = parser.data try: pyparser._on_status_complete() @@ -695,30 +748,35 @@ cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: pyparser._last_error = exc return -1 else: - if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT + if ( + pyparser._cparser.upgrade or + pyparser._cparser.method == cparser.HTTP_CONNECT + ): return 2 else: return 0 -cdef int cb_on_body(cparser.http_parser* parser, +cdef int cb_on_body(cparser.llhttp_t* parser, const char *at, size_t length) except -1: cdef HttpParser pyparser = parser.data cdef bytes body = at[:length] try: pyparser._payload.feed_data(body, length) - except BaseException as exc: + except BaseException as underlying_exc: + reraised_exc = underlying_exc if pyparser._payload_exception is not None: - pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) - else: - pyparser._payload.set_exception(exc) + reraised_exc = pyparser._payload_exception(str(underlying_exc)) + + set_exception(pyparser._payload, reraised_exc, underlying_exc) + pyparser._payload_error = 1 return -1 else: return 0 -cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: +cdef int cb_on_message_complete(cparser.llhttp_t* parser) except -1: cdef HttpParser pyparser = parser.data try: pyparser._started = False @@ -730,7 +788,7 @@ cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: return 0 -cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: +cdef int cb_on_chunk_header(cparser.llhttp_t* parser) except -1: cdef HttpParser pyparser = parser.data try: pyparser._on_chunk_header() @@ -741,7 +799,7 @@ cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: return 0 -cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: +cdef int cb_on_chunk_complete(cparser.llhttp_t* parser) except -1: cdef HttpParser pyparser = parser.data try: pyparser._on_chunk_complete() @@ -752,124 +810,29 @@ cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: return 0 -cdef parser_error_from_errno(cparser.http_errno errno): - cdef bytes desc = cparser.http_errno_description(errno) - - if errno in (cparser.HPE_CB_message_begin, - cparser.HPE_CB_url, - cparser.HPE_CB_header_field, - cparser.HPE_CB_header_value, - cparser.HPE_CB_headers_complete, - cparser.HPE_CB_body, - cparser.HPE_CB_message_complete, - cparser.HPE_CB_status, - cparser.HPE_CB_chunk_header, - cparser.HPE_CB_chunk_complete): - cls = BadHttpMessage - - elif errno == cparser.HPE_INVALID_STATUS: - cls = BadStatusLine - - elif errno == cparser.HPE_INVALID_METHOD: - cls = BadStatusLine - +cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer): + cdef cparser.llhttp_errno_t errno = cparser.llhttp_get_errno(parser) + cdef bytes desc = cparser.llhttp_get_error_reason(parser) + + err_msg = "{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer) + + if errno in {cparser.HPE_CB_MESSAGE_BEGIN, + cparser.HPE_CB_HEADERS_COMPLETE, + cparser.HPE_CB_MESSAGE_COMPLETE, + cparser.HPE_CB_CHUNK_HEADER, + cparser.HPE_CB_CHUNK_COMPLETE, + cparser.HPE_INVALID_CONSTANT, + cparser.HPE_INVALID_HEADER_TOKEN, + cparser.HPE_INVALID_CONTENT_LENGTH, + cparser.HPE_INVALID_CHUNK_SIZE, + cparser.HPE_INVALID_EOF_STATE, + cparser.HPE_INVALID_TRANSFER_ENCODING}: + return BadHttpMessage(err_msg) + elif errno in {cparser.HPE_INVALID_STATUS, + cparser.HPE_INVALID_METHOD, + cparser.HPE_INVALID_VERSION}: + return BadStatusLine(error=err_msg) elif errno == cparser.HPE_INVALID_URL: - cls = InvalidURLError - - else: - cls = BadHttpMessage - - return cls(desc.decode('latin-1')) - + return InvalidURLError(err_msg) -def parse_url(url): - cdef: - Py_buffer py_buf - char* buf_data - - PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) - try: - buf_data = py_buf.buf - return _parse_url(buf_data, py_buf.len) - finally: - PyBuffer_Release(&py_buf) - - -cdef _parse_url(char* buf_data, size_t length): - cdef: - cparser.http_parser_url* parsed - int res - str schema = None - str host = None - object port = None - str path = None - str query = None - str fragment = None - str user = None - str password = None - str userinfo = None - object result = None - int off - int ln - - parsed = \ - PyMem_Malloc(sizeof(cparser.http_parser_url)) - if parsed is NULL: - raise MemoryError() - cparser.http_parser_url_init(parsed) - try: - res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) - - if res == 0: - if parsed.field_set & (1 << cparser.UF_SCHEMA): - off = parsed.field_data[cparser.UF_SCHEMA].off - ln = parsed.field_data[cparser.UF_SCHEMA].len - schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - else: - schema = '' - - if parsed.field_set & (1 << cparser.UF_HOST): - off = parsed.field_data[cparser.UF_HOST].off - ln = parsed.field_data[cparser.UF_HOST].len - host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - else: - host = '' - - if parsed.field_set & (1 << cparser.UF_PORT): - port = parsed.port - - if parsed.field_set & (1 << cparser.UF_PATH): - off = parsed.field_data[cparser.UF_PATH].off - ln = parsed.field_data[cparser.UF_PATH].len - path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - else: - path = '' - - if parsed.field_set & (1 << cparser.UF_QUERY): - off = parsed.field_data[cparser.UF_QUERY].off - ln = parsed.field_data[cparser.UF_QUERY].len - query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - else: - query = '' - - if parsed.field_set & (1 << cparser.UF_FRAGMENT): - off = parsed.field_data[cparser.UF_FRAGMENT].off - ln = parsed.field_data[cparser.UF_FRAGMENT].len - fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - else: - fragment = '' - - if parsed.field_set & (1 << cparser.UF_USERINFO): - off = parsed.field_data[cparser.UF_USERINFO].off - ln = parsed.field_data[cparser.UF_USERINFO].len - userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') - - user, sep, password = userinfo.partition(':') - - return URL_build(scheme=schema, - user=user, password=password, host=host, port=port, - path=path, query_string=query, fragment=fragment, encoded=True) - else: - raise InvalidURLError("invalid url {!r}".format(buf_data)) - finally: - PyMem_Free(parsed) + return BadHttpMessage(err_msg) diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.c b/dist/ba_data/python-site-packages/aiohttp/_http_writer.c deleted file mode 100644 index 770c93a7..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_http_writer.c +++ /dev/null @@ -1,5840 +0,0 @@ -/* Generated by Cython 0.29.21 */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_21" -#define CYTHON_HEX_VERSION 0x001D15F0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__aiohttp___http_writer -#define __PYX_HAVE_API__aiohttp___http_writer -/* Early includes */ -#include -#include -#include -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "aiohttp\\_http_writer.pyx", - "type.pxd", -}; - -/*--- Type declarations ---*/ -struct __pyx_t_7aiohttp_12_http_writer_Writer; - -/* "aiohttp/_http_writer.pyx":18 - * # ----------------- writer --------------------------- - * - * cdef struct Writer: # <<<<<<<<<<<<<< - * char *buf - * Py_ssize_t size - */ -struct __pyx_t_7aiohttp_12_http_writer_Writer { - char *buf; - Py_ssize_t size; - Py_ssize_t pos; -}; - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* WriteUnraisableException.proto */ -static void __Pyx_WriteUnraisable(const char *name, int clineno, - int lineno, const char *filename, - int full_traceback, int nogil); - -/* unicode_iter.proto */ -static CYTHON_INLINE int __Pyx_init_unicode_iteration( - PyObject* ustring, Py_ssize_t *length, void** data, int *kind); - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* ReRaiseException.proto */ -static CYTHON_INLINE void __Pyx_ReraiseException(void); - -/* IterFinish.proto */ -static CYTHON_INLINE int __Pyx_IterFinish(void); - -/* PyObjectCallNoArg.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); -#else -#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) -#endif - -/* PyObjectGetMethod.proto */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -/* PyObjectCallMethod0.proto */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* UnpackItemEndCheck.proto */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); - -/* RaiseNoneIterError.proto */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); - -/* UnpackTupleError.proto */ -static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); - -/* UnpackTuple2.proto */ -#define __Pyx_unpack_tuple2(tuple, value1, value2, is_tuple, has_known_size, decref_tuple)\ - (likely(is_tuple || PyTuple_Check(tuple)) ?\ - (likely(has_known_size || PyTuple_GET_SIZE(tuple) == 2) ?\ - __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple) :\ - (__Pyx_UnpackTupleError(tuple, 2), -1)) :\ - __Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple)) -static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( - PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple); -static int __Pyx_unpack_tuple2_generic( - PyObject* tuple, PyObject** value1, PyObject** value2, int has_known_size, int decref_tuple); - -/* dict_iter.proto */ -static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name, - Py_ssize_t* p_orig_length, int* p_is_dict); -static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos, - PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict); - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* SwapException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 -}; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'cpython.bytes' */ - -/* Module declarations from 'cpython.exc' */ - -/* Module declarations from 'cpython.mem' */ - -/* Module declarations from 'libc.stdint' */ - -/* Module declarations from 'aiohttp._http_writer' */ -static char __pyx_v_7aiohttp_12_http_writer_BUFFER[0x4000]; -static PyObject *__pyx_v_7aiohttp_12_http_writer__istr = 0; -static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__init_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *); /*proto*/ -static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__release_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *); /*proto*/ -static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_byte(struct __pyx_t_7aiohttp_12_http_writer_Writer *, uint8_t); /*proto*/ -static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_utf8(struct __pyx_t_7aiohttp_12_http_writer_Writer *, Py_UCS4); /*proto*/ -static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_str(struct __pyx_t_7aiohttp_12_http_writer_Writer *, PyObject *); /*proto*/ -static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *); /*proto*/ -#define __Pyx_MODULE_NAME "aiohttp._http_writer" -extern int __pyx_module_is_main_aiohttp___http_writer; -int __pyx_module_is_main_aiohttp___http_writer = 0; - -/* Implementation of 'aiohttp._http_writer' */ -static PyObject *__pyx_builtin_TypeError; -static const char __pyx_k_key[] = "key"; -static const char __pyx_k_ret[] = "ret"; -static const char __pyx_k_val[] = "val"; -static const char __pyx_k_istr[] = "istr"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_items[] = "items"; -static const char __pyx_k_format[] = "format"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_writer[] = "writer"; -static const char __pyx_k_headers[] = "headers"; -static const char __pyx_k_TypeError[] = "TypeError"; -static const char __pyx_k_multidict[] = "multidict"; -static const char __pyx_k_status_line[] = "status_line"; -static const char __pyx_k_serialize_headers[] = "_serialize_headers"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_aiohttp__http_writer[] = "aiohttp._http_writer"; -static const char __pyx_k_aiohttp__http_writer_pyx[] = "aiohttp\\_http_writer.pyx"; -static const char __pyx_k_Cannot_serialize_non_str_key_r[] = "Cannot serialize non-str key {!r}"; -static PyObject *__pyx_kp_u_Cannot_serialize_non_str_key_r; -static PyObject *__pyx_n_s_TypeError; -static PyObject *__pyx_n_s_aiohttp__http_writer; -static PyObject *__pyx_kp_s_aiohttp__http_writer_pyx; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_format; -static PyObject *__pyx_n_s_headers; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_istr; -static PyObject *__pyx_n_s_items; -static PyObject *__pyx_n_s_key; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_multidict; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_ret; -static PyObject *__pyx_n_s_serialize_headers; -static PyObject *__pyx_n_s_status_line; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_val; -static PyObject *__pyx_n_s_writer; -static PyObject *__pyx_pf_7aiohttp_12_http_writer__serialize_headers(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_status_line, PyObject *__pyx_v_headers); /* proto */ -static PyObject *__pyx_tuple_; -static PyObject *__pyx_codeobj__2; -/* Late includes */ - -/* "aiohttp/_http_writer.pyx":24 - * - * - * cdef inline void _init_writer(Writer* writer): # <<<<<<<<<<<<<< - * writer.buf = &BUFFER[0] - * writer.size = BUF_SIZE - */ - -static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__init_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_init_writer", 0); - - /* "aiohttp/_http_writer.pyx":25 - * - * cdef inline void _init_writer(Writer* writer): - * writer.buf = &BUFFER[0] # <<<<<<<<<<<<<< - * writer.size = BUF_SIZE - * writer.pos = 0 - */ - __pyx_v_writer->buf = (&(__pyx_v_7aiohttp_12_http_writer_BUFFER[0])); - - /* "aiohttp/_http_writer.pyx":26 - * cdef inline void _init_writer(Writer* writer): - * writer.buf = &BUFFER[0] - * writer.size = BUF_SIZE # <<<<<<<<<<<<<< - * writer.pos = 0 - * - */ - __pyx_v_writer->size = 0x4000; - - /* "aiohttp/_http_writer.pyx":27 - * writer.buf = &BUFFER[0] - * writer.size = BUF_SIZE - * writer.pos = 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_writer->pos = 0; - - /* "aiohttp/_http_writer.pyx":24 - * - * - * cdef inline void _init_writer(Writer* writer): # <<<<<<<<<<<<<< - * writer.buf = &BUFFER[0] - * writer.size = BUF_SIZE - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "aiohttp/_http_writer.pyx":30 - * - * - * cdef inline void _release_writer(Writer* writer): # <<<<<<<<<<<<<< - * if writer.buf != BUFFER: - * PyMem_Free(writer.buf) - */ - -static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__release_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("_release_writer", 0); - - /* "aiohttp/_http_writer.pyx":31 - * - * cdef inline void _release_writer(Writer* writer): - * if writer.buf != BUFFER: # <<<<<<<<<<<<<< - * PyMem_Free(writer.buf) - * - */ - __pyx_t_1 = ((__pyx_v_writer->buf != __pyx_v_7aiohttp_12_http_writer_BUFFER) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":32 - * cdef inline void _release_writer(Writer* writer): - * if writer.buf != BUFFER: - * PyMem_Free(writer.buf) # <<<<<<<<<<<<<< - * - * - */ - PyMem_Free(__pyx_v_writer->buf); - - /* "aiohttp/_http_writer.pyx":31 - * - * cdef inline void _release_writer(Writer* writer): - * if writer.buf != BUFFER: # <<<<<<<<<<<<<< - * PyMem_Free(writer.buf) - * - */ - } - - /* "aiohttp/_http_writer.pyx":30 - * - * - * cdef inline void _release_writer(Writer* writer): # <<<<<<<<<<<<<< - * if writer.buf != BUFFER: - * PyMem_Free(writer.buf) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "aiohttp/_http_writer.pyx":35 - * - * - * cdef inline int _write_byte(Writer* writer, uint8_t ch): # <<<<<<<<<<<<<< - * cdef char * buf - * cdef Py_ssize_t size - */ - -static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_byte(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer, uint8_t __pyx_v_ch) { - char *__pyx_v_buf; - Py_ssize_t __pyx_v_size; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_write_byte", 0); - - /* "aiohttp/_http_writer.pyx":39 - * cdef Py_ssize_t size - * - * if writer.pos == writer.size: # <<<<<<<<<<<<<< - * # reallocate - * size = writer.size + BUF_SIZE - */ - __pyx_t_1 = ((__pyx_v_writer->pos == __pyx_v_writer->size) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":41 - * if writer.pos == writer.size: - * # reallocate - * size = writer.size + BUF_SIZE # <<<<<<<<<<<<<< - * if writer.buf == BUFFER: - * buf = PyMem_Malloc(size) - */ - __pyx_v_size = (__pyx_v_writer->size + 0x4000); - - /* "aiohttp/_http_writer.pyx":42 - * # reallocate - * size = writer.size + BUF_SIZE - * if writer.buf == BUFFER: # <<<<<<<<<<<<<< - * buf = PyMem_Malloc(size) - * if buf == NULL: - */ - __pyx_t_1 = ((__pyx_v_writer->buf == __pyx_v_7aiohttp_12_http_writer_BUFFER) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":43 - * size = writer.size + BUF_SIZE - * if writer.buf == BUFFER: - * buf = PyMem_Malloc(size) # <<<<<<<<<<<<<< - * if buf == NULL: - * PyErr_NoMemory() - */ - __pyx_v_buf = ((char *)PyMem_Malloc(__pyx_v_size)); - - /* "aiohttp/_http_writer.pyx":44 - * if writer.buf == BUFFER: - * buf = PyMem_Malloc(size) - * if buf == NULL: # <<<<<<<<<<<<<< - * PyErr_NoMemory() - * return -1 - */ - __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":45 - * buf = PyMem_Malloc(size) - * if buf == NULL: - * PyErr_NoMemory() # <<<<<<<<<<<<<< - * return -1 - * memcpy(buf, writer.buf, writer.size) - */ - __pyx_t_2 = PyErr_NoMemory(); if (unlikely(__pyx_t_2 == ((PyObject *)NULL))) __PYX_ERR(0, 45, __pyx_L1_error) - - /* "aiohttp/_http_writer.pyx":46 - * if buf == NULL: - * PyErr_NoMemory() - * return -1 # <<<<<<<<<<<<<< - * memcpy(buf, writer.buf, writer.size) - * else: - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":44 - * if writer.buf == BUFFER: - * buf = PyMem_Malloc(size) - * if buf == NULL: # <<<<<<<<<<<<<< - * PyErr_NoMemory() - * return -1 - */ - } - - /* "aiohttp/_http_writer.pyx":47 - * PyErr_NoMemory() - * return -1 - * memcpy(buf, writer.buf, writer.size) # <<<<<<<<<<<<<< - * else: - * buf = PyMem_Realloc(writer.buf, size) - */ - (void)(memcpy(__pyx_v_buf, __pyx_v_writer->buf, __pyx_v_writer->size)); - - /* "aiohttp/_http_writer.pyx":42 - * # reallocate - * size = writer.size + BUF_SIZE - * if writer.buf == BUFFER: # <<<<<<<<<<<<<< - * buf = PyMem_Malloc(size) - * if buf == NULL: - */ - goto __pyx_L4; - } - - /* "aiohttp/_http_writer.pyx":49 - * memcpy(buf, writer.buf, writer.size) - * else: - * buf = PyMem_Realloc(writer.buf, size) # <<<<<<<<<<<<<< - * if buf == NULL: - * PyErr_NoMemory() - */ - /*else*/ { - __pyx_v_buf = ((char *)PyMem_Realloc(__pyx_v_writer->buf, __pyx_v_size)); - - /* "aiohttp/_http_writer.pyx":50 - * else: - * buf = PyMem_Realloc(writer.buf, size) - * if buf == NULL: # <<<<<<<<<<<<<< - * PyErr_NoMemory() - * return -1 - */ - __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":51 - * buf = PyMem_Realloc(writer.buf, size) - * if buf == NULL: - * PyErr_NoMemory() # <<<<<<<<<<<<<< - * return -1 - * writer.buf = buf - */ - __pyx_t_2 = PyErr_NoMemory(); if (unlikely(__pyx_t_2 == ((PyObject *)NULL))) __PYX_ERR(0, 51, __pyx_L1_error) - - /* "aiohttp/_http_writer.pyx":52 - * if buf == NULL: - * PyErr_NoMemory() - * return -1 # <<<<<<<<<<<<<< - * writer.buf = buf - * writer.size = size - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":50 - * else: - * buf = PyMem_Realloc(writer.buf, size) - * if buf == NULL: # <<<<<<<<<<<<<< - * PyErr_NoMemory() - * return -1 - */ - } - } - __pyx_L4:; - - /* "aiohttp/_http_writer.pyx":53 - * PyErr_NoMemory() - * return -1 - * writer.buf = buf # <<<<<<<<<<<<<< - * writer.size = size - * writer.buf[writer.pos] = ch - */ - __pyx_v_writer->buf = __pyx_v_buf; - - /* "aiohttp/_http_writer.pyx":54 - * return -1 - * writer.buf = buf - * writer.size = size # <<<<<<<<<<<<<< - * writer.buf[writer.pos] = ch - * writer.pos += 1 - */ - __pyx_v_writer->size = __pyx_v_size; - - /* "aiohttp/_http_writer.pyx":39 - * cdef Py_ssize_t size - * - * if writer.pos == writer.size: # <<<<<<<<<<<<<< - * # reallocate - * size = writer.size + BUF_SIZE - */ - } - - /* "aiohttp/_http_writer.pyx":55 - * writer.buf = buf - * writer.size = size - * writer.buf[writer.pos] = ch # <<<<<<<<<<<<<< - * writer.pos += 1 - * return 0 - */ - (__pyx_v_writer->buf[__pyx_v_writer->pos]) = ((char)__pyx_v_ch); - - /* "aiohttp/_http_writer.pyx":56 - * writer.size = size - * writer.buf[writer.pos] = ch - * writer.pos += 1 # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_v_writer->pos = (__pyx_v_writer->pos + 1); - - /* "aiohttp/_http_writer.pyx":57 - * writer.buf[writer.pos] = ch - * writer.pos += 1 - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":35 - * - * - * cdef inline int _write_byte(Writer* writer, uint8_t ch): # <<<<<<<<<<<<<< - * cdef char * buf - * cdef Py_ssize_t size - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_WriteUnraisable("aiohttp._http_writer._write_byte", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_writer.pyx":60 - * - * - * cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): # <<<<<<<<<<<<<< - * cdef uint64_t utf = symbol - * - */ - -static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_utf8(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer, Py_UCS4 __pyx_v_symbol) { - uint64_t __pyx_v_utf; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - __Pyx_RefNannySetupContext("_write_utf8", 0); - - /* "aiohttp/_http_writer.pyx":61 - * - * cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): - * cdef uint64_t utf = symbol # <<<<<<<<<<<<<< - * - * if utf < 0x80: - */ - __pyx_v_utf = ((uint64_t)__pyx_v_symbol); - - /* "aiohttp/_http_writer.pyx":63 - * cdef uint64_t utf = symbol - * - * if utf < 0x80: # <<<<<<<<<<<<<< - * return _write_byte(writer, utf) - * elif utf < 0x800: - */ - __pyx_t_1 = ((__pyx_v_utf < 0x80) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":64 - * - * if utf < 0x80: - * return _write_byte(writer, utf) # <<<<<<<<<<<<<< - * elif utf < 0x800: - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: - */ - __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)__pyx_v_utf)); - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":63 - * cdef uint64_t utf = symbol - * - * if utf < 0x80: # <<<<<<<<<<<<<< - * return _write_byte(writer, utf) - * elif utf < 0x800: - */ - } - - /* "aiohttp/_http_writer.pyx":65 - * if utf < 0x80: - * return _write_byte(writer, utf) - * elif utf < 0x800: # <<<<<<<<<<<<<< - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: - * return -1 - */ - __pyx_t_1 = ((__pyx_v_utf < 0x800) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":66 - * return _write_byte(writer, utf) - * elif utf < 0x800: - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: # <<<<<<<<<<<<<< - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0xc0 | (__pyx_v_utf >> 6)))) < 0) != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":67 - * elif utf < 0x800: - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: - * return -1 # <<<<<<<<<<<<<< - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * elif 0xD800 <= utf <= 0xDFFF: - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":66 - * return _write_byte(writer, utf) - * elif utf < 0x800: - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: # <<<<<<<<<<<<<< - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - */ - } - - /* "aiohttp/_http_writer.pyx":68 - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) # <<<<<<<<<<<<<< - * elif 0xD800 <= utf <= 0xDFFF: - * # surogate pair, ignored - */ - __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | (__pyx_v_utf & 0x3f)))); - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":65 - * if utf < 0x80: - * return _write_byte(writer, utf) - * elif utf < 0x800: # <<<<<<<<<<<<<< - * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: - * return -1 - */ - } - - /* "aiohttp/_http_writer.pyx":69 - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * elif 0xD800 <= utf <= 0xDFFF: # <<<<<<<<<<<<<< - * # surogate pair, ignored - * return 0 - */ - __pyx_t_1 = (0xD800 <= __pyx_v_utf); - if (__pyx_t_1) { - __pyx_t_1 = (__pyx_v_utf <= 0xDFFF); - } - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":71 - * elif 0xD800 <= utf <= 0xDFFF: - * # surogate pair, ignored - * return 0 # <<<<<<<<<<<<<< - * elif utf < 0x10000: - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":69 - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * elif 0xD800 <= utf <= 0xDFFF: # <<<<<<<<<<<<<< - * # surogate pair, ignored - * return 0 - */ - } - - /* "aiohttp/_http_writer.pyx":72 - * # surogate pair, ignored - * return 0 - * elif utf < 0x10000: # <<<<<<<<<<<<<< - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: - * return -1 - */ - __pyx_t_2 = ((__pyx_v_utf < 0x10000) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":73 - * return 0 - * elif utf < 0x10000: - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: # <<<<<<<<<<<<<< - * return -1 - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: - */ - __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0xe0 | (__pyx_v_utf >> 12)))) < 0) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":74 - * elif utf < 0x10000: - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: - * return -1 # <<<<<<<<<<<<<< - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":73 - * return 0 - * elif utf < 0x10000: - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: # <<<<<<<<<<<<<< - * return -1 - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":75 - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: - * return -1 - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: # <<<<<<<<<<<<<< - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - */ - __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | ((__pyx_v_utf >> 6) & 0x3f)))) < 0) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":76 - * return -1 - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 # <<<<<<<<<<<<<< - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * elif utf > 0x10FFFF: - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":75 - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: - * return -1 - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: # <<<<<<<<<<<<<< - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - */ - } - - /* "aiohttp/_http_writer.pyx":77 - * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) # <<<<<<<<<<<<<< - * elif utf > 0x10FFFF: - * # symbol is too large - */ - __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | (__pyx_v_utf & 0x3f)))); - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":72 - * # surogate pair, ignored - * return 0 - * elif utf < 0x10000: # <<<<<<<<<<<<<< - * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: - * return -1 - */ - } - - /* "aiohttp/_http_writer.pyx":78 - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * elif utf > 0x10FFFF: # <<<<<<<<<<<<<< - * # symbol is too large - * return 0 - */ - __pyx_t_2 = ((__pyx_v_utf > 0x10FFFF) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":80 - * elif utf > 0x10FFFF: - * # symbol is too large - * return 0 # <<<<<<<<<<<<<< - * else: - * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":78 - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * elif utf > 0x10FFFF: # <<<<<<<<<<<<<< - * # symbol is too large - * return 0 - */ - } - - /* "aiohttp/_http_writer.pyx":82 - * return 0 - * else: - * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: # <<<<<<<<<<<<<< - * return -1 - * if _write_byte(writer, - */ - /*else*/ { - __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0xf0 | (__pyx_v_utf >> 18)))) < 0) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":83 - * else: - * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: - * return -1 # <<<<<<<<<<<<<< - * if _write_byte(writer, - * (0x80 | ((utf >> 12) & 0x3f))) < 0: - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":82 - * return 0 - * else: - * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: # <<<<<<<<<<<<<< - * return -1 - * if _write_byte(writer, - */ - } - - /* "aiohttp/_http_writer.pyx":85 - * return -1 - * if _write_byte(writer, - * (0x80 | ((utf >> 12) & 0x3f))) < 0: # <<<<<<<<<<<<<< - * return -1 - * if _write_byte(writer, - */ - __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | ((__pyx_v_utf >> 12) & 0x3f)))) < 0) != 0); - - /* "aiohttp/_http_writer.pyx":84 - * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: - * return -1 - * if _write_byte(writer, # <<<<<<<<<<<<<< - * (0x80 | ((utf >> 12) & 0x3f))) < 0: - * return -1 - */ - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":86 - * if _write_byte(writer, - * (0x80 | ((utf >> 12) & 0x3f))) < 0: - * return -1 # <<<<<<<<<<<<<< - * if _write_byte(writer, - * (0x80 | ((utf >> 6) & 0x3f))) < 0: - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":84 - * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: - * return -1 - * if _write_byte(writer, # <<<<<<<<<<<<<< - * (0x80 | ((utf >> 12) & 0x3f))) < 0: - * return -1 - */ - } - - /* "aiohttp/_http_writer.pyx":88 - * return -1 - * if _write_byte(writer, - * (0x80 | ((utf >> 6) & 0x3f))) < 0: # <<<<<<<<<<<<<< - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - */ - __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | ((__pyx_v_utf >> 6) & 0x3f)))) < 0) != 0); - - /* "aiohttp/_http_writer.pyx":87 - * (0x80 | ((utf >> 12) & 0x3f))) < 0: - * return -1 - * if _write_byte(writer, # <<<<<<<<<<<<<< - * (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 - */ - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":89 - * if _write_byte(writer, - * (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 # <<<<<<<<<<<<<< - * return _write_byte(writer, (0x80 | (utf & 0x3f))) - * - */ - __pyx_r = -1; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":87 - * (0x80 | ((utf >> 12) & 0x3f))) < 0: - * return -1 - * if _write_byte(writer, # <<<<<<<<<<<<<< - * (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 - */ - } - - /* "aiohttp/_http_writer.pyx":90 - * (0x80 | ((utf >> 6) & 0x3f))) < 0: - * return -1 - * return _write_byte(writer, (0x80 | (utf & 0x3f))) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | (__pyx_v_utf & 0x3f)))); - goto __pyx_L0; - } - - /* "aiohttp/_http_writer.pyx":60 - * - * - * cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): # <<<<<<<<<<<<<< - * cdef uint64_t utf = symbol - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_writer.pyx":93 - * - * - * cdef inline int _write_str(Writer* writer, str s): # <<<<<<<<<<<<<< - * cdef Py_UCS4 ch - * for ch in s: - */ - -static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_str(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer, PyObject *__pyx_v_s) { - Py_UCS4 __pyx_v_ch; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - void *__pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - int __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_write_str", 0); - - /* "aiohttp/_http_writer.pyx":95 - * cdef inline int _write_str(Writer* writer, str s): - * cdef Py_UCS4 ch - * for ch in s: # <<<<<<<<<<<<<< - * if _write_utf8(writer, ch) < 0: - * return -1 - */ - if (unlikely(__pyx_v_s == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); - __PYX_ERR(0, 95, __pyx_L1_error) - } - __Pyx_INCREF(__pyx_v_s); - __pyx_t_1 = __pyx_v_s; - __pyx_t_6 = __Pyx_init_unicode_iteration(__pyx_t_1, (&__pyx_t_3), (&__pyx_t_4), (&__pyx_t_5)); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 95, __pyx_L1_error) - for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_3; __pyx_t_7++) { - __pyx_t_2 = __pyx_t_7; - __pyx_v_ch = __Pyx_PyUnicode_READ(__pyx_t_5, __pyx_t_4, __pyx_t_2); - - /* "aiohttp/_http_writer.pyx":96 - * cdef Py_UCS4 ch - * for ch in s: - * if _write_utf8(writer, ch) < 0: # <<<<<<<<<<<<<< - * return -1 - * - */ - __pyx_t_8 = ((__pyx_f_7aiohttp_12_http_writer__write_utf8(__pyx_v_writer, __pyx_v_ch) < 0) != 0); - if (__pyx_t_8) { - - /* "aiohttp/_http_writer.pyx":97 - * for ch in s: - * if _write_utf8(writer, ch) < 0: - * return -1 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = -1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":96 - * cdef Py_UCS4 ch - * for ch in s: - * if _write_utf8(writer, ch) < 0: # <<<<<<<<<<<<<< - * return -1 - * - */ - } - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_http_writer.pyx":93 - * - * - * cdef inline int _write_str(Writer* writer, str s): # <<<<<<<<<<<<<< - * cdef Py_UCS4 ch - * for ch in s: - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_WriteUnraisable("aiohttp._http_writer._write_str", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_writer.pyx":102 - * # --------------- _serialize_headers ---------------------- - * - * cdef str to_str(object s): # <<<<<<<<<<<<<< - * typ = type(s) - * if typ is str: - */ - -static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *__pyx_v_s) { - PyTypeObject *__pyx_v_typ = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("to_str", 0); - - /* "aiohttp/_http_writer.pyx":103 - * - * cdef str to_str(object s): - * typ = type(s) # <<<<<<<<<<<<<< - * if typ is str: - * return s - */ - __Pyx_INCREF(((PyObject *)Py_TYPE(__pyx_v_s))); - __pyx_v_typ = ((PyTypeObject*)((PyObject *)Py_TYPE(__pyx_v_s))); - - /* "aiohttp/_http_writer.pyx":104 - * cdef str to_str(object s): - * typ = type(s) - * if typ is str: # <<<<<<<<<<<<<< - * return s - * elif typ is _istr: - */ - __pyx_t_1 = (__pyx_v_typ == (&PyUnicode_Type)); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "aiohttp/_http_writer.pyx":105 - * typ = type(s) - * if typ is str: - * return s # <<<<<<<<<<<<<< - * elif typ is _istr: - * return PyObject_Str(s) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject*)__pyx_v_s)); - __pyx_r = ((PyObject*)__pyx_v_s); - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":104 - * cdef str to_str(object s): - * typ = type(s) - * if typ is str: # <<<<<<<<<<<<<< - * return s - * elif typ is _istr: - */ - } - - /* "aiohttp/_http_writer.pyx":106 - * if typ is str: - * return s - * elif typ is _istr: # <<<<<<<<<<<<<< - * return PyObject_Str(s) - * elif not isinstance(s, str): - */ - __pyx_t_2 = (__pyx_v_typ == ((PyTypeObject*)__pyx_v_7aiohttp_12_http_writer__istr)); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "aiohttp/_http_writer.pyx":107 - * return s - * elif typ is _istr: - * return PyObject_Str(s) # <<<<<<<<<<<<<< - * elif not isinstance(s, str): - * raise TypeError("Cannot serialize non-str key {!r}".format(s)) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PyObject_Str(__pyx_v_s); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(PyUnicode_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(0, 107, __pyx_L1_error) - __pyx_r = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "aiohttp/_http_writer.pyx":106 - * if typ is str: - * return s - * elif typ is _istr: # <<<<<<<<<<<<<< - * return PyObject_Str(s) - * elif not isinstance(s, str): - */ - } - - /* "aiohttp/_http_writer.pyx":108 - * elif typ is _istr: - * return PyObject_Str(s) - * elif not isinstance(s, str): # <<<<<<<<<<<<<< - * raise TypeError("Cannot serialize non-str key {!r}".format(s)) - * else: - */ - __pyx_t_1 = PyUnicode_Check(__pyx_v_s); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "aiohttp/_http_writer.pyx":109 - * return PyObject_Str(s) - * elif not isinstance(s, str): - * raise TypeError("Cannot serialize non-str key {!r}".format(s)) # <<<<<<<<<<<<<< - * else: - * return str(s) - */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_serialize_non_str_key_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_v_s) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_s); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(0, 109, __pyx_L1_error) - - /* "aiohttp/_http_writer.pyx":108 - * elif typ is _istr: - * return PyObject_Str(s) - * elif not isinstance(s, str): # <<<<<<<<<<<<<< - * raise TypeError("Cannot serialize non-str key {!r}".format(s)) - * else: - */ - } - - /* "aiohttp/_http_writer.pyx":111 - * raise TypeError("Cannot serialize non-str key {!r}".format(s)) - * else: - * return str(s) # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_s); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_r = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; - goto __pyx_L0; - } - - /* "aiohttp/_http_writer.pyx":102 - * # --------------- _serialize_headers ---------------------- - * - * cdef str to_str(object s): # <<<<<<<<<<<<<< - * typ = type(s) - * if typ is str: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("aiohttp._http_writer.to_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_typ); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "aiohttp/_http_writer.pyx":114 - * - * - * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< - * cdef Writer writer - * cdef object key - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7aiohttp_12_http_writer_1_serialize_headers = {"_serialize_headers", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_status_line = 0; - PyObject *__pyx_v_headers = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_serialize_headers (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_status_line,&__pyx_n_s_headers,0}; - PyObject* values[2] = {0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_status_line)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_headers)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("_serialize_headers", 1, 2, 2, 1); __PYX_ERR(0, 114, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_serialize_headers") < 0)) __PYX_ERR(0, 114, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - } - __pyx_v_status_line = ((PyObject*)values[0]); - __pyx_v_headers = values[1]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("_serialize_headers", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 114, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._http_writer._serialize_headers", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_status_line), (&PyUnicode_Type), 1, "status_line", 1))) __PYX_ERR(0, 114, __pyx_L1_error) - __pyx_r = __pyx_pf_7aiohttp_12_http_writer__serialize_headers(__pyx_self, __pyx_v_status_line, __pyx_v_headers); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_12_http_writer__serialize_headers(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_status_line, PyObject *__pyx_v_headers) { - struct __pyx_t_7aiohttp_12_http_writer_Writer __pyx_v_writer; - PyObject *__pyx_v_key = 0; - PyObject *__pyx_v_val = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - char const *__pyx_t_9; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_serialize_headers", 0); - - /* "aiohttp/_http_writer.pyx":120 - * cdef bytes ret - * - * _init_writer(&writer) # <<<<<<<<<<<<<< - * - * try: - */ - __pyx_f_7aiohttp_12_http_writer__init_writer((&__pyx_v_writer)); - - /* "aiohttp/_http_writer.pyx":122 - * _init_writer(&writer) - * - * try: # <<<<<<<<<<<<<< - * if _write_str(&writer, status_line) < 0: - * raise - */ - /*try:*/ { - - /* "aiohttp/_http_writer.pyx":123 - * - * try: - * if _write_str(&writer, status_line) < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\r') < 0: - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_str((&__pyx_v_writer), __pyx_v_status_line) < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":124 - * try: - * if _write_str(&writer, status_line) < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b'\r') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 124, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":123 - * - * try: - * if _write_str(&writer, status_line) < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\r') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":125 - * if _write_str(&writer, status_line) < 0: - * raise - * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\n') < 0: - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\r') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":126 - * raise - * if _write_byte(&writer, b'\r') < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b'\n') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 126, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":125 - * if _write_str(&writer, status_line) < 0: - * raise - * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\n') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":127 - * if _write_byte(&writer, b'\r') < 0: - * raise - * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< - * raise - * - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\n') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":128 - * raise - * if _write_byte(&writer, b'\n') < 0: - * raise # <<<<<<<<<<<<<< - * - * for key, val in headers.items(): - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 128, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":127 - * if _write_byte(&writer, b'\r') < 0: - * raise - * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< - * raise - * - */ - } - - /* "aiohttp/_http_writer.pyx":130 - * raise - * - * for key, val in headers.items(): # <<<<<<<<<<<<<< - * if _write_str(&writer, to_str(key)) < 0: - * raise - */ - __pyx_t_3 = 0; - if (unlikely(__pyx_v_headers == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); - __PYX_ERR(0, 130, __pyx_L4_error) - } - __pyx_t_6 = __Pyx_dict_iterator(__pyx_v_headers, 0, __pyx_n_s_items, (&__pyx_t_4), (&__pyx_t_5)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 130, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_2); - __pyx_t_2 = __pyx_t_6; - __pyx_t_6 = 0; - while (1) { - __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_2, __pyx_t_4, &__pyx_t_3, &__pyx_t_6, &__pyx_t_7, NULL, __pyx_t_5); - if (unlikely(__pyx_t_8 == 0)) break; - if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 130, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_XDECREF_SET(__pyx_v_val, __pyx_t_7); - __pyx_t_7 = 0; - - /* "aiohttp/_http_writer.pyx":131 - * - * for key, val in headers.items(): - * if _write_str(&writer, to_str(key)) < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b':') < 0: - */ - __pyx_t_7 = __pyx_f_7aiohttp_12_http_writer_to_str(__pyx_v_key); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 131, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_str((&__pyx_v_writer), ((PyObject*)__pyx_t_7)) < 0) != 0); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":132 - * for key, val in headers.items(): - * if _write_str(&writer, to_str(key)) < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b':') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 132, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":131 - * - * for key, val in headers.items(): - * if _write_str(&writer, to_str(key)) < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b':') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":133 - * if _write_str(&writer, to_str(key)) < 0: - * raise - * if _write_byte(&writer, b':') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b' ') < 0: - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), ':') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":134 - * raise - * if _write_byte(&writer, b':') < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b' ') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 134, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":133 - * if _write_str(&writer, to_str(key)) < 0: - * raise - * if _write_byte(&writer, b':') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b' ') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":135 - * if _write_byte(&writer, b':') < 0: - * raise - * if _write_byte(&writer, b' ') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_str(&writer, to_str(val)) < 0: - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), ' ') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":136 - * raise - * if _write_byte(&writer, b' ') < 0: - * raise # <<<<<<<<<<<<<< - * if _write_str(&writer, to_str(val)) < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 136, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":135 - * if _write_byte(&writer, b':') < 0: - * raise - * if _write_byte(&writer, b' ') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_str(&writer, to_str(val)) < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":137 - * if _write_byte(&writer, b' ') < 0: - * raise - * if _write_str(&writer, to_str(val)) < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\r') < 0: - */ - __pyx_t_7 = __pyx_f_7aiohttp_12_http_writer_to_str(__pyx_v_val); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 137, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_str((&__pyx_v_writer), ((PyObject*)__pyx_t_7)) < 0) != 0); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":138 - * raise - * if _write_str(&writer, to_str(val)) < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b'\r') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 138, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":137 - * if _write_byte(&writer, b' ') < 0: - * raise - * if _write_str(&writer, to_str(val)) < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\r') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":139 - * if _write_str(&writer, to_str(val)) < 0: - * raise - * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\n') < 0: - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\r') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":140 - * raise - * if _write_byte(&writer, b'\r') < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b'\n') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 140, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":139 - * if _write_str(&writer, to_str(val)) < 0: - * raise - * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\n') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":141 - * if _write_byte(&writer, b'\r') < 0: - * raise - * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< - * raise - * - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\n') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":142 - * raise - * if _write_byte(&writer, b'\n') < 0: - * raise # <<<<<<<<<<<<<< - * - * if _write_byte(&writer, b'\r') < 0: - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 142, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":141 - * if _write_byte(&writer, b'\r') < 0: - * raise - * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< - * raise - * - */ - } - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_writer.pyx":144 - * raise - * - * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\n') < 0: - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\r') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":145 - * - * if _write_byte(&writer, b'\r') < 0: - * raise # <<<<<<<<<<<<<< - * if _write_byte(&writer, b'\n') < 0: - * raise - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 145, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":144 - * raise - * - * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< - * raise - * if _write_byte(&writer, b'\n') < 0: - */ - } - - /* "aiohttp/_http_writer.pyx":146 - * if _write_byte(&writer, b'\r') < 0: - * raise - * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< - * raise - * - */ - __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\n') < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "aiohttp/_http_writer.pyx":147 - * raise - * if _write_byte(&writer, b'\n') < 0: - * raise # <<<<<<<<<<<<<< - * - * return PyBytes_FromStringAndSize(writer.buf, writer.pos) - */ - __Pyx_ReraiseException(); __PYX_ERR(0, 147, __pyx_L4_error) - - /* "aiohttp/_http_writer.pyx":146 - * if _write_byte(&writer, b'\r') < 0: - * raise - * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< - * raise - * - */ - } - - /* "aiohttp/_http_writer.pyx":149 - * raise - * - * return PyBytes_FromStringAndSize(writer.buf, writer.pos) # <<<<<<<<<<<<<< - * finally: - * _release_writer(&writer) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = PyBytes_FromStringAndSize(__pyx_v_writer.buf, __pyx_v_writer.pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 149, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L3_return; - } - - /* "aiohttp/_http_writer.pyx":151 - * return PyBytes_FromStringAndSize(writer.buf, writer.pos) - * finally: - * _release_writer(&writer) # <<<<<<<<<<<<<< - */ - /*finally:*/ { - __pyx_L4_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12) < 0)) __Pyx_ErrFetch(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); - __Pyx_XGOTREF(__pyx_t_10); - __Pyx_XGOTREF(__pyx_t_11); - __Pyx_XGOTREF(__pyx_t_12); - __Pyx_XGOTREF(__pyx_t_13); - __Pyx_XGOTREF(__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_15); - __pyx_t_5 = __pyx_lineno; __pyx_t_8 = __pyx_clineno; __pyx_t_9 = __pyx_filename; - { - __pyx_f_7aiohttp_12_http_writer__release_writer((&__pyx_v_writer)); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_13); - __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15); - } - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_ErrRestore(__pyx_t_10, __pyx_t_11, __pyx_t_12); - __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; - __pyx_lineno = __pyx_t_5; __pyx_clineno = __pyx_t_8; __pyx_filename = __pyx_t_9; - goto __pyx_L1_error; - } - __pyx_L3_return: { - __pyx_t_15 = __pyx_r; - __pyx_r = 0; - __pyx_f_7aiohttp_12_http_writer__release_writer((&__pyx_v_writer)); - __pyx_r = __pyx_t_15; - __pyx_t_15 = 0; - goto __pyx_L0; - } - } - - /* "aiohttp/_http_writer.pyx":114 - * - * - * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< - * cdef Writer writer - * cdef object key - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("aiohttp._http_writer._serialize_headers", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_key); - __Pyx_XDECREF(__pyx_v_val); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__http_writer(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__http_writer}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "_http_writer", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_Cannot_serialize_non_str_key_r, __pyx_k_Cannot_serialize_non_str_key_r, sizeof(__pyx_k_Cannot_serialize_non_str_key_r), 0, 1, 0, 0}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_n_s_aiohttp__http_writer, __pyx_k_aiohttp__http_writer, sizeof(__pyx_k_aiohttp__http_writer), 0, 0, 1, 1}, - {&__pyx_kp_s_aiohttp__http_writer_pyx, __pyx_k_aiohttp__http_writer_pyx, sizeof(__pyx_k_aiohttp__http_writer_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_headers, __pyx_k_headers, sizeof(__pyx_k_headers), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_istr, __pyx_k_istr, sizeof(__pyx_k_istr), 0, 0, 1, 1}, - {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, - {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_multidict, __pyx_k_multidict, sizeof(__pyx_k_multidict), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_ret, __pyx_k_ret, sizeof(__pyx_k_ret), 0, 0, 1, 1}, - {&__pyx_n_s_serialize_headers, __pyx_k_serialize_headers, sizeof(__pyx_k_serialize_headers), 0, 0, 1, 1}, - {&__pyx_n_s_status_line, __pyx_k_status_line, sizeof(__pyx_k_status_line), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_val, __pyx_k_val, sizeof(__pyx_k_val), 0, 0, 1, 1}, - {&__pyx_n_s_writer, __pyx_k_writer, sizeof(__pyx_k_writer), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 109, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "aiohttp/_http_writer.pyx":114 - * - * - * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< - * cdef Writer writer - * cdef object key - */ - __pyx_tuple_ = PyTuple_Pack(6, __pyx_n_s_status_line, __pyx_n_s_headers, __pyx_n_s_writer, __pyx_n_s_key, __pyx_n_s_val, __pyx_n_s_ret); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__http_writer_pyx, __pyx_n_s_serialize_headers, 114, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 114, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __pyx_v_7aiohttp_12_http_writer__istr = Py_None; Py_INCREF(Py_None); - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_http_writer(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_http_writer(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__http_writer(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__http_writer(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__http_writer(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_http_writer' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__http_writer(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_http_writer", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_aiohttp___http_writer) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "aiohttp._http_writer")) { - if (unlikely(PyDict_SetItemString(modules, "aiohttp._http_writer", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - (void)__Pyx_modinit_type_init_code(); - if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "aiohttp/_http_writer.pyx":8 - * from libc.string cimport memcpy - * - * from multidict import istr # <<<<<<<<<<<<<< - * - * DEF BUF_SIZE = 16 * 1024 # 16KiB - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_istr); - __Pyx_GIVEREF(__pyx_n_s_istr); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_istr); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_multidict, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_istr); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_istr, __pyx_t_1) < 0) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_writer.pyx":13 - * cdef char BUFFER[BUF_SIZE] - * - * cdef object _istr = istr # <<<<<<<<<<<<<< - * - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_istr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_writer__istr); - __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_writer__istr, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __pyx_t_2 = 0; - - /* "aiohttp/_http_writer.pyx":114 - * - * - * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< - * cdef Writer writer - * cdef object key - */ - __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_writer_1_serialize_headers, NULL, __pyx_n_s_aiohttp__http_writer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_serialize_headers, __pyx_t_2) < 0) __PYX_ERR(0, 114, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "aiohttp/_http_writer.pyx":1 - * from cpython.bytes cimport PyBytes_FromStringAndSize # <<<<<<<<<<<<<< - * from cpython.exc cimport PyErr_NoMemory - * from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._http_writer", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init aiohttp._http_writer"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* WriteUnraisableException */ -static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, - CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, - int full_traceback, CYTHON_UNUSED int nogil) { - PyObject *old_exc, *old_val, *old_tb; - PyObject *ctx; - __Pyx_PyThreadState_declare -#ifdef WITH_THREAD - PyGILState_STATE state; - if (nogil) - state = PyGILState_Ensure(); -#ifdef _MSC_VER - else state = (PyGILState_STATE)-1; -#endif -#endif - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); - if (full_traceback) { - Py_XINCREF(old_exc); - Py_XINCREF(old_val); - Py_XINCREF(old_tb); - __Pyx_ErrRestore(old_exc, old_val, old_tb); - PyErr_PrintEx(1); - } - #if PY_MAJOR_VERSION < 3 - ctx = PyString_FromString(name); - #else - ctx = PyUnicode_FromString(name); - #endif - __Pyx_ErrRestore(old_exc, old_val, old_tb); - if (!ctx) { - PyErr_WriteUnraisable(Py_None); - } else { - PyErr_WriteUnraisable(ctx); - Py_DECREF(ctx); - } -#ifdef WITH_THREAD - if (nogil) - PyGILState_Release(state); -#endif -} - -/* unicode_iter */ -static CYTHON_INLINE int __Pyx_init_unicode_iteration( - PyObject* ustring, Py_ssize_t *length, void** data, int *kind) { -#if CYTHON_PEP393_ENABLED - if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return -1; - *kind = PyUnicode_KIND(ustring); - *length = PyUnicode_GET_LENGTH(ustring); - *data = PyUnicode_DATA(ustring); -#else - *kind = 0; - *length = PyUnicode_GET_SIZE(ustring); - *data = (void*)PyUnicode_AS_UNICODE(ustring); -#endif - return 0; -} - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCall2Args */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", - name, type->tp_name, Py_TYPE(obj)->tp_name); - return 0; -} - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* ReRaiseException */ -static CYTHON_INLINE void __Pyx_ReraiseException(void) { - PyObject *type = NULL, *value = NULL, *tb = NULL; -#if CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = PyThreadState_GET(); - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - type = exc_info->exc_type; - value = exc_info->exc_value; - tb = exc_info->exc_traceback; - #else - type = tstate->exc_type; - value = tstate->exc_value; - tb = tstate->exc_traceback; - #endif -#else - PyErr_GetExcInfo(&type, &value, &tb); -#endif - if (!type || type == Py_None) { -#if !CYTHON_FAST_THREAD_STATE - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tb); -#endif - PyErr_SetString(PyExc_RuntimeError, - "No active exception to reraise"); - } else { -#if CYTHON_FAST_THREAD_STATE - Py_INCREF(type); - Py_XINCREF(value); - Py_XINCREF(tb); -#endif - PyErr_Restore(type, value, tb); - } -} - -/* IterFinish */ -static CYTHON_INLINE int __Pyx_IterFinish(void) { -#if CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* exc_type = tstate->curexc_type; - if (unlikely(exc_type)) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { - PyObject *exc_value, *exc_tb; - exc_value = tstate->curexc_value; - exc_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; - Py_DECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - return 0; - } else { - return -1; - } - } - return 0; -#else - if (unlikely(PyErr_Occurred())) { - if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { - PyErr_Clear(); - return 0; - } else { - return -1; - } - } - return 0; -#endif -} - -/* PyObjectCallNoArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, NULL, 0); - } -#endif -#ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) -#else - if (likely(PyCFunction_Check(func))) -#endif - { - if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { - return __Pyx_PyObject_CallMethO(func, NULL); - } - } - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); -} -#endif - -/* PyObjectGetMethod */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { - PyObject *attr; -#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrgetfunc f = NULL; - PyObject **dictptr, *dict; - int meth_found = 0; - assert (*method == NULL); - if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; - } - if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { - return 0; - } - descr = _PyType_Lookup(tp, name); - if (likely(descr != NULL)) { - Py_INCREF(descr); -#if PY_MAJOR_VERSION >= 3 - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) - #endif -#else - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr))) - #endif -#endif - { - meth_found = 1; - } else { - f = Py_TYPE(descr)->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - } - } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - attr = __Pyx_PyDict_GetItemStr(dict, name); - if (attr != NULL) { - Py_INCREF(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - goto try_unpack; - } - Py_DECREF(dict); - } - if (meth_found) { - *method = descr; - return 1; - } - if (f != NULL) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - if (descr != NULL) { - *method = descr; - return 0; - } - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(name)); -#endif - return 0; -#else - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; -#endif -try_unpack: -#if CYTHON_UNPACK_METHODS - if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { - PyObject *function = PyMethod_GET_FUNCTION(attr); - Py_INCREF(function); - Py_DECREF(attr); - *method = function; - return 1; - } -#endif - *method = attr; - return 0; -} - -/* PyObjectCallMethod0 */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { - PyObject *method = NULL, *result = NULL; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_CallOneArg(method, obj); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) goto bad; - result = __Pyx_PyObject_CallNoArg(method); - Py_DECREF(method); -bad: - return result; -} - -/* RaiseNeedMoreValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* RaiseTooManyValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* UnpackItemEndCheck */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { - if (unlikely(retval)) { - Py_DECREF(retval); - __Pyx_RaiseTooManyValuesError(expected); - return -1; - } else { - return __Pyx_IterFinish(); - } - return 0; -} - -/* RaiseNoneIterError */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* UnpackTupleError */ -static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { - if (t == Py_None) { - __Pyx_RaiseNoneNotIterableError(); - } else if (PyTuple_GET_SIZE(t) < index) { - __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); - } else { - __Pyx_RaiseTooManyValuesError(index); - } -} - -/* UnpackTuple2 */ -static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( - PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) { - PyObject *value1 = NULL, *value2 = NULL; -#if CYTHON_COMPILING_IN_PYPY - value1 = PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad; - value2 = PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad; -#else - value1 = PyTuple_GET_ITEM(tuple, 0); Py_INCREF(value1); - value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value2); -#endif - if (decref_tuple) { - Py_DECREF(tuple); - } - *pvalue1 = value1; - *pvalue2 = value2; - return 0; -#if CYTHON_COMPILING_IN_PYPY -bad: - Py_XDECREF(value1); - Py_XDECREF(value2); - if (decref_tuple) { Py_XDECREF(tuple); } - return -1; -#endif -} -static int __Pyx_unpack_tuple2_generic(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, - int has_known_size, int decref_tuple) { - Py_ssize_t index; - PyObject *value1 = NULL, *value2 = NULL, *iter = NULL; - iternextfunc iternext; - iter = PyObject_GetIter(tuple); - if (unlikely(!iter)) goto bad; - if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; } - iternext = Py_TYPE(iter)->tp_iternext; - value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; } - value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; } - if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad; - Py_DECREF(iter); - *pvalue1 = value1; - *pvalue2 = value2; - return 0; -unpacking_failed: - if (!has_known_size && __Pyx_IterFinish() == 0) - __Pyx_RaiseNeedMoreValuesError(index); -bad: - Py_XDECREF(iter); - Py_XDECREF(value1); - Py_XDECREF(value2); - if (decref_tuple) { Py_XDECREF(tuple); } - return -1; -} - -/* dict_iter */ -static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name, - Py_ssize_t* p_orig_length, int* p_source_is_dict) { - is_dict = is_dict || likely(PyDict_CheckExact(iterable)); - *p_source_is_dict = is_dict; - if (is_dict) { -#if !CYTHON_COMPILING_IN_PYPY - *p_orig_length = PyDict_Size(iterable); - Py_INCREF(iterable); - return iterable; -#elif PY_MAJOR_VERSION >= 3 - static PyObject *py_items = NULL, *py_keys = NULL, *py_values = NULL; - PyObject **pp = NULL; - if (method_name) { - const char *name = PyUnicode_AsUTF8(method_name); - if (strcmp(name, "iteritems") == 0) pp = &py_items; - else if (strcmp(name, "iterkeys") == 0) pp = &py_keys; - else if (strcmp(name, "itervalues") == 0) pp = &py_values; - if (pp) { - if (!*pp) { - *pp = PyUnicode_FromString(name + 4); - if (!*pp) - return NULL; - } - method_name = *pp; - } - } -#endif - } - *p_orig_length = 0; - if (method_name) { - PyObject* iter; - iterable = __Pyx_PyObject_CallMethod0(iterable, method_name); - if (!iterable) - return NULL; -#if !CYTHON_COMPILING_IN_PYPY - if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable)) - return iterable; -#endif - iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - return iter; - } - return PyObject_GetIter(iterable); -} -static CYTHON_INLINE int __Pyx_dict_iter_next( - PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, - PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) { - PyObject* next_item; -#if !CYTHON_COMPILING_IN_PYPY - if (source_is_dict) { - PyObject *key, *value; - if (unlikely(orig_length != PyDict_Size(iter_obj))) { - PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); - return -1; - } - if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) { - return 0; - } - if (pitem) { - PyObject* tuple = PyTuple_New(2); - if (unlikely(!tuple)) { - return -1; - } - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(tuple, 0, key); - PyTuple_SET_ITEM(tuple, 1, value); - *pitem = tuple; - } else { - if (pkey) { - Py_INCREF(key); - *pkey = key; - } - if (pvalue) { - Py_INCREF(value); - *pvalue = value; - } - } - return 1; - } else if (PyTuple_CheckExact(iter_obj)) { - Py_ssize_t pos = *ppos; - if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0; - *ppos = pos + 1; - next_item = PyTuple_GET_ITEM(iter_obj, pos); - Py_INCREF(next_item); - } else if (PyList_CheckExact(iter_obj)) { - Py_ssize_t pos = *ppos; - if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0; - *ppos = pos + 1; - next_item = PyList_GET_ITEM(iter_obj, pos); - Py_INCREF(next_item); - } else -#endif - { - next_item = PyIter_Next(iter_obj); - if (unlikely(!next_item)) { - return __Pyx_IterFinish(); - } - } - if (pitem) { - *pitem = next_item; - } else if (pkey && pvalue) { - if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1)) - return -1; - } else if (pkey) { - *pkey = next_item; - } else { - *pvalue = next_item; - } - return 1; -} - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* SwapException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = *type; - exc_info->exc_value = *value; - exc_info->exc_traceback = *tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = *type; - tstate->exc_value = *value; - tstate->exc_traceback = *tb; - #endif - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); - PyErr_SetExcInfo(*type, *value, *tb); - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* TypeImport */ -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ip) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_http_writer.cp39-win_amd64.pyd deleted file mode 100644 index 698179fc..00000000 Binary files a/dist/ba_data/python-site-packages/aiohttp/_http_writer.cp39-win_amd64.pyd and /dev/null differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/aiohttp/_http_writer.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..008c2987 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_http_writer.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx b/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx index 84b42fa1..eff85219 100644 --- a/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx +++ b/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx @@ -111,6 +111,14 @@ cdef str to_str(object s): return str(s) +cdef void _safe_header(str string) except *: + if "\r" in string or "\n" in string: + raise ValueError( + "Newline or carriage return character detected in HTTP status message or " + "header. This is a potential security issue." + ) + + def _serialize_headers(str status_line, headers): cdef Writer writer cdef object key @@ -119,6 +127,10 @@ def _serialize_headers(str status_line, headers): _init_writer(&writer) + for key, val in headers.items(): + _safe_header(to_str(key)) + _safe_header(to_str(val)) + try: if _write_str(&writer, status_line) < 0: raise diff --git a/dist/ba_data/python-site-packages/aiohttp/_websocket.c b/dist/ba_data/python-site-packages/aiohttp/_websocket.c deleted file mode 100644 index f3e5c323..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/_websocket.c +++ /dev/null @@ -1,3588 +0,0 @@ -/* Generated by Cython 0.29.21 */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_21" -#define CYTHON_HEX_VERSION 0x001D15F0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__aiohttp___websocket -#define __PYX_HAVE_API__aiohttp___websocket -/* Early includes */ -#include -#include -#include "pythread.h" -#include -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "aiohttp\\_websocket.pyx", - "type.pxd", - "bool.pxd", - "complex.pxd", -}; - -/*--- Type declarations ---*/ - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 -}; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); -#endif - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - - -/* Module declarations from 'cpython.version' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'cpython.ref' */ - -/* Module declarations from 'cpython.exc' */ - -/* Module declarations from 'cpython.module' */ - -/* Module declarations from 'cpython.mem' */ - -/* Module declarations from 'cpython.tuple' */ - -/* Module declarations from 'cpython.list' */ - -/* Module declarations from 'cpython.sequence' */ - -/* Module declarations from 'cpython.mapping' */ - -/* Module declarations from 'cpython.iterator' */ - -/* Module declarations from 'cpython.number' */ - -/* Module declarations from 'cpython.int' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.bool' */ -static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; - -/* Module declarations from 'cpython.long' */ - -/* Module declarations from 'cpython.float' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.complex' */ -static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; - -/* Module declarations from 'cpython.string' */ - -/* Module declarations from 'cpython.unicode' */ - -/* Module declarations from 'cpython.dict' */ - -/* Module declarations from 'cpython.instance' */ - -/* Module declarations from 'cpython.function' */ - -/* Module declarations from 'cpython.method' */ - -/* Module declarations from 'cpython.weakref' */ - -/* Module declarations from 'cpython.getargs' */ - -/* Module declarations from 'cpython.pythread' */ - -/* Module declarations from 'cpython.pystate' */ - -/* Module declarations from 'cpython.cobject' */ - -/* Module declarations from 'cpython.oldbuffer' */ - -/* Module declarations from 'cpython.set' */ - -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'cpython.bytes' */ - -/* Module declarations from 'cpython.pycapsule' */ - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'libc.stdint' */ - -/* Module declarations from 'aiohttp._websocket' */ -#define __Pyx_MODULE_NAME "aiohttp._websocket" -extern int __pyx_module_is_main_aiohttp___websocket; -int __pyx_module_is_main_aiohttp___websocket = 0; - -/* Implementation of 'aiohttp._websocket' */ -static PyObject *__pyx_builtin_range; -static const char __pyx_k_i[] = "i"; -static const char __pyx_k_data[] = "data"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_mask[] = "mask"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_in_buf[] = "in_buf"; -static const char __pyx_k_data_len[] = "data_len"; -static const char __pyx_k_mask_buf[] = "mask_buf"; -static const char __pyx_k_uint32_msk[] = "uint32_msk"; -static const char __pyx_k_uint64_msk[] = "uint64_msk"; -static const char __pyx_k_aiohttp__websocket[] = "aiohttp._websocket"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_websocket_mask_cython[] = "_websocket_mask_cython"; -static const char __pyx_k_aiohttp__websocket_pyx[] = "aiohttp\\_websocket.pyx"; -static PyObject *__pyx_n_s_aiohttp__websocket; -static PyObject *__pyx_kp_s_aiohttp__websocket_pyx; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_data; -static PyObject *__pyx_n_s_data_len; -static PyObject *__pyx_n_s_i; -static PyObject *__pyx_n_s_in_buf; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_mask; -static PyObject *__pyx_n_s_mask_buf; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_range; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_uint32_msk; -static PyObject *__pyx_n_s_uint64_msk; -static PyObject *__pyx_n_s_websocket_mask_cython; -static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_mask, PyObject *__pyx_v_data); /* proto */ -static PyObject *__pyx_tuple_; -static PyObject *__pyx_codeobj__2; -/* Late includes */ - -/* "aiohttp/_websocket.pyx":11 - * - * - * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates its `data` argument - * """ - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython[] = "Note, this function mutates its `data` argument\n "; -static PyMethodDef __pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython = {"_websocket_mask_cython", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython}; -static PyObject *__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_mask = 0; - PyObject *__pyx_v_data = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_websocket_mask_cython (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_mask,&__pyx_n_s_data,0}; - PyObject* values[2] = {0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("_websocket_mask_cython", 1, 2, 2, 1); __PYX_ERR(0, 11, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_websocket_mask_cython") < 0)) __PYX_ERR(0, 11, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - } - __pyx_v_mask = values[0]; - __pyx_v_data = values[1]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("_websocket_mask_cython", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 11, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("aiohttp._websocket._websocket_mask_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(__pyx_self, __pyx_v_mask, __pyx_v_data); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_mask, PyObject *__pyx_v_data) { - Py_ssize_t __pyx_v_data_len; - Py_ssize_t __pyx_v_i; - unsigned char *__pyx_v_in_buf; - unsigned char const *__pyx_v_mask_buf; - uint32_t __pyx_v_uint32_msk; - uint64_t __pyx_v_uint64_msk; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - char *__pyx_t_5; - uint64_t *__pyx_t_6; - long __pyx_t_7; - uint32_t *__pyx_t_8; - Py_ssize_t __pyx_t_9; - Py_ssize_t __pyx_t_10; - Py_ssize_t __pyx_t_11; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_websocket_mask_cython", 0); - __Pyx_INCREF(__pyx_v_mask); - __Pyx_INCREF(__pyx_v_data); - - /* "aiohttp/_websocket.pyx":22 - * uint64_t uint64_msk - * - * assert len(mask) == 4 # <<<<<<<<<<<<<< - * - * if not isinstance(mask, bytes): - */ - #ifndef CYTHON_WITHOUT_ASSERTIONS - if (unlikely(!Py_OptimizeFlag)) { - __pyx_t_1 = PyObject_Length(__pyx_v_mask); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 22, __pyx_L1_error) - if (unlikely(!((__pyx_t_1 == 4) != 0))) { - PyErr_SetNone(PyExc_AssertionError); - __PYX_ERR(0, 22, __pyx_L1_error) - } - } - #endif - - /* "aiohttp/_websocket.pyx":24 - * assert len(mask) == 4 - * - * if not isinstance(mask, bytes): # <<<<<<<<<<<<<< - * mask = bytes(mask) - * - */ - __pyx_t_2 = PyBytes_Check(__pyx_v_mask); - __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); - if (__pyx_t_3) { - - /* "aiohttp/_websocket.pyx":25 - * - * if not isinstance(mask, bytes): - * mask = bytes(mask) # <<<<<<<<<<<<<< - * - * if isinstance(data, bytearray): - */ - __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF_SET(__pyx_v_mask, __pyx_t_4); - __pyx_t_4 = 0; - - /* "aiohttp/_websocket.pyx":24 - * assert len(mask) == 4 - * - * if not isinstance(mask, bytes): # <<<<<<<<<<<<<< - * mask = bytes(mask) - * - */ - } - - /* "aiohttp/_websocket.pyx":27 - * mask = bytes(mask) - * - * if isinstance(data, bytearray): # <<<<<<<<<<<<<< - * data = data - * else: - */ - __pyx_t_3 = PyByteArray_Check(__pyx_v_data); - __pyx_t_2 = (__pyx_t_3 != 0); - if (__pyx_t_2) { - - /* "aiohttp/_websocket.pyx":28 - * - * if isinstance(data, bytearray): - * data = data # <<<<<<<<<<<<<< - * else: - * data = bytearray(data) - */ - __pyx_t_4 = __pyx_v_data; - __Pyx_INCREF(__pyx_t_4); - __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_4); - __pyx_t_4 = 0; - - /* "aiohttp/_websocket.pyx":27 - * mask = bytes(mask) - * - * if isinstance(data, bytearray): # <<<<<<<<<<<<<< - * data = data - * else: - */ - goto __pyx_L4; - } - - /* "aiohttp/_websocket.pyx":30 - * data = data - * else: - * data = bytearray(data) # <<<<<<<<<<<<<< - * - * data_len = len(data) - */ - /*else*/ { - __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyByteArray_Type)), __pyx_v_data); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_4); - __pyx_t_4 = 0; - } - __pyx_L4:; - - /* "aiohttp/_websocket.pyx":32 - * data = bytearray(data) - * - * data_len = len(data) # <<<<<<<<<<<<<< - * in_buf = PyByteArray_AsString(data) - * mask_buf = PyBytes_AsString(mask) - */ - __pyx_t_1 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 32, __pyx_L1_error) - __pyx_v_data_len = __pyx_t_1; - - /* "aiohttp/_websocket.pyx":33 - * - * data_len = len(data) - * in_buf = PyByteArray_AsString(data) # <<<<<<<<<<<<<< - * mask_buf = PyBytes_AsString(mask) - * uint32_msk = (mask_buf)[0] - */ - if (!(likely(PyByteArray_CheckExact(__pyx_v_data))||((__pyx_v_data) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytearray", Py_TYPE(__pyx_v_data)->tp_name), 0))) __PYX_ERR(0, 33, __pyx_L1_error) - __pyx_t_5 = PyByteArray_AsString(((PyObject*)__pyx_v_data)); if (unlikely(__pyx_t_5 == ((char *)NULL))) __PYX_ERR(0, 33, __pyx_L1_error) - __pyx_v_in_buf = ((unsigned char *)__pyx_t_5); - - /* "aiohttp/_websocket.pyx":34 - * data_len = len(data) - * in_buf = PyByteArray_AsString(data) - * mask_buf = PyBytes_AsString(mask) # <<<<<<<<<<<<<< - * uint32_msk = (mask_buf)[0] - * - */ - __pyx_t_5 = PyBytes_AsString(__pyx_v_mask); if (unlikely(__pyx_t_5 == ((char *)NULL))) __PYX_ERR(0, 34, __pyx_L1_error) - __pyx_v_mask_buf = ((unsigned char const *)__pyx_t_5); - - /* "aiohttp/_websocket.pyx":35 - * in_buf = PyByteArray_AsString(data) - * mask_buf = PyBytes_AsString(mask) - * uint32_msk = (mask_buf)[0] # <<<<<<<<<<<<<< - * - * # TODO: align in_data ptr to achieve even faster speeds - */ - __pyx_v_uint32_msk = (((uint32_t *)__pyx_v_mask_buf)[0]); - - /* "aiohttp/_websocket.pyx":40 - * # does it need in python ?! malloc() always aligns to sizeof(long) bytes - * - * if sizeof(size_t) >= 8: # <<<<<<<<<<<<<< - * uint64_msk = uint32_msk - * uint64_msk = (uint64_msk << 32) | uint32_msk - */ - __pyx_t_2 = (((sizeof(size_t)) >= 8) != 0); - if (__pyx_t_2) { - - /* "aiohttp/_websocket.pyx":41 - * - * if sizeof(size_t) >= 8: - * uint64_msk = uint32_msk # <<<<<<<<<<<<<< - * uint64_msk = (uint64_msk << 32) | uint32_msk - * - */ - __pyx_v_uint64_msk = __pyx_v_uint32_msk; - - /* "aiohttp/_websocket.pyx":42 - * if sizeof(size_t) >= 8: - * uint64_msk = uint32_msk - * uint64_msk = (uint64_msk << 32) | uint32_msk # <<<<<<<<<<<<<< - * - * while data_len >= 8: - */ - __pyx_v_uint64_msk = ((__pyx_v_uint64_msk << 32) | __pyx_v_uint32_msk); - - /* "aiohttp/_websocket.pyx":44 - * uint64_msk = (uint64_msk << 32) | uint32_msk - * - * while data_len >= 8: # <<<<<<<<<<<<<< - * (in_buf)[0] ^= uint64_msk - * in_buf += 8 - */ - while (1) { - __pyx_t_2 = ((__pyx_v_data_len >= 8) != 0); - if (!__pyx_t_2) break; - - /* "aiohttp/_websocket.pyx":45 - * - * while data_len >= 8: - * (in_buf)[0] ^= uint64_msk # <<<<<<<<<<<<<< - * in_buf += 8 - * data_len -= 8 - */ - __pyx_t_6 = ((uint64_t *)__pyx_v_in_buf); - __pyx_t_7 = 0; - (__pyx_t_6[__pyx_t_7]) = ((__pyx_t_6[__pyx_t_7]) ^ __pyx_v_uint64_msk); - - /* "aiohttp/_websocket.pyx":46 - * while data_len >= 8: - * (in_buf)[0] ^= uint64_msk - * in_buf += 8 # <<<<<<<<<<<<<< - * data_len -= 8 - * - */ - __pyx_v_in_buf = (__pyx_v_in_buf + 8); - - /* "aiohttp/_websocket.pyx":47 - * (in_buf)[0] ^= uint64_msk - * in_buf += 8 - * data_len -= 8 # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_data_len = (__pyx_v_data_len - 8); - } - - /* "aiohttp/_websocket.pyx":40 - * # does it need in python ?! malloc() always aligns to sizeof(long) bytes - * - * if sizeof(size_t) >= 8: # <<<<<<<<<<<<<< - * uint64_msk = uint32_msk - * uint64_msk = (uint64_msk << 32) | uint32_msk - */ - } - - /* "aiohttp/_websocket.pyx":50 - * - * - * while data_len >= 4: # <<<<<<<<<<<<<< - * (in_buf)[0] ^= uint32_msk - * in_buf += 4 - */ - while (1) { - __pyx_t_2 = ((__pyx_v_data_len >= 4) != 0); - if (!__pyx_t_2) break; - - /* "aiohttp/_websocket.pyx":51 - * - * while data_len >= 4: - * (in_buf)[0] ^= uint32_msk # <<<<<<<<<<<<<< - * in_buf += 4 - * data_len -= 4 - */ - __pyx_t_8 = ((uint32_t *)__pyx_v_in_buf); - __pyx_t_7 = 0; - (__pyx_t_8[__pyx_t_7]) = ((__pyx_t_8[__pyx_t_7]) ^ __pyx_v_uint32_msk); - - /* "aiohttp/_websocket.pyx":52 - * while data_len >= 4: - * (in_buf)[0] ^= uint32_msk - * in_buf += 4 # <<<<<<<<<<<<<< - * data_len -= 4 - * - */ - __pyx_v_in_buf = (__pyx_v_in_buf + 4); - - /* "aiohttp/_websocket.pyx":53 - * (in_buf)[0] ^= uint32_msk - * in_buf += 4 - * data_len -= 4 # <<<<<<<<<<<<<< - * - * for i in range(0, data_len): - */ - __pyx_v_data_len = (__pyx_v_data_len - 4); - } - - /* "aiohttp/_websocket.pyx":55 - * data_len -= 4 - * - * for i in range(0, data_len): # <<<<<<<<<<<<<< - * in_buf[i] ^= mask_buf[i] - */ - __pyx_t_1 = __pyx_v_data_len; - __pyx_t_9 = __pyx_t_1; - for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { - __pyx_v_i = __pyx_t_10; - - /* "aiohttp/_websocket.pyx":56 - * - * for i in range(0, data_len): - * in_buf[i] ^= mask_buf[i] # <<<<<<<<<<<<<< - */ - __pyx_t_11 = __pyx_v_i; - (__pyx_v_in_buf[__pyx_t_11]) = ((__pyx_v_in_buf[__pyx_t_11]) ^ (__pyx_v_mask_buf[__pyx_v_i])); - } - - /* "aiohttp/_websocket.pyx":11 - * - * - * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates its `data` argument - * """ - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("aiohttp._websocket._websocket_mask_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_mask); - __Pyx_XDECREF(__pyx_v_data); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__websocket(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__websocket}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "_websocket", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_n_s_aiohttp__websocket, __pyx_k_aiohttp__websocket, sizeof(__pyx_k_aiohttp__websocket), 0, 0, 1, 1}, - {&__pyx_kp_s_aiohttp__websocket_pyx, __pyx_k_aiohttp__websocket_pyx, sizeof(__pyx_k_aiohttp__websocket_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1}, - {&__pyx_n_s_data_len, __pyx_k_data_len, sizeof(__pyx_k_data_len), 0, 0, 1, 1}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_in_buf, __pyx_k_in_buf, sizeof(__pyx_k_in_buf), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_mask, __pyx_k_mask, sizeof(__pyx_k_mask), 0, 0, 1, 1}, - {&__pyx_n_s_mask_buf, __pyx_k_mask_buf, sizeof(__pyx_k_mask_buf), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_uint32_msk, __pyx_k_uint32_msk, sizeof(__pyx_k_uint32_msk), 0, 0, 1, 1}, - {&__pyx_n_s_uint64_msk, __pyx_k_uint64_msk, sizeof(__pyx_k_uint64_msk), 0, 0, 1, 1}, - {&__pyx_n_s_websocket_mask_cython, __pyx_k_websocket_mask_cython, sizeof(__pyx_k_websocket_mask_cython), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 55, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "aiohttp/_websocket.pyx":11 - * - * - * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates its `data` argument - * """ - */ - __pyx_tuple_ = PyTuple_Pack(8, __pyx_n_s_mask, __pyx_n_s_data, __pyx_n_s_data_len, __pyx_n_s_i, __pyx_n_s_in_buf, __pyx_n_s_mask_buf, __pyx_n_s_uint32_msk, __pyx_n_s_uint64_msk); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(2, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__websocket_pyx, __pyx_n_s_websocket_mask_cython, 11, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(2, 8, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_7complex_complex) __PYX_ERR(3, 15, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_websocket(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_websocket(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__websocket(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__websocket(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__websocket(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_websocket' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__websocket(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_websocket", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_aiohttp___websocket) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "aiohttp._websocket")) { - if (unlikely(PyDict_SetItemString(modules, "aiohttp._websocket", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - (void)__Pyx_modinit_type_init_code(); - if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "aiohttp/_websocket.pyx":11 - * - * - * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< - * """Note, this function mutates its `data` argument - * """ - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython, NULL, __pyx_n_s_aiohttp__websocket); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_websocket_mask_cython, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "aiohttp/_websocket.pyx":1 - * from cpython cimport PyBytes_AsString # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init aiohttp._websocket", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init aiohttp._websocket"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* TypeImport */ -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ip) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_websocket.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_websocket.cp39-win_amd64.pyd deleted file mode 100644 index d750da71..00000000 Binary files a/dist/ba_data/python-site-packages/aiohttp/_websocket.cp39-win_amd64.pyd and /dev/null differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_websocket.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/aiohttp/_websocket.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..1742cbf2 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_websocket.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/aiohttp/abc.py b/dist/ba_data/python-site-packages/aiohttp/abc.py index 4abfd798..ee838998 100644 --- a/dist/ba_data/python-site-packages/aiohttp/abc.py +++ b/dist/ba_data/python-site-packages/aiohttp/abc.py @@ -22,7 +22,7 @@ from .helpers import get_running_loop from .typedefs import LooseCookies -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_app import Application from .web_exceptions import HTTPException from .web_request import BaseRequest, Request @@ -65,7 +65,9 @@ def handler(self) -> Callable[[Request], Awaitable[StreamResponse]]: @property @abstractmethod - def expect_handler(self) -> Callable[[Request], Awaitable[None]]: + def expect_handler( + self, + ) -> Callable[[Request], Awaitable[Optional[StreamResponse]]]: """Expect handler for 100-continue processing""" @property # pragma: no branch @@ -129,12 +131,15 @@ async def close(self) -> None: """Release resolver""" -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: IterableBase = Iterable[Morsel[str]] else: IterableBase = Iterable +ClearCookiePredicate = Callable[["Morsel[str]"], bool] + + class AbstractCookieJar(Sized, IterableBase): """Abstract Cookie Jar.""" @@ -142,8 +147,12 @@ def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: self._loop = get_running_loop(loop) @abstractmethod - def clear(self) -> None: - """Clear all cookies.""" + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: + """Clear all cookies if no predicate is passed.""" + + @abstractmethod + def clear_domain(self, domain: str) -> None: + """Clear all cookies for domain and all subdomains.""" @abstractmethod def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: @@ -159,7 +168,7 @@ class AbstractStreamWriter(ABC): buffer_size = 0 output_size = 0 - length = 0 # type: Optional[int] + length: Optional[int] = 0 @abstractmethod async def write(self, chunk: bytes) -> None: diff --git a/dist/ba_data/python-site-packages/aiohttp/base_protocol.py b/dist/ba_data/python-site-packages/aiohttp/base_protocol.py index 01e18310..dc1f24f9 100644 --- a/dist/ba_data/python-site-packages/aiohttp/base_protocol.py +++ b/dist/ba_data/python-site-packages/aiohttp/base_protocol.py @@ -1,6 +1,7 @@ import asyncio from typing import Optional, cast +from .helpers import set_exception from .tcp_helpers import tcp_nodelay @@ -15,13 +16,17 @@ class BaseProtocol(asyncio.Protocol): ) def __init__(self, loop: asyncio.AbstractEventLoop) -> None: - self._loop = loop # type: asyncio.AbstractEventLoop + self._loop: asyncio.AbstractEventLoop = loop self._paused = False - self._drain_waiter = None # type: Optional[asyncio.Future[None]] - self._connection_lost = False + self._drain_waiter: Optional[asyncio.Future[None]] = None self._reading_paused = False - self.transport = None # type: Optional[asyncio.Transport] + self.transport: Optional[asyncio.Transport] = None + + @property + def connected(self) -> bool: + """Return True if the connection is open.""" + return self.transport is not None def pause_writing(self) -> None: assert not self._paused @@ -59,7 +64,6 @@ def connection_made(self, transport: asyncio.BaseTransport) -> None: self.transport = tr def connection_lost(self, exc: Optional[BaseException]) -> None: - self._connection_lost = True # Wake up the writer if currently paused. self.transport = None if not self._paused: @@ -73,15 +77,19 @@ def connection_lost(self, exc: Optional[BaseException]) -> None: if exc is None: waiter.set_result(None) else: - waiter.set_exception(exc) + set_exception( + waiter, + ConnectionError("Connection lost"), + exc, + ) async def _drain_helper(self) -> None: - if self._connection_lost: + if not self.connected: raise ConnectionResetError("Connection lost") if not self._paused: return waiter = self._drain_waiter - assert waiter is None or waiter.cancelled() - waiter = self._loop.create_future() - self._drain_waiter = waiter - await waiter + if waiter is None: + waiter = self._loop.create_future() + self._drain_waiter = waiter + await asyncio.shield(waiter) diff --git a/dist/ba_data/python-site-packages/aiohttp/client.py b/dist/ba_data/python-site-packages/aiohttp/client.py index a9da8e15..32d2c3b7 100644 --- a/dist/ba_data/python-site-packages/aiohttp/client.py +++ b/dist/ba_data/python-site-packages/aiohttp/client.py @@ -8,12 +8,15 @@ import sys import traceback import warnings +from contextlib import suppress from types import SimpleNamespace, TracebackType from typing import ( + TYPE_CHECKING, Any, Awaitable, Callable, Coroutine, + Final, FrozenSet, Generator, Generic, @@ -71,13 +74,14 @@ ) from .cookiejar import CookieJar from .helpers import ( + _SENTINEL, DEBUG, - PY_36, BasicAuth, - CeilTimeout, TimeoutHandle, + ceil_timeout, + get_env_proxy_for_url, get_running_loop, - proxies_from_env, + method_must_be_empty_body, sentinel, strip_auth_from_url, ) @@ -127,10 +131,10 @@ ) -try: +if TYPE_CHECKING: from ssl import SSLContext -except ImportError: # pragma: no cover - SSLContext = object # type: ignore +else: + SSLContext = None @attr.s(auto_attribs=True, frozen=True, slots=True) @@ -139,6 +143,7 @@ class ClientTimeout: connect: Optional[float] = None sock_read: Optional[float] = None sock_connect: Optional[float] = None + ceil_threshold: float = 5 # pool_queue_timeout: Optional[float] = None # dns_resolution_timeout: Optional[float] = None @@ -155,9 +160,10 @@ class ClientTimeout: # 5 Minute default read timeout -DEFAULT_TIMEOUT = ClientTimeout(total=5 * 60) +DEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60) _RetType = TypeVar("_RetType") +_CharsetResolver = Callable[[ClientResponse, bytes], str] class ClientSession: @@ -165,6 +171,7 @@ class ClientSession: ATTRS = frozenset( [ + "_base_url", "_source_traceback", "_connector", "requote_redirect_url", @@ -186,13 +193,18 @@ class ClientSession: "_ws_response_class", "_trace_configs", "_read_bufsize", + "_max_line_size", + "_max_field_size", + "_resolve_charset", ] ) - _source_traceback = None + _source_traceback: Optional[traceback.StackSummary] = None + _connector: Optional[BaseConnector] = None def __init__( self, + base_url: Optional[StrOrURL] = None, *, connector: Optional[BaseConnector] = None, loop: Optional[asyncio.AbstractEventLoop] = None, @@ -207,47 +219,25 @@ def __init__( version: HttpVersion = http.HttpVersion11, cookie_jar: Optional[AbstractCookieJar] = None, connector_owner: bool = True, - raise_for_status: bool = False, - read_timeout: Union[float, object] = sentinel, + raise_for_status: Union[ + bool, Callable[[ClientResponse], Awaitable[None]] + ] = False, + read_timeout: Union[float, _SENTINEL] = sentinel, conn_timeout: Optional[float] = None, timeout: Union[object, ClientTimeout] = sentinel, auto_decompress: bool = True, trust_env: bool = False, requote_redirect_url: bool = True, trace_configs: Optional[List[TraceConfig]] = None, - read_bufsize: int = 2 ** 16, + read_bufsize: int = 2**16, + max_line_size: int = 8190, + max_field_size: int = 8190, + fallback_charset_resolver: _CharsetResolver = lambda r, b: "utf-8", ) -> None: - - if loop is None: - if connector is not None: - loop = connector._loop - - loop = get_running_loop(loop) - - if connector is None: - connector = TCPConnector(loop=loop) - - if connector._loop is not loop: - raise RuntimeError("Session and connector has to use same event loop") - - self._loop = loop - - if loop.get_debug(): - self._source_traceback = traceback.extract_stack(sys._getframe(1)) - - if cookie_jar is None: - cookie_jar = CookieJar(loop=loop) - self._cookie_jar = cookie_jar - - if cookies is not None: - self._cookie_jar.update_cookies(cookies) - - self._connector = connector # type: Optional[BaseConnector] - self._connector_owner = connector_owner - self._default_auth = auth - self._version = version - self._json_serialize = json_serialize - if timeout is sentinel: + # We initialise _connector to None immediately, as it's referenced in __del__() + # and could cause issues if an exception occurs during initialisation. + self._connector: Optional[BaseConnector] = None + if timeout is sentinel or timeout is None: self._timeout = DEFAULT_TIMEOUT if read_timeout is not sentinel: warnings.warn( @@ -264,7 +254,12 @@ def __init__( stacklevel=2, ) else: - self._timeout = timeout # type: ignore + if not isinstance(timeout, ClientTimeout): + raise ValueError( + f"timeout parameter cannot be of {type(timeout)} type, " + "please use 'timeout=ClientTimeout(...)'", + ) + self._timeout = timeout if read_timeout is not sentinel: raise ValueError( "read_timeout and timeout parameters " @@ -277,20 +272,59 @@ def __init__( "conflict, please setup " "timeout.connect" ) + if loop is None: + if connector is not None: + loop = connector._loop + + loop = get_running_loop(loop) + + if base_url is None or isinstance(base_url, URL): + self._base_url: Optional[URL] = base_url + else: + self._base_url = URL(base_url) + assert ( + self._base_url.origin() == self._base_url + ), "Only absolute URLs without path part are supported" + + if connector is None: + connector = TCPConnector(loop=loop) + + if connector._loop is not loop: + raise RuntimeError("Session and connector has to use same event loop") + + self._loop = loop + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + if cookie_jar is None: + cookie_jar = CookieJar(loop=loop) + self._cookie_jar = cookie_jar + + if cookies is not None: + self._cookie_jar.update_cookies(cookies) + + self._connector = connector + self._connector_owner = connector_owner + self._default_auth = auth + self._version = version + self._json_serialize = json_serialize self._raise_for_status = raise_for_status self._auto_decompress = auto_decompress self._trust_env = trust_env self._requote_redirect_url = requote_redirect_url self._read_bufsize = read_bufsize + self._max_line_size = max_line_size + self._max_field_size = max_field_size # Convert to list of tuples if headers: - real_headers = CIMultiDict(headers) # type: CIMultiDict[str] + real_headers: CIMultiDict[str] = CIMultiDict(headers) else: real_headers = CIMultiDict() - self._default_headers = real_headers # type: CIMultiDict[str] + self._default_headers: CIMultiDict[str] = real_headers if skip_auto_headers is not None: - self._skip_auto_headers = frozenset([istr(i) for i in skip_auto_headers]) + self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers) else: self._skip_auto_headers = frozenset() @@ -302,6 +336,8 @@ def __init__( for trace_config in self._trace_configs: trace_config.freeze() + self._resolve_charset = fallback_charset_resolver + def __init_subclass__(cls: Type["ClientSession"]) -> None: warnings.warn( "Inheritance class {} from ClientSession " @@ -324,10 +360,7 @@ def __setattr__(self, name: str, val: Any) -> None: def __del__(self, _warnings: Any = warnings) -> None: if not self.closed: - if PY_36: - kwargs = {"source": self} - else: - kwargs = {} + kwargs = {"source": self} _warnings.warn( f"Unclosed client session {self!r}", ResourceWarning, **kwargs ) @@ -342,6 +375,14 @@ def request( """Perform HTTP request.""" return _RequestContextManager(self._request(method, url, **kwargs)) + def _build_url(self, str_or_url: StrOrURL) -> URL: + url = URL(str_or_url) + if self._base_url is None: + return url + else: + assert not url.is_absolute() and url.path.startswith("/") + return self._base_url.join(url) + async def _request( self, method: str, @@ -359,18 +400,24 @@ async def _request( compress: Optional[str] = None, chunked: Optional[bool] = None, expect100: bool = False, - raise_for_status: Optional[bool] = None, + raise_for_status: Union[ + None, bool, Callable[[ClientResponse], Awaitable[None]] + ] = None, read_until_eof: bool = True, proxy: Optional[StrOrURL] = None, proxy_auth: Optional[BasicAuth] = None, - timeout: Union[ClientTimeout, object] = sentinel, + timeout: Union[ClientTimeout, _SENTINEL] = sentinel, verify_ssl: Optional[bool] = None, fingerprint: Optional[bytes] = None, ssl_context: Optional[SSLContext] = None, - ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None, + ssl: Union[SSLContext, bool, Fingerprint] = True, + server_hostname: Optional[str] = None, proxy_headers: Optional[LooseHeaders] = None, trace_request_ctx: Optional[SimpleNamespace] = None, read_bufsize: Optional[int] = None, + auto_decompress: Optional[bool] = None, + max_line_size: Optional[int] = None, + max_field_size: Optional[int] = None, ) -> ClientResponse: # NOTE: timeout clamps existing connect and read timeouts. We cannot @@ -395,13 +442,14 @@ async def _request( redirects = 0 history = [] version = self._version + params = params or {} # Merge with default headers and transform to CIMultiDict headers = self._prepare_headers(headers) proxy_headers = self._prepare_headers(proxy_headers) try: - url = URL(str_or_url) + url = self._build_url(str_or_url) except ValueError as e: raise InvalidURL(str_or_url) from e @@ -417,20 +465,31 @@ async def _request( raise InvalidURL(proxy) from e if timeout is sentinel: - real_timeout = self._timeout # type: ClientTimeout + real_timeout: ClientTimeout = self._timeout else: if not isinstance(timeout, ClientTimeout): - real_timeout = ClientTimeout(total=timeout) # type: ignore + real_timeout = ClientTimeout(total=timeout) else: real_timeout = timeout # timeout is cumulative for all request operations # (request, redirects, responses, data consuming) - tm = TimeoutHandle(self._loop, real_timeout.total) + tm = TimeoutHandle( + self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold + ) handle = tm.start() if read_bufsize is None: read_bufsize = self._read_bufsize + if auto_decompress is None: + auto_decompress = self._auto_decompress + + if max_line_size is None: + max_line_size = self._max_line_size + + if max_field_size is None: + max_field_size = self._max_field_size + traces = [ Trace( self, @@ -441,7 +500,7 @@ async def _request( ] for trace in traces: - await trace.send_request_start(method, url, headers) + await trace.send_request_start(method, url.update_query(params), headers) timer = tm.timer() try: @@ -483,11 +542,8 @@ async def _request( if proxy is not None: proxy = URL(proxy) elif self._trust_env: - for scheme, proxy_info in proxies_from_env().items(): - if scheme == url.scheme: - proxy = proxy_info.proxy - proxy_auth = proxy_info.proxy_auth - break + with suppress(LookupError): + proxy, proxy_auth = get_env_proxy_for_url(url) req = self._request_class( method, @@ -508,14 +564,19 @@ async def _request( proxy_auth=proxy_auth, timer=timer, session=self, - ssl=ssl, + ssl=ssl if ssl is not None else True, + server_hostname=server_hostname, proxy_headers=proxy_headers, traces=traces, + trust_env=self.trust_env, ) # connection timeout try: - with CeilTimeout(real_timeout.connect, loop=self._loop): + async with ceil_timeout( + real_timeout.connect, + ceil_threshold=real_timeout.ceil_threshold, + ): assert self._connector is not None conn = await self._connector.connect( req, traces=traces, timeout=real_timeout @@ -530,11 +591,14 @@ async def _request( assert conn.protocol is not None conn.protocol.set_response_params( timer=timer, - skip_payload=method.upper() == "HEAD", + skip_payload=method_must_be_empty_body(method), read_until_eof=read_until_eof, - auto_decompress=self._auto_decompress, + auto_decompress=auto_decompress, read_timeout=real_timeout.sock_read, read_bufsize=read_bufsize, + timeout_ceil_threshold=self._connector._timeout_ceil_threshold, + max_line_size=max_line_size, + max_field_size=max_field_size, ) try: @@ -551,6 +615,8 @@ async def _request( except ClientError: raise except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise ClientOSError(*exc.args) from exc self._cookie_jar.update_cookies(resp.cookies, resp.url) @@ -560,7 +626,7 @@ async def _request( for trace in traces: await trace.send_request_redirect( - method, url, headers, resp + method, url.update_query(params), headers, resp ) redirects += 1 @@ -612,7 +678,7 @@ async def _request( headers.pop(hdrs.AUTHORIZATION, None) url = parsed_url - params = None + params = {} resp.release() continue @@ -621,7 +687,12 @@ async def _request( # check response status if raise_for_status is None: raise_for_status = self._raise_for_status - if raise_for_status: + + if raise_for_status is None: + pass + elif callable(raise_for_status): + await raise_for_status(resp) + elif raise_for_status: resp.raise_for_status() # register connection @@ -634,7 +705,9 @@ async def _request( resp._history = tuple(history) for trace in traces: - await trace.send_request_end(method, url, headers, resp) + await trace.send_request_end( + method, url.update_query(params), headers, resp + ) return resp except BaseException as e: @@ -645,7 +718,9 @@ async def _request( handle = None for trace in traces: - await trace.send_request_exception(method, url, headers, e) + await trace.send_request_exception( + method, url.update_query(params), headers, e + ) raise def ws_connect( @@ -661,10 +736,11 @@ def ws_connect( heartbeat: Optional[float] = None, auth: Optional[BasicAuth] = None, origin: Optional[str] = None, + params: Optional[Mapping[str, str]] = None, headers: Optional[LooseHeaders] = None, proxy: Optional[StrOrURL] = None, proxy_auth: Optional[BasicAuth] = None, - ssl: Union[SSLContext, bool, None, Fingerprint] = None, + ssl: Union[SSLContext, bool, None, Fingerprint] = True, verify_ssl: Optional[bool] = None, fingerprint: Optional[bytes] = None, ssl_context: Optional[SSLContext] = None, @@ -685,6 +761,7 @@ def ws_connect( heartbeat=heartbeat, auth=auth, origin=origin, + params=params, headers=headers, proxy=proxy, proxy_auth=proxy_auth, @@ -711,10 +788,11 @@ async def _ws_connect( heartbeat: Optional[float] = None, auth: Optional[BasicAuth] = None, origin: Optional[str] = None, + params: Optional[Mapping[str, str]] = None, headers: Optional[LooseHeaders] = None, proxy: Optional[StrOrURL] = None, proxy_auth: Optional[BasicAuth] = None, - ssl: Union[SSLContext, bool, None, Fingerprint] = None, + ssl: Optional[Union[SSLContext, bool, Fingerprint]] = True, verify_ssl: Optional[bool] = None, fingerprint: Optional[bytes] = None, ssl_context: Optional[SSLContext] = None, @@ -724,13 +802,13 @@ async def _ws_connect( ) -> ClientWebSocketResponse: if headers is None: - real_headers = CIMultiDict() # type: CIMultiDict[str] + real_headers: CIMultiDict[str] = CIMultiDict() else: real_headers = CIMultiDict(headers) default_headers = { hdrs.UPGRADE: "websocket", - hdrs.CONNECTION: "upgrade", + hdrs.CONNECTION: "Upgrade", hdrs.SEC_WEBSOCKET_VERSION: "13", } @@ -748,12 +826,16 @@ async def _ws_connect( extstr = ws_ext_gen(compress=compress) real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr + # For the sake of backward compatibility, if user passes in None, convert it to True + if ssl is None: + ssl = True ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) # send request resp = await self.request( method, url, + params=params, headers=real_headers, read_until_eof=False, auth=auth, @@ -842,9 +924,9 @@ async def _ws_connect( assert conn_proto is not None transport = conn.transport assert transport is not None - reader = FlowControlDataQueue( - conn_proto, 2 ** 16, loop=self._loop - ) # type: FlowControlDataQueue[WSMessage] + reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue( + conn_proto, 2**16, loop=self._loop + ) conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader) writer = WebSocketWriter( conn_proto, @@ -879,7 +961,7 @@ def _prepare_headers(self, headers: Optional[LooseHeaders]) -> "CIMultiDict[str] if headers: if not isinstance(headers, (MultiDictProxy, MultiDict)): headers = CIMultiDict(headers) - added_names = set() # type: Set[str] + added_names: Set[str] = set() for key, value in headers.items(): if key in added_names: result.add(key, value) @@ -1001,7 +1083,7 @@ def loop(self) -> asyncio.AbstractEventLoop: return self._loop @property - def timeout(self) -> Union[object, ClientTimeout]: + def timeout(self) -> ClientTimeout: """Timeout for the session.""" return self._timeout @@ -1034,23 +1116,21 @@ def connector_owner(self) -> bool: def raise_for_status( self, ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]: - """ - Should `ClientResponse.raise_for_status()` - be called for each response - """ + """Should `ClientResponse.raise_for_status()` be called for each response.""" return self._raise_for_status @property def auto_decompress(self) -> bool: - """Should the body response be automatically decompressed""" + """Should the body response be automatically decompressed.""" return self._auto_decompress @property def trust_env(self) -> bool: """ - Should get proxies information - from HTTP_PROXY / HTTPS_PROXY environment variables - or ~/.netrc file if present + Should proxies information from environment or netrc be trusted. + + Information is from HTTP_PROXY / HTTPS_PROXY environment variables + or ~/.netrc file if present. """ return self._trust_env @@ -1100,8 +1180,8 @@ def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> No def send(self, arg: None) -> "asyncio.Future[Any]": return self._coro.send(arg) - def throw(self, arg: BaseException) -> None: # type: ignore - self._coro.throw(arg) + def throw(self, *args: Any, **kwargs: Any) -> "asyncio.Future[Any]": + return self._coro.throw(*args, **kwargs) def close(self) -> None: return self._coro.close() @@ -1119,6 +1199,8 @@ async def __aenter__(self) -> _RetType: class _RequestContextManager(_BaseRequestContextManager[ClientResponse]): + __slots__ = () + async def __aexit__( self, exc_type: Optional[Type[BaseException]], @@ -1131,9 +1213,12 @@ async def __aexit__( # explicitly. Otherwise connection error handling should kick in # and close/recycle the connection as required. self._resp.release() + await self._resp.wait_for_close() class _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]): + __slots__ = () + async def __aexit__( self, exc_type: Optional[Type[BaseException]], @@ -1153,7 +1238,7 @@ def __init__( session: ClientSession, ) -> None: self._coro = coro - self._resp = None # type: Optional[ClientResponse] + self._resp: Optional[ClientResponse] = None self._session = session async def __aenter__(self) -> ClientResponse: @@ -1201,8 +1286,12 @@ def request( connector: Optional[BaseConnector] = None, read_bufsize: Optional[int] = None, loop: Optional[asyncio.AbstractEventLoop] = None, + max_line_size: int = 8190, + max_field_size: int = 8190, ) -> _SessionRequestContextManager: - """Constructs and sends a request. Returns response object. + """Constructs and sends a request. + + Returns response object. method - HTTP method url - request url params - (optional) Dictionary or bytes to be sent in the query @@ -1270,6 +1359,8 @@ def request( proxy=proxy, proxy_auth=proxy_auth, read_bufsize=read_bufsize, + max_line_size=max_line_size, + max_field_size=max_field_size, ), session, ) diff --git a/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py b/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py index f4be3bfb..9b6e4420 100644 --- a/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py +++ b/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py @@ -4,6 +4,7 @@ import warnings from typing import TYPE_CHECKING, Any, Optional, Tuple, Union +from .http_parser import RawResponseMessage from .typedefs import LooseHeaders try: @@ -11,10 +12,10 @@ SSLContext = ssl.SSLContext except ImportError: # pragma: no cover - ssl = SSLContext = None # type: ignore + ssl = SSLContext = None # type: ignore[assignment] -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .client_reqrep import ClientResponse, ConnectionKey, Fingerprint, RequestInfo else: RequestInfo = ClientResponse = ConnectionKey = None @@ -46,9 +47,13 @@ class ClientError(Exception): class ClientResponseError(ClientError): - """Connection error during reading response. + """Base class for exceptions that occur after getting a response. - request_info: instance of RequestInfo + request_info: An instance of RequestInfo. + history: A sequence of responses, if redirects occurred. + status: HTTP status code. + message: Error message. + headers: Response headers. """ def __init__( @@ -99,7 +104,7 @@ def __repr__(self) -> str: args += f", message={self.message!r}" if self.headers is not None: args += f", headers={self.headers!r}" - return "{}({})".format(type(self).__name__, args) + return f"{type(self).__name__}({args})" @property def code(self) -> int: @@ -153,7 +158,7 @@ class ClientConnectorError(ClientOSError): """Client connector error. Raised in :class:`aiohttp.connector.TCPConnector` if - connection to proxy can not be established. + a connection can not be established. """ def __init__(self, connection_key: ConnectionKey, os_error: OSError) -> None: @@ -175,12 +180,12 @@ def port(self) -> Optional[int]: return self._conn_key.port @property - def ssl(self) -> Union[SSLContext, None, bool, "Fingerprint"]: + def ssl(self) -> Union[SSLContext, bool, "Fingerprint"]: return self._conn_key.ssl def __str__(self) -> str: return "Cannot connect to host {0.host}:{0.port} ssl:{1} [{2}]".format( - self, self.ssl if self.ssl is not None else "default", self.strerror + self, "default" if self.ssl is True else self.ssl, self.strerror ) # OSError.__reduce__ does too much black magick @@ -195,6 +200,29 @@ class ClientProxyConnectionError(ClientConnectorError): """ +class UnixClientConnectorError(ClientConnectorError): + """Unix connector error. + + Raised in :py:class:`aiohttp.connector.UnixConnector` + if connection to unix socket can not be established. + """ + + def __init__( + self, path: str, connection_key: ConnectionKey, os_error: OSError + ) -> None: + self._path = path + super().__init__(connection_key, os_error) + + @property + def path(self) -> str: + return self._path + + def __str__(self) -> str: + return "Cannot connect to unix socket {0.path} ssl:{1} [{2}]".format( + self, "default" if self.ssl is True else self.ssl, self.strerror + ) + + class ServerConnectionError(ClientConnectionError): """Server connection errors.""" @@ -202,7 +230,7 @@ class ServerConnectionError(ClientConnectionError): class ServerDisconnectedError(ServerConnectionError): """Server disconnected.""" - def __init__(self, message: Optional[str] = None) -> None: + def __init__(self, message: Union[RawResponseMessage, str, None] = None) -> None: if message is None: message = "Server disconnected" @@ -238,7 +266,8 @@ class InvalidURL(ClientError, ValueError): """Invalid URL. URL used for fetching is malformed, e.g. it doesn't contains host - part.""" + part. + """ # Derive from ValueError for backward compatibility @@ -279,11 +308,11 @@ class ClientSSLError(ClientConnectorError): ssl_error_bases = (ClientSSLError,) -class ClientConnectorSSLError(*ssl_error_bases): # type: ignore +class ClientConnectorSSLError(*ssl_error_bases): # type: ignore[misc] """Response ssl error.""" -class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore +class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore[misc] """Response certificate error.""" def __init__( diff --git a/dist/ba_data/python-site-packages/aiohttp/client_proto.py b/dist/ba_data/python-site-packages/aiohttp/client_proto.py index 2973342e..723f5aae 100644 --- a/dist/ba_data/python-site-packages/aiohttp/client_proto.py +++ b/dist/ba_data/python-site-packages/aiohttp/client_proto.py @@ -9,8 +9,14 @@ ServerDisconnectedError, ServerTimeoutError, ) -from .helpers import BaseTimerContext +from .helpers import ( + _EXC_SENTINEL, + BaseTimerContext, + set_exception, + status_code_must_be_empty_body, +) from .http import HttpResponseParser, RawResponseMessage +from .http_exceptions import HttpProcessingError from .streams import EMPTY_PAYLOAD, DataQueue, StreamReader @@ -23,7 +29,7 @@ def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._should_close = False - self._payload = None + self._payload: Optional[StreamReader] = None self._skip_payload = False self._payload_parser = None @@ -31,10 +37,12 @@ def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._tail = b"" self._upgraded = False - self._parser = None # type: Optional[HttpResponseParser] + self._parser: Optional[HttpResponseParser] = None - self._read_timeout = None # type: Optional[float] - self._read_timeout_handle = None # type: Optional[asyncio.TimerHandle] + self._read_timeout: Optional[float] = None + self._read_timeout_handle: Optional[asyncio.TimerHandle] = None + + self._timeout_ceil_threshold: Optional[float] = 5 @property def upgraded(self) -> bool: @@ -71,28 +79,50 @@ def is_connected(self) -> bool: def connection_lost(self, exc: Optional[BaseException]) -> None: self._drop_timeout() + original_connection_error = exc + reraised_exc = original_connection_error + + connection_closed_cleanly = original_connection_error is None + if self._payload_parser is not None: - with suppress(Exception): + with suppress(Exception): # FIXME: log this somehow? self._payload_parser.feed_eof() uncompleted = None if self._parser is not None: try: uncompleted = self._parser.feed_eof() - except Exception: + except Exception as underlying_exc: if self._payload is not None: - self._payload.set_exception( - ClientPayloadError("Response payload is not completed") + client_payload_exc_msg = ( + f"Response payload is not completed: {underlying_exc !r}" + ) + if not connection_closed_cleanly: + client_payload_exc_msg = ( + f"{client_payload_exc_msg !s}. " + f"{original_connection_error !r}" + ) + set_exception( + self._payload, + ClientPayloadError(client_payload_exc_msg), + underlying_exc, ) if not self.is_eof(): - if isinstance(exc, OSError): - exc = ClientOSError(*exc.args) - if exc is None: - exc = ServerDisconnectedError(uncompleted) + if isinstance(original_connection_error, OSError): + reraised_exc = ClientOSError(*original_connection_error.args) + if connection_closed_cleanly: + reraised_exc = ServerDisconnectedError(uncompleted) # assigns self._should_close to True as side effect, # we do it anyway below - self.set_exception(exc) + underlying_non_eof_exc = ( + _EXC_SENTINEL + if connection_closed_cleanly + else original_connection_error + ) + assert underlying_non_eof_exc is not None + assert reraised_exc is not None + self.set_exception(reraised_exc, underlying_non_eof_exc) self._should_close = True self._parser = None @@ -100,7 +130,7 @@ def connection_lost(self, exc: Optional[BaseException]) -> None: self._payload_parser = None self._reading_paused = False - super().connection_lost(exc) + super().connection_lost(reraised_exc) def eof_received(self) -> None: # should call parser.feed_eof() most likely @@ -114,10 +144,14 @@ def resume_reading(self) -> None: super().resume_reading() self._reschedule_timeout() - def set_exception(self, exc: BaseException) -> None: + def set_exception( + self, + exc: BaseException, + exc_cause: BaseException = _EXC_SENTINEL, + ) -> None: self._should_close = True self._drop_timeout() - super().set_exception(exc) + super().set_exception(exc, exc_cause) def set_parser(self, parser: Any, payload: Any) -> None: # TODO: actual types are: @@ -142,12 +176,16 @@ def set_response_params( read_until_eof: bool = False, auto_decompress: bool = True, read_timeout: Optional[float] = None, - read_bufsize: int = 2 ** 16 + read_bufsize: int = 2**16, + timeout_ceil_threshold: float = 5, + max_line_size: int = 8190, + max_field_size: int = 8190, ) -> None: self._skip_payload = skip_payload self._read_timeout = read_timeout - self._reschedule_timeout() + + self._timeout_ceil_threshold = timeout_ceil_threshold self._parser = HttpResponseParser( self, @@ -158,6 +196,8 @@ def set_response_params( response_with_body=not skip_payload, read_until_eof=read_until_eof, auto_decompress=auto_decompress, + max_line_size=max_line_size, + max_field_size=max_field_size, ) if self._tail: @@ -181,11 +221,14 @@ def _reschedule_timeout(self) -> None: else: self._read_timeout_handle = None + def start_timeout(self) -> None: + self._reschedule_timeout() + def _on_read_timeout(self) -> None: exc = ServerTimeoutError("Timeout on reading data from socket") self.set_exception(exc) if self._payload is not None: - self._payload.set_exception(exc) + set_exception(self._payload, exc) def data_received(self, data: bytes) -> None: self._reschedule_timeout() @@ -211,27 +254,29 @@ def data_received(self, data: bytes) -> None: # parse http messages try: messages, upgraded, tail = self._parser.feed_data(data) - except BaseException as exc: + except BaseException as underlying_exc: if self.transport is not None: # connection.release() could be called BEFORE # data_received(), the transport is already # closed in this case self.transport.close() # should_close is True after the call - self.set_exception(exc) + self.set_exception(HttpProcessingError(), underlying_exc) return self._upgraded = upgraded - payload = None + payload: Optional[StreamReader] = None for message, payload in messages: if message.should_close: self._should_close = True self._payload = payload - if self._skip_payload or message.code in (204, 304): - self.feed_data((message, EMPTY_PAYLOAD), 0) # type: ignore + if self._skip_payload or status_code_must_be_empty_body( + message.code + ): + self.feed_data((message, EMPTY_PAYLOAD), 0) else: self.feed_data((message, payload), 0) if payload is not None: diff --git a/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py b/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py index d826bfeb..afe719da 100644 --- a/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py +++ b/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py @@ -1,5 +1,6 @@ import asyncio import codecs +import contextlib import functools import io import re @@ -12,6 +13,7 @@ from typing import ( TYPE_CHECKING, Any, + Callable, Dict, Iterable, List, @@ -37,18 +39,27 @@ InvalidURL, ServerFingerprintMismatch, ) +from .compression_utils import HAS_BROTLI from .formdata import FormData from .helpers import ( - PY_36, BaseTimerContext, BasicAuth, HeadersMixin, TimerNoop, + basicauth_from_netrc, + netrc_from_env, noop, reify, + set_exception, set_result, ) -from .http import SERVER_SOFTWARE, HttpVersion10, HttpVersion11, StreamWriter +from .http import ( + SERVER_SOFTWARE, + HttpVersion, + HttpVersion10, + HttpVersion11, + StreamWriter, +) from .log import client_logger from .streams import StreamReader from .typedefs import ( @@ -63,27 +74,27 @@ import ssl from ssl import SSLContext except ImportError: # pragma: no cover - ssl = None # type: ignore - SSLContext = object # type: ignore - -try: - import cchardet as chardet -except ImportError: # pragma: no cover - import chardet # type: ignore + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] __all__ = ("ClientRequest", "ClientResponse", "RequestInfo", "Fingerprint") -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .client import ClientSession from .connector import Connection from .tracing import Trace +_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") json_re = re.compile(r"^application/(?:[\w.+-]+?\+)?json") +def _gen_default_accept_encoding() -> str: + return "gzip, deflate, br" if HAS_BROTLI else "gzip, deflate" + + @attr.s(auto_attribs=True, frozen=True, slots=True) class ContentDisposition: type: Optional[str] @@ -140,22 +151,24 @@ def check(self, transport: asyncio.Transport) -> None: if ssl is not None: SSL_ALLOWED_TYPES = (ssl.SSLContext, bool, Fingerprint, type(None)) else: # pragma: no cover - SSL_ALLOWED_TYPES = type(None) + SSL_ALLOWED_TYPES = (bool, type(None)) def _merge_ssl_params( - ssl: Union["SSLContext", bool, Fingerprint, None], + ssl: Union["SSLContext", bool, Fingerprint], verify_ssl: Optional[bool], ssl_context: Optional["SSLContext"], fingerprint: Optional[bytes], -) -> Union["SSLContext", bool, Fingerprint, None]: +) -> Union["SSLContext", bool, Fingerprint]: + if ssl is None: + ssl = True # Double check for backwards compatibility if verify_ssl is not None and not verify_ssl: warnings.warn( "verify_ssl is deprecated, use ssl=False instead", DeprecationWarning, stacklevel=3, ) - if ssl is not None: + if ssl is not True: raise ValueError( "verify_ssl, ssl_context, fingerprint and ssl " "parameters are mutually exclusive" @@ -168,7 +181,7 @@ def _merge_ssl_params( DeprecationWarning, stacklevel=3, ) - if ssl is not None: + if ssl is not True: raise ValueError( "verify_ssl, ssl_context, fingerprint and ssl " "parameters are mutually exclusive" @@ -181,7 +194,7 @@ def _merge_ssl_params( DeprecationWarning, stacklevel=3, ) - if ssl is not None: + if ssl is not True: raise ValueError( "verify_ssl, ssl_context, fingerprint and ssl " "parameters are mutually exclusive" @@ -203,7 +216,7 @@ class ConnectionKey: host: str port: Optional[int] is_ssl: bool - ssl: Union[SSLContext, None, bool, Fingerprint] + ssl: Union[SSLContext, bool, Fingerprint] proxy: Optional[URL] proxy_auth: Optional[BasicAuth] proxy_headers_hash: Optional[int] # hash(CIMultiDict) @@ -229,14 +242,14 @@ class ClientRequest: DEFAULT_HEADERS = { hdrs.ACCEPT: "*/*", - hdrs.ACCEPT_ENCODING: "gzip, deflate", + hdrs.ACCEPT_ENCODING: _gen_default_accept_encoding(), } body = b"" auth = None response = None - _writer = None # async task for streaming data + __writer = None # async task for streaming data _continue = None # waiter future for '100 Continue' response # N.B. @@ -265,14 +278,22 @@ def __init__( proxy_auth: Optional[BasicAuth] = None, timer: Optional[BaseTimerContext] = None, session: Optional["ClientSession"] = None, - ssl: Union[SSLContext, bool, Fingerprint, None] = None, + ssl: Union[SSLContext, bool, Fingerprint] = True, proxy_headers: Optional[LooseHeaders] = None, traces: Optional[List["Trace"]] = None, + trust_env: bool = False, + server_hostname: Optional[str] = None, ): - if loop is None: loop = asyncio.get_event_loop() + match = _CONTAINS_CONTROL_CHAR_RE.search(method) + if match: + raise ValueError( + f"Method cannot contain non-token characters {method!r} " + "(found at least {match.group()!r})" + ) + assert isinstance(url, URL), url assert isinstance(proxy, (URL, type(None))), proxy # FIXME: session is None in tests only, need to fix tests @@ -294,9 +315,10 @@ def __init__( real_response_class = ClientResponse else: real_response_class = response_class - self.response_class = real_response_class # type: Type[ClientResponse] + self.response_class: Type[ClientResponse] = real_response_class self._timer = timer if timer is not None else TimerNoop() - self._ssl = ssl + self._ssl = ssl if ssl is not None else True + self.server_hostname = server_hostname if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) @@ -307,31 +329,44 @@ def __init__( self.update_auto_headers(skip_auto_headers) self.update_cookies(cookies) self.update_content_encoding(data) - self.update_auth(auth) + self.update_auth(auth, trust_env) self.update_proxy(proxy, proxy_auth, proxy_headers) self.update_body_from_data(data) - if data or self.method not in self.GET_METHODS: + if data is not None or self.method not in self.GET_METHODS: self.update_transfer_encoding() self.update_expect_continue(expect100) if traces is None: traces = [] self._traces = traces + def __reset_writer(self, _: object = None) -> None: + self.__writer = None + + @property + def _writer(self) -> Optional["asyncio.Task[None]"]: + return self.__writer + + @_writer.setter + def _writer(self, writer: Optional["asyncio.Task[None]"]) -> None: + if self.__writer is not None: + self.__writer.remove_done_callback(self.__reset_writer) + self.__writer = writer + if writer is not None: + writer.add_done_callback(self.__reset_writer) + def is_ssl(self) -> bool: return self.url.scheme in ("https", "wss") @property - def ssl(self) -> Union["SSLContext", None, bool, Fingerprint]: + def ssl(self) -> Union["SSLContext", bool, Fingerprint]: return self._ssl @property def connection_key(self) -> ConnectionKey: proxy_headers = self.proxy_headers if proxy_headers: - h = hash( - tuple((k, v) for k, v in proxy_headers.items()) - ) # type: Optional[int] + h: Optional[int] = hash(tuple((k, v) for k, v in proxy_headers.items())) else: h = None return ConnectionKey( @@ -356,7 +391,7 @@ def port(self) -> Optional[int]: @property def request_info(self) -> RequestInfo: - headers = CIMultiDictProxy(self.headers) # type: CIMultiDictProxy[str] + headers: CIMultiDictProxy[str] = CIMultiDictProxy(self.headers) return RequestInfo(self.url, self.method, headers, self.original_url) def update_host(self, url: URL) -> None: @@ -387,21 +422,23 @@ def update_version(self, version: Union[http.HttpVersion, str]) -> None: def update_headers(self, headers: Optional[LooseHeaders]) -> None: """Update request headers.""" - self.headers = CIMultiDict() # type: CIMultiDict[str] + self.headers: CIMultiDict[str] = CIMultiDict() # add host netloc = cast(str, self.url.raw_host) if helpers.is_ipv6_address(netloc): netloc = f"[{netloc}]" + # See https://github.com/aio-libs/aiohttp/issues/3636. + netloc = netloc.rstrip(".") if self.url.port is not None and not self.url.is_default_port(): netloc += ":" + str(self.url.port) self.headers[hdrs.HOST] = netloc if headers: if isinstance(headers, (dict, MultiDictProxy, MultiDict)): - headers = headers.items() # type: ignore + headers = headers.items() # type: ignore[assignment] - for key, value in headers: # type: ignore + for key, value in headers: # type: ignore[misc] # A special case for Host header if key.lower() == "host": self.headers[key] = value @@ -413,7 +450,7 @@ def update_auto_headers(self, skip_auto_headers: Iterable[str]) -> None: (hdr, None) for hdr in sorted(skip_auto_headers) ) used_headers = self.headers.copy() - used_headers.extend(self.skip_auto_headers) # type: ignore + used_headers.extend(self.skip_auto_headers) # type: ignore[arg-type] for hdr, val in self.DEFAULT_HEADERS.items(): if hdr not in used_headers: @@ -427,7 +464,7 @@ def update_cookies(self, cookies: Optional[LooseCookies]) -> None: if not cookies: return - c = SimpleCookie() # type: SimpleCookie[str] + c = SimpleCookie() if hdrs.COOKIE in self.headers: c.load(self.headers.get(hdrs.COOKIE, "")) del self.headers[hdrs.COOKIE] @@ -435,7 +472,7 @@ def update_cookies(self, cookies: Optional[LooseCookies]) -> None: if isinstance(cookies, Mapping): iter_cookies = cookies.items() else: - iter_cookies = cookies # type: ignore + iter_cookies = cookies # type: ignore[assignment] for name, value in iter_cookies: if isinstance(value, Morsel): # Preserve coded_value @@ -443,13 +480,13 @@ def update_cookies(self, cookies: Optional[LooseCookies]) -> None: mrsl_val.set(value.key, value.value, value.coded_value) c[name] = mrsl_val else: - c[name] = value # type: ignore + c[name] = value # type: ignore[assignment] self.headers[hdrs.COOKIE] = c.output(header="", sep=";").strip() def update_content_encoding(self, data: Any) -> None: """Set request content encoding.""" - if not data: + if data is None: return enc = self.headers.get(hdrs.CONTENT_ENCODING, "").lower() @@ -486,10 +523,14 @@ def update_transfer_encoding(self) -> None: if hdrs.CONTENT_LENGTH not in self.headers: self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) - def update_auth(self, auth: Optional[BasicAuth]) -> None: + def update_auth(self, auth: Optional[BasicAuth], trust_env: bool = False) -> None: """Set basic auth.""" if auth is None: auth = self.auth + if auth is None and trust_env and self.url.host is not None: + netrc_obj = netrc_from_env() + with contextlib.suppress(LookupError): + auth = basicauth_from_netrc(netrc_obj, self.url.host) if auth is None: return @@ -499,7 +540,7 @@ def update_auth(self, auth: Optional[BasicAuth]) -> None: self.headers[hdrs.AUTHORIZATION] = auth.encode() def update_body_from_data(self, body: Any) -> None: - if not body: + if body is None: return # FormData @@ -547,8 +588,6 @@ def update_proxy( proxy_auth: Optional[BasicAuth], proxy_headers: Optional[LooseHeaders], ) -> None: - if proxy and not proxy.scheme == "http": - raise ValueError("Only http proxies are supported") if proxy_auth and not isinstance(proxy_auth, helpers.BasicAuth): raise ValueError("proxy_auth must be None or BasicAuth() tuple") self.proxy = proxy @@ -575,8 +614,11 @@ async def write_bytes( """Support coroutines that yields bytes objects.""" # 100 response if self._continue is not None: - await writer.drain() - await self._continue + try: + await writer.drain() + await self._continue + except asyncio.CancelledError: + return protocol = conn.protocol assert protocol is not None @@ -585,26 +627,36 @@ async def write_bytes( await self.body.write(writer) else: if isinstance(self.body, (bytes, bytearray)): - self.body = (self.body,) # type: ignore + self.body = (self.body,) # type: ignore[assignment] for chunk in self.body: - await writer.write(chunk) # type: ignore + await writer.write(chunk) # type: ignore[arg-type] + except OSError as underlying_exc: + reraised_exc = underlying_exc + exc_is_not_timeout = underlying_exc.errno is not None or not isinstance( + underlying_exc, asyncio.TimeoutError + ) + if exc_is_not_timeout: + reraised_exc = ClientOSError( + underlying_exc.errno, + f"Can not write request body for {self.url !s}", + ) + + set_exception(protocol, reraised_exc, underlying_exc) + except asyncio.CancelledError: await writer.write_eof() - except OSError as exc: - new_exc = ClientOSError( - exc.errno, "Can not write request body for %s" % self.url + except Exception as underlying_exc: + set_exception( + protocol, + ClientConnectionError( + f"Failed to send bytes into the underlying connection {conn !s}", + ), + underlying_exc, ) - new_exc.__context__ = exc - new_exc.__cause__ = exc - protocol.set_exception(new_exc) - except asyncio.CancelledError as exc: - if not conn.closed: - protocol.set_exception(exc) - except Exception as exc: - protocol.set_exception(exc) - finally: - self._writer = None + else: + await writer.write_eof() + protocol.start_timeout() async def send(self, conn: "Connection") -> "ClientResponse": # Specify request target: @@ -632,6 +684,9 @@ async def send(self, conn: "Connection") -> "ClientResponse": on_chunk_sent=functools.partial( self._on_chunk_request_sent, self.method, self.url ), + on_headers_sent=functools.partial( + self._on_headers_request_sent, self.method, self.url + ), ) if self.compress: @@ -662,8 +717,8 @@ async def send(self, conn: "Connection") -> "ClientResponse": self.headers[hdrs.CONNECTION] = connection # status + headers - status_line = "{0} {1} HTTP/{2[0]}.{2[1]}".format( - self.method, path, self.version + status_line = "{0} {1} HTTP/{v.major}.{v.minor}".format( + self.method, path, v=self.version ) await writer.write_headers(status_line, self.headers) @@ -686,39 +741,48 @@ async def send(self, conn: "Connection") -> "ClientResponse": async def close(self) -> None: if self._writer is not None: - try: + with contextlib.suppress(asyncio.CancelledError): await self._writer - finally: - self._writer = None def terminate(self) -> None: if self._writer is not None: if not self.loop.is_closed(): self._writer.cancel() + self._writer.remove_done_callback(self.__reset_writer) self._writer = None async def _on_chunk_request_sent(self, method: str, url: URL, chunk: bytes) -> None: for trace in self._traces: await trace.send_request_chunk_sent(method, url, chunk) + async def _on_headers_request_sent( + self, method: str, url: URL, headers: "CIMultiDict[str]" + ) -> None: + for trace in self._traces: + await trace.send_request_headers(method, url, headers) + class ClientResponse(HeadersMixin): + # Some of these attributes are None when created, + # but will be set by the start() method. + # As the end user will likely never see the None values, we cheat the types below. # from the Status-Line of the response - version = None # HTTP-Version - status = None # type: int # Status-Code - reason = None # Reason-Phrase + version: Optional[HttpVersion] = None # HTTP-Version + status: int = None # type: ignore[assignment] # Status-Code + reason: Optional[str] = None # Reason-Phrase - content = None # type: StreamReader # Payload stream - _headers = None # type: CIMultiDictProxy[str] # Response headers - _raw_headers = None # type: RawHeaders # Response raw headers + content: StreamReader = None # type: ignore[assignment] # Payload stream + _headers: CIMultiDictProxy[str] = None # type: ignore[assignment] + _raw_headers: RawHeaders = None # type: ignore[assignment] _connection = None # current connection - _source_traceback = None - # setted up by ClientRequest after ClientResponse object creation + _source_traceback: Optional[traceback.StackSummary] = None + # set up by ClientRequest after ClientResponse object creation # post-init stage allows to not change ctor signature _closed = True # to allow __del__ for non-initialized properly response _released = False + __writer = None def __init__( self, @@ -736,25 +800,49 @@ def __init__( assert isinstance(url, URL) self.method = method - self.cookies = SimpleCookie() # type: SimpleCookie[str] + self.cookies = SimpleCookie() self._real_url = url self._url = url.with_fragment(None) - self._body = None # type: Any - self._writer = writer # type: Optional[asyncio.Task[None]] + self._body: Any = None + self._writer: Optional[asyncio.Task[None]] = writer self._continue = continue100 # None by default self._closed = True - self._history = () # type: Tuple[ClientResponse, ...] + self._history: Tuple[ClientResponse, ...] = () self._request_info = request_info self._timer = timer if timer is not None else TimerNoop() - self._cache = {} # type: Dict[str, Any] + self._cache: Dict[str, Any] = {} self._traces = traces self._loop = loop # store a reference to session #1985 - self._session = session # type: Optional[ClientSession] + self._session: Optional[ClientSession] = session + # Save reference to _resolve_charset, so that get_encoding() will still + # work after the response has finished reading the body. + if session is None: + # TODO: Fix session=None in tests (see ClientRequest.__init__). + self._resolve_charset: Callable[ + ["ClientResponse", bytes], str + ] = lambda *_: "utf-8" + else: + self._resolve_charset = session._resolve_charset if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) + def __reset_writer(self, _: object = None) -> None: + self.__writer = None + + @property + def _writer(self) -> Optional["asyncio.Task[None]"]: + return self.__writer + + @_writer.setter + def _writer(self, writer: Optional["asyncio.Task[None]"]) -> None: + if self.__writer is not None: + self.__writer.remove_done_callback(self.__reset_writer) + self.__writer = writer + if writer is not None: + writer.add_done_callback(self.__reset_writer) + @reify def url(self) -> URL: return self._url @@ -804,10 +892,7 @@ def __del__(self, _warnings: Any = warnings) -> None: self._cleanup_writer() if self._loop.get_debug(): - if PY_36: - kwargs = {"source": self} - else: - kwargs = {} + kwargs = {"source": self} _warnings.warn(f"Unclosed response {self!r}", ResourceWarning, **kwargs) context = {"client_response": self, "message": "Unclosed response"} if self._source_traceback: @@ -822,7 +907,7 @@ def __repr__(self) -> str: "ascii", "backslashreplace" ).decode("ascii") else: - ascii_encodable_reason = self.reason + ascii_encodable_reason = "None" print( "".format( ascii_encodable_url, self.status, ascii_encodable_reason @@ -848,7 +933,7 @@ def links(self) -> "MultiDictProxy[MultiDictProxy[Union[str, URL]]]": if not links_str: return MultiDictProxy(MultiDict()) - links = MultiDict() # type: MultiDict[MultiDictProxy[Union[str, URL]]] + links: MultiDict[MultiDictProxy[Union[str, URL]]] = MultiDict() for val in re.split(r",(?=\s*<)", links_str): match = re.match(r"\s*<(.*)>(.*)", val) @@ -858,7 +943,7 @@ def links(self) -> "MultiDictProxy[MultiDictProxy[Union[str, URL]]]": url, params_str = match.groups() params = params_str.split(";")[1:] - link = MultiDict() # type: MultiDict[Union[str, URL]] + link: MultiDict[Union[str, URL]] = MultiDict() for param in params: match = re.match(r"^\s*(\S*)\s*=\s*(['\"]?)(.*?)(\2)\s*$", param, re.M) @@ -869,11 +954,11 @@ def links(self) -> "MultiDictProxy[MultiDictProxy[Union[str, URL]]]": link.add(key, value) - key = link.get("rel", url) # type: ignore + key = link.get("rel", url) link.add("url", self.url.join(URL(url))) - links.add(key, MultiDictProxy(link)) + links.add(str(key), MultiDictProxy(link)) return MultiDictProxy(links) @@ -887,7 +972,8 @@ async def start(self, connection: "Connection") -> "ClientResponse": while True: # read response try: - message, payload = await self._protocol.read() # type: ignore + protocol = self._protocol + message, payload = await protocol.read() # type: ignore[union-attr] except http.HttpProcessingError as exc: raise ClientResponseError( self.request_info, @@ -931,20 +1017,14 @@ def _response_eof(self) -> None: if self._closed: return - if self._connection is not None: - # websocket, protocol could be None because - # connection could be detached - if ( - self._connection.protocol is not None - and self._connection.protocol.upgraded - ): - return - - self._connection.release() - self._connection = None + # protocol could be None because connection could be detached + protocol = self._connection and self._connection.protocol + if protocol is not None and protocol.upgraded: + return self._closed = True self._cleanup_writer() + self._release_connection() @property def closed(self) -> bool: @@ -953,30 +1033,24 @@ def closed(self) -> bool: def close(self) -> None: if not self._released: self._notify_content() - if self._closed: - return self._closed = True if self._loop is None or self._loop.is_closed(): return + self._cleanup_writer() if self._connection is not None: self._connection.close() self._connection = None - self._cleanup_writer() def release(self) -> Any: if not self._released: self._notify_content() - if self._closed: - return noop() self._closed = True - if self._connection is not None: - self._connection.release() - self._connection = None self._cleanup_writer() + self._release_connection() return noop() @property @@ -986,14 +1060,10 @@ def ok(self) -> bool: This is **not** a check for ``200 OK`` but a check that the response status is under 400. """ - try: - self.raise_for_status() - except ClientResponseError: - return False - return True + return 400 > self.status def raise_for_status(self) -> None: - if 400 <= self.status: + if not self.ok: # reason should always be not None for a started response assert self.reason is not None self.release() @@ -1005,24 +1075,33 @@ def raise_for_status(self) -> None: headers=self.headers, ) + def _release_connection(self) -> None: + if self._connection is not None: + if self._writer is None: + self._connection.release() + self._connection = None + else: + self._writer.add_done_callback(lambda f: self._release_connection()) + + async def _wait_released(self) -> None: + if self._writer is not None: + await self._writer + self._release_connection() + def _cleanup_writer(self) -> None: if self._writer is not None: self._writer.cancel() - self._writer = None self._session = None def _notify_content(self) -> None: content = self.content if content and content.exception() is None: - content.set_exception(ClientConnectionError("Connection closed")) + set_exception(content, ClientConnectionError("Connection closed")) self._released = True async def wait_for_close(self) -> None: if self._writer is not None: - try: - await self._writer - finally: - self._writer = None + await self._writer self.release() async def read(self) -> bytes: @@ -1037,10 +1116,13 @@ async def read(self) -> bytes: except BaseException: self.close() raise - elif self._released: + elif self._released: # Response explicitly released raise ClientConnectionError("Connection closed") - return self._body + protocol = self._connection and self._connection.protocol + if protocol is None or not protocol.upgraded: + await self._wait_released() # Underlying connection released + return self._body # type: ignore[no-any-return] def get_encoding(self) -> str: ctype = self.headers.get(hdrs.CONTENT_TYPE, "").lower() @@ -1048,27 +1130,22 @@ def get_encoding(self) -> str: encoding = mimetype.parameters.get("charset") if encoding: - try: - codecs.lookup(encoding) - except LookupError: - encoding = None - if not encoding: - if mimetype.type == "application" and ( - mimetype.subtype == "json" or mimetype.subtype == "rdap" - ): - # RFC 7159 states that the default encoding is UTF-8. - # RFC 7483 defines application/rdap+json - encoding = "utf-8" - elif self._body is None: - raise RuntimeError( - "Cannot guess the encoding of " "a not yet read body" - ) - else: - encoding = chardet.detect(self._body)["encoding"] - if not encoding: - encoding = "utf-8" + with contextlib.suppress(LookupError): + return codecs.lookup(encoding).name + + if mimetype.type == "application" and ( + mimetype.subtype == "json" or mimetype.subtype == "rdap" + ): + # RFC 7159 states that the default encoding is UTF-8. + # RFC 7483 defines application/rdap+json + return "utf-8" - return encoding + if self._body is None: + raise RuntimeError( + "Cannot compute fallback encoding of a not yet read body" + ) + + return self._resolve_charset(self, self._body) async def text(self, encoding: Optional[str] = None, errors: str = "strict") -> str: """Read response payload and decode.""" @@ -1078,7 +1155,9 @@ async def text(self, encoding: Optional[str] = None, errors: str = "strict") -> if encoding is None: encoding = self.get_encoding() - return self._body.decode(encoding, errors=errors) # type: ignore + return self._body.decode( # type: ignore[no-any-return,union-attr] + encoding, errors=errors + ) async def json( self, @@ -1103,7 +1182,7 @@ async def json( headers=self.headers, ) - stripped = self._body.strip() # type: ignore + stripped = self._body.strip() # type: ignore[union-attr] if not stripped: return None @@ -1125,3 +1204,4 @@ async def __aexit__( # for exceptions, response object can close connection # if state is broken self.release() + await self.wait_for_close() diff --git a/dist/ba_data/python-site-packages/aiohttp/client_ws.py b/dist/ba_data/python-site-packages/aiohttp/client_ws.py index 28fa371c..d9c74a30 100644 --- a/dist/ba_data/python-site-packages/aiohttp/client_ws.py +++ b/dist/ba_data/python-site-packages/aiohttp/client_ws.py @@ -1,9 +1,8 @@ """WebSocket client for asyncio.""" import asyncio -from typing import Any, Optional - -import async_timeout +import sys +from typing import Any, Optional, cast from .client_exceptions import ClientError from .client_reqrep import ClientResponse @@ -12,6 +11,7 @@ WS_CLOSED_MESSAGE, WS_CLOSING_MESSAGE, WebSocketError, + WSCloseCode, WSMessage, WSMsgType, ) @@ -24,6 +24,11 @@ JSONEncoder, ) +if sys.version_info >= (3, 11): + import asyncio as async_timeout +else: + import async_timeout + class ClientWebSocketResponse: def __init__( @@ -50,19 +55,19 @@ def __init__( self._protocol = protocol self._closed = False self._closing = False - self._close_code = None # type: Optional[int] + self._close_code: Optional[int] = None self._timeout = timeout self._receive_timeout = receive_timeout self._autoclose = autoclose self._autoping = autoping self._heartbeat = heartbeat - self._heartbeat_cb = None + self._heartbeat_cb: Optional[asyncio.TimerHandle] = None if heartbeat is not None: self._pong_heartbeat = heartbeat / 2.0 - self._pong_response_cb = None + self._pong_response_cb: Optional[asyncio.TimerHandle] = None self._loop = loop - self._waiting = None # type: Optional[asyncio.Future[bool]] - self._exception = None # type: Optional[BaseException] + self._waiting: Optional[asyncio.Future[bool]] = None + self._exception: Optional[BaseException] = None self._compress = compress self._client_notakeover = client_notakeover @@ -82,7 +87,12 @@ def _reset_heartbeat(self) -> None: if self._heartbeat is not None: self._heartbeat_cb = call_later( - self._send_heartbeat, self._heartbeat, self._loop + self._send_heartbeat, + self._heartbeat, + self._loop, + timeout_ceil_threshold=self._conn._connector._timeout_ceil_threshold + if self._conn is not None + else 5, ) def _send_heartbeat(self) -> None: @@ -95,13 +105,18 @@ def _send_heartbeat(self) -> None: if self._pong_response_cb is not None: self._pong_response_cb.cancel() self._pong_response_cb = call_later( - self._pong_not_received, self._pong_heartbeat, self._loop + self._pong_not_received, + self._pong_heartbeat, + self._loop, + timeout_ceil_threshold=self._conn._connector._timeout_ceil_threshold + if self._conn is not None + else 5, ) def _pong_not_received(self) -> None: if not self._closed: self._closed = True - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE self._exception = asyncio.TimeoutError() self._response.close() @@ -163,10 +178,11 @@ async def send_json( ) -> None: await self.send_str(dumps(data), compress=compress) - async def close(self, *, code: int = 1000, message: bytes = b"") -> bool: + async def close(self, *, code: int = WSCloseCode.OK, message: bytes = b"") -> bool: # we need to break `receive()` cycle first, # `close()` may be called from different task - if self._waiting is not None and not self._closed: + if self._waiting is not None and not self._closing: + self._closing = True self._reader.feed_data(WS_CLOSING_MESSAGE, 0) await self._waiting @@ -176,29 +192,29 @@ async def close(self, *, code: int = 1000, message: bytes = b"") -> bool: try: await self._writer.close(code, message) except asyncio.CancelledError: - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE self._response.close() raise except Exception as exc: - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE self._exception = exc self._response.close() return True - if self._closing: + if self._close_code: self._response.close() return True while True: try: - with async_timeout.timeout(self._timeout, loop=self._loop): + async with async_timeout.timeout(self._timeout): msg = await self._reader.read() except asyncio.CancelledError: - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE self._response.close() raise except Exception as exc: - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE self._exception = exc self._response.close() return True @@ -224,9 +240,7 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage: try: self._waiting = self._loop.create_future() try: - with async_timeout.timeout( - timeout or self._receive_timeout, loop=self._loop - ): + async with async_timeout.timeout(timeout or self._receive_timeout): msg = await self._reader.read() self._reset_heartbeat() finally: @@ -234,15 +248,15 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage: self._waiting = None set_result(waiter, True) except (asyncio.CancelledError, asyncio.TimeoutError): - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE raise except EofStream: - self._close_code = 1000 + self._close_code = WSCloseCode.OK await self.close() return WSMessage(WSMsgType.CLOSED, None, None) except ClientError: self._closed = True - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE return WS_CLOSED_MESSAGE except WebSocketError as exc: self._close_code = exc.code @@ -251,7 +265,7 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage: except Exception as exc: self._exception = exc self._closing = True - self._close_code = 1006 + self._close_code = WSCloseCode.ABNORMAL_CLOSURE await self.close() return WSMessage(WSMsgType.ERROR, exc, None) @@ -274,13 +288,13 @@ async def receive_str(self, *, timeout: Optional[float] = None) -> str: msg = await self.receive(timeout) if msg.type != WSMsgType.TEXT: raise TypeError(f"Received message {msg.type}:{msg.data!r} is not str") - return msg.data + return cast(str, msg.data) async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes: msg = await self.receive(timeout) if msg.type != WSMsgType.BINARY: raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes") - return msg.data + return cast(bytes, msg.data) async def receive_json( self, diff --git a/dist/ba_data/python-site-packages/aiohttp/compression_utils.py b/dist/ba_data/python-site-packages/aiohttp/compression_utils.py new file mode 100644 index 00000000..9631d377 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/compression_utils.py @@ -0,0 +1,157 @@ +import asyncio +import zlib +from concurrent.futures import Executor +from typing import Optional, cast + +try: + try: + import brotlicffi as brotli + except ImportError: + import brotli + + HAS_BROTLI = True +except ImportError: # pragma: no cover + HAS_BROTLI = False + +MAX_SYNC_CHUNK_SIZE = 1024 + + +def encoding_to_mode( + encoding: Optional[str] = None, + suppress_deflate_header: bool = False, +) -> int: + if encoding == "gzip": + return 16 + zlib.MAX_WBITS + + return -zlib.MAX_WBITS if suppress_deflate_header else zlib.MAX_WBITS + + +class ZlibBaseHandler: + def __init__( + self, + mode: int, + executor: Optional[Executor] = None, + max_sync_chunk_size: Optional[int] = MAX_SYNC_CHUNK_SIZE, + ): + self._mode = mode + self._executor = executor + self._max_sync_chunk_size = max_sync_chunk_size + + +class ZLibCompressor(ZlibBaseHandler): + def __init__( + self, + encoding: Optional[str] = None, + suppress_deflate_header: bool = False, + level: Optional[int] = None, + wbits: Optional[int] = None, + strategy: int = zlib.Z_DEFAULT_STRATEGY, + executor: Optional[Executor] = None, + max_sync_chunk_size: Optional[int] = MAX_SYNC_CHUNK_SIZE, + ): + super().__init__( + mode=encoding_to_mode(encoding, suppress_deflate_header) + if wbits is None + else wbits, + executor=executor, + max_sync_chunk_size=max_sync_chunk_size, + ) + if level is None: + self._compressor = zlib.compressobj(wbits=self._mode, strategy=strategy) + else: + self._compressor = zlib.compressobj( + wbits=self._mode, strategy=strategy, level=level + ) + self._compress_lock = asyncio.Lock() + + def compress_sync(self, data: bytes) -> bytes: + return self._compressor.compress(data) + + async def compress(self, data: bytes) -> bytes: + async with self._compress_lock: + # To ensure the stream is consistent in the event + # there are multiple writers, we need to lock + # the compressor so that only one writer can + # compress at a time. + if ( + self._max_sync_chunk_size is not None + and len(data) > self._max_sync_chunk_size + ): + return await asyncio.get_event_loop().run_in_executor( + self._executor, self.compress_sync, data + ) + return self.compress_sync(data) + + def flush(self, mode: int = zlib.Z_FINISH) -> bytes: + return self._compressor.flush(mode) + + +class ZLibDecompressor(ZlibBaseHandler): + def __init__( + self, + encoding: Optional[str] = None, + suppress_deflate_header: bool = False, + executor: Optional[Executor] = None, + max_sync_chunk_size: Optional[int] = MAX_SYNC_CHUNK_SIZE, + ): + super().__init__( + mode=encoding_to_mode(encoding, suppress_deflate_header), + executor=executor, + max_sync_chunk_size=max_sync_chunk_size, + ) + self._decompressor = zlib.decompressobj(wbits=self._mode) + + def decompress_sync(self, data: bytes, max_length: int = 0) -> bytes: + return self._decompressor.decompress(data, max_length) + + async def decompress(self, data: bytes, max_length: int = 0) -> bytes: + if ( + self._max_sync_chunk_size is not None + and len(data) > self._max_sync_chunk_size + ): + return await asyncio.get_event_loop().run_in_executor( + self._executor, self.decompress_sync, data, max_length + ) + return self.decompress_sync(data, max_length) + + def flush(self, length: int = 0) -> bytes: + return ( + self._decompressor.flush(length) + if length > 0 + else self._decompressor.flush() + ) + + @property + def eof(self) -> bool: + return self._decompressor.eof + + @property + def unconsumed_tail(self) -> bytes: + return self._decompressor.unconsumed_tail + + @property + def unused_data(self) -> bytes: + return self._decompressor.unused_data + + +class BrotliDecompressor: + # Supports both 'brotlipy' and 'Brotli' packages + # since they share an import name. The top branches + # are for 'brotlipy' and bottom branches for 'Brotli' + def __init__(self) -> None: + if not HAS_BROTLI: + raise RuntimeError( + "The brotli decompression is not available. " + "Please install `Brotli` module" + ) + self._obj = brotli.Decompressor() + + def decompress_sync(self, data: bytes) -> bytes: + if hasattr(self._obj, "decompress"): + return cast(bytes, self._obj.decompress(data)) + return cast(bytes, self._obj.process(data)) + + def flush(self) -> bytes: + if hasattr(self._obj, "flush"): + return cast(bytes, self._obj.flush()) + return b"" diff --git a/dist/ba_data/python-site-packages/aiohttp/connector.py b/dist/ba_data/python-site-packages/aiohttp/connector.py index 748b22a4..f95ebe84 100644 --- a/dist/ba_data/python-site-packages/aiohttp/connector.py +++ b/dist/ba_data/python-site-packages/aiohttp/connector.py @@ -6,6 +6,7 @@ import warnings from collections import defaultdict, deque from contextlib import suppress +from http import HTTPStatus from http.cookies import SimpleCookie from itertools import cycle, islice from time import monotonic @@ -19,6 +20,7 @@ Dict, Iterator, List, + Literal, Optional, Set, Tuple, @@ -39,13 +41,13 @@ ClientHttpProxyError, ClientProxyConnectionError, ServerFingerprintMismatch, + UnixClientConnectorError, cert_errors, ssl_errors, ) from .client_proto import ResponseHandler from .client_reqrep import ClientRequest, Fingerprint, _merge_ssl_params -from .helpers import PY_36, CeilTimeout, get_running_loop, is_ip_address, noop, sentinel -from .http import RESPONSES +from .helpers import ceil_timeout, get_running_loop, is_ip_address, noop, sentinel from .locks import EventResultOrError from .resolver import DefaultResolver @@ -54,14 +56,14 @@ SSLContext = ssl.SSLContext except ImportError: # pragma: no cover - ssl = None # type: ignore - SSLContext = object # type: ignore + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] __all__ = ("BaseConnector", "TCPConnector", "UnixConnector", "NamedPipeConnector") -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .client import ClientTimeout from .client_reqrep import ConnectionKey from .tracing import Trace @@ -102,8 +104,8 @@ def __init__( self._key = key self._connector = connector self._loop = loop - self._protocol = protocol # type: Optional[ResponseHandler] - self._callbacks = [] # type: List[Callable[[], None]] + self._protocol: Optional[ResponseHandler] = protocol + self._callbacks: List[Callable[[], None]] = [] if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) @@ -113,10 +115,7 @@ def __repr__(self) -> str: def __del__(self, _warnings: Any = warnings) -> None: if self._protocol is not None: - if PY_36: - kwargs = {"source": self} - else: - kwargs = {} + kwargs = {"source": self} _warnings.warn(f"Unclosed connection {self!r}", ResourceWarning, **kwargs) if self._loop.is_closed(): return @@ -128,6 +127,10 @@ def __del__(self, _warnings: Any = warnings) -> None: context["source_traceback"] = self._source_traceback self._loop.call_exception_handler(context) + def __bool__(self) -> Literal[True]: + """Force subclasses to not be falsy, to make checks simpler.""" + return True + @property def loop(self) -> asyncio.AbstractEventLoop: warnings.warn( @@ -178,7 +181,7 @@ def closed(self) -> bool: class _TransportPlaceholder: - """ placeholder for BaseConnector.connect function """ + """placeholder for BaseConnector.connect function""" def close(self) -> None: pass @@ -194,6 +197,8 @@ class BaseConnector: limit_per_host - Number of simultaneous connections to one host. enable_cleanup_closed - Enables clean-up closed ssl transports. Disabled by default. + timeout_ceil_threshold - Trigger ceiling of timeout values when + it's above timeout_ceil_threshold. loop - Optional event loop. """ @@ -212,6 +217,7 @@ def __init__( limit_per_host: int = 0, enable_cleanup_closed: bool = False, loop: Optional[asyncio.AbstractEventLoop] = None, + timeout_ceil_threshold: float = 5, ) -> None: if force_close: @@ -224,38 +230,37 @@ def __init__( keepalive_timeout = 15.0 loop = get_running_loop(loop) + self._timeout_ceil_threshold = timeout_ceil_threshold self._closed = False if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - self._conns = ( - {} - ) # type: Dict[ConnectionKey, List[Tuple[ResponseHandler, float]]] + self._conns: Dict[ConnectionKey, List[Tuple[ResponseHandler, float]]] = {} self._limit = limit self._limit_per_host = limit_per_host - self._acquired = set() # type: Set[ResponseHandler] - self._acquired_per_host = defaultdict( - set - ) # type: DefaultDict[ConnectionKey, Set[ResponseHandler]] + self._acquired: Set[ResponseHandler] = set() + self._acquired_per_host: DefaultDict[ + ConnectionKey, Set[ResponseHandler] + ] = defaultdict(set) self._keepalive_timeout = cast(float, keepalive_timeout) self._force_close = force_close # {host_key: FIFO list of waiters} - self._waiters = defaultdict(deque) # type: ignore + self._waiters = defaultdict(deque) # type: ignore[var-annotated] self._loop = loop self._factory = functools.partial(ResponseHandler, loop=loop) - self.cookies = SimpleCookie() # type: SimpleCookie[str] + self.cookies = SimpleCookie() # start keep-alive connection cleanup task - self._cleanup_handle = None + self._cleanup_handle: Optional[asyncio.TimerHandle] = None # start cleanup closed transports task - self._cleanup_closed_handle = None + self._cleanup_closed_handle: Optional[asyncio.TimerHandle] = None self._cleanup_closed_disabled = not enable_cleanup_closed - self._cleanup_closed_transports = [] # type: List[Optional[asyncio.Transport]] + self._cleanup_closed_transports: List[Optional[asyncio.Transport]] = [] self._cleanup_closed() def __del__(self, _warnings: Any = warnings) -> None: @@ -268,10 +273,7 @@ def __del__(self, _warnings: Any = warnings) -> None: self._close() - if PY_36: - kwargs = {"source": self} - else: - kwargs = {} + kwargs = {"source": self} _warnings.warn(f"Unclosed connector {self!r}", ResourceWarning, **kwargs) context = { "connector": self, @@ -284,14 +286,14 @@ def __del__(self, _warnings: Any = warnings) -> None: def __enter__(self) -> "BaseConnector": warnings.warn( - '"witn Connector():" is deprecated, ' + '"with Connector():" is deprecated, ' 'use "async with Connector():" instead', DeprecationWarning, ) return self def __exit__(self, *exc: Any) -> None: - self.close() + self._close() async def __aenter__(self) -> "BaseConnector": return self @@ -320,12 +322,10 @@ def limit(self) -> int: @property def limit_per_host(self) -> int: - """The limit_per_host for simultaneous connections - to the same endpoint. + """The limit for simultaneous connections to the same endpoint. Endpoints are the same if they are have equal (host, port, is_ssl) triple. - """ return self._limit_per_host @@ -367,7 +367,11 @@ def _cleanup(self) -> None: if self._conns: self._cleanup_handle = helpers.weakref_handle( - self, "_cleanup", timeout, self._loop + self, + "_cleanup", + timeout, + self._loop, + timeout_ceil_threshold=self._timeout_ceil_threshold, ) def _drop_acquired_per_host( @@ -383,6 +387,7 @@ def _drop_acquired_per_host( def _cleanup_closed(self) -> None: """Double confirmation for transport close. + Some broken ssl servers may leave socket open without proper close. """ if self._cleanup_closed_handle: @@ -396,7 +401,11 @@ def _cleanup_closed(self) -> None: if not self._cleanup_closed_disabled: self._cleanup_closed_handle = helpers.weakref_handle( - self, "_cleanup_closed", self._cleanup_closed_period, self._loop + self, + "_cleanup_closed", + self._cleanup_closed_period, + self._loop, + timeout_ceil_threshold=self._timeout_ceil_threshold, ) def close(self) -> Awaitable[None]: @@ -451,13 +460,13 @@ def closed(self) -> bool: def _available_connections(self, key: "ConnectionKey") -> int: """ - Return number of available connections taking into account - the limit, limit_per_host and the connection key. + Return number of available connections. - If it returns less than 1 means that there is no connections - availables. - """ + The limit, limit_per_host and the connection key are taken into account. + If it returns less than 1 means that there are no connections + available. + """ if self._limit: # total calc available connections available = self._limit - len(self._acquired) @@ -483,7 +492,7 @@ def _available_connections(self, key: "ConnectionKey") -> int: return available async def connect( - self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout" ) -> Connection: """Get from pool or create new connection.""" key = req.connection_key @@ -552,8 +561,14 @@ async def connect( await trace.send_connection_create_end() else: if traces: + # Acquire the connection to prevent race conditions with limits + placeholder = cast(ResponseHandler, _TransportPlaceholder()) + self._acquired.add(placeholder) + self._acquired_per_host[key].add(placeholder) for trace in traces: await trace.send_connection_reuseconn() + self._acquired.remove(placeholder) + self._drop_acquired_per_host(key, placeholder) self._acquired.add(proto) self._acquired_per_host[key].add(proto) @@ -592,7 +607,9 @@ def _get(self, key: "ConnectionKey") -> Optional[ResponseHandler]: def _release_waiter(self) -> None: """ - Iterates over all waiters till found one that is not finsihed and + Iterates over all waiters until one to be released is found. + + The one to be released is not finished and belongs to a host that has available connections. """ if not self._waiters: @@ -659,21 +676,23 @@ def _release( if self._cleanup_handle is None: self._cleanup_handle = helpers.weakref_handle( - self, "_cleanup", self._keepalive_timeout, self._loop + self, + "_cleanup", + self._keepalive_timeout, + self._loop, + timeout_ceil_threshold=self._timeout_ceil_threshold, ) async def _create_connection( - self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout" ) -> ResponseHandler: raise NotImplementedError() class _DNSCacheTable: def __init__(self, ttl: Optional[float] = None) -> None: - self._addrs_rr = ( - {} - ) # type: Dict[Tuple[str, int], Tuple[Iterator[Dict[str, Any]], int]] - self._timestamps = {} # type: Dict[Tuple[str, int], float] + self._addrs_rr: Dict[Tuple[str, int], Tuple[Iterator[Dict[str, Any]], int]] = {} + self._timestamps: Dict[Tuple[str, int], float] = {} self._ttl = ttl def __contains__(self, host: object) -> bool: @@ -682,13 +701,13 @@ def __contains__(self, host: object) -> bool: def add(self, key: Tuple[str, int], addrs: List[Dict[str, Any]]) -> None: self._addrs_rr[key] = (cycle(addrs), len(addrs)) - if self._ttl: + if self._ttl is not None: self._timestamps[key] = monotonic() def remove(self, key: Tuple[str, int]) -> None: self._addrs_rr.pop(key, None) - if self._ttl: + if self._ttl is not None: self._timestamps.pop(key, None) def clear(self) -> None: @@ -743,7 +762,7 @@ def __init__( ttl_dns_cache: Optional[int] = 10, family: int = 0, ssl_context: Optional[SSLContext] = None, - ssl: Union[None, bool, Fingerprint, SSLContext] = None, + ssl: Union[bool, Fingerprint, SSLContext] = True, local_addr: Optional[Tuple[str, int]] = None, resolver: Optional[AbstractResolver] = None, keepalive_timeout: Union[None, float, object] = sentinel, @@ -752,6 +771,7 @@ def __init__( limit_per_host: int = 0, enable_cleanup_closed: bool = False, loop: Optional[asyncio.AbstractEventLoop] = None, + timeout_ceil_threshold: float = 5, ): super().__init__( keepalive_timeout=keepalive_timeout, @@ -760,6 +780,7 @@ def __init__( limit_per_host=limit_per_host, enable_cleanup_closed=enable_cleanup_closed, loop=loop, + timeout_ceil_threshold=timeout_ceil_threshold, ) self._ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) @@ -769,9 +790,7 @@ def __init__( self._use_dns_cache = use_dns_cache self._cached_hosts = _DNSCacheTable(ttl=ttl_dns_cache) - self._throttle_dns_events = ( - {} - ) # type: Dict[Tuple[str, int], EventResultOrError] + self._throttle_dns_events: Dict[Tuple[str, int], EventResultOrError] = {} self._family = family self._local_addr = local_addr @@ -806,6 +825,7 @@ def clear_dns_cache( async def _resolve_host( self, host: str, port: int, traces: Optional[List["Trace"]] = None ) -> List[Dict[str, Any]]: + """Resolve host and return list of addresses.""" if is_ip_address(host): return [ { @@ -833,8 +853,7 @@ async def _resolve_host( return res key = (host, port) - - if (key in self._cached_hosts) and (not self._cached_hosts.expired(key)): + if key in self._cached_hosts and not self._cached_hosts.expired(key): # get result early, before any await (#4014) result = self._cached_hosts.next_addrs(key) @@ -843,6 +862,39 @@ async def _resolve_host( await trace.send_dns_cache_hit(host) return result + # + # If multiple connectors are resolving the same host, we wait + # for the first one to resolve and then use the result for all of them. + # We use a throttle event to ensure that we only resolve the host once + # and then use the result for all the waiters. + # + # In this case we need to create a task to ensure that we can shield + # the task from cancellation as cancelling this lookup should not cancel + # the underlying lookup or else the cancel event will get broadcast to + # all the waiters across all connections. + # + resolved_host_task = asyncio.create_task( + self._resolve_host_with_throttle(key, host, port, traces) + ) + try: + return await asyncio.shield(resolved_host_task) + except asyncio.CancelledError: + + def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: + with suppress(Exception, asyncio.CancelledError): + fut.result() + + resolved_host_task.add_done_callback(drop_exception) + raise + + async def _resolve_host_with_throttle( + self, + key: Tuple[str, int], + host: str, + port: int, + traces: Optional[List["Trace"]], + ) -> List[Dict[str, Any]]: + """Resolve host with a dns events throttle.""" if key in self._throttle_dns_events: # get event early, before any await (#4014) event = self._throttle_dns_events[key] @@ -880,7 +932,7 @@ async def _resolve_host( return self._cached_hosts.next_addrs(key) async def _create_connection( - self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout" ) -> ResponseHandler: """Create connection. @@ -899,9 +951,11 @@ def _make_ssl_context(verified: bool) -> SSLContext: if verified: return ssl.create_default_context() else: - sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) sslcontext.options |= ssl.OP_NO_SSLv2 sslcontext.options |= ssl.OP_NO_SSLv3 + sslcontext.check_hostname = False + sslcontext.verify_mode = ssl.CERT_NONE try: sslcontext.options |= ssl.OP_NO_COMPRESSION except AttributeError as attr_err: @@ -914,7 +968,7 @@ def _make_ssl_context(verified: bool) -> SSLContext: sslcontext.set_default_verify_paths() return sslcontext - def _get_ssl_context(self, req: "ClientRequest") -> Optional[SSLContext]: + def _get_ssl_context(self, req: ClientRequest) -> Optional[SSLContext]: """Logic to get the correct SSL context 0. if req.ssl is false, return None @@ -934,20 +988,20 @@ def _get_ssl_context(self, req: "ClientRequest") -> Optional[SSLContext]: sslcontext = req.ssl if isinstance(sslcontext, ssl.SSLContext): return sslcontext - if sslcontext is not None: + if sslcontext is not True: # not verified or fingerprinted return self._make_ssl_context(False) sslcontext = self._ssl if isinstance(sslcontext, ssl.SSLContext): return sslcontext - if sslcontext is not None: + if sslcontext is not True: # not verified or fingerprinted return self._make_ssl_context(False) return self._make_ssl_context(True) else: return None - def _get_fingerprint(self, req: "ClientRequest") -> Optional["Fingerprint"]: + def _get_fingerprint(self, req: ClientRequest) -> Optional["Fingerprint"]: ret = req.ssl if isinstance(ret, Fingerprint): return ret @@ -959,24 +1013,172 @@ def _get_fingerprint(self, req: "ClientRequest") -> Optional["Fingerprint"]: async def _wrap_create_connection( self, *args: Any, - req: "ClientRequest", + req: ClientRequest, timeout: "ClientTimeout", client_error: Type[Exception] = ClientConnectorError, **kwargs: Any, ) -> Tuple[asyncio.Transport, ResponseHandler]: try: - with CeilTimeout(timeout.sock_connect): - return await self._loop.create_connection(*args, **kwargs) # type: ignore # noqa + async with ceil_timeout( + timeout.sock_connect, ceil_threshold=timeout.ceil_threshold + ): + return await self._loop.create_connection(*args, **kwargs) except cert_errors as exc: raise ClientConnectorCertificateError(req.connection_key, exc) from exc except ssl_errors as exc: raise ClientConnectorSSLError(req.connection_key, exc) from exc except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise client_error(req.connection_key, exc) from exc + def _fail_on_no_start_tls(self, req: "ClientRequest") -> None: + """Raise a :py:exc:`RuntimeError` on missing ``start_tls()``. + + It is necessary for TLS-in-TLS so that it is possible to + send HTTPS queries through HTTPS proxies. + + This doesn't affect regular HTTP requests, though. + """ + if not req.is_ssl(): + return + + proxy_url = req.proxy + assert proxy_url is not None + if proxy_url.scheme != "https": + return + + self._check_loop_for_start_tls() + + def _check_loop_for_start_tls(self) -> None: + try: + self._loop.start_tls + except AttributeError as attr_exc: + raise RuntimeError( + "An HTTPS request is being sent through an HTTPS proxy. " + "This needs support for TLS in TLS but it is not implemented " + "in your runtime for the stdlib asyncio.\n\n" + "Please upgrade to Python 3.11 or higher. For more details, " + "please see:\n" + "* https://bugs.python.org/issue37179\n" + "* https://github.com/python/cpython/pull/28073\n" + "* https://docs.aiohttp.org/en/stable/" + "client_advanced.html#proxy-support\n" + "* https://github.com/aio-libs/aiohttp/discussions/6044\n", + ) from attr_exc + + def _loop_supports_start_tls(self) -> bool: + try: + self._check_loop_for_start_tls() + except RuntimeError: + return False + else: + return True + + def _warn_about_tls_in_tls( + self, + underlying_transport: asyncio.Transport, + req: ClientRequest, + ) -> None: + """Issue a warning if the requested URL has HTTPS scheme.""" + if req.request_info.url.scheme != "https": + return + + asyncio_supports_tls_in_tls = getattr( + underlying_transport, + "_start_tls_compatible", + False, + ) + + if asyncio_supports_tls_in_tls: + return + + warnings.warn( + "An HTTPS request is being sent through an HTTPS proxy. " + "This support for TLS in TLS is known to be disabled " + "in the stdlib asyncio (Python <3.11). This is why you'll probably see " + "an error in the log below.\n\n" + "It is possible to enable it via monkeypatching. " + "For more details, see:\n" + "* https://bugs.python.org/issue37179\n" + "* https://github.com/python/cpython/pull/28073\n\n" + "You can temporarily patch this as follows:\n" + "* https://docs.aiohttp.org/en/stable/client_advanced.html#proxy-support\n" + "* https://github.com/aio-libs/aiohttp/discussions/6044\n", + RuntimeWarning, + source=self, + # Why `4`? At least 3 of the calls in the stack originate + # from the methods in this class. + stacklevel=3, + ) + + async def _start_tls_connection( + self, + underlying_transport: asyncio.Transport, + req: ClientRequest, + timeout: "ClientTimeout", + client_error: Type[Exception] = ClientConnectorError, + ) -> Tuple[asyncio.BaseTransport, ResponseHandler]: + """Wrap the raw TCP transport with TLS.""" + tls_proto = self._factory() # Create a brand new proto for TLS + + # Safety of the `cast()` call here is based on the fact that + # internally `_get_ssl_context()` only returns `None` when + # `req.is_ssl()` evaluates to `False` which is never gonna happen + # in this code path. Of course, it's rather fragile + # maintainability-wise but this is to be solved separately. + sslcontext = cast(ssl.SSLContext, self._get_ssl_context(req)) + + try: + async with ceil_timeout( + timeout.sock_connect, ceil_threshold=timeout.ceil_threshold + ): + try: + tls_transport = await self._loop.start_tls( + underlying_transport, + tls_proto, + sslcontext, + server_hostname=req.server_hostname or req.host, + ssl_handshake_timeout=timeout.total, + ) + except BaseException: + # We need to close the underlying transport since + # `start_tls()` probably failed before it had a + # chance to do this: + underlying_transport.close() + raise + except cert_errors as exc: + raise ClientConnectorCertificateError(req.connection_key, exc) from exc + except ssl_errors as exc: + raise ClientConnectorSSLError(req.connection_key, exc) from exc + except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise client_error(req.connection_key, exc) from exc + except TypeError as type_err: + # Example cause looks like this: + # TypeError: transport is not supported by start_tls() + + raise ClientConnectionError( + "Cannot initialize a TLS-in-TLS connection to host " + f"{req.host!s}:{req.port:d} through an underlying connection " + f"to an HTTPS proxy {req.proxy!s} ssl:{req.ssl or 'default'} " + f"[{type_err!s}]" + ) from type_err + else: + if tls_transport is None: + msg = "Failed to start TLS (possibly caused by closing transport)" + raise client_error(req.connection_key, OSError(msg)) + tls_proto.connection_made( + tls_transport + ) # Kick the state machine of the new TLS protocol + + return tls_transport, tls_proto + async def _create_direct_connection( self, - req: "ClientRequest", + req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout", *, @@ -987,35 +1189,39 @@ async def _create_direct_connection( host = req.url.raw_host assert host is not None + # Replace multiple trailing dots with a single one. + # A trailing dot is only present for fully-qualified domain names. + # See https://github.com/aio-libs/aiohttp/pull/7364. + if host.endswith(".."): + host = host.rstrip(".") + "." port = req.port assert port is not None - host_resolved = asyncio.ensure_future( - self._resolve_host(host, port, traces=traces), loop=self._loop - ) try: # Cancelling this lookup should not cancel the underlying lookup # or else the cancel event will get broadcast to all the waiters # across all connections. - hosts = await asyncio.shield(host_resolved) - except asyncio.CancelledError: - - def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: - with suppress(Exception, asyncio.CancelledError): - fut.result() - - host_resolved.add_done_callback(drop_exception) - raise + hosts = await self._resolve_host(host, port, traces=traces) except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise # in case of proxy it is not ClientProxyConnectionError # it is problem of resolving proxy ip itself raise ClientConnectorError(req.connection_key, exc) from exc - last_exc = None # type: Optional[Exception] + last_exc: Optional[Exception] = None for hinfo in hosts: host = hinfo["host"] port = hinfo["port"] + # Strip trailing dots, certificates contain FQDN without dots. + # See https://github.com/aio-libs/aiohttp/issues/3636 + server_hostname = ( + (req.server_hostname or hinfo["hostname"]).rstrip(".") + if sslcontext + else None + ) + try: transp, proto = await self._wrap_create_connection( self._factory, @@ -1026,7 +1232,7 @@ def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: family=hinfo["family"], proto=hinfo["proto"], flags=hinfo["flags"], - server_hostname=hinfo["hostname"] if sslcontext else None, + server_hostname=server_hostname, local_addr=self._local_addr, req=req, client_error=client_error, @@ -1051,11 +1257,14 @@ def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: raise last_exc async def _create_proxy_connection( - self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" - ) -> Tuple[asyncio.Transport, ResponseHandler]: - headers = {} # type: Dict[str, str] + self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout" + ) -> Tuple[asyncio.BaseTransport, ResponseHandler]: + self._fail_on_no_start_tls(req) + runtime_has_start_tls = self._loop_supports_start_tls() + + headers: Dict[str, str] = {} if req.proxy_headers is not None: - headers = req.proxy_headers # type: ignore + headers = req.proxy_headers # type: ignore[assignment] headers[hdrs.HOST] = req.headers[hdrs.HOST] url = req.proxy @@ -1087,7 +1296,9 @@ async def _create_proxy_connection( proxy_req.headers[hdrs.PROXY_AUTHORIZATION] = auth if req.is_ssl(): - sslcontext = self._get_ssl_context(req) + if runtime_has_start_tls: + self._warn_about_tls_in_tls(transport, req) + # For HTTPS requests over HTTP proxy # we must notify proxy to tunnel connection # so we send CONNECT command: @@ -1107,7 +1318,14 @@ async def _create_proxy_connection( try: protocol = conn._protocol assert protocol is not None - protocol.set_response_params() + + # read_until_eof=True will ensure the connection isn't closed + # once the response is received and processed allowing + # START_TLS to work on the connection below. + protocol.set_response_params( + read_until_eof=runtime_has_start_tls, + timeout_ceil_threshold=self._timeout_ceil_threshold, + ) resp = await proxy_resp.start(conn) except BaseException: proxy_resp.close() @@ -1120,7 +1338,7 @@ async def _create_proxy_connection( if resp.status != 200: message = resp.reason if message is None: - message = RESPONSES[resp.status][0] + message = HTTPStatus(resp.status).phrase raise ClientHttpProxyError( proxy_resp.request_info, resp.history, @@ -1128,21 +1346,42 @@ async def _create_proxy_connection( message=message, headers=resp.headers, ) - rawsock = transport.get_extra_info("socket", default=None) - if rawsock is None: - raise RuntimeError("Transport does not expose socket instance") - # Duplicate the socket, so now we can close proxy transport - rawsock = rawsock.dup() - finally: + if not runtime_has_start_tls: + rawsock = transport.get_extra_info("socket", default=None) + if rawsock is None: + raise RuntimeError( + "Transport does not expose socket instance" + ) + # Duplicate the socket, so now we can close proxy transport + rawsock = rawsock.dup() + except BaseException: + # It shouldn't be closed in `finally` because it's fed to + # `loop.start_tls()` and the docs say not to touch it after + # passing there. transport.close() - - transport, proto = await self._wrap_create_connection( - self._factory, - timeout=timeout, - ssl=sslcontext, - sock=rawsock, - server_hostname=req.host, + raise + finally: + if not runtime_has_start_tls: + transport.close() + + if not runtime_has_start_tls: + # HTTP proxy with support for upgrade to HTTPS + sslcontext = self._get_ssl_context(req) + return await self._wrap_create_connection( + self._factory, + timeout=timeout, + ssl=sslcontext, + sock=rawsock, + server_hostname=req.host, + req=req, + ) + + return await self._start_tls_connection( + # Access the old transport for the last time before it's + # closed and forgotten forever: + transport, req=req, + timeout=timeout, ) finally: proxy_resp.close() @@ -1186,24 +1425,28 @@ def path(self) -> str: return self._path async def _create_connection( - self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout" ) -> ResponseHandler: try: - with CeilTimeout(timeout.sock_connect): + async with ceil_timeout( + timeout.sock_connect, ceil_threshold=timeout.ceil_threshold + ): _, proto = await self._loop.create_unix_connection( self._factory, self._path ) except OSError as exc: - raise ClientConnectorError(req.connection_key, exc) from exc + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise + raise UnixClientConnectorError(self.path, req.connection_key, exc) from exc - return cast(ResponseHandler, proto) + return proto class NamedPipeConnector(BaseConnector): """Named pipe connector. Only supported by the proactor event loop. - See also: https://docs.python.org/3.7/library/asyncio-eventloop.html + See also: https://docs.python.org/3/library/asyncio-eventloop.html path - Windows named pipe path. keepalive_timeout - (optional) Keep-alive timeout. @@ -1230,7 +1473,9 @@ def __init__( limit_per_host=limit_per_host, loop=loop, ) - if not isinstance(self._loop, asyncio.ProactorEventLoop): # type: ignore + if not isinstance( + self._loop, asyncio.ProactorEventLoop # type: ignore[attr-defined] + ): raise RuntimeError( "Named Pipes only available in proactor " "loop under windows" ) @@ -1242,11 +1487,13 @@ def path(self) -> str: return self._path async def _create_connection( - self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout" ) -> ResponseHandler: try: - with CeilTimeout(timeout.sock_connect): - _, proto = await self._loop.create_pipe_connection( # type: ignore + async with ceil_timeout( + timeout.sock_connect, ceil_threshold=timeout.ceil_threshold + ): + _, proto = await self._loop.create_pipe_connection( # type: ignore[attr-defined] self._factory, self._path ) # the drain is required so that the connection_made is called @@ -1257,6 +1504,8 @@ async def _create_connection( # other option is to manually set transport like # `proto.transport = trans` except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise ClientConnectorError(req.connection_key, exc) from exc return cast(ResponseHandler, proto) diff --git a/dist/ba_data/python-site-packages/aiohttp/cookiejar.py b/dist/ba_data/python-site-packages/aiohttp/cookiejar.py index b6b59d62..a348f112 100644 --- a/dist/ba_data/python-site-packages/aiohttp/cookiejar.py +++ b/dist/ba_data/python-site-packages/aiohttp/cookiejar.py @@ -1,16 +1,21 @@ import asyncio +import calendar +import contextlib import datetime import os # noqa import pathlib import pickle import re +import time from collections import defaultdict from http.cookies import BaseCookie, Morsel, SimpleCookie +from math import ceil from typing import ( # noqa DefaultDict, Dict, Iterable, Iterator, + List, Mapping, Optional, Set, @@ -21,9 +26,9 @@ from yarl import URL -from .abc import AbstractCookieJar -from .helpers import is_ip_address, next_whole_second -from .typedefs import LooseCookies, PathLike +from .abc import AbstractCookieJar, ClearCookiePredicate +from .helpers import is_ip_address +from .typedefs import LooseCookies, PathLike, StrOrURL __all__ = ("CookieJar", "DummyCookieJar") @@ -50,32 +55,53 @@ class CookieJar(AbstractCookieJar): DATE_YEAR_RE = re.compile(r"(\d{2,4})") - MAX_TIME = datetime.datetime.max.replace(tzinfo=datetime.timezone.utc) - - MAX_32BIT_TIME = datetime.datetime.utcfromtimestamp(2 ** 31 - 1) + # calendar.timegm() fails for timestamps after datetime.datetime.max + # Minus one as a loss of precision occurs when timestamp() is called. + MAX_TIME = ( + int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1 + ) + try: + calendar.timegm(time.gmtime(MAX_TIME)) + except (OSError, ValueError): + # Hit the maximum representable time on Windows + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64 + # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere + MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1)) + except OverflowError: + # #4515: datetime.max may not be representable on 32-bit platforms + MAX_TIME = 2**31 - 1 + # Avoid minuses in the future, 3x faster + SUB_MAX_TIME = MAX_TIME - 1 def __init__( self, *, unsafe: bool = False, quote_cookie: bool = True, - loop: Optional[asyncio.AbstractEventLoop] = None + treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, ) -> None: super().__init__(loop=loop) - self._cookies = defaultdict( + self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict( SimpleCookie - ) # type: DefaultDict[str, SimpleCookie[str]] - self._host_only_cookies = set() # type: Set[Tuple[str, str]] + ) + self._host_only_cookies: Set[Tuple[str, str]] = set() self._unsafe = unsafe self._quote_cookie = quote_cookie - self._next_expiration = next_whole_second() - self._expirations = {} # type: Dict[Tuple[str, str], datetime.datetime] - # #4515: datetime.max may not be representable on 32-bit platforms - self._max_time = self.MAX_TIME - try: - self._max_time.timestamp() - except OverflowError: - self._max_time = self.MAX_32BIT_TIME + if treat_as_secure_origin is None: + treat_as_secure_origin = [] + elif isinstance(treat_as_secure_origin, URL): + treat_as_secure_origin = [treat_as_secure_origin.origin()] + elif isinstance(treat_as_secure_origin, str): + treat_as_secure_origin = [URL(treat_as_secure_origin).origin()] + else: + treat_as_secure_origin = [ + URL(url).origin() if isinstance(url, str) else url.origin() + for url in treat_as_secure_origin + ] + self._treat_as_secure_origin = treat_as_secure_origin + self._next_expiration: float = ceil(time.time()) + self._expirations: Dict[Tuple[str, str, str], float] = {} def save(self, file_path: PathLike) -> None: file_path = pathlib.Path(file_path) @@ -87,11 +113,39 @@ def load(self, file_path: PathLike) -> None: with file_path.open(mode="rb") as f: self._cookies = pickle.load(f) - def clear(self) -> None: - self._cookies.clear() - self._host_only_cookies.clear() - self._next_expiration = next_whole_second() - self._expirations.clear() + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: + if predicate is None: + self._next_expiration = ceil(time.time()) + self._cookies.clear() + self._host_only_cookies.clear() + self._expirations.clear() + return + + to_del = [] + now = time.time() + for (domain, path), cookie in self._cookies.items(): + for name, morsel in cookie.items(): + key = (domain, path, name) + if ( + key in self._expirations and self._expirations[key] <= now + ) or predicate(morsel): + to_del.append(key) + + for domain, path, name in to_del: + self._host_only_cookies.discard((domain, name)) + key = (domain, path, name) + if key in self._expirations: + del self._expirations[(domain, path, name)] + self._cookies[(domain, path)].pop(name, None) + + self._next_expiration = ( + min(*self._expirations.values(), self.SUB_MAX_TIME) + 1 + if self._expirations + else self.MAX_TIME + ) + + def clear_domain(self, domain: str) -> None: + self.clear(lambda x: self._is_domain_match(domain, x["domain"])) def __iter__(self) -> "Iterator[Morsel[str]]": self._do_expiration() @@ -102,35 +156,11 @@ def __len__(self) -> int: return sum(1 for i in self) def _do_expiration(self) -> None: - now = datetime.datetime.now(datetime.timezone.utc) - if self._next_expiration > now: - return - if not self._expirations: - return - next_expiration = self._max_time - to_del = [] - cookies = self._cookies - expirations = self._expirations - for (domain, name), when in expirations.items(): - if when <= now: - cookies[domain].pop(name, None) - to_del.append((domain, name)) - self._host_only_cookies.discard((domain, name)) - else: - next_expiration = min(next_expiration, when) - for key in to_del: - del expirations[key] - - try: - self._next_expiration = next_expiration.replace( - microsecond=0 - ) + datetime.timedelta(seconds=1) - except OverflowError: - self._next_expiration = self._max_time - - def _expire_cookie(self, when: datetime.datetime, domain: str, name: str) -> None: + self.clear(lambda x: False) + + def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None: self._next_expiration = min(self._next_expiration, when) - self._expirations[(domain, name)] = when + self._expirations[(domain, path, name)] = when def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: """Update cookies.""" @@ -145,8 +175,8 @@ def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> No for name, cookie in cookies: if not isinstance(cookie, Morsel): - tmp = SimpleCookie() # type: SimpleCookie[str] - tmp[name] = cookie # type: ignore + tmp = SimpleCookie() + tmp[name] = cookie # type: ignore[assignment] cookie = tmp[name] domain = cookie["domain"] @@ -186,13 +216,8 @@ def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> No if max_age: try: delta_seconds = int(max_age) - try: - max_age_expiration = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(seconds=delta_seconds) - except OverflowError: - max_age_expiration = self._max_time - self._expire_cookie(max_age_expiration, domain, name) + max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME) + self._expire_cookie(max_age_expiration, domain, path, name) except ValueError: cookie["max-age"] = "" @@ -201,27 +226,38 @@ def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> No if expires: expire_time = self._parse_date(expires) if expire_time: - self._expire_cookie(expire_time, domain, name) + self._expire_cookie(expire_time, domain, path, name) else: cookie["expires"] = "" - self._cookies[domain][name] = cookie + self._cookies[(domain, path)][name] = cookie self._do_expiration() - def filter_cookies( - self, request_url: URL = URL() - ) -> Union["BaseCookie[str]", "SimpleCookie[str]"]: + def filter_cookies(self, request_url: URL = URL()) -> "BaseCookie[str]": """Returns this jar's cookies filtered by their attributes.""" - self._do_expiration() - request_url = URL(request_url) - filtered: Union["SimpleCookie[str]", "BaseCookie[str]"] = ( + filtered: Union[SimpleCookie, "BaseCookie[str]"] = ( SimpleCookie() if self._quote_cookie else BaseCookie() ) + if not self._cookies: + # Skip do_expiration() if there are no cookies. + return filtered + self._do_expiration() + if not self._cookies: + # Skip rest of function if no non-expired cookies. + return filtered + request_url = URL(request_url) hostname = request_url.raw_host or "" - is_not_secure = request_url.scheme not in ("https", "wss") - for cookie in self: + is_not_secure = request_url.scheme not in ("https", "wss") + if is_not_secure and self._treat_as_secure_origin: + request_origin = URL() + with contextlib.suppress(ValueError): + request_origin = request_url.origin() + is_not_secure = request_origin not in self._treat_as_secure_origin + + # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4 + for cookie in sorted(self, key=lambda c: len(c["path"])): name = cookie.key domain = cookie["domain"] @@ -289,7 +325,7 @@ def _is_path_match(req_path: str, cookie_path: str) -> bool: return non_matching.startswith("/") @classmethod - def _parse_date(cls, date_str: str) -> Optional[datetime.datetime]: + def _parse_date(cls, date_str: str) -> Optional[int]: """Implements date string parsing adhering to RFC 6265.""" if not date_str: return None @@ -312,7 +348,7 @@ def _parse_date(cls, date_str: str) -> Optional[datetime.datetime]: time_match = cls.DATE_HMS_TIME_RE.match(token) if time_match: found_time = True - hour, minute, second = [int(s) for s in time_match.groups()] + hour, minute, second = (int(s) for s in time_match.groups()) continue if not found_day: @@ -350,9 +386,7 @@ def _parse_date(cls, date_str: str) -> Optional[datetime.datetime]: if year < 1601 or hour > 23 or minute > 59 or second > 59: return None - return datetime.datetime( - year, month, day, hour, minute, second, tzinfo=datetime.timezone.utc - ) + return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1)) class DummyCookieJar(AbstractCookieJar): @@ -372,7 +406,10 @@ def __iter__(self) -> "Iterator[Morsel[str]]": def __len__(self) -> int: return 0 - def clear(self) -> None: + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: + pass + + def clear_domain(self, domain: str) -> None: pass def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: diff --git a/dist/ba_data/python-site-packages/aiohttp/formdata.py b/dist/ba_data/python-site-packages/aiohttp/formdata.py index 900716b7..2b75b3de 100644 --- a/dist/ba_data/python-site-packages/aiohttp/formdata.py +++ b/dist/ba_data/python-site-packages/aiohttp/formdata.py @@ -1,4 +1,5 @@ import io +import warnings from typing import Any, Iterable, List, Optional from urllib.parse import urlencode @@ -12,8 +13,10 @@ class FormData: - """Helper class for multipart/form-data and - application/x-www-form-urlencoded body generation.""" + """Helper class for form body generation. + + Supports multipart/form-data and application/x-www-form-urlencoded. + """ def __init__( self, @@ -22,7 +25,7 @@ def __init__( charset: Optional[str] = None, ) -> None: self._writer = multipart.MultipartWriter("form-data") - self._fields = [] # type: List[Any] + self._fields: List[Any] = [] self._is_multipart = False self._is_processed = False self._quote_fields = quote_fields @@ -45,16 +48,21 @@ def add_field( *, content_type: Optional[str] = None, filename: Optional[str] = None, - content_transfer_encoding: Optional[str] = None + content_transfer_encoding: Optional[str] = None, ) -> None: if isinstance(value, io.IOBase): self._is_multipart = True elif isinstance(value, (bytes, bytearray, memoryview)): + msg = ( + "In v4, passing bytes will no longer create a file field. " + "Please explicitly use the filename parameter or pass a BytesIO object." + ) if filename is None and content_transfer_encoding is None: + warnings.warn(msg, DeprecationWarning) filename = name - type_options = MultiDict({"name": name}) # type: MultiDict[str] + type_options: MultiDict[str] = MultiDict({"name": name}) if filename is not None and not isinstance(filename, str): raise TypeError( "filename must be an instance of str. " "Got: %s" % filename @@ -79,7 +87,11 @@ def add_field( "content_transfer_encoding must be an instance" " of str. Got: %s" % content_transfer_encoding ) - headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding + msg = ( + "content_transfer_encoding is deprecated. " + "To maintain compatibility with v4 please pass a BytesPayload." + ) + warnings.warn(msg, DeprecationWarning) self._is_multipart = True self._fields.append((type_options, headers, value)) @@ -92,14 +104,14 @@ def add_fields(self, *fields: Any) -> None: if isinstance(rec, io.IOBase): k = guess_filename(rec, "unknown") - self.add_field(k, rec) # type: ignore + self.add_field(k, rec) # type: ignore[arg-type] elif isinstance(rec, (MultiDictProxy, MultiDict)): to_add.extend(rec.items()) elif isinstance(rec, (list, tuple)) and len(rec) == 2: k, fp = rec - self.add_field(k, fp) # type: ignore + self.add_field(k, fp) # type: ignore[arg-type] else: raise TypeError( diff --git a/dist/ba_data/python-site-packages/aiohttp/frozenlist.py b/dist/ba_data/python-site-packages/aiohttp/frozenlist.py deleted file mode 100644 index 46b26108..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/frozenlist.py +++ /dev/null @@ -1,72 +0,0 @@ -from collections.abc import MutableSequence -from functools import total_ordering - -from .helpers import NO_EXTENSIONS - - -@total_ordering -class FrozenList(MutableSequence): - - __slots__ = ("_frozen", "_items") - - def __init__(self, items=None): - self._frozen = False - if items is not None: - items = list(items) - else: - items = [] - self._items = items - - @property - def frozen(self): - return self._frozen - - def freeze(self): - self._frozen = True - - def __getitem__(self, index): - return self._items[index] - - def __setitem__(self, index, value): - if self._frozen: - raise RuntimeError("Cannot modify frozen list.") - self._items[index] = value - - def __delitem__(self, index): - if self._frozen: - raise RuntimeError("Cannot modify frozen list.") - del self._items[index] - - def __len__(self): - return self._items.__len__() - - def __iter__(self): - return self._items.__iter__() - - def __reversed__(self): - return self._items.__reversed__() - - def __eq__(self, other): - return list(self) == other - - def __le__(self, other): - return list(self) <= other - - def insert(self, pos, item): - if self._frozen: - raise RuntimeError("Cannot modify frozen list.") - self._items.insert(pos, item) - - def __repr__(self): - return f"" - - -PyFrozenList = FrozenList - -try: - from aiohttp._frozenlist import FrozenList as CFrozenList # type: ignore - - if not NO_EXTENSIONS: - FrozenList = CFrozenList # type: ignore -except ImportError: # pragma: no cover - pass diff --git a/dist/ba_data/python-site-packages/aiohttp/frozenlist.pyi b/dist/ba_data/python-site-packages/aiohttp/frozenlist.pyi deleted file mode 100644 index 72ab0867..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/frozenlist.pyi +++ /dev/null @@ -1,46 +0,0 @@ -from typing import ( - Generic, - Iterable, - Iterator, - List, - MutableSequence, - Optional, - TypeVar, - Union, - overload, -) - -_T = TypeVar("_T") -_Arg = Union[List[_T], Iterable[_T]] - -class FrozenList(MutableSequence[_T], Generic[_T]): - def __init__(self, items: Optional[_Arg[_T]] = ...) -> None: ... - @property - def frozen(self) -> bool: ... - def freeze(self) -> None: ... - @overload - def __getitem__(self, i: int) -> _T: ... - @overload - def __getitem__(self, s: slice) -> FrozenList[_T]: ... - @overload - def __setitem__(self, i: int, o: _T) -> None: ... - @overload - def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... - @overload - def __delitem__(self, i: int) -> None: ... - @overload - def __delitem__(self, i: slice) -> None: ... - def __len__(self) -> int: ... - def __iter__(self) -> Iterator[_T]: ... - def __reversed__(self) -> Iterator[_T]: ... - def __eq__(self, other: object) -> bool: ... - def __le__(self, other: FrozenList[_T]) -> bool: ... - def __ne__(self, other: object) -> bool: ... - def __lt__(self, other: FrozenList[_T]) -> bool: ... - def __ge__(self, other: FrozenList[_T]) -> bool: ... - def __gt__(self, other: FrozenList[_T]) -> bool: ... - def insert(self, pos: int, item: _T) -> None: ... - def __repr__(self) -> str: ... - -# types for C accelerators are the same -CFrozenList = PyFrozenList = FrozenList diff --git a/dist/ba_data/python-site-packages/aiohttp/hdrs.py b/dist/ba_data/python-site-packages/aiohttp/hdrs.py index f04a5457..2f1f5e02 100644 --- a/dist/ba_data/python-site-packages/aiohttp/hdrs.py +++ b/dist/ba_data/python-site-packages/aiohttp/hdrs.py @@ -2,21 +2,22 @@ # After changing the file content call ./tools/gen.py # to regenerate the headers parser +from typing import Final, Set from multidict import istr -METH_ANY = "*" -METH_CONNECT = "CONNECT" -METH_HEAD = "HEAD" -METH_GET = "GET" -METH_DELETE = "DELETE" -METH_OPTIONS = "OPTIONS" -METH_PATCH = "PATCH" -METH_POST = "POST" -METH_PUT = "PUT" -METH_TRACE = "TRACE" +METH_ANY: Final[str] = "*" +METH_CONNECT: Final[str] = "CONNECT" +METH_HEAD: Final[str] = "HEAD" +METH_GET: Final[str] = "GET" +METH_DELETE: Final[str] = "DELETE" +METH_OPTIONS: Final[str] = "OPTIONS" +METH_PATCH: Final[str] = "PATCH" +METH_POST: Final[str] = "POST" +METH_PUT: Final[str] = "PUT" +METH_TRACE: Final[str] = "TRACE" -METH_ALL = { +METH_ALL: Final[Set[str]] = { METH_CONNECT, METH_HEAD, METH_GET, @@ -28,81 +29,80 @@ METH_TRACE, } - -ACCEPT = istr("Accept") -ACCEPT_CHARSET = istr("Accept-Charset") -ACCEPT_ENCODING = istr("Accept-Encoding") -ACCEPT_LANGUAGE = istr("Accept-Language") -ACCEPT_RANGES = istr("Accept-Ranges") -ACCESS_CONTROL_MAX_AGE = istr("Access-Control-Max-Age") -ACCESS_CONTROL_ALLOW_CREDENTIALS = istr("Access-Control-Allow-Credentials") -ACCESS_CONTROL_ALLOW_HEADERS = istr("Access-Control-Allow-Headers") -ACCESS_CONTROL_ALLOW_METHODS = istr("Access-Control-Allow-Methods") -ACCESS_CONTROL_ALLOW_ORIGIN = istr("Access-Control-Allow-Origin") -ACCESS_CONTROL_EXPOSE_HEADERS = istr("Access-Control-Expose-Headers") -ACCESS_CONTROL_REQUEST_HEADERS = istr("Access-Control-Request-Headers") -ACCESS_CONTROL_REQUEST_METHOD = istr("Access-Control-Request-Method") -AGE = istr("Age") -ALLOW = istr("Allow") -AUTHORIZATION = istr("Authorization") -CACHE_CONTROL = istr("Cache-Control") -CONNECTION = istr("Connection") -CONTENT_DISPOSITION = istr("Content-Disposition") -CONTENT_ENCODING = istr("Content-Encoding") -CONTENT_LANGUAGE = istr("Content-Language") -CONTENT_LENGTH = istr("Content-Length") -CONTENT_LOCATION = istr("Content-Location") -CONTENT_MD5 = istr("Content-MD5") -CONTENT_RANGE = istr("Content-Range") -CONTENT_TRANSFER_ENCODING = istr("Content-Transfer-Encoding") -CONTENT_TYPE = istr("Content-Type") -COOKIE = istr("Cookie") -DATE = istr("Date") -DESTINATION = istr("Destination") -DIGEST = istr("Digest") -ETAG = istr("Etag") -EXPECT = istr("Expect") -EXPIRES = istr("Expires") -FORWARDED = istr("Forwarded") -FROM = istr("From") -HOST = istr("Host") -IF_MATCH = istr("If-Match") -IF_MODIFIED_SINCE = istr("If-Modified-Since") -IF_NONE_MATCH = istr("If-None-Match") -IF_RANGE = istr("If-Range") -IF_UNMODIFIED_SINCE = istr("If-Unmodified-Since") -KEEP_ALIVE = istr("Keep-Alive") -LAST_EVENT_ID = istr("Last-Event-ID") -LAST_MODIFIED = istr("Last-Modified") -LINK = istr("Link") -LOCATION = istr("Location") -MAX_FORWARDS = istr("Max-Forwards") -ORIGIN = istr("Origin") -PRAGMA = istr("Pragma") -PROXY_AUTHENTICATE = istr("Proxy-Authenticate") -PROXY_AUTHORIZATION = istr("Proxy-Authorization") -RANGE = istr("Range") -REFERER = istr("Referer") -RETRY_AFTER = istr("Retry-After") -SEC_WEBSOCKET_ACCEPT = istr("Sec-WebSocket-Accept") -SEC_WEBSOCKET_VERSION = istr("Sec-WebSocket-Version") -SEC_WEBSOCKET_PROTOCOL = istr("Sec-WebSocket-Protocol") -SEC_WEBSOCKET_EXTENSIONS = istr("Sec-WebSocket-Extensions") -SEC_WEBSOCKET_KEY = istr("Sec-WebSocket-Key") -SEC_WEBSOCKET_KEY1 = istr("Sec-WebSocket-Key1") -SERVER = istr("Server") -SET_COOKIE = istr("Set-Cookie") -TE = istr("TE") -TRAILER = istr("Trailer") -TRANSFER_ENCODING = istr("Transfer-Encoding") -UPGRADE = istr("Upgrade") -URI = istr("URI") -USER_AGENT = istr("User-Agent") -VARY = istr("Vary") -VIA = istr("Via") -WANT_DIGEST = istr("Want-Digest") -WARNING = istr("Warning") -WWW_AUTHENTICATE = istr("WWW-Authenticate") -X_FORWARDED_FOR = istr("X-Forwarded-For") -X_FORWARDED_HOST = istr("X-Forwarded-Host") -X_FORWARDED_PROTO = istr("X-Forwarded-Proto") +ACCEPT: Final[istr] = istr("Accept") +ACCEPT_CHARSET: Final[istr] = istr("Accept-Charset") +ACCEPT_ENCODING: Final[istr] = istr("Accept-Encoding") +ACCEPT_LANGUAGE: Final[istr] = istr("Accept-Language") +ACCEPT_RANGES: Final[istr] = istr("Accept-Ranges") +ACCESS_CONTROL_MAX_AGE: Final[istr] = istr("Access-Control-Max-Age") +ACCESS_CONTROL_ALLOW_CREDENTIALS: Final[istr] = istr("Access-Control-Allow-Credentials") +ACCESS_CONTROL_ALLOW_HEADERS: Final[istr] = istr("Access-Control-Allow-Headers") +ACCESS_CONTROL_ALLOW_METHODS: Final[istr] = istr("Access-Control-Allow-Methods") +ACCESS_CONTROL_ALLOW_ORIGIN: Final[istr] = istr("Access-Control-Allow-Origin") +ACCESS_CONTROL_EXPOSE_HEADERS: Final[istr] = istr("Access-Control-Expose-Headers") +ACCESS_CONTROL_REQUEST_HEADERS: Final[istr] = istr("Access-Control-Request-Headers") +ACCESS_CONTROL_REQUEST_METHOD: Final[istr] = istr("Access-Control-Request-Method") +AGE: Final[istr] = istr("Age") +ALLOW: Final[istr] = istr("Allow") +AUTHORIZATION: Final[istr] = istr("Authorization") +CACHE_CONTROL: Final[istr] = istr("Cache-Control") +CONNECTION: Final[istr] = istr("Connection") +CONTENT_DISPOSITION: Final[istr] = istr("Content-Disposition") +CONTENT_ENCODING: Final[istr] = istr("Content-Encoding") +CONTENT_LANGUAGE: Final[istr] = istr("Content-Language") +CONTENT_LENGTH: Final[istr] = istr("Content-Length") +CONTENT_LOCATION: Final[istr] = istr("Content-Location") +CONTENT_MD5: Final[istr] = istr("Content-MD5") +CONTENT_RANGE: Final[istr] = istr("Content-Range") +CONTENT_TRANSFER_ENCODING: Final[istr] = istr("Content-Transfer-Encoding") +CONTENT_TYPE: Final[istr] = istr("Content-Type") +COOKIE: Final[istr] = istr("Cookie") +DATE: Final[istr] = istr("Date") +DESTINATION: Final[istr] = istr("Destination") +DIGEST: Final[istr] = istr("Digest") +ETAG: Final[istr] = istr("Etag") +EXPECT: Final[istr] = istr("Expect") +EXPIRES: Final[istr] = istr("Expires") +FORWARDED: Final[istr] = istr("Forwarded") +FROM: Final[istr] = istr("From") +HOST: Final[istr] = istr("Host") +IF_MATCH: Final[istr] = istr("If-Match") +IF_MODIFIED_SINCE: Final[istr] = istr("If-Modified-Since") +IF_NONE_MATCH: Final[istr] = istr("If-None-Match") +IF_RANGE: Final[istr] = istr("If-Range") +IF_UNMODIFIED_SINCE: Final[istr] = istr("If-Unmodified-Since") +KEEP_ALIVE: Final[istr] = istr("Keep-Alive") +LAST_EVENT_ID: Final[istr] = istr("Last-Event-ID") +LAST_MODIFIED: Final[istr] = istr("Last-Modified") +LINK: Final[istr] = istr("Link") +LOCATION: Final[istr] = istr("Location") +MAX_FORWARDS: Final[istr] = istr("Max-Forwards") +ORIGIN: Final[istr] = istr("Origin") +PRAGMA: Final[istr] = istr("Pragma") +PROXY_AUTHENTICATE: Final[istr] = istr("Proxy-Authenticate") +PROXY_AUTHORIZATION: Final[istr] = istr("Proxy-Authorization") +RANGE: Final[istr] = istr("Range") +REFERER: Final[istr] = istr("Referer") +RETRY_AFTER: Final[istr] = istr("Retry-After") +SEC_WEBSOCKET_ACCEPT: Final[istr] = istr("Sec-WebSocket-Accept") +SEC_WEBSOCKET_VERSION: Final[istr] = istr("Sec-WebSocket-Version") +SEC_WEBSOCKET_PROTOCOL: Final[istr] = istr("Sec-WebSocket-Protocol") +SEC_WEBSOCKET_EXTENSIONS: Final[istr] = istr("Sec-WebSocket-Extensions") +SEC_WEBSOCKET_KEY: Final[istr] = istr("Sec-WebSocket-Key") +SEC_WEBSOCKET_KEY1: Final[istr] = istr("Sec-WebSocket-Key1") +SERVER: Final[istr] = istr("Server") +SET_COOKIE: Final[istr] = istr("Set-Cookie") +TE: Final[istr] = istr("TE") +TRAILER: Final[istr] = istr("Trailer") +TRANSFER_ENCODING: Final[istr] = istr("Transfer-Encoding") +UPGRADE: Final[istr] = istr("Upgrade") +URI: Final[istr] = istr("URI") +USER_AGENT: Final[istr] = istr("User-Agent") +VARY: Final[istr] = istr("Vary") +VIA: Final[istr] = istr("Via") +WANT_DIGEST: Final[istr] = istr("Want-Digest") +WARNING: Final[istr] = istr("Warning") +WWW_AUTHENTICATE: Final[istr] = istr("WWW-Authenticate") +X_FORWARDED_FOR: Final[istr] = istr("X-Forwarded-For") +X_FORWARDED_HOST: Final[istr] = istr("X-Forwarded-Host") +X_FORWARDED_PROTO: Final[istr] = istr("X-Forwarded-Proto") diff --git a/dist/ba_data/python-site-packages/aiohttp/helpers.py b/dist/ba_data/python-site-packages/aiohttp/helpers.py index bbf5f129..284033b7 100644 --- a/dist/ba_data/python-site-packages/aiohttp/helpers.py +++ b/dist/ba_data/python-site-packages/aiohttp/helpers.py @@ -3,8 +3,9 @@ import asyncio import base64 import binascii -import cgi +import contextlib import datetime +import enum import functools import inspect import netrc @@ -17,12 +18,15 @@ import weakref from collections import namedtuple from contextlib import suppress +from email.parser import HeaderParser +from email.utils import parsedate from math import ceil from pathlib import Path from types import TracebackType from typing import ( Any, Callable, + ContextManager, Dict, Generator, Generic, @@ -32,66 +36,49 @@ Mapping, Optional, Pattern, - Set, + Protocol, Tuple, Type, TypeVar, Union, - cast, + get_args, + overload, ) from urllib.parse import quote -from urllib.request import getproxies +from urllib.request import getproxies, proxy_bypass -import async_timeout import attr -from multidict import MultiDict, MultiDictProxy -from typing_extensions import Protocol +from multidict import MultiDict, MultiDictProxy, MultiMapping from yarl import URL from . import hdrs from .log import client_logger, internal_logger -from .typedefs import PathLike # noqa -__all__ = ("BasicAuth", "ChainMapProxy") +if sys.version_info >= (3, 11): + import asyncio as async_timeout +else: + import async_timeout -PY_36 = sys.version_info >= (3, 6) -PY_37 = sys.version_info >= (3, 7) -PY_38 = sys.version_info >= (3, 8) +__all__ = ("BasicAuth", "ChainMapProxy", "ETag") -if not PY_37: - import idna_ssl +IS_MACOS = platform.system() == "Darwin" +IS_WINDOWS = platform.system() == "Windows" - idna_ssl.patch_match_hostname() - -try: - from typing import ContextManager -except ImportError: - from typing_extensions import ContextManager - - -def all_tasks( - loop: Optional[asyncio.AbstractEventLoop] = None, -) -> Set["asyncio.Task[Any]"]: - tasks = list(asyncio.Task.all_tasks(loop)) - return {t for t in tasks if not t.done()} - - -if PY_37: - all_tasks = getattr(asyncio, "all_tasks") +PY_310 = sys.version_info >= (3, 10) +PY_311 = sys.version_info >= (3, 11) _T = TypeVar("_T") _S = TypeVar("_S") +_SENTINEL = enum.Enum("_SENTINEL", "sentinel") +sentinel = _SENTINEL.sentinel -sentinel = object() # type: Any -NO_EXTENSIONS = bool(os.environ.get("AIOHTTP_NO_EXTENSIONS")) # type: bool +NO_EXTENSIONS = bool(os.environ.get("AIOHTTP_NO_EXTENSIONS")) -# N.B. sys.flags.dev_mode is available on Python 3.7+, use getattr -# for compatibility with older versions -DEBUG = getattr(sys.flags, "dev_mode", False) or ( +DEBUG = sys.flags.dev_mode or ( not sys.flags.ignore_environment and bool(os.environ.get("PYTHONASYNCIODEBUG")) -) # type: bool +) CHAR = {chr(i) for i in range(0, 128)} @@ -197,7 +184,9 @@ def strip_auth_from_url(url: URL) -> Tuple[URL, Optional[BasicAuth]]: def netrc_from_env() -> Optional[netrc.netrc]: - """Attempt to load the netrc file from the path specified by the env-var + """Load netrc from file. + + Attempt to load it from the path specified by the env-var NETRC or in the default location in the user's home directory. Returns None if it couldn't be found or fails to parse. @@ -218,17 +207,18 @@ def netrc_from_env() -> Optional[netrc.netrc]: ) return None - netrc_path = home_dir / ( - "_netrc" if platform.system() == "Windows" else ".netrc" - ) + netrc_path = home_dir / ("_netrc" if IS_WINDOWS else ".netrc") try: return netrc.netrc(str(netrc_path)) except netrc.NetrcParseError as e: client_logger.warning("Could not parse .netrc file: %s", e) except OSError as e: + netrc_exists = False + with contextlib.suppress(OSError): + netrc_exists = netrc_path.is_file() # we couldn't read the file (doesn't exist, permissions, etc.) - if netrc_env or netrc_path.is_file(): + if netrc_env or netrc_exists: # only warn if the environment wanted us to load it, # or it appears like the default file does actually exist client_logger.warning("Could not read .netrc file: %s", e) @@ -242,27 +232,57 @@ class ProxyInfo: proxy_auth: Optional[BasicAuth] +def basicauth_from_netrc(netrc_obj: Optional[netrc.netrc], host: str) -> BasicAuth: + """ + Return :py:class:`~aiohttp.BasicAuth` credentials for ``host`` from ``netrc_obj``. + + :raises LookupError: if ``netrc_obj`` is :py:data:`None` or if no + entry is found for the ``host``. + """ + if netrc_obj is None: + raise LookupError("No .netrc file found") + auth_from_netrc = netrc_obj.authenticators(host) + + if auth_from_netrc is None: + raise LookupError(f"No entry for {host!s} found in the `.netrc` file.") + login, account, password = auth_from_netrc + + # TODO(PY311): username = login or account + # Up to python 3.10, account could be None if not specified, + # and login will be empty string if not specified. From 3.11, + # login and account will be empty string if not specified. + username = login if (login or account is None) else account + + # TODO(PY311): Remove this, as password will be empty string + # if not specified + if password is None: + password = "" + + return BasicAuth(username, password) + + def proxies_from_env() -> Dict[str, ProxyInfo]: - proxy_urls = {k: URL(v) for k, v in getproxies().items() if k in ("http", "https")} + proxy_urls = { + k: URL(v) + for k, v in getproxies().items() + if k in ("http", "https", "ws", "wss") + } netrc_obj = netrc_from_env() stripped = {k: strip_auth_from_url(v) for k, v in proxy_urls.items()} ret = {} for proto, val in stripped.items(): proxy, auth = val - if proxy.scheme == "https": - client_logger.warning("HTTPS proxies %s are not supported, ignoring", proxy) + if proxy.scheme in ("https", "wss"): + client_logger.warning( + "%s proxies %s are not supported, ignoring", proxy.scheme.upper(), proxy + ) continue if netrc_obj and auth is None: - auth_from_netrc = None if proxy.host is not None: - auth_from_netrc = netrc_obj.authenticators(proxy.host) - if auth_from_netrc is not None: - # auth_from_netrc is a (`user`, `account`, `password`) tuple, - # `user` and `account` both can be username, - # if `user` is None, use `account` - *logins, password = auth_from_netrc - login = logins[0] if logins[0] else logins[-1] - auth = BasicAuth(cast(str, login), cast(str, password)) + try: + auth = basicauth_from_netrc(netrc_obj, proxy.host) + except LookupError: + auth = None ret[proto] = ProxyInfo(proxy, auth) return ret @@ -270,10 +290,7 @@ def proxies_from_env() -> Dict[str, ProxyInfo]: def current_task( loop: Optional[asyncio.AbstractEventLoop] = None, ) -> "Optional[asyncio.Task[Any]]": - if PY_37: - return asyncio.current_task(loop=loop) - else: - return asyncio.Task.current_task(loop=loop) + return asyncio.current_task(loop=loop) def get_running_loop( @@ -297,11 +314,25 @@ def get_running_loop( def isasyncgenfunction(obj: Any) -> bool: func = getattr(inspect, "isasyncgenfunction", None) if func is not None: - return func(obj) + return func(obj) # type: ignore[no-any-return] else: return False +def get_env_proxy_for_url(url: URL) -> Tuple[URL, Optional[BasicAuth]]: + """Get a permitted proxy for the given URL from the env.""" + if url.host is not None and proxy_bypass(url.host): + raise LookupError(f"Proxying is disallowed for `{url.host!r}`") + + proxies_in_env = proxies_from_env() + try: + proxy_info = proxies_in_env[url.scheme] + except KeyError: + raise LookupError(f"No proxies found for `{url!s}` in the env") + else: + return proxy_info.proxy, proxy_info.proxy_auth + + @attr.s(auto_attribs=True, frozen=True, slots=True) class MimeType: type: str @@ -331,27 +362,19 @@ def parse_mimetype(mimetype: str) -> MimeType: ) parts = mimetype.split(";") - params = MultiDict() # type: MultiDict[str] + params: MultiDict[str] = MultiDict() for item in parts[1:]: if not item: continue - key, value = cast( - Tuple[str, str], item.split("=", 1) if "=" in item else (item, "") - ) + key, _, value = item.partition("=") params.add(key.lower().strip(), value.strip(' "')) fulltype = parts[0].strip().lower() if fulltype == "*": fulltype = "*/*" - mtype, stype = ( - cast(Tuple[str, str], fulltype.split("/", 1)) - if "/" in fulltype - else (fulltype, "") - ) - stype, suffix = ( - cast(Tuple[str, str], stype.split("+", 1)) if "+" in stype else (stype, "") - ) + mtype, _, stype = fulltype.partition("/") + stype, _, suffix = stype.partition("+") return MimeType( type=mtype, subtype=stype, suffix=suffix, parameters=MultiDictProxy(params) @@ -365,14 +388,41 @@ def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]: return default +not_qtext_re = re.compile(r"[^\041\043-\133\135-\176]") +QCONTENT = {chr(i) for i in range(0x20, 0x7F)} | {"\t"} + + +def quoted_string(content: str) -> str: + """Return 7-bit content as quoted-string. + + Format content into a quoted-string as defined in RFC5322 for + Internet Message Format. Notice that this is not the 8-bit HTTP + format, but the 7-bit email format. Content must be in usascii or + a ValueError is raised. + """ + if not (QCONTENT > set(content)): + raise ValueError(f"bad content for quoted-string {content!r}") + return not_qtext_re.sub(lambda x: "\\" + x.group(0), content) + + def content_disposition_header( - disptype: str, quote_fields: bool = True, **params: str + disptype: str, quote_fields: bool = True, _charset: str = "utf-8", **params: str ) -> str: - """Sets ``Content-Disposition`` header. + """Sets ``Content-Disposition`` header for MIME. + + This is the MIME payload Content-Disposition header from RFC 2183 + and RFC 7579 section 4.2, not the HTTP Content-Disposition from + RFC 6266. disptype is a disposition type: inline, attachment, form-data. Should be valid extension token (see RFC 2183) + quote_fields performs value quoting to 7-bit MIME headers + according to RFC 7578. Set to quote_fields to False if recipient + can take 8-bit file names and field values. + + _charset specifies the charset to use when quote_fields is True. + params is a dict with disposition params. """ if not disptype or not (TOKEN > set(disptype)): @@ -386,26 +436,40 @@ def content_disposition_header( raise ValueError( "bad content disposition parameter" " {!r}={!r}".format(key, val) ) - qval = quote(val, "") if quote_fields else val - lparams.append((key, '"%s"' % qval)) - if key == "filename": - lparams.append(("filename*", "utf-8''" + qval)) + if quote_fields: + if key.lower() == "filename": + qval = quote(val, "", encoding=_charset) + lparams.append((key, '"%s"' % qval)) + else: + try: + qval = quoted_string(val) + except ValueError: + qval = "".join( + (_charset, "''", quote(val, "", encoding=_charset)) + ) + lparams.append((key + "*", qval)) + else: + lparams.append((key, '"%s"' % qval)) + else: + qval = val.replace("\\", "\\\\").replace('"', '\\"') + lparams.append((key, '"%s"' % qval)) sparams = "; ".join("=".join(pair) for pair in lparams) value = "; ".join((value, sparams)) return value -class _TSelf(Protocol): - _cache: Dict[str, Any] +class _TSelf(Protocol, Generic[_T]): + _cache: Dict[str, _T] class reify(Generic[_T]): - """Use as a class method decorator. It operates almost exactly like + """Use as a class method decorator. + + It operates almost exactly like the Python `@property` decorator, but it puts the result of the method it decorates into the instance dict after the first call, effectively replacing the function it decorates with an instance variable. It is, in Python parlance, a data descriptor. - """ def __init__(self, wrapped: Callable[..., _T]) -> None: @@ -413,7 +477,7 @@ def __init__(self, wrapped: Callable[..., _T]) -> None: self.__doc__ = wrapped.__doc__ self.name = wrapped.__name__ - def __get__(self, inst: _TSelf, owner: Optional[Type[Any]] = None) -> _T: + def __get__(self, inst: _TSelf[_T], owner: Optional[Type[Any]] = None) -> _T: try: try: return inst._cache[self.name] @@ -426,7 +490,7 @@ def __get__(self, inst: _TSelf, owner: Optional[Type[Any]] = None) -> _T: return self raise - def __set__(self, inst: _TSelf, value: _T) -> None: + def __set__(self, inst: _TSelf[_T], value: _T) -> None: raise AttributeError("reified property is read-only") @@ -436,7 +500,7 @@ def __set__(self, inst: _TSelf, value: _T) -> None: from ._helpers import reify as reify_c if not NO_EXTENSIONS: - reify = reify_c # type: ignore + reify = reify_c # type: ignore[misc,assignment] except ImportError: pass @@ -470,7 +534,7 @@ def _is_ip_address( elif isinstance(host, (bytes, bytearray, memoryview)): return bool(regexb.match(host)) else: - raise TypeError("{} [{}] is not a str or bytes".format(host, type(host))) + raise TypeError(f"{host} [{type(host)}] is not a str or bytes") is_ipv4_address = functools.partial(_is_ip_address, _ipv4_regex, _ipv4_regexb) @@ -481,14 +545,7 @@ def is_ip_address(host: Optional[Union[str, bytes, bytearray, memoryview]]) -> b return is_ipv4_address(host) or is_ipv6_address(host) -def next_whole_second() -> datetime.datetime: - """Return current time rounded up to the next whole second.""" - return datetime.datetime.now(datetime.timezone.utc).replace( - microsecond=0 - ) + datetime.timedelta(seconds=0) - - -_cached_current_datetime = None # type: Optional[int] +_cached_current_datetime: Optional[int] = None _cached_formatted_datetime = "" @@ -532,7 +589,7 @@ def rfc822_formatted_time() -> str: return _cached_formatted_datetime -def _weakref_handle(info): # type: ignore +def _weakref_handle(info: "Tuple[weakref.ref[object], str]") -> None: ref, name = info ob = ref() if ob is not None: @@ -540,34 +597,51 @@ def _weakref_handle(info): # type: ignore getattr(ob, name)() -def weakref_handle(ob, name, timeout, loop): # type: ignore +def weakref_handle( + ob: object, + name: str, + timeout: float, + loop: asyncio.AbstractEventLoop, + timeout_ceil_threshold: float = 5, +) -> Optional[asyncio.TimerHandle]: if timeout is not None and timeout > 0: when = loop.time() + timeout - if timeout >= 5: + if timeout >= timeout_ceil_threshold: when = ceil(when) return loop.call_at(when, _weakref_handle, (weakref.ref(ob), name)) + return None -def call_later(cb, timeout, loop): # type: ignore +def call_later( + cb: Callable[[], Any], + timeout: float, + loop: asyncio.AbstractEventLoop, + timeout_ceil_threshold: float = 5, +) -> Optional[asyncio.TimerHandle]: if timeout is not None and timeout > 0: when = loop.time() + timeout - if timeout > 5: + if timeout > timeout_ceil_threshold: when = ceil(when) return loop.call_at(when, cb) + return None class TimeoutHandle: - """ Timeout handle """ + """Timeout handle""" def __init__( - self, loop: asyncio.AbstractEventLoop, timeout: Optional[float] + self, + loop: asyncio.AbstractEventLoop, + timeout: Optional[float], + ceil_threshold: float = 5, ) -> None: self._timeout = timeout self._loop = loop - self._callbacks = ( - [] - ) # type: List[Tuple[Callable[..., None], Tuple[Any, ...], Dict[str, Any]]] + self._ceil_threshold = ceil_threshold + self._callbacks: List[ + Tuple[Callable[..., None], Tuple[Any, ...], Dict[str, Any]] + ] = [] def register( self, callback: Callable[..., None], *args: Any, **kwargs: Any @@ -581,7 +655,7 @@ def start(self) -> Optional[asyncio.Handle]: timeout = self._timeout if timeout is not None and timeout > 0: when = self._loop.time() + timeout - if timeout >= 5: + if timeout >= self._ceil_threshold: when = ceil(when) return self._loop.call_at(when, self.__call__) else: @@ -604,7 +678,8 @@ def __call__(self) -> None: class BaseTimerContext(ContextManager["BaseTimerContext"]): - pass + def assert_timeout(self) -> None: + """Raise TimeoutError if timeout has been exceeded.""" class TimerNoop(BaseTimerContext): @@ -621,13 +696,18 @@ def __exit__( class TimerContext(BaseTimerContext): - """ Low resolution timeout context manager """ + """Low resolution timeout context manager""" def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop - self._tasks = [] # type: List[asyncio.Task[Any]] + self._tasks: List[asyncio.Task[Any]] = [] self._cancelled = False + def assert_timeout(self) -> None: + """Raise TimeoutError if timer has already been cancelled.""" + if self._cancelled: + raise asyncio.TimeoutError from None + def __enter__(self) -> BaseTimerContext: task = current_task(loop=self._loop) @@ -637,7 +717,6 @@ def __enter__(self) -> BaseTimerContext: ) if self._cancelled: - task.cancel() raise asyncio.TimeoutError from None self._tasks.append(task) @@ -664,60 +743,61 @@ def timeout(self) -> None: self._cancelled = True -class CeilTimeout(async_timeout.timeout): - def __enter__(self) -> async_timeout.timeout: - if self._timeout is not None: - self._task = current_task(loop=self._loop) - if self._task is None: - raise RuntimeError( - "Timeout context manager should be used inside a task" - ) - now = self._loop.time() - delay = self._timeout - when = now + delay - if delay > 5: - when = ceil(when) - self._cancel_handler = self._loop.call_at(when, self._cancel_task) - return self +def ceil_timeout( + delay: Optional[float], ceil_threshold: float = 5 +) -> async_timeout.Timeout: + if delay is None or delay <= 0: + return async_timeout.timeout(None) + loop = get_running_loop() + now = loop.time() + when = now + delay + if delay > ceil_threshold: + when = ceil(when) + return async_timeout.timeout_at(when) -class HeadersMixin: +class HeadersMixin: ATTRS = frozenset(["_content_type", "_content_dict", "_stored_content_type"]) - _content_type = None # type: Optional[str] - _content_dict = None # type: Optional[Dict[str, str]] - _stored_content_type = sentinel + _headers: MultiMapping[str] - def _parse_content_type(self, raw: str) -> None: + _content_type: Optional[str] = None + _content_dict: Optional[Dict[str, str]] = None + _stored_content_type: Union[str, None, _SENTINEL] = sentinel + + def _parse_content_type(self, raw: Optional[str]) -> None: self._stored_content_type = raw if raw is None: # default value according to RFC 2616 self._content_type = "application/octet-stream" self._content_dict = {} else: - self._content_type, self._content_dict = cgi.parse_header(raw) + msg = HeaderParser().parsestr("Content-Type: " + raw) + self._content_type = msg.get_content_type() + params = msg.get_params(()) + self._content_dict = dict(params[1:]) # First element is content type again @property def content_type(self) -> str: """The value of content part for Content-Type HTTP header.""" - raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore + raw = self._headers.get(hdrs.CONTENT_TYPE) if self._stored_content_type != raw: self._parse_content_type(raw) - return self._content_type # type: ignore + return self._content_type # type: ignore[return-value] @property def charset(self) -> Optional[str]: """The value of charset part for Content-Type HTTP header.""" - raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore + raw = self._headers.get(hdrs.CONTENT_TYPE) if self._stored_content_type != raw: self._parse_content_type(raw) - return self._content_dict.get("charset") # type: ignore + return self._content_dict.get("charset") # type: ignore[union-attr] @property def content_length(self) -> Optional[int]: """The value of Content-Length HTTP header.""" - content_length = self._headers.get(hdrs.CONTENT_LENGTH) # type: ignore + content_length = self._headers.get(hdrs.CONTENT_LENGTH) if content_length is not None: return int(content_length) @@ -730,15 +810,92 @@ def set_result(fut: "asyncio.Future[_T]", result: _T) -> None: fut.set_result(result) -def set_exception(fut: "asyncio.Future[_T]", exc: BaseException) -> None: - if not fut.done(): - fut.set_exception(exc) +_EXC_SENTINEL = BaseException() + + +class ErrorableProtocol(Protocol): + def set_exception( + self, + exc: BaseException, + exc_cause: BaseException = ..., + ) -> None: + ... # pragma: no cover + + +def set_exception( + fut: "asyncio.Future[_T] | ErrorableProtocol", + exc: BaseException, + exc_cause: BaseException = _EXC_SENTINEL, +) -> None: + """Set future exception. + + If the future is marked as complete, this function is a no-op. + + :param exc_cause: An exception that is a direct cause of ``exc``. + Only set if provided. + """ + if asyncio.isfuture(fut) and fut.done(): + return + + exc_is_sentinel = exc_cause is _EXC_SENTINEL + exc_causes_itself = exc is exc_cause + if not exc_is_sentinel and not exc_causes_itself: + exc.__cause__ = exc_cause + + fut.set_exception(exc) -class ChainMapProxy(Mapping[str, Any]): +@functools.total_ordering +class AppKey(Generic[_T]): + """Keys for static typing support in Application.""" + + __slots__ = ("_name", "_t", "__orig_class__") + + # This may be set by Python when instantiating with a generic type. We need to + # support this, in order to support types that are not concrete classes, + # like Iterable, which can't be passed as the second parameter to __init__. + __orig_class__: Type[object] + + def __init__(self, name: str, t: Optional[Type[_T]] = None): + # Prefix with module name to help deduplicate key names. + frame = inspect.currentframe() + while frame: + if frame.f_code.co_name == "": + module: str = frame.f_globals["__name__"] + break + frame = frame.f_back + + self._name = module + "." + name + self._t = t + + def __lt__(self, other: object) -> bool: + if isinstance(other, AppKey): + return self._name < other._name + return True # Order AppKey above other types. + + def __repr__(self) -> str: + t = self._t + if t is None: + with suppress(AttributeError): + # Set to type arg. + t = get_args(self.__orig_class__)[0] + + if t is None: + t_repr = "<>" + elif isinstance(t, type): + if t.__module__ == "builtins": + t_repr = t.__qualname__ + else: + t_repr = f"{t.__module__}.{t.__qualname__}" + else: + t_repr = repr(t) + return f"" + + +class ChainMapProxy(Mapping[Union[str, AppKey[Any]], Any]): __slots__ = ("_maps",) - def __init__(self, maps: Iterable[Mapping[str, Any]]) -> None: + def __init__(self, maps: Iterable[Mapping[Union[str, AppKey[Any]], Any]]) -> None: self._maps = tuple(maps) def __init_subclass__(cls) -> None: @@ -747,7 +904,15 @@ def __init_subclass__(cls) -> None: "is forbidden".format(cls.__name__) ) + @overload # type: ignore[override] + def __getitem__(self, key: AppKey[_T]) -> _T: + ... + + @overload def __getitem__(self, key: str) -> Any: + ... + + def __getitem__(self, key: Union[str, AppKey[_T]]) -> Any: for mapping in self._maps: try: return mapping[key] @@ -755,15 +920,30 @@ def __getitem__(self, key: str) -> Any: pass raise KeyError(key) - def get(self, key: str, default: Any = None) -> Any: - return self[key] if key in self else default + @overload # type: ignore[override] + def get(self, key: AppKey[_T], default: _S) -> Union[_T, _S]: + ... + + @overload + def get(self, key: AppKey[_T], default: None = ...) -> Optional[_T]: + ... + + @overload + def get(self, key: str, default: Any = ...) -> Any: + ... + + def get(self, key: Union[str, AppKey[_T]], default: Any = None) -> Any: + try: + return self[key] + except KeyError: + return default def __len__(self) -> int: # reuses stored hash values if possible - return len(set().union(*self._maps)) # type: ignore + return len(set().union(*self._maps)) - def __iter__(self) -> Iterator[str]: - d = {} # type: Dict[str, Any] + def __iter__(self) -> Iterator[Union[str, AppKey[Any]]]: + d: Dict[Union[str, AppKey[Any]], Any] = {} for mapping in reversed(self._maps): # reuses stored hash values if possible d.update(mapping) @@ -778,3 +958,72 @@ def __bool__(self) -> bool: def __repr__(self) -> str: content = ", ".join(map(repr, self._maps)) return f"ChainMapProxy({content})" + + +# https://tools.ietf.org/html/rfc7232#section-2.3 +_ETAGC = r"[!\x23-\x7E\x80-\xff]+" +_ETAGC_RE = re.compile(_ETAGC) +_QUOTED_ETAG = rf'(W/)?"({_ETAGC})"' +QUOTED_ETAG_RE = re.compile(_QUOTED_ETAG) +LIST_QUOTED_ETAG_RE = re.compile(rf"({_QUOTED_ETAG})(?:\s*,\s*|$)|(.)") + +ETAG_ANY = "*" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ETag: + value: str + is_weak: bool = False + + +def validate_etag_value(value: str) -> None: + if value != ETAG_ANY and not _ETAGC_RE.fullmatch(value): + raise ValueError( + f"Value {value!r} is not a valid etag. Maybe it contains '\"'?" + ) + + +def parse_http_date(date_str: Optional[str]) -> Optional[datetime.datetime]: + """Process a date string, return a datetime object""" + if date_str is not None: + timetuple = parsedate(date_str) + if timetuple is not None: + with suppress(ValueError): + return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) + return None + + +def must_be_empty_body(method: str, code: int) -> bool: + """Check if a request must return an empty body.""" + return ( + status_code_must_be_empty_body(code) + or method_must_be_empty_body(method) + or (200 <= code < 300 and method.upper() == hdrs.METH_CONNECT) + ) + + +def method_must_be_empty_body(method: str) -> bool: + """Check if a method must return an empty body.""" + # https://datatracker.ietf.org/doc/html/rfc9112#section-6.3-2.1 + # https://datatracker.ietf.org/doc/html/rfc9112#section-6.3-2.2 + return method.upper() == hdrs.METH_HEAD + + +def status_code_must_be_empty_body(code: int) -> bool: + """Check if a status code must return an empty body.""" + # https://datatracker.ietf.org/doc/html/rfc9112#section-6.3-2.1 + return code in {204, 304} or 100 <= code < 200 + + +def should_remove_content_length(method: str, code: int) -> bool: + """Check if a Content-Length header should be removed. + + This should always be a subset of must_be_empty_body + """ + # https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6-8 + # https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4.5-4 + return ( + code in {204, 304} + or 100 <= code < 200 + or (200 <= code < 300 and method.upper() == hdrs.METH_CONNECT) + ) diff --git a/dist/ba_data/python-site-packages/aiohttp/http.py b/dist/ba_data/python-site-packages/aiohttp/http.py index 415ffbf5..a1feae2d 100644 --- a/dist/ba_data/python-site-packages/aiohttp/http.py +++ b/dist/ba_data/python-site-packages/aiohttp/http.py @@ -1,5 +1,5 @@ -import http.server import sys +from http import HTTPStatus from typing import Mapping, Tuple from . import __version__ @@ -63,10 +63,10 @@ ) -SERVER_SOFTWARE = "Python/{0[0]}.{0[1]} aiohttp/{1}".format( +SERVER_SOFTWARE: str = "Python/{0[0]}.{0[1]} aiohttp/{1}".format( sys.version_info, __version__ -) # type: str +) -RESPONSES = ( - http.server.BaseHTTPRequestHandler.responses -) # type: Mapping[int, Tuple[str, str]] +RESPONSES: Mapping[int, Tuple[str, str]] = { + v: (v.phrase, v.description) for v in HTTPStatus.__members__.values() +} diff --git a/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py b/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py index c885f80f..72eac3a3 100644 --- a/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py +++ b/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py @@ -1,6 +1,7 @@ """Low-level http related exceptions.""" +from textwrap import indent from typing import Optional, Union from .typedefs import _CIMultiDict @@ -35,10 +36,11 @@ def __init__( self.message = message def __str__(self) -> str: - return f"{self.code}, message={self.message!r}" + msg = indent(self.message, " ") + return f"{self.code}, message:\n{msg}" def __repr__(self) -> str: - return f"<{self.__class__.__name__}: {self}>" + return f"<{self.__class__.__name__}: {self.code}, message={self.message!r}>" class BadHttpMessage(HttpProcessingError): @@ -85,18 +87,17 @@ def __init__( class InvalidHeader(BadHttpMessage): def __init__(self, hdr: Union[bytes, str]) -> None: - if isinstance(hdr, bytes): - hdr = hdr.decode("utf-8", "surrogateescape") - super().__init__(f"Invalid HTTP Header: {hdr}") - self.hdr = hdr + hdr_s = hdr.decode(errors="backslashreplace") if isinstance(hdr, bytes) else hdr + super().__init__(f"Invalid HTTP header: {hdr!r}") + self.hdr = hdr_s self.args = (hdr,) class BadStatusLine(BadHttpMessage): - def __init__(self, line: str = "") -> None: + def __init__(self, line: str = "", error: Optional[str] = None) -> None: if not isinstance(line, str): line = repr(line) - super().__init__(f"Bad status line {line!r}") + super().__init__(error or f"Bad status line {line!r}") self.args = (line,) self.line = line diff --git a/dist/ba_data/python-site-packages/aiohttp/http_parser.py b/dist/ba_data/python-site-packages/aiohttp/http_parser.py index 71ba815a..01351191 100644 --- a/dist/ba_data/python-site-packages/aiohttp/http_parser.py +++ b/dist/ba_data/python-site-packages/aiohttp/http_parser.py @@ -1,23 +1,48 @@ import abc import asyncio -import collections import re import string -import zlib +from contextlib import suppress from enum import IntEnum -from typing import Any, List, Optional, Tuple, Type, Union +from typing import ( + Any, + ClassVar, + Final, + Generic, + List, + Literal, + NamedTuple, + Optional, + Pattern, + Set, + Tuple, + Type, + TypeVar, + Union, +) from multidict import CIMultiDict, CIMultiDictProxy, istr from yarl import URL from . import hdrs from .base_protocol import BaseProtocol -from .helpers import NO_EXTENSIONS, BaseTimerContext +from .compression_utils import HAS_BROTLI, BrotliDecompressor, ZLibDecompressor +from .helpers import ( + _EXC_SENTINEL, + DEBUG, + NO_EXTENSIONS, + BaseTimerContext, + method_must_be_empty_body, + set_exception, + status_code_must_be_empty_body, +) from .http_exceptions import ( + BadHttpMessage, BadStatusLine, ContentEncodingError, ContentLengthError, InvalidHeader, + InvalidURLError, LineTooLong, TransferEncodingError, ) @@ -26,14 +51,6 @@ from .streams import EMPTY_PAYLOAD, StreamReader from .typedefs import RawHeaders -try: - import brotli - - HAS_BROTLI = True -except ImportError: # pragma: no cover - HAS_BROTLI = False - - __all__ = ( "HeadersParser", "HttpParser", @@ -43,49 +60,50 @@ "RawResponseMessage", ) -ASCIISET = set(string.printable) +_SEP = Literal[b"\r\n", b"\n"] -# See https://tools.ietf.org/html/rfc7230#section-3.1.1 -# and https://tools.ietf.org/html/rfc7230#appendix-B +ASCIISET: Final[Set[str]] = set(string.printable) + +# See https://www.rfc-editor.org/rfc/rfc9110.html#name-overview +# and https://www.rfc-editor.org/rfc/rfc9110.html#name-tokens # # method = token # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / # "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA # token = 1*tchar -METHRE = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+") -VERSRE = re.compile(r"HTTP/(\d+).(\d+)") -HDRRE = re.compile(rb"[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]") +_TCHAR_SPECIALS: Final[str] = re.escape("!#$%&'*+-.^_`|~") +TOKENRE: Final[Pattern[str]] = re.compile(f"[0-9A-Za-z{_TCHAR_SPECIALS}]+") +VERSRE: Final[Pattern[str]] = re.compile(r"HTTP/(\d)\.(\d)", re.ASCII) +DIGITS: Final[Pattern[str]] = re.compile(r"\d+", re.ASCII) +HEXDIGITS: Final[Pattern[bytes]] = re.compile(rb"[0-9a-fA-F]+") -RawRequestMessage = collections.namedtuple( - "RawRequestMessage", - [ - "method", - "path", - "version", - "headers", - "raw_headers", - "should_close", - "compression", - "upgrade", - "chunked", - "url", - ], -) -RawResponseMessage = collections.namedtuple( - "RawResponseMessage", - [ - "version", - "code", - "reason", - "headers", - "raw_headers", - "should_close", - "compression", - "upgrade", - "chunked", - ], -) +class RawRequestMessage(NamedTuple): + method: str + path: str + version: HttpVersion + headers: "CIMultiDictProxy[str]" + raw_headers: RawHeaders + should_close: bool + compression: Optional[str] + upgrade: bool + chunked: bool + url: URL + + +class RawResponseMessage(NamedTuple): + version: HttpVersion + code: int + reason: str + headers: CIMultiDictProxy[str] + raw_headers: RawHeaders + should_close: bool + compression: Optional[str] + upgrade: bool + chunked: bool + + +_MsgT = TypeVar("_MsgT", RawRequestMessage, RawResponseMessage) class ParseState(IntEnum): @@ -110,15 +128,18 @@ def __init__( max_line_size: int = 8190, max_headers: int = 32768, max_field_size: int = 8190, + lax: bool = False, ) -> None: self.max_line_size = max_line_size self.max_headers = max_headers self.max_field_size = max_field_size + self._lax = lax def parse_headers( self, lines: List[bytes] ) -> Tuple["CIMultiDictProxy[str]", RawHeaders]: - headers = CIMultiDict() # type: CIMultiDict[str] + headers: CIMultiDict[str] = CIMultiDict() + # note: "raw" does not mean inclusion of OWS before/after the field value raw_headers = [] lines_idx = 1 @@ -132,18 +153,25 @@ def parse_headers( except ValueError: raise InvalidHeader(line) from None - bname = bname.strip(b" \t") - bvalue = bvalue.lstrip() - if HDRRE.search(bname): + if len(bname) == 0: raise InvalidHeader(bname) + + # https://www.rfc-editor.org/rfc/rfc9112.html#section-5.1-2 + if {bname[0], bname[-1]} & {32, 9}: # {" ", "\t"} + raise InvalidHeader(line) + + bvalue = bvalue.lstrip(b" \t") if len(bname) > self.max_field_size: raise LineTooLong( "request header name {}".format( - bname.decode("utf8", "xmlcharrefreplace") + bname.decode("utf8", "backslashreplace") ), str(self.max_field_size), str(len(bname)), ) + name = bname.decode("utf-8", "surrogateescape") + if not TOKENRE.fullmatch(name): + raise InvalidHeader(bname) header_length = len(bvalue) @@ -152,8 +180,9 @@ def parse_headers( line = lines[lines_idx] # consume continuation lines - continuation = line and line[0] in (32, 9) # (' ', '\t') + continuation = self._lax and line and line[0] in (32, 9) # (' ', '\t') + # Deprecated: https://www.rfc-editor.org/rfc/rfc9112.html#name-obsolete-line-folding if continuation: bvalue_lst = [bvalue] while continuation: @@ -161,7 +190,7 @@ def parse_headers( if header_length > self.max_field_size: raise LineTooLong( "request header field {}".format( - bname.decode("utf8", "xmlcharrefreplace") + bname.decode("utf8", "backslashreplace") ), str(self.max_field_size), str(header_length), @@ -182,28 +211,38 @@ def parse_headers( if header_length > self.max_field_size: raise LineTooLong( "request header field {}".format( - bname.decode("utf8", "xmlcharrefreplace") + bname.decode("utf8", "backslashreplace") ), str(self.max_field_size), str(header_length), ) - bvalue = bvalue.strip() - name = bname.decode("utf-8", "surrogateescape") + bvalue = bvalue.strip(b" \t") value = bvalue.decode("utf-8", "surrogateescape") + # https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5-5 + if "\n" in value or "\r" in value or "\x00" in value: + raise InvalidHeader(bvalue) + headers.add(name, value) raw_headers.append((bname, bvalue)) return (CIMultiDictProxy(headers), tuple(raw_headers)) -class HttpParser(abc.ABC): +def _is_supported_upgrade(headers: CIMultiDictProxy[str]) -> bool: + """Check if the upgrade header is supported.""" + return headers.get(hdrs.UPGRADE, "").lower() in {"tcp", "websocket"} + + +class HttpParser(abc.ABC, Generic[_MsgT]): + lax: ClassVar[bool] = False + def __init__( self, protocol: Optional[BaseProtocol] = None, loop: Optional[asyncio.AbstractEventLoop] = None, - limit: int = 2 ** 16, + limit: int = 2**16, max_line_size: int = 8190, max_headers: int = 32768, max_field_size: int = 8190, @@ -229,20 +268,22 @@ def __init__( self.response_with_body = response_with_body self.read_until_eof = read_until_eof - self._lines = [] # type: List[bytes] + self._lines: List[bytes] = [] self._tail = b"" self._upgraded = False self._payload = None - self._payload_parser = None # type: Optional[HttpPayloadParser] + self._payload_parser: Optional[HttpPayloadParser] = None self._auto_decompress = auto_decompress self._limit = limit - self._headers_parser = HeadersParser(max_line_size, max_headers, max_field_size) + self._headers_parser = HeadersParser( + max_line_size, max_headers, max_field_size, self.lax + ) @abc.abstractmethod - def parse_message(self, lines: List[bytes]) -> Any: + def parse_message(self, lines: List[bytes]) -> _MsgT: pass - def feed_eof(self) -> Any: + def feed_eof(self) -> Optional[_MsgT]: if self._payload_parser is not None: self._payload_parser.feed_eof() self._payload_parser = None @@ -254,20 +295,19 @@ def feed_eof(self) -> Any: if self._lines: if self._lines[-1] != "\r\n": self._lines.append(b"") - try: + with suppress(Exception): return self.parse_message(self._lines) - except Exception: - return None + return None def feed_data( self, data: bytes, - SEP: bytes = b"\r\n", + SEP: _SEP = b"\r\n", EMPTY: bytes = b"", CONTENT_LENGTH: istr = hdrs.CONTENT_LENGTH, METH_CONNECT: str = hdrs.METH_CONNECT, SEC_WEBSOCKET_KEY1: istr = hdrs.SEC_WEBSOCKET_KEY1, - ) -> Tuple[List[Any], bool, bytes]: + ) -> Tuple[List[Tuple[_MsgT, StreamReader]], bool, bytes]: messages = [] @@ -286,45 +326,59 @@ def feed_data( pos = data.find(SEP, start_pos) # consume \r\n if pos == start_pos and not self._lines: - start_pos = pos + 2 + start_pos = pos + len(SEP) continue if pos >= start_pos: # line found - self._lines.append(data[start_pos:pos]) - start_pos = pos + 2 + line = data[start_pos:pos] + if SEP == b"\n": # For lax response parsing + line = line.rstrip(b"\r") + self._lines.append(line) + start_pos = pos + len(SEP) # \r\n\r\n found if self._lines[-1] == EMPTY: try: - msg = self.parse_message(self._lines) + msg: _MsgT = self.parse_message(self._lines) finally: self._lines.clear() - # payload length - length = msg.headers.get(CONTENT_LENGTH) - if length is not None: - try: - length = int(length) - except ValueError: - raise InvalidHeader(CONTENT_LENGTH) - if length < 0: + def get_content_length() -> Optional[int]: + # payload length + length_hdr = msg.headers.get(CONTENT_LENGTH) + if length_hdr is None: + return None + + # Shouldn't allow +/- or other number formats. + # https://www.rfc-editor.org/rfc/rfc9110#section-8.6-2 + # msg.headers is already stripped of leading/trailing wsp + if not DIGITS.fullmatch(length_hdr): raise InvalidHeader(CONTENT_LENGTH) + return int(length_hdr) + + length = get_content_length() # do not support old websocket spec if SEC_WEBSOCKET_KEY1 in msg.headers: raise InvalidHeader(SEC_WEBSOCKET_KEY1) - self._upgraded = msg.upgrade + self._upgraded = msg.upgrade and _is_supported_upgrade( + msg.headers + ) method = getattr(msg, "method", self.method) + # code is only present on responses + code = getattr(msg, "code", 0) assert self.protocol is not None # calculate payload - if ( - (length is not None and length > 0) - or msg.chunked - and not msg.upgrade + empty_body = status_code_must_be_empty_body(code) or bool( + method and method_must_be_empty_body(method) + ) + if not empty_body and ( + ((length is not None and length > 0) or msg.chunked) + and not self._upgraded ): payload = StreamReader( self.protocol, @@ -342,10 +396,12 @@ def feed_data( readall=self.readall, response_with_body=self.response_with_body, auto_decompress=self._auto_decompress, + lax=self.lax, ) if not payload_parser.done: self._payload_parser = payload_parser elif method == METH_CONNECT: + assert isinstance(msg, RawRequestMessage) payload = StreamReader( self.protocol, timer=self.timer, @@ -359,34 +415,31 @@ def feed_data( compression=msg.compression, readall=True, auto_decompress=self._auto_decompress, + lax=self.lax, + ) + elif not empty_body and length is None and self.read_until_eof: + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + payload_parser = HttpPayloadParser( + payload, + length=length, + chunked=msg.chunked, + method=method, + compression=msg.compression, + code=self.code, + readall=True, + response_with_body=self.response_with_body, + auto_decompress=self._auto_decompress, + lax=self.lax, ) + if not payload_parser.done: + self._payload_parser = payload_parser else: - if ( - getattr(msg, "code", 100) >= 199 - and length is None - and self.read_until_eof - ): - payload = StreamReader( - self.protocol, - timer=self.timer, - loop=loop, - limit=self._limit, - ) - payload_parser = HttpPayloadParser( - payload, - length=length, - chunked=msg.chunked, - method=method, - compression=msg.compression, - code=self.code, - readall=True, - response_with_body=self.response_with_body, - auto_decompress=self._auto_decompress, - ) - if not payload_parser.done: - self._payload_parser = payload_parser - else: - payload = EMPTY_PAYLOAD # type: ignore + payload = EMPTY_PAYLOAD messages.append((msg, payload)) else: @@ -404,14 +457,17 @@ def feed_data( assert not self._lines assert self._payload_parser is not None try: - eof, data = self._payload_parser.feed_data(data[start_pos:]) - except BaseException as exc: + eof, data = self._payload_parser.feed_data(data[start_pos:], SEP) + except BaseException as underlying_exc: + reraised_exc = underlying_exc if self.payload_exception is not None: - self._payload_parser.payload.set_exception( - self.payload_exception(str(exc)) - ) - else: - self._payload_parser.payload.set_exception(exc) + reraised_exc = self.payload_exception(str(underlying_exc)) + + set_exception( + self._payload_parser.payload, + reraised_exc, + underlying_exc, + ) eof = True data = b"" @@ -447,6 +503,24 @@ def parse_headers( upgrade = False chunked = False + # https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5-6 + # https://www.rfc-editor.org/rfc/rfc9110.html#name-collected-abnf + singletons = ( + hdrs.CONTENT_LENGTH, + hdrs.CONTENT_LOCATION, + hdrs.CONTENT_RANGE, + hdrs.CONTENT_TYPE, + hdrs.ETAG, + hdrs.HOST, + hdrs.MAX_FORWARDS, + hdrs.SERVER, + hdrs.TRANSFER_ENCODING, + hdrs.USER_AGENT, + ) + bad_hdr = next((h for h in singletons if len(headers.getall(h, ())) > 1), None) + if bad_hdr is not None: + raise BadHttpMessage(f"Duplicate '{bad_hdr}' header found.") + # keep-alive conn = headers.get(hdrs.CONNECTION) if conn: @@ -455,7 +529,8 @@ def parse_headers( close_conn = True elif v == "keep-alive": close_conn = False - elif v == "upgrade": + # https://www.rfc-editor.org/rfc/rfc9110.html#name-101-switching-protocols + elif v == "upgrade" and headers.get(hdrs.UPGRADE): upgrade = True # encoding @@ -467,29 +542,40 @@ def parse_headers( # chunking te = headers.get(hdrs.TRANSFER_ENCODING) - if te and "chunked" in te.lower(): - chunked = True + if te is not None: + if "chunked" == te.lower(): + chunked = True + else: + raise BadHttpMessage("Request has invalid `Transfer-Encoding`") + + if hdrs.CONTENT_LENGTH in headers: + raise BadHttpMessage( + "Transfer-Encoding can't be present with Content-Length", + ) return (headers, raw_headers, close_conn, encoding, upgrade, chunked) def set_upgraded(self, val: bool) -> None: """Set connection upgraded (to websocket) mode. + :param bool val: new state. """ self._upgraded = val -class HttpRequestParser(HttpParser): - """Read request status line. Exception .http_exceptions.BadStatusLine +class HttpRequestParser(HttpParser[RawRequestMessage]): + """Read request status line. + + Exception .http_exceptions.BadStatusLine could be raised in case of any errors in status line. Returns RawRequestMessage. """ - def parse_message(self, lines: List[bytes]) -> Any: + def parse_message(self, lines: List[bytes]) -> RawRequestMessage: # request line line = lines[0].decode("utf-8", "surrogateescape") try: - method, path, version = line.split(None, 2) + method, path, version = line.split(" ", maxsplit=2) except ValueError: raise BadStatusLine(line) from None @@ -498,22 +584,48 @@ def parse_message(self, lines: List[bytes]) -> Any: "Status line is too long", str(self.max_line_size), str(len(path)) ) - path_part, _hash_separator, url_fragment = path.partition("#") - path_part, _question_mark_separator, qs_part = path_part.partition("?") - # method - if not METHRE.match(method): + if not TOKENRE.fullmatch(method): raise BadStatusLine(method) # version - try: - if version.startswith("HTTP/"): - n1, n2 = version[5:].split(".", 1) - version_o = HttpVersion(int(n1), int(n2)) - else: - raise BadStatusLine(version) - except Exception: - raise BadStatusLine(version) + match = VERSRE.fullmatch(version) + if match is None: + raise BadStatusLine(line) + version_o = HttpVersion(int(match.group(1)), int(match.group(2))) + + if method == "CONNECT": + # authority-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.3 + url = URL.build(authority=path, encoded=True) + elif path.startswith("/"): + # origin-form, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.1 + path_part, _hash_separator, url_fragment = path.partition("#") + path_part, _question_mark_separator, qs_part = path_part.partition("?") + + # NOTE: `yarl.URL.build()` is used to mimic what the Cython-based + # NOTE: parser does, otherwise it results into the same + # NOTE: HTTP Request-Line input producing different + # NOTE: `yarl.URL()` objects + url = URL.build( + path=path_part, + query_string=qs_part, + fragment=url_fragment, + encoded=True, + ) + elif path == "*" and method == "OPTIONS": + # asterisk-form, + url = URL(path, encoded=True) + else: + # absolute-form for proxy maybe, + # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.2 + url = URL(path, encoded=True) + if url.scheme == "": + # not absolute-form + raise InvalidURLError( + path.encode(errors="surrogateescape").decode("latin1") + ) # read headers ( @@ -541,35 +653,42 @@ def parse_message(self, lines: List[bytes]) -> Any: compression, upgrade, chunked, - # NOTE: `yarl.URL.build()` is used to mimic what the Cython-based - # NOTE: parser does, otherwise it results into the same - # NOTE: HTTP Request-Line input producing different - # NOTE: `yarl.URL()` objects - URL.build( - path=path_part, - query_string=qs_part, - fragment=url_fragment, - encoded=True, - ), + url, ) -class HttpResponseParser(HttpParser): +class HttpResponseParser(HttpParser[RawResponseMessage]): """Read response status line and headers. BadStatusLine could be raised in case of any errors in status line. - Returns RawResponseMessage""" + Returns RawResponseMessage. + """ - def parse_message(self, lines: List[bytes]) -> Any: + # Lax mode should only be enabled on response parser. + lax = not DEBUG + + def feed_data( + self, + data: bytes, + SEP: Optional[_SEP] = None, + *args: Any, + **kwargs: Any, + ) -> Tuple[List[Tuple[RawResponseMessage, StreamReader]], bool, bytes]: + if SEP is None: + SEP = b"\r\n" if DEBUG else b"\n" + return super().feed_data(data, SEP, *args, **kwargs) + + def parse_message(self, lines: List[bytes]) -> RawResponseMessage: line = lines[0].decode("utf-8", "surrogateescape") try: - version, status = line.split(None, 1) + version, status = line.split(maxsplit=1) except ValueError: raise BadStatusLine(line) from None try: - status, reason = status.split(None, 1) + status, reason = status.split(maxsplit=1) except ValueError: + status = status.strip() reason = "" if len(reason) > self.max_line_size: @@ -578,19 +697,15 @@ def parse_message(self, lines: List[bytes]) -> Any: ) # version - match = VERSRE.match(version) + match = VERSRE.fullmatch(version) if match is None: raise BadStatusLine(line) version_o = HttpVersion(int(match.group(1)), int(match.group(2))) - # The status code is a three-digit number - try: - status_i = int(status) - except ValueError: - raise BadStatusLine(line) from None - - if status_i > 999: + # The status code is a three-digit ASCII number, no padding + if len(status) != 3 or not DIGITS.fullmatch(status): raise BadStatusLine(line) + status_i = int(status) # read headers ( @@ -603,7 +718,16 @@ def parse_message(self, lines: List[bytes]) -> Any: ) = self.parse_headers(lines) if close is None: - close = version_o <= HttpVersion10 + if version_o <= HttpVersion10: + close = True + # https://www.rfc-editor.org/rfc/rfc9112.html#name-message-body-length + elif 100 <= status_i < 200 or status_i in {204, 304}: + close = False + elif hdrs.CONTENT_LENGTH in headers or hdrs.TRANSFER_ENCODING in headers: + close = False + else: + # https://www.rfc-editor.org/rfc/rfc9112.html#section-6.3-2.8 + close = True return RawResponseMessage( version_o, @@ -630,6 +754,7 @@ def __init__( readall: bool = False, response_with_body: bool = True, auto_decompress: bool = True, + lax: bool = False, ) -> None: self._length = 0 self._type = ParseState.PARSE_NONE @@ -637,13 +762,14 @@ def __init__( self._chunk_size = 0 self._chunk_tail = b"" self._auto_decompress = auto_decompress + self._lax = lax self.done = False # payload decompression wrapper if response_with_body and compression and self._auto_decompress: - real_payload = DeflateBuffer( + real_payload: Union[StreamReader, DeflateBuffer] = DeflateBuffer( payload, compression - ) # type: Union[StreamReader, DeflateBuffer] + ) else: real_payload = payload @@ -688,7 +814,7 @@ def feed_eof(self) -> None: ) def feed_data( - self, chunk: bytes, SEP: bytes = b"\r\n", CHUNK_EXT: bytes = b";" + self, chunk: bytes, SEP: _SEP = b"\r\n", CHUNK_EXT: bytes = b";" ) -> Tuple[bool, bytes]: # Read specified amount of bytes if self._type == ParseState.PARSE_LENGTH: @@ -725,18 +851,22 @@ def feed_data( else: size_b = chunk[:pos] - try: - size = int(bytes(size_b), 16) - except ValueError: + if self._lax: # Allow whitespace in lax mode. + size_b = size_b.strip() + + if not re.fullmatch(HEXDIGITS, size_b): exc = TransferEncodingError( chunk[:pos].decode("ascii", "surrogateescape") ) - self.payload.set_exception(exc) - raise exc from None + set_exception(self.payload, exc) + raise exc + size = int(bytes(size_b), 16) - chunk = chunk[pos + 2 :] + chunk = chunk[pos + len(SEP) :] if size == 0: # eof marker self._chunk = ChunkState.PARSE_MAYBE_TRAILERS + if self._lax and chunk.startswith(b"\r"): + chunk = chunk[1:] else: self._chunk = ChunkState.PARSE_CHUNKED_CHUNK self._chunk_size = size @@ -758,13 +888,15 @@ def feed_data( self._chunk_size = 0 self.payload.feed_data(chunk[:required], required) chunk = chunk[required:] + if self._lax and chunk.startswith(b"\r"): + chunk = chunk[1:] self._chunk = ChunkState.PARSE_CHUNKED_CHUNK_EOF self.payload.end_http_chunk_receiving() # toss the CRLF at the end of the chunk if self._chunk == ChunkState.PARSE_CHUNKED_CHUNK_EOF: - if chunk[:2] == SEP: - chunk = chunk[2:] + if chunk[: len(SEP)] == SEP: + chunk = chunk[len(SEP) :] self._chunk = ChunkState.PARSE_CHUNKED_SIZE else: self._chunk_tail = chunk @@ -772,13 +904,13 @@ def feed_data( # if stream does not contain trailer, after 0\r\n # we should get another \r\n otherwise - # trailers needs to be skiped until \r\n\r\n + # trailers needs to be skipped until \r\n\r\n if self._chunk == ChunkState.PARSE_MAYBE_TRAILERS: - head = chunk[:2] + head = chunk[: len(SEP)] if head == SEP: # end of stream self.payload.feed_eof() - return True, chunk[2:] + return True, chunk[len(SEP) :] # Both CR and LF, or only LF may not be received yet. It is # expected that CRLF or LF will be shown at the very first # byte next time, otherwise trailers should come. The last @@ -796,7 +928,7 @@ def feed_data( if self._chunk == ChunkState.PARSE_TRAILERS: pos = chunk.find(SEP) if pos >= 0: - chunk = chunk[pos + 2 :] + chunk = chunk[pos + len(SEP) :] self._chunk = ChunkState.PARSE_MAYBE_TRAILERS else: self._chunk_tail = chunk @@ -812,25 +944,31 @@ def feed_data( class DeflateBuffer: """DeflateStream decompress stream and feed data into specified stream.""" + decompressor: Any + def __init__(self, out: StreamReader, encoding: Optional[str]) -> None: self.out = out self.size = 0 self.encoding = encoding self._started_decoding = False + self.decompressor: Union[BrotliDecompressor, ZLibDecompressor] if encoding == "br": if not HAS_BROTLI: # pragma: no cover raise ContentEncodingError( "Can not decode content-encoding: brotli (br). " - "Please install `brotlipy`" + "Please install `Brotli`" ) - self.decompressor = brotli.Decompressor() + self.decompressor = BrotliDecompressor() else: - zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS - self.decompressor = zlib.decompressobj(wbits=zlib_mode) + self.decompressor = ZLibDecompressor(encoding=encoding) - def set_exception(self, exc: BaseException) -> None: - self.out.set_exception(exc) + def set_exception( + self, + exc: BaseException, + exc_cause: BaseException = _EXC_SENTINEL, + ) -> None: + set_exception(self.out, exc, exc_cause) def feed_data(self, chunk: bytes, size: int) -> None: if not size: @@ -848,10 +986,12 @@ def feed_data(self, chunk: bytes, size: int) -> None: ): # Change the decoder to decompress incorrectly compressed data # Actually we should issue a warning about non-RFC-compliant data. - self.decompressor = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + self.decompressor = ZLibDecompressor( + encoding=self.encoding, suppress_deflate_header=True + ) try: - chunk = self.decompressor.decompress(chunk) + chunk = self.decompressor.decompress_sync(chunk) except Exception: raise ContentEncodingError( "Can not decode content-encoding: %s" % self.encoding @@ -886,7 +1026,7 @@ def end_http_chunk_receiving(self) -> None: try: if not NO_EXTENSIONS: - from ._http_parser import ( # type: ignore + from ._http_parser import ( # type: ignore[import-not-found,no-redef] HttpRequestParser, HttpResponseParser, RawRequestMessage, diff --git a/dist/ba_data/python-site-packages/aiohttp/http_websocket.py b/dist/ba_data/python-site-packages/aiohttp/http_websocket.py index 5cdaeea4..39f2e4a5 100644 --- a/dist/ba_data/python-site-packages/aiohttp/http_websocket.py +++ b/dist/ba_data/python-site-packages/aiohttp/http_websocket.py @@ -1,7 +1,7 @@ """WebSocket protocol versions 13 and 8.""" import asyncio -import collections +import functools import json import random import re @@ -9,10 +9,23 @@ import zlib from enum import IntEnum from struct import Struct -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import ( + Any, + Callable, + Final, + List, + NamedTuple, + Optional, + Pattern, + Set, + Tuple, + Union, + cast, +) from .base_protocol import BaseProtocol -from .helpers import NO_EXTENSIONS +from .compression_utils import ZLibCompressor, ZLibDecompressor +from .helpers import NO_EXTENSIONS, set_exception from .streams import DataQueue __all__ = ( @@ -33,6 +46,7 @@ class WSCloseCode(IntEnum): GOING_AWAY = 1001 PROTOCOL_ERROR = 1002 UNSUPPORTED_DATA = 1003 + ABNORMAL_CLOSURE = 1006 INVALID_TEXT = 1007 POLICY_VIOLATION = 1008 MESSAGE_TOO_BIG = 1009 @@ -40,9 +54,19 @@ class WSCloseCode(IntEnum): INTERNAL_ERROR = 1011 SERVICE_RESTART = 1012 TRY_AGAIN_LATER = 1013 + BAD_GATEWAY = 1014 + +ALLOWED_CLOSE_CODES: Final[Set[int]] = {int(i) for i in WSCloseCode} -ALLOWED_CLOSE_CODES = {int(i) for i in WSCloseCode} +# For websockets, keeping latency low is extremely important as implementations +# generally expect to be able to send and receive messages quickly. We use a +# larger chunk size than the default to reduce the number of executor calls +# since the executor is a significant source of latency and overhead when +# the chunks are small. A size of 5KiB was chosen because it is also the +# same value python-zlib-ng choose to use as the threshold to release the GIL. + +WEBSOCKET_MAX_SYNC_CHUNK_SIZE = 5 * 1024 class WSMsgType(IntEnum): @@ -69,7 +93,7 @@ class WSMsgType(IntEnum): error = ERROR -WS_KEY = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" +WS_KEY: Final[bytes] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" UNPACK_LEN2 = Struct("!H").unpack_from @@ -79,14 +103,16 @@ class WSMsgType(IntEnum): PACK_LEN2 = Struct("!BBH").pack PACK_LEN3 = Struct("!BBQ").pack PACK_CLOSE_CODE = Struct("!H").pack -MSG_SIZE = 2 ** 14 -DEFAULT_LIMIT = 2 ** 16 - +MSG_SIZE: Final[int] = 2**14 +DEFAULT_LIMIT: Final[int] = 2**16 -_WSMessageBase = collections.namedtuple("_WSMessageBase", ["type", "data", "extra"]) +class WSMessage(NamedTuple): + type: WSMsgType + # To type correctly, this would need some kind of tagged union for each type. + data: Any + extra: Optional[str] -class WSMessage(_WSMessageBase): def json(self, *, loads: Callable[[Any], Any] = json.loads) -> Any: """Return parsed JSON data. @@ -107,18 +133,20 @@ def __init__(self, code: int, message: str) -> None: super().__init__(code, message) def __str__(self) -> str: - return self.args[1] + return cast(str, self.args[1]) class WSHandshakeError(Exception): """WebSocket protocol handshake error.""" -native_byteorder = sys.byteorder +native_byteorder: Final[str] = sys.byteorder # Used by _websocket_mask_python -_XOR_TABLE = [bytes(a ^ b for a in range(256)) for b in range(256)] +@functools.lru_cache +def _xor_table() -> List[bytes]: + return [bytes(a ^ b for a in range(256)) for b in range(256)] def _websocket_mask_python(mask: bytes, data: bytearray) -> None: @@ -138,6 +166,7 @@ def _websocket_mask_python(mask: bytes, data: bytearray) -> None: assert len(mask) == 4, mask if data: + _XOR_TABLE = _xor_table() a, b, c, d = (_XOR_TABLE[n] for n in mask) data[::4] = data[::4].translate(a) data[1::4] = data[1::4].translate(b) @@ -149,16 +178,16 @@ def _websocket_mask_python(mask: bytes, data: bytearray) -> None: _websocket_mask = _websocket_mask_python else: try: - from ._websocket import _websocket_mask_cython # type: ignore + from ._websocket import _websocket_mask_cython # type: ignore[import-not-found] _websocket_mask = _websocket_mask_cython except ImportError: # pragma: no cover _websocket_mask = _websocket_mask_python -_WS_DEFLATE_TRAILING = bytes([0x00, 0x00, 0xFF, 0xFF]) +_WS_DEFLATE_TRAILING: Final[bytes] = bytes([0x00, 0x00, 0xFF, 0xFF]) -_WS_EXT_RE = re.compile( +_WS_EXT_RE: Final[Pattern[str]] = re.compile( r"^(?:;\s*(?:" r"(server_no_context_takeover)|" r"(client_no_context_takeover)|" @@ -166,7 +195,7 @@ def _websocket_mask_python(mask: bytes, data: bytearray) -> None: r"(client_max_window_bits(?:=(\d+))?)))*$" ) -_WS_EXT_RE_SPLIT = re.compile(r"permessage-deflate([^,]+)?") +_WS_EXT_RE_SPLIT: Final[Pattern[str]] = re.compile(r"permessage-deflate([^,]+)?") def ws_ext_parse(extstr: Optional[str], isserver: bool = False) -> Tuple[int, bool]: @@ -256,22 +285,22 @@ def __init__( self.queue = queue self._max_msg_size = max_msg_size - self._exc = None # type: Optional[BaseException] + self._exc: Optional[BaseException] = None self._partial = bytearray() self._state = WSParserState.READ_HEADER - self._opcode = None # type: Optional[int] + self._opcode: Optional[int] = None self._frame_fin = False - self._frame_opcode = None # type: Optional[int] + self._frame_opcode: Optional[int] = None self._frame_payload = bytearray() self._tail = b"" self._has_mask = False - self._frame_mask = None # type: Optional[bytes] + self._frame_mask: Optional[bytes] = None self._payload_length = 0 self._payload_length_flag = 0 - self._compressed = None # type: Optional[bool] - self._decompressobj = None # type: Any # zlib.decompressobj actually + self._compressed: Optional[bool] = None + self._decompressobj: Optional[ZLibDecompressor] = None self._compress = compress def feed_eof(self) -> None: @@ -285,13 +314,13 @@ def feed_data(self, data: bytes) -> Tuple[bool, bytes]: return self._feed_data(data) except Exception as exc: self._exc = exc - self.queue.set_exception(exc) + set_exception(self.queue, exc) return True, b"" def _feed_data(self, data: bytes) -> Tuple[bool, bytes]: for fin, opcode, payload, compressed in self.parse_frame(data): if compressed and not self._decompressobj: - self._decompressobj = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + self._decompressobj = ZLibDecompressor(suppress_deflate_header=True) if opcode == WSMsgType.CLOSE: if len(payload) >= 2: close_code = UNPACK_CLOSE_CODE(payload[:2])[0] @@ -376,8 +405,9 @@ def _feed_data(self, data: bytes) -> Tuple[bool, bytes]: # Decompress process must to be done after all packets # received. if compressed: + assert self._decompressobj is not None self._partial.extend(_WS_DEFLATE_TRAILING) - payload_merged = self._decompressobj.decompress( + payload_merged = self._decompressobj.decompress_sync( self._partial, self._max_msg_size ) if self._decompressobj.unconsumed_tail: @@ -575,7 +605,7 @@ def __init__( *, use_mask: bool = False, limit: int = DEFAULT_LIMIT, - random: Any = random.Random(), + random: random.Random = random.Random(), compress: int = 0, notakeover: bool = False, ) -> None: @@ -588,7 +618,7 @@ def __init__( self._closing = False self._limit = limit self._output_size = 0 - self._compressobj = None # type: Any # actually compressobj + self._compressobj: Any = None # actually compressobj async def _send_frame( self, message: bytes, opcode: int, compress: Optional[int] = None @@ -605,16 +635,18 @@ async def _send_frame( if (compress or self.compress) and opcode < 8: if compress: # Do not set self._compress if compressing is for this frame - compressobj = zlib.compressobj(level=zlib.Z_BEST_SPEED, wbits=-compress) + compressobj = self._make_compress_obj(compress) else: # self.compress if not self._compressobj: - self._compressobj = zlib.compressobj( - level=zlib.Z_BEST_SPEED, wbits=-self.compress - ) + self._compressobj = self._make_compress_obj(self.compress) compressobj = self._compressobj - message = compressobj.compress(message) - message = message + compressobj.flush( + message = await compressobj.compress(message) + # Its critical that we do not return control to the event + # loop until we have finished sending all the compressed + # data. Otherwise we could end up mixing compressed frames + # if there are multiple coroutines compressing data. + message += compressobj.flush( zlib.Z_FULL_FLUSH if self.notakeover else zlib.Z_SYNC_FLUSH ) if message.endswith(_WS_DEFLATE_TRAILING): @@ -636,37 +668,47 @@ async def _send_frame( else: header = PACK_LEN3(0x80 | rsv | opcode, 127 | mask_bit, msg_length) if use_mask: - mask = self.randrange(0, 0xFFFFFFFF) - mask = mask.to_bytes(4, "big") + mask_int = self.randrange(0, 0xFFFFFFFF) + mask = mask_int.to_bytes(4, "big") message = bytearray(message) _websocket_mask(mask, message) self._write(header + mask + message) - self._output_size += len(header) + len(mask) + len(message) + self._output_size += len(header) + len(mask) + msg_length else: - if len(message) > MSG_SIZE: + if msg_length > MSG_SIZE: self._write(header) self._write(message) else: self._write(header + message) - self._output_size += len(header) + len(message) + self._output_size += len(header) + msg_length + + # It is safe to return control to the event loop when using compression + # after this point as we have already sent or buffered all the data. if self._output_size > self._limit: self._output_size = 0 await self.protocol._drain_helper() + def _make_compress_obj(self, compress: int) -> ZLibCompressor: + return ZLibCompressor( + level=zlib.Z_BEST_SPEED, + wbits=-compress, + max_sync_chunk_size=WEBSOCKET_MAX_SYNC_CHUNK_SIZE, + ) + def _write(self, data: bytes) -> None: if self.transport is None or self.transport.is_closing(): raise ConnectionResetError("Cannot write to closing transport") self.transport.write(data) - async def pong(self, message: bytes = b"") -> None: + async def pong(self, message: Union[bytes, str] = b"") -> None: """Send pong message.""" if isinstance(message, str): message = message.encode("utf-8") await self._send_frame(message, WSMsgType.PONG) - async def ping(self, message: bytes = b"") -> None: + async def ping(self, message: Union[bytes, str] = b"") -> None: """Send ping message.""" if isinstance(message, str): message = message.encode("utf-8") @@ -686,7 +728,7 @@ async def send( else: await self._send_frame(message, WSMsgType.TEXT, compress) - async def close(self, code: int = 1000, message: bytes = b"") -> None: + async def close(self, code: int = 1000, message: Union[bytes, str] = b"") -> None: """Close the websocket, sending the specified code and message.""" if isinstance(message, str): message = message.encode("utf-8") diff --git a/dist/ba_data/python-site-packages/aiohttp/http_writer.py b/dist/ba_data/python-site-packages/aiohttp/http_writer.py index d261fc4e..d6b02e6f 100644 --- a/dist/ba_data/python-site-packages/aiohttp/http_writer.py +++ b/dist/ba_data/python-site-packages/aiohttp/http_writer.py @@ -1,24 +1,30 @@ """Http related parsers and protocol.""" import asyncio -import collections import zlib -from typing import Any, Awaitable, Callable, Optional, Union # noqa +from typing import Any, Awaitable, Callable, NamedTuple, Optional, Union # noqa from multidict import CIMultiDict from .abc import AbstractStreamWriter from .base_protocol import BaseProtocol +from .compression_utils import ZLibCompressor from .helpers import NO_EXTENSIONS __all__ = ("StreamWriter", "HttpVersion", "HttpVersion10", "HttpVersion11") -HttpVersion = collections.namedtuple("HttpVersion", ["major", "minor"]) + +class HttpVersion(NamedTuple): + major: int + minor: int + + HttpVersion10 = HttpVersion(1, 0) HttpVersion11 = HttpVersion(1, 1) _T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] +_T_OnHeadersSent = Optional[Callable[["CIMultiDict[str]"], Awaitable[None]]] class StreamWriter(AbstractStreamWriter): @@ -27,9 +33,9 @@ def __init__( protocol: BaseProtocol, loop: asyncio.AbstractEventLoop, on_chunk_sent: _T_OnChunkSent = None, + on_headers_sent: _T_OnHeadersSent = None, ) -> None: self._protocol = protocol - self._transport = protocol.transport self.loop = loop self.length = None @@ -38,14 +44,15 @@ def __init__( self.output_size = 0 self._eof = False - self._compress = None # type: Any + self._compress: Optional[ZLibCompressor] = None self._drain_waiter = None - self._on_chunk_sent = on_chunk_sent # type: _T_OnChunkSent + self._on_chunk_sent: _T_OnChunkSent = on_chunk_sent + self._on_headers_sent: _T_OnHeadersSent = on_headers_sent @property def transport(self) -> Optional[asyncio.Transport]: - return self._transport + return self._protocol.transport @property def protocol(self) -> BaseProtocol: @@ -54,18 +61,19 @@ def protocol(self) -> BaseProtocol: def enable_chunking(self) -> None: self.chunked = True - def enable_compression(self, encoding: str = "deflate") -> None: - zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS - self._compress = zlib.compressobj(wbits=zlib_mode) + def enable_compression( + self, encoding: str = "deflate", strategy: int = zlib.Z_DEFAULT_STRATEGY + ) -> None: + self._compress = ZLibCompressor(encoding=encoding, strategy=strategy) def _write(self, chunk: bytes) -> None: size = len(chunk) self.buffer_size += size self.output_size += size - - if self._transport is None or self._transport.is_closing(): + transport = self.transport + if not self._protocol.connected or transport is None or transport.is_closing(): raise ConnectionResetError("Cannot write to closing transport") - self._transport.write(chunk) + transport.write(chunk) async def write( self, chunk: bytes, *, drain: bool = True, LIMIT: int = 0x10000 @@ -85,7 +93,7 @@ async def write( chunk = chunk.cast("c") if self._compress is not None: - chunk = self._compress.compress(chunk) + chunk = await self._compress.compress(chunk) if not chunk: return @@ -114,6 +122,9 @@ async def write_headers( self, status_line: str, headers: "CIMultiDict[str]" ) -> None: """Write request/response status and headers.""" + if self._on_headers_sent is not None: + await self._on_headers_sent(headers) + # status + headers buf = _serialize_headers(status_line, headers) self._write(buf) @@ -127,9 +138,9 @@ async def write_eof(self, chunk: bytes = b"") -> None: if self._compress: if chunk: - chunk = self._compress.compress(chunk) + chunk = await self._compress.compress(chunk) - chunk = chunk + self._compress.flush() + chunk += self._compress.flush() if chunk and self.chunked: chunk_len = ("%x\r\n" % len(chunk)).encode("ascii") chunk = chunk_len + chunk + b"\r\n0\r\n\r\n" @@ -147,7 +158,6 @@ async def write_eof(self, chunk: bytes = b"") -> None: await self.drain() self._eof = True - self._transport = None async def drain(self) -> None: """Flush the write buffer. @@ -161,19 +171,25 @@ async def drain(self) -> None: await self._protocol._drain_helper() +def _safe_header(string: str) -> str: + if "\r" in string or "\n" in string: + raise ValueError( + "Newline or carriage return detected in headers. " + "Potential header injection attack." + ) + return string + + def _py_serialize_headers(status_line: str, headers: "CIMultiDict[str]") -> bytes: - line = ( - status_line - + "\r\n" - + "".join([k + ": " + v + "\r\n" for k, v in headers.items()]) - ) - return line.encode("utf-8") + b"\r\n" + headers_gen = (_safe_header(k) + ": " + _safe_header(v) for k, v in headers.items()) + line = status_line + "\r\n" + "\r\n".join(headers_gen) + "\r\n\r\n" + return line.encode("utf-8") _serialize_headers = _py_serialize_headers try: - import aiohttp._http_writer as _http_writer # type: ignore + import aiohttp._http_writer as _http_writer # type: ignore[import-not-found] _c_serialize_headers = _http_writer._serialize_headers if not NO_EXTENSIONS: diff --git a/dist/ba_data/python-site-packages/aiohttp/locks.py b/dist/ba_data/python-site-packages/aiohttp/locks.py index ce5b9c6f..de2dc83d 100644 --- a/dist/ba_data/python-site-packages/aiohttp/locks.py +++ b/dist/ba_data/python-site-packages/aiohttp/locks.py @@ -1,16 +1,12 @@ import asyncio import collections -from typing import Any, Optional - -try: - from typing import Deque -except ImportError: - from typing_extensions import Deque +from typing import Any, Deque, Optional class EventResultOrError: - """ - This class wrappers the Event asyncio lock allowing either awake the + """Event asyncio lock helper class. + + Wraps the Event asyncio lock allowing either to awake the locked Tasks without any error or raising an exception. thanks to @vorpalsmith for the simple design. @@ -18,9 +14,9 @@ class EventResultOrError: def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop - self._exc = None # type: Optional[BaseException] + self._exc: Optional[BaseException] = None self._event = asyncio.Event() - self._waiters = collections.deque() # type: Deque[asyncio.Future[Any]] + self._waiters: Deque[asyncio.Future[Any]] = collections.deque() def set(self, exc: Optional[BaseException] = None) -> None: self._exc = exc @@ -40,6 +36,6 @@ async def wait(self) -> Any: return val def cancel(self) -> None: - """ Cancel all waiters """ + """Cancel all waiters""" for waiter in self._waiters: waiter.cancel() diff --git a/dist/ba_data/python-site-packages/aiohttp/multipart.py b/dist/ba_data/python-site-packages/aiohttp/multipart.py index 9e1ca92d..71fc2654 100644 --- a/dist/ba_data/python-site-packages/aiohttp/multipart.py +++ b/dist/ba_data/python-site-packages/aiohttp/multipart.py @@ -11,6 +11,7 @@ TYPE_CHECKING, Any, AsyncIterator, + Deque, Dict, Iterator, List, @@ -20,11 +21,13 @@ Tuple, Type, Union, + cast, ) from urllib.parse import parse_qsl, unquote, urlencode -from multidict import CIMultiDict, CIMultiDictProxy, MultiMapping +from multidict import CIMultiDict, CIMultiDictProxy +from .compression_utils import ZLibCompressor, ZLibDecompressor from .hdrs import ( CONTENT_DISPOSITION, CONTENT_ENCODING, @@ -56,7 +59,7 @@ ) -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .client_reqrep import ClientResponse @@ -101,7 +104,7 @@ def unescape(text: str, *, chars: str = "".join(map(re.escape, CHAR))) -> str: warnings.warn(BadContentDispositionHeader(header)) return None, {} - params = {} # type: Dict[str, str] + params: Dict[str, str] = {} while parts: item = parts.pop(0) @@ -152,7 +155,7 @@ def unescape(text: str, *, chars: str = "".join(map(re.escape, CHAR))) -> str: elif parts: # maybe just ; in filename, in any case this is just # one case fix, for proper fix we need to redesign parser - _value = "{};{}".format(value, parts[0]) + _value = f"{value};{parts[0]}" if is_quoted(_value): parts.pop(0) value = unescape(_value[1:-1].lstrip("\\/")) @@ -240,8 +243,10 @@ async def next( return item async def release(self) -> None: - """Releases the connection gracefully, reading all the content - to the void.""" + """Release the connection gracefully. + + All remaining content is read to the void. + """ await self.resp.release() @@ -251,23 +256,31 @@ class BodyPartReader: chunk_size = 8192 def __init__( - self, boundary: bytes, headers: "CIMultiDictProxy[str]", content: StreamReader + self, + boundary: bytes, + headers: "CIMultiDictProxy[str]", + content: StreamReader, + *, + subtype: str = "mixed", + default_charset: Optional[str] = None, ) -> None: self.headers = headers self._boundary = boundary self._content = content + self._default_charset = default_charset self._at_eof = False - length = self.headers.get(CONTENT_LENGTH, None) + self._is_form_data = subtype == "form-data" + # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8 + length = None if self._is_form_data else self.headers.get(CONTENT_LENGTH, None) self._length = int(length) if length is not None else None self._read_bytes = 0 - # TODO: typeing.Deque is not supported by Python 3.5 - self._unread = deque() # type: Any - self._prev_chunk = None # type: Optional[bytes] + self._unread: Deque[bytes] = deque() + self._prev_chunk: Optional[bytes] = None self._content_eof = 0 - self._cache = {} # type: Dict[str, Any] + self._cache: Dict[str, Any] = {} def __aiter__(self) -> AsyncIterator["BodyPartReader"]: - return self # type: ignore + return self # type: ignore[return-value] async def __anext__(self) -> bytes: part = await self.next() @@ -325,6 +338,8 @@ async def _read_chunk_from_length(self, size: int) -> bytes: assert self._length is not None, "Content-Length required for chunked read" chunk_size = min(size, self._length - self._read_bytes) chunk = await self._content.read(chunk_size) + if self._content.at_eof(): + self._at_eof = True return chunk async def _read_chunk_from_stream(self, size: int) -> bytes: @@ -400,8 +415,8 @@ async def release(self) -> None: async def text(self, *, encoding: Optional[str] = None) -> str: """Like read(), but assumes that body part contains text data.""" data = await self.read(decode=True) - # see https://www.w3.org/TR/html5/forms.html#multipart/form-data-encoding-algorithm # NOQA - # and https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-send # NOQA + # see https://www.w3.org/TR/html5/forms.html#multipart/form-data-encoding-algorithm + # and https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-send encoding = encoding or self.get_charset(default="utf-8") return data.decode(encoding) @@ -411,12 +426,10 @@ async def json(self, *, encoding: Optional[str] = None) -> Optional[Dict[str, An if not data: return None encoding = encoding or self.get_charset(default="utf-8") - return json.loads(data.decode(encoding)) + return cast(Dict[str, Any], json.loads(data.decode(encoding))) async def form(self, *, encoding: Optional[str] = None) -> List[Tuple[str, str]]: - """Like read(), but assumes that body parts contains form - urlencoded data. - """ + """Like read(), but assumes that body parts contain form urlencoded data.""" data = await self.read(decode=True) if not data: return [] @@ -424,8 +437,13 @@ async def form(self, *, encoding: Optional[str] = None) -> List[Tuple[str, str]] real_encoding = encoding else: real_encoding = self.get_charset(default="utf-8") + try: + decoded_data = data.rstrip().decode(real_encoding) + except UnicodeDecodeError: + raise ValueError("data cannot be decoded with %s encoding" % real_encoding) + return parse_qsl( - data.rstrip().decode(real_encoding), + decoded_data, keep_blank_values=True, encoding=real_encoding, ) @@ -435,26 +453,29 @@ def at_eof(self) -> bool: return self._at_eof def decode(self, data: bytes) -> bytes: - """Decodes data according the specified Content-Encoding + """Decodes data. + + Decoding is done according the specified Content-Encoding or Content-Transfer-Encoding headers value. """ if CONTENT_TRANSFER_ENCODING in self.headers: data = self._decode_content_transfer(data) - if CONTENT_ENCODING in self.headers: + # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8 + if not self._is_form_data and CONTENT_ENCODING in self.headers: return self._decode_content(data) return data def _decode_content(self, data: bytes) -> bytes: encoding = self.headers.get(CONTENT_ENCODING, "").lower() - - if encoding == "deflate": - return zlib.decompress(data, -zlib.MAX_WBITS) - elif encoding == "gzip": - return zlib.decompress(data, 16 + zlib.MAX_WBITS) - elif encoding == "identity": + if encoding == "identity": return data - else: - raise RuntimeError(f"unknown content encoding: {encoding}") + if encoding in {"deflate", "gzip"}: + return ZLibDecompressor( + encoding=encoding, + suppress_deflate_header=True, + ).decompress_sync(data) + + raise RuntimeError(f"unknown content encoding: {encoding}") def _decode_content_transfer(self, data: bytes) -> bytes: encoding = self.headers.get(CONTENT_TRANSFER_ENCODING, "").lower() @@ -474,21 +495,22 @@ def get_charset(self, default: str) -> str: """Returns charset parameter from Content-Type header or default.""" ctype = self.headers.get(CONTENT_TYPE, "") mimetype = parse_mimetype(ctype) - return mimetype.parameters.get("charset", default) + return mimetype.parameters.get("charset", self._default_charset or default) @reify def name(self) -> Optional[str]: - """Returns name specified in Content-Disposition header or None - if missed or header is malformed. - """ + """Returns name specified in Content-Disposition header. + If the header is missing or malformed, returns None. + """ _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION)) return content_disposition_filename(params, "name") @reify def filename(self) -> Optional[str]: - """Returns filename specified in Content-Disposition header or None - if missed or header is malformed. + """Returns filename specified in Content-Disposition header. + + Returns None if the header is missing or malformed. """ _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION)) return content_disposition_filename(params, "filename") @@ -499,7 +521,7 @@ class BodyPartReaderPayload(Payload): def __init__(self, value: BodyPartReader, *args: Any, **kwargs: Any) -> None: super().__init__(value, *args, **kwargs) - params = {} # type: Dict[str, str] + params: Dict[str, str] = {} if value.name is not None: params["name"] = value.name if value.filename is not None: @@ -510,10 +532,10 @@ def __init__(self, value: BodyPartReader, *args: Any, **kwargs: Any) -> None: async def write(self, writer: Any) -> None: field = self._value - chunk = await field.read_chunk(size=2 ** 16) + chunk = await field.read_chunk(size=2**16) while chunk: await writer.write(field.decode(chunk)) - chunk = await field.read_chunk(size=2 ** 16) + chunk = await field.read_chunk(size=2**16) class MultipartReader: @@ -528,20 +550,26 @@ class MultipartReader: part_reader_cls = BodyPartReader def __init__(self, headers: Mapping[str, str], content: StreamReader) -> None: + self._mimetype = parse_mimetype(headers[CONTENT_TYPE]) + assert self._mimetype.type == "multipart", "multipart/* content type expected" + if "boundary" not in self._mimetype.parameters: + raise ValueError( + "boundary missed for Content-Type: %s" % headers[CONTENT_TYPE] + ) + self.headers = headers self._boundary = ("--" + self._get_boundary()).encode() self._content = content - self._last_part = ( - None - ) # type: Optional[Union['MultipartReader', BodyPartReader]] + self._default_charset: Optional[str] = None + self._last_part: Optional[Union["MultipartReader", BodyPartReader]] = None self._at_eof = False self._at_bof = True - self._unread = [] # type: List[bytes] + self._unread: List[bytes] = [] def __aiter__( self, ) -> AsyncIterator["BodyPartReader"]: - return self # type: ignore + return self # type: ignore[return-value] async def __anext__( self, @@ -566,9 +594,7 @@ def from_response( return obj def at_eof(self) -> bool: - """Returns True if the final boundary was reached or - False otherwise. - """ + """Returns True if the final boundary was reached, false otherwise.""" return self._at_eof async def next( @@ -586,7 +612,24 @@ async def next( await self._read_boundary() if self._at_eof: # we just read the last boundary, nothing to do there return None - self._last_part = await self.fetch_next_part() + + part = await self.fetch_next_part() + # https://datatracker.ietf.org/doc/html/rfc7578#section-4.6 + if ( + self._last_part is None + and self._mimetype.subtype == "form-data" + and isinstance(part, BodyPartReader) + ): + _, params = parse_content_disposition(part.headers.get(CONTENT_DISPOSITION)) + if params.get("name") == "_charset_": + # Longest encoding in https://encoding.spec.whatwg.org/encodings.json + # is 19 characters, so 32 should be more than enough for any valid encoding. + charset = await part.read_chunk(32) + if len(charset) > 31: + raise RuntimeError("Invalid default charset") + self._default_charset = charset.strip().decode() + part = await self.fetch_next_part() + self._last_part = part return self._last_part async def release(self) -> None: @@ -608,8 +651,9 @@ def _get_part_reader( self, headers: "CIMultiDictProxy[str]", ) -> Union["MultipartReader", BodyPartReader]: - """Dispatches the response by the `Content-Type` header, returning - suitable reader instance. + """Dispatches the response by the `Content-Type` header. + + Returns a suitable reader instance. :param dict headers: Response headers """ @@ -621,19 +665,16 @@ def _get_part_reader( return type(self)(headers, self._content) return self.multipart_reader_cls(headers, self._content) else: - return self.part_reader_cls(self._boundary, headers, self._content) - - def _get_boundary(self) -> str: - mimetype = parse_mimetype(self.headers[CONTENT_TYPE]) - - assert mimetype.type == "multipart", "multipart/* content type expected" - - if "boundary" not in mimetype.parameters: - raise ValueError( - "boundary missed for Content-Type: %s" % self.headers[CONTENT_TYPE] + return self.part_reader_cls( + self._boundary, + headers, + self._content, + subtype=self._mimetype.subtype, + default_charset=self._default_charset, ) - boundary = mimetype.parameters["boundary"] + def _get_boundary(self) -> str: + boundary = self._mimetype.parameters["boundary"] if len(boundary) > 70: raise ValueError("boundary %r is too long (70 chars max)" % boundary) @@ -723,7 +764,8 @@ def __init__(self, subtype: str = "mixed", boundary: Optional[str] = None) -> No super().__init__(None, content_type=ctype) - self._parts = [] # type: List[_Part] + self._parts: List[_Part] = [] + self._is_form_data = subtype == "form-data" def __enter__(self) -> "MultipartWriter": return self @@ -745,14 +787,14 @@ def __len__(self) -> int: def __bool__(self) -> bool: return True - _valid_tchar_regex = re.compile(br"\A[!#$%&'*+\-.^_`|~\w]+\Z") - _invalid_qdtext_char_regex = re.compile(br"[\x00-\x08\x0A-\x1F\x7F]") + _valid_tchar_regex = re.compile(rb"\A[!#$%&'*+\-.^_`|~\w]+\Z") + _invalid_qdtext_char_regex = re.compile(rb"[\x00-\x08\x0A-\x1F\x7F]") @property def _boundary_value(self) -> str: """Wrap boundary parameter value in quotes, if necessary. - Reads self.boundary and returns a unicode sting. + Reads self.boundary and returns a unicode string. """ # Refer to RFCs 7231, 7230, 5234. # @@ -784,7 +826,7 @@ def _boundary_value(self) -> str: def boundary(self) -> str: return self._boundary.decode("ascii") - def append(self, obj: Any, headers: Optional[MultiMapping[str]] = None) -> Payload: + def append(self, obj: Any, headers: Optional[Mapping[str, str]] = None) -> Payload: if headers is None: headers = CIMultiDict() @@ -801,38 +843,44 @@ def append(self, obj: Any, headers: Optional[MultiMapping[str]] = None) -> Paylo def append_payload(self, payload: Payload) -> Payload: """Adds a new body part to multipart writer.""" - # compression - encoding = payload.headers.get( - CONTENT_ENCODING, - "", - ).lower() # type: Optional[str] - if encoding and encoding not in ("deflate", "gzip", "identity"): - raise RuntimeError(f"unknown content encoding: {encoding}") - if encoding == "identity": - encoding = None - - # te encoding - te_encoding = payload.headers.get( - CONTENT_TRANSFER_ENCODING, - "", - ).lower() # type: Optional[str] - if te_encoding not in ("", "base64", "quoted-printable", "binary"): - raise RuntimeError( - "unknown content transfer encoding: {}" "".format(te_encoding) + encoding: Optional[str] = None + te_encoding: Optional[str] = None + if self._is_form_data: + # https://datatracker.ietf.org/doc/html/rfc7578#section-4.7 + # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8 + assert ( + not {CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING} + & payload.headers.keys() ) - if te_encoding == "binary": - te_encoding = None - - # size - size = payload.size - if size is not None and not (encoding or te_encoding): - payload.headers[CONTENT_LENGTH] = str(size) - - self._parts.append((payload, encoding, te_encoding)) # type: ignore + # Set default Content-Disposition in case user doesn't create one + if CONTENT_DISPOSITION not in payload.headers: + name = f"section-{len(self._parts)}" + payload.set_content_disposition("form-data", name=name) + else: + # compression + encoding = payload.headers.get(CONTENT_ENCODING, "").lower() + if encoding and encoding not in ("deflate", "gzip", "identity"): + raise RuntimeError(f"unknown content encoding: {encoding}") + if encoding == "identity": + encoding = None + + # te encoding + te_encoding = payload.headers.get(CONTENT_TRANSFER_ENCODING, "").lower() + if te_encoding not in ("", "base64", "quoted-printable", "binary"): + raise RuntimeError(f"unknown content transfer encoding: {te_encoding}") + if te_encoding == "binary": + te_encoding = None + + # size + size = payload.size + if size is not None and not (encoding or te_encoding): + payload.headers[CONTENT_LENGTH] = str(size) + + self._parts.append((payload, encoding, te_encoding)) # type: ignore[arg-type] return payload def append_json( - self, obj: Any, headers: Optional[MultiMapping[str]] = None + self, obj: Any, headers: Optional[Mapping[str, str]] = None ) -> Payload: """Helper to append JSON part.""" if headers is None: @@ -843,7 +891,7 @@ def append_json( def append_form( self, obj: Union[Sequence[Tuple[str, str]], Mapping[str, str]], - headers: Optional[MultiMapping[str]] = None, + headers: Optional[Mapping[str, str]] = None, ) -> Payload: """Helper to append form urlencoded part.""" assert isinstance(obj, (Sequence, Mapping)) @@ -884,6 +932,11 @@ def size(self) -> Optional[int]: async def write(self, writer: Any, close_boundary: bool = True) -> None: """Write body.""" for part, encoding, te_encoding in self._parts: + if self._is_form_data: + # https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 + assert CONTENT_DISPOSITION in part.headers + assert "name=" in part.headers[CONTENT_DISPOSITION] + await writer.write(b"--" + self._boundary + b"\r\n") await writer.write(part._binary_headers) @@ -893,7 +946,7 @@ async def write(self, writer: Any, close_boundary: bool = True) -> None: w.enable_compression(encoding) if te_encoding: w.enable_encoding(te_encoding) - await part.write(w) # type: ignore + await part.write(w) # type: ignore[arg-type] await w.write_eof() else: await part.write(writer) @@ -907,9 +960,9 @@ async def write(self, writer: Any, close_boundary: bool = True) -> None: class MultipartPayloadWriter: def __init__(self, writer: Any) -> None: self._writer = writer - self._encoding = None # type: Optional[str] - self._compress = None # type: Any - self._encoding_buffer = None # type: Optional[bytearray] + self._encoding: Optional[str] = None + self._compress: Optional[ZLibCompressor] = None + self._encoding_buffer: Optional[bytearray] = None def enable_encoding(self, encoding: str) -> None: if encoding == "base64": @@ -918,9 +971,14 @@ def enable_encoding(self, encoding: str) -> None: elif encoding == "quoted-printable": self._encoding = "quoted-printable" - def enable_compression(self, encoding: str = "deflate") -> None: - zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else -zlib.MAX_WBITS - self._compress = zlib.compressobj(wbits=zlib_mode) + def enable_compression( + self, encoding: str = "deflate", strategy: int = zlib.Z_DEFAULT_STRATEGY + ) -> None: + self._compress = ZLibCompressor( + encoding=encoding, + suppress_deflate_header=True, + strategy=strategy, + ) async def write_eof(self) -> None: if self._compress is not None: @@ -936,7 +994,7 @@ async def write_eof(self) -> None: async def write(self, chunk: bytes) -> None: if self._compress is not None: if chunk: - chunk = self._compress.compress(chunk) + chunk = await self._compress.compress(chunk) if not chunk: return diff --git a/dist/ba_data/python-site-packages/aiohttp/payload.py b/dist/ba_data/python-site-packages/aiohttp/payload.py index c63dd220..6593b05c 100644 --- a/dist/ba_data/python-site-packages/aiohttp/payload.py +++ b/dist/ba_data/python-site-packages/aiohttp/payload.py @@ -13,9 +13,9 @@ Any, ByteString, Dict, + Final, Iterable, Optional, - Text, TextIO, Tuple, Type, @@ -27,7 +27,7 @@ from . import hdrs from .abc import AbstractStreamWriter from .helpers import ( - PY_36, + _SENTINEL, content_disposition_header, guess_filename, parse_mimetype, @@ -52,10 +52,9 @@ "AsyncIterablePayload", ) -TOO_LARGE_BYTES_BODY = 2 ** 20 # 1 MB +TOO_LARGE_BYTES_BODY: Final[int] = 2**20 # 1 MB - -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from typing import List @@ -89,6 +88,10 @@ def __call__(self, factory: Type["Payload"]) -> Type["Payload"]: return factory +PayloadType = Type["Payload"] +_PayloadRegistryItem = Tuple[PayloadType, Any] + + class PayloadRegistry: """Payload registry. @@ -96,12 +99,16 @@ class PayloadRegistry: """ def __init__(self) -> None: - self._first = [] # type: List[Tuple[Type[Payload], Any]] - self._normal = [] # type: List[Tuple[Type[Payload], Any]] - self._last = [] # type: List[Tuple[Type[Payload], Any]] + self._first: List[_PayloadRegistryItem] = [] + self._normal: List[_PayloadRegistryItem] = [] + self._last: List[_PayloadRegistryItem] = [] def get( - self, data: Any, *args: Any, _CHAIN: Any = chain, **kwargs: Any + self, + data: Any, + *args: Any, + _CHAIN: "Type[chain[_PayloadRegistryItem]]" = chain, + **kwargs: Any, ) -> "Payload": if isinstance(data, Payload): return data @@ -112,7 +119,7 @@ def get( raise LookupError() def register( - self, factory: Type["Payload"], type: Any, *, order: Order = Order.normal + self, factory: PayloadType, type: Any, *, order: Order = Order.normal ) -> None: if order is Order.try_first: self._first.append((factory, type)) @@ -126,8 +133,8 @@ def register( class Payload(ABC): - _default_content_type = "application/octet-stream" # type: str - _size = None # type: Optional[int] + _default_content_type: str = "application/octet-stream" + _size: Optional[int] = None def __init__( self, @@ -135,14 +142,14 @@ def __init__( headers: Optional[ Union[_CIMultiDict, Dict[str, str], Iterable[Tuple[str, str]]] ] = None, - content_type: Optional[str] = sentinel, + content_type: Union[str, None, _SENTINEL] = sentinel, filename: Optional[str] = None, encoding: Optional[str] = None, **kwargs: Any, ) -> None: self._encoding = encoding self._filename = filename - self._headers = CIMultiDict() # type: _CIMultiDict + self._headers: _CIMultiDict = CIMultiDict() self._value = value if content_type is not sentinel and content_type is not None: self._headers[hdrs.CONTENT_TYPE] = content_type @@ -190,11 +197,15 @@ def content_type(self) -> str: return self._headers[hdrs.CONTENT_TYPE] def set_content_disposition( - self, disptype: str, quote_fields: bool = True, **params: Any + self, + disptype: str, + quote_fields: bool = True, + _charset: str = "utf-8", + **params: Any, ) -> None: """Sets ``Content-Disposition`` header.""" self._headers[hdrs.CONTENT_DISPOSITION] = content_disposition_header( - disptype, quote_fields=quote_fields, **params + disptype, quote_fields=quote_fields, _charset=_charset, **params ) @abstractmethod @@ -208,9 +219,7 @@ async def write(self, writer: AbstractStreamWriter) -> None: class BytesPayload(Payload): def __init__(self, value: ByteString, *args: Any, **kwargs: Any) -> None: if not isinstance(value, (bytes, bytearray, memoryview)): - raise TypeError( - "value argument must be byte-ish, not {!r}".format(type(value)) - ) + raise TypeError(f"value argument must be byte-ish, not {type(value)!r}") if "content_type" not in kwargs: kwargs["content_type"] = "application/octet-stream" @@ -223,10 +232,7 @@ def __init__(self, value: ByteString, *args: Any, **kwargs: Any) -> None: self._size = len(value) if self._size > TOO_LARGE_BYTES_BODY: - if PY_36: - kwargs = {"source": self} - else: - kwargs = {} + kwargs = {"source": self} warnings.warn( "Sending a large body directly with raw bytes might" " lock the event loop. You should probably pass an " @@ -242,7 +248,7 @@ async def write(self, writer: AbstractStreamWriter) -> None: class StringPayload(BytesPayload): def __init__( self, - value: Text, + value: str, *args: Any, encoding: Optional[str] = None, content_type: Optional[str] = None, @@ -276,6 +282,8 @@ def __init__(self, value: IO[str], *args: Any, **kwargs: Any) -> None: class IOBasePayload(Payload): + _value: IO[Any] + def __init__( self, value: IO[Any], disposition: str = "attachment", *args: Any, **kwargs: Any ) -> None: @@ -291,15 +299,17 @@ def __init__( async def write(self, writer: AbstractStreamWriter) -> None: loop = asyncio.get_event_loop() try: - chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + chunk = await loop.run_in_executor(None, self._value.read, 2**16) while chunk: await writer.write(chunk) - chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + chunk = await loop.run_in_executor(None, self._value.read, 2**16) finally: await loop.run_in_executor(None, self._value.close) class TextIOPayload(IOBasePayload): + _value: TextIO + def __init__( self, value: TextIO, @@ -338,10 +348,15 @@ def size(self) -> Optional[int]: async def write(self, writer: AbstractStreamWriter) -> None: loop = asyncio.get_event_loop() try: - chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + chunk = await loop.run_in_executor(None, self._value.read, 2**16) while chunk: - await writer.write(chunk.encode(self._encoding)) - chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + data = ( + chunk.encode(encoding=self._encoding) + if self._encoding + else chunk.encode() + ) + await writer.write(data) + chunk = await loop.run_in_executor(None, self._value.read, 2**16) finally: await loop.run_in_executor(None, self._value.close) @@ -386,7 +401,7 @@ def __init__( ) -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from typing import AsyncIterable, AsyncIterator _AsyncIterator = AsyncIterator[bytes] @@ -400,13 +415,13 @@ def __init__( class AsyncIterablePayload(Payload): - _iter = None # type: Optional[_AsyncIterator] + _iter: Optional[_AsyncIterator] = None def __init__(self, value: _AsyncIterable, *args: Any, **kwargs: Any) -> None: if not isinstance(value, AsyncIterable): raise TypeError( "value argument must support " - "collections.abc.AsyncIterablebe interface, " + "collections.abc.AsyncIterable interface, " "got {!r}".format(type(value)) ) diff --git a/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py b/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py index 3b2de151..364f763a 100644 --- a/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py +++ b/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py @@ -1,4 +1,5 @@ -""" Payload implemenation for coroutines as data provider. +""" +Payload implementation for coroutines as data provider. As a simple case, you can upload data from file:: @@ -43,7 +44,7 @@ def __init__( self.kwargs = kwargs async def __call__(self, writer: AbstractStreamWriter) -> None: - await self.coro(writer, *self.args, **self.kwargs) # type: ignore + await self.coro(writer, *self.args, **self.kwargs) class streamer: diff --git a/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py b/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py index 52042934..5754747b 100644 --- a/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py +++ b/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py @@ -1,11 +1,11 @@ import asyncio import contextlib import warnings -from collections.abc import Callable +from typing import Any, Awaitable, Callable, Dict, Iterator, Optional, Type, Union import pytest -from aiohttp.helpers import PY_37, isasyncgenfunction +from aiohttp.helpers import isasyncgenfunction from aiohttp.web import Application from .test_utils import ( @@ -22,15 +22,14 @@ try: import uvloop except ImportError: # pragma: no cover - uvloop = None + uvloop = None # type: ignore[assignment] -try: - import tokio -except ImportError: # pragma: no cover - tokio = None +AiohttpClient = Callable[[Union[Application, BaseTestServer]], Awaitable[TestClient]] +AiohttpRawServer = Callable[[Application], Awaitable[RawTestServer]] +AiohttpServer = Callable[[Application], Awaitable[TestServer]] -def pytest_addoption(parser): # type: ignore +def pytest_addoption(parser): # type: ignore[no-untyped-def] parser.addoption( "--aiohttp-fast", action="store_true", @@ -41,7 +40,7 @@ def pytest_addoption(parser): # type: ignore "--aiohttp-loop", action="store", default="pyloop", - help="run tests with specific loop: pyloop, uvloop, tokio or all", + help="run tests with specific loop: pyloop, uvloop or all", ) parser.addoption( "--aiohttp-enable-loop-debug", @@ -51,8 +50,9 @@ def pytest_addoption(parser): # type: ignore ) -def pytest_fixture_setup(fixturedef): # type: ignore - """ +def pytest_fixture_setup(fixturedef): # type: ignore[no-untyped-def] + """Set up pytest fixture. + Allow fixtures to be coroutines. Run coroutine fixtures in an event loop. """ func = fixturedef.func @@ -72,7 +72,7 @@ def pytest_fixture_setup(fixturedef): # type: ignore fixturedef.argnames += ("request",) strip_request = True - def wrapper(*args, **kwargs): # type: ignore + def wrapper(*args, **kwargs): # type: ignore[no-untyped-def] request = kwargs["request"] if strip_request: del kwargs["request"] @@ -93,7 +93,7 @@ def wrapper(*args, **kwargs): # type: ignore # then advance it again in a finalizer gen = func(*args, **kwargs) - def finalizer(): # type: ignore + def finalizer(): # type: ignore[no-untyped-def] try: return _loop.run_until_complete(gen.__anext__()) except StopAsyncIteration: @@ -108,21 +108,22 @@ def finalizer(): # type: ignore @pytest.fixture -def fast(request): # type: ignore +def fast(request): # type: ignore[no-untyped-def] """--fast config option""" return request.config.getoption("--aiohttp-fast") @pytest.fixture -def loop_debug(request): # type: ignore +def loop_debug(request): # type: ignore[no-untyped-def] """--enable-loop-debug config option""" return request.config.getoption("--aiohttp-enable-loop-debug") @contextlib.contextmanager -def _runtime_warning_context(): # type: ignore - """ - Context manager which checks for RuntimeWarnings, specifically to +def _runtime_warning_context(): # type: ignore[no-untyped-def] + """Context manager which checks for RuntimeWarnings. + + This exists specifically to avoid "coroutine 'X' was never awaited" warnings being missed. If RuntimeWarnings occur in the context a RuntimeError is raised. @@ -143,9 +144,10 @@ def _runtime_warning_context(): # type: ignore @contextlib.contextmanager -def _passthrough_loop_context(loop, fast=False): # type: ignore - """ - setups and tears down a loop unless one is passed in via the loop +def _passthrough_loop_context(loop, fast=False): # type: ignore[no-untyped-def] + """Passthrough loop context. + + Sets up and tears down a loop unless one is passed in via the loop argument when it's passed straight through. """ if loop: @@ -158,18 +160,14 @@ def _passthrough_loop_context(loop, fast=False): # type: ignore teardown_test_loop(loop, fast=fast) -def pytest_pycollect_makeitem(collector, name, obj): # type: ignore - """ - Fix pytest collecting for coroutines. - """ +def pytest_pycollect_makeitem(collector, name, obj): # type: ignore[no-untyped-def] + """Fix pytest collecting for coroutines.""" if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj): return list(collector._genfunctions(name, obj)) -def pytest_pyfunc_call(pyfuncitem): # type: ignore - """ - Run coroutines in an event loop instead of a normal function call. - """ +def pytest_pyfunc_call(pyfuncitem): # type: ignore[no-untyped-def] + """Run coroutines in an event loop instead of a normal function call.""" fast = pyfuncitem.config.getoption("--aiohttp-fast") if asyncio.iscoroutinefunction(pyfuncitem.function): existing_loop = pyfuncitem.funcargs.get( @@ -186,23 +184,21 @@ def pytest_pyfunc_call(pyfuncitem): # type: ignore return True -def pytest_generate_tests(metafunc): # type: ignore +def pytest_generate_tests(metafunc): # type: ignore[no-untyped-def] if "loop_factory" not in metafunc.fixturenames: return loops = metafunc.config.option.aiohttp_loop + avail_factories: Dict[str, Type[asyncio.AbstractEventLoopPolicy]] avail_factories = {"pyloop": asyncio.DefaultEventLoopPolicy} if uvloop is not None: # pragma: no cover avail_factories["uvloop"] = uvloop.EventLoopPolicy - if tokio is not None: # pragma: no cover - avail_factories["tokio"] = tokio.EventLoopPolicy - if loops == "all": - loops = "pyloop,uvloop?,tokio?" + loops = "pyloop,uvloop?" - factories = {} # type: ignore + factories = {} # type: ignore[var-annotated] for name in loops.split(","): required = not name.endswith("?") name = name.strip(" ?") @@ -221,7 +217,7 @@ def pytest_generate_tests(metafunc): # type: ignore @pytest.fixture -def loop(loop_factory, fast, loop_debug): # type: ignore +def loop(loop_factory, fast, loop_debug): # type: ignore[no-untyped-def] """Return an instance of the event loop.""" policy = loop_factory() asyncio.set_event_loop_policy(policy) @@ -233,13 +229,9 @@ def loop(loop_factory, fast, loop_debug): # type: ignore @pytest.fixture -def proactor_loop(): # type: ignore - if not PY_37: - policy = asyncio.get_event_loop_policy() - policy._loop_factory = asyncio.ProactorEventLoop # type: ignore - else: - policy = asyncio.WindowsProactorEventLoopPolicy() # type: ignore - asyncio.set_event_loop_policy(policy) +def proactor_loop(): # type: ignore[no-untyped-def] + policy = asyncio.WindowsProactorEventLoopPolicy() # type: ignore[attr-defined] + asyncio.set_event_loop_policy(policy) with loop_context(policy.new_event_loop) as _loop: asyncio.set_event_loop(_loop) @@ -247,7 +239,7 @@ def proactor_loop(): # type: ignore @pytest.fixture -def unused_port(aiohttp_unused_port): # type: ignore # pragma: no cover +def unused_port(aiohttp_unused_port: Callable[[], int]) -> Callable[[], int]: warnings.warn( "Deprecated, use aiohttp_unused_port fixture instead", DeprecationWarning, @@ -257,20 +249,20 @@ def unused_port(aiohttp_unused_port): # type: ignore # pragma: no cover @pytest.fixture -def aiohttp_unused_port(): # type: ignore +def aiohttp_unused_port() -> Callable[[], int]: """Return a port that is unused on the current host.""" return _unused_port @pytest.fixture -def aiohttp_server(loop): # type: ignore +def aiohttp_server(loop: asyncio.AbstractEventLoop) -> Iterator[AiohttpServer]: """Factory to create a TestServer instance, given an app. aiohttp_server(app, **kwargs) """ servers = [] - async def go(app, *, port=None, **kwargs): # type: ignore + async def go(app, *, port=None, **kwargs): # type: ignore[no-untyped-def] server = TestServer(app, port=port) await server.start_server(loop=loop, **kwargs) servers.append(server) @@ -278,7 +270,7 @@ async def go(app, *, port=None, **kwargs): # type: ignore yield go - async def finalize(): # type: ignore + async def finalize() -> None: while servers: await servers.pop().close() @@ -286,7 +278,7 @@ async def finalize(): # type: ignore @pytest.fixture -def test_server(aiohttp_server): # type: ignore # pragma: no cover +def test_server(aiohttp_server): # type: ignore[no-untyped-def] # pragma: no cover warnings.warn( "Deprecated, use aiohttp_server fixture instead", DeprecationWarning, @@ -296,14 +288,14 @@ def test_server(aiohttp_server): # type: ignore # pragma: no cover @pytest.fixture -def aiohttp_raw_server(loop): # type: ignore +def aiohttp_raw_server(loop: asyncio.AbstractEventLoop) -> Iterator[AiohttpRawServer]: """Factory to create a RawTestServer instance, given a web handler. aiohttp_raw_server(handler, **kwargs) """ servers = [] - async def go(handler, *, port=None, **kwargs): # type: ignore + async def go(handler, *, port=None, **kwargs): # type: ignore[no-untyped-def] server = RawTestServer(handler, port=port) await server.start_server(loop=loop, **kwargs) servers.append(server) @@ -311,7 +303,7 @@ async def go(handler, *, port=None, **kwargs): # type: ignore yield go - async def finalize(): # type: ignore + async def finalize() -> None: while servers: await servers.pop().close() @@ -319,7 +311,9 @@ async def finalize(): # type: ignore @pytest.fixture -def raw_test_server(aiohttp_raw_server): # type: ignore # pragma: no cover +def raw_test_server( # type: ignore[no-untyped-def] # pragma: no cover + aiohttp_raw_server, +): warnings.warn( "Deprecated, use aiohttp_raw_server fixture instead", DeprecationWarning, @@ -329,7 +323,9 @@ def raw_test_server(aiohttp_raw_server): # type: ignore # pragma: no cover @pytest.fixture -def aiohttp_client(loop): # type: ignore +def aiohttp_client( + loop: asyncio.AbstractEventLoop, +) -> Iterator[AiohttpClient]: """Factory to create a TestClient instance. aiohttp_client(app, **kwargs) @@ -338,9 +334,14 @@ def aiohttp_client(loop): # type: ignore """ clients = [] - async def go(__param, *args, server_kwargs=None, **kwargs): # type: ignore + async def go( + __param: Union[Application, BaseTestServer], + *args: Any, + server_kwargs: Optional[Dict[str, Any]] = None, + **kwargs: Any + ) -> TestClient: - if isinstance(__param, Callable) and not isinstance( # type: ignore + if isinstance(__param, Callable) and not isinstance( # type: ignore[arg-type] __param, (Application, BaseTestServer) ): __param = __param(loop, *args, **kwargs) @@ -363,7 +364,7 @@ async def go(__param, *args, server_kwargs=None, **kwargs): # type: ignore yield go - async def finalize(): # type: ignore + async def finalize() -> None: while clients: await clients.pop().close() @@ -371,7 +372,7 @@ async def finalize(): # type: ignore @pytest.fixture -def test_client(aiohttp_client): # type: ignore # pragma: no cover +def test_client(aiohttp_client): # type: ignore[no-untyped-def] # pragma: no cover warnings.warn( "Deprecated, use aiohttp_client fixture instead", DeprecationWarning, diff --git a/dist/ba_data/python-site-packages/aiohttp/resolver.py b/dist/ba_data/python-site-packages/aiohttp/resolver.py index 2974bcad..6c17b1e7 100644 --- a/dist/ba_data/python-site-packages/aiohttp/resolver.py +++ b/dist/ba_data/python-site-packages/aiohttp/resolver.py @@ -1,6 +1,6 @@ import asyncio import socket -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Type, Union from .abc import AbstractResolver from .helpers import get_running_loop @@ -18,8 +18,10 @@ class ThreadedResolver(AbstractResolver): - """Use Executor for synchronous getaddrinfo() calls, which defaults to - concurrent.futures.ThreadPoolExecutor. + """Threaded resolver. + + Uses an Executor for synchronous getaddrinfo() calls. + concurrent.futures.ThreadPoolExecutor is used by default. """ def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: @@ -38,16 +40,24 @@ async def resolve( hosts = [] for family, _, proto, _, address in infos: - if family == socket.AF_INET6 and address[3]: # type: ignore - # This is essential for link-local IPv6 addresses. - # LL IPv6 is a VERY rare case. Strictly speaking, we should use - # getnameinfo() unconditionally, but performance makes sense. - host, _port = socket.getnameinfo( - address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV - ) - port = int(_port) - else: - host, port = address[:2] + if family == socket.AF_INET6: + if len(address) < 3: + # IPv6 is not supported by Python build, + # or IPv6 is not enabled in the host + continue + if address[3]: + # This is essential for link-local IPv6 addresses. + # LL IPv6 is a VERY rare case. Strictly speaking, we should use + # getnameinfo() unconditionally, but performance makes sense. + host, _port = socket.getnameinfo( + address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV + ) + port = int(_port) + else: + host, port = address[:2] + else: # IPv4 + assert family == socket.AF_INET + host, port = address # type: ignore[misc] hosts.append( { "hostname": hostname, @@ -143,7 +153,8 @@ async def _resolve_with_query( return hosts async def close(self) -> None: - return self._resolver.cancel() + self._resolver.cancel() -DefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver +_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]] +DefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver diff --git a/dist/ba_data/python-site-packages/aiohttp/signals.py b/dist/ba_data/python-site-packages/aiohttp/signals.py deleted file mode 100644 index d406c024..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/signals.py +++ /dev/null @@ -1,34 +0,0 @@ -from aiohttp.frozenlist import FrozenList - -__all__ = ("Signal",) - - -class Signal(FrozenList): - """Coroutine-based signal implementation. - - To connect a callback to a signal, use any list method. - - Signals are fired using the send() coroutine, which takes named - arguments. - """ - - __slots__ = ("_owner",) - - def __init__(self, owner): - super().__init__() - self._owner = owner - - def __repr__(self): - return "".format( - self._owner, self.frozen, list(self) - ) - - async def send(self, *args, **kwargs): - """ - Sends data to all registered receivers. - """ - if not self.frozen: - raise RuntimeError("Cannot send non-frozen signal.") - - for receiver in self: - await receiver(*args, **kwargs) # type: ignore diff --git a/dist/ba_data/python-site-packages/aiohttp/signals.pyi b/dist/ba_data/python-site-packages/aiohttp/signals.pyi deleted file mode 100644 index 455f8e2f..00000000 --- a/dist/ba_data/python-site-packages/aiohttp/signals.pyi +++ /dev/null @@ -1,12 +0,0 @@ -from typing import Any, Generic, TypeVar - -from aiohttp.frozenlist import FrozenList - -__all__ = ("Signal",) - -_T = TypeVar("_T") - -class Signal(FrozenList[_T], Generic[_T]): - def __init__(self, owner: Any) -> None: ... - def __repr__(self) -> str: ... - async def send(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/dist/ba_data/python-site-packages/aiohttp/streams.py b/dist/ba_data/python-site-packages/aiohttp/streams.py index 42970b53..b9b9c3fd 100644 --- a/dist/ba_data/python-site-packages/aiohttp/streams.py +++ b/dist/ba_data/python-site-packages/aiohttp/streams.py @@ -1,17 +1,28 @@ import asyncio import collections import warnings -from typing import Awaitable, Callable, Generic, List, Optional, Tuple, TypeVar +from typing import ( + Awaitable, + Callable, + Deque, + Final, + Generic, + List, + Optional, + Tuple, + TypeVar, +) from .base_protocol import BaseProtocol -from .helpers import BaseTimerContext, set_exception, set_result +from .helpers import ( + _EXC_SENTINEL, + BaseTimerContext, + TimerNoop, + set_exception, + set_result, +) from .log import internal_logger -try: # pragma: no cover - from typing import Deque -except ImportError: - from typing_extensions import Deque - __all__ = ( "EMPTY_PAYLOAD", "EofStream", @@ -60,31 +71,23 @@ async def __anext__(self) -> Tuple[bytes, bool]: class AsyncStreamReaderMixin: def __aiter__(self) -> AsyncStreamIterator[bytes]: - return AsyncStreamIterator(self.readline) # type: ignore + return AsyncStreamIterator(self.readline) # type: ignore[attr-defined] def iter_chunked(self, n: int) -> AsyncStreamIterator[bytes]: - """Returns an asynchronous iterator that yields chunks of size n. - - Python-3.5 available for Python 3.5+ only - """ - return AsyncStreamIterator(lambda: self.read(n)) # type: ignore + """Returns an asynchronous iterator that yields chunks of size n.""" + return AsyncStreamIterator(lambda: self.read(n)) # type: ignore[attr-defined] def iter_any(self) -> AsyncStreamIterator[bytes]: - """Returns an asynchronous iterator that yields all the available - data as soon as it is received - - Python-3.5 available for Python 3.5+ only - """ - return AsyncStreamIterator(self.readany) # type: ignore + """Yield all available data as soon as it is received.""" + return AsyncStreamIterator(self.readany) # type: ignore[attr-defined] def iter_chunks(self) -> ChunkTupleAsyncStreamIterator: - """Returns an asynchronous iterator that yields chunks of data - as they are received by the server. The yielded objects are tuples - of (bytes, bool) as returned by the StreamReader.readchunk method. + """Yield chunks of data as they are received by the server. - Python-3.5 available for Python 3.5+ only + The yielded objects are tuples + of (bytes, bool) as returned by the StreamReader.readchunk method. """ - return ChunkTupleAsyncStreamIterator(self) # type: ignore + return ChunkTupleAsyncStreamIterator(self) # type: ignore[arg-type] class StreamReader(AsyncStreamReaderMixin): @@ -109,7 +112,7 @@ def __init__( limit: int, *, timer: Optional[BaseTimerContext] = None, - loop: Optional[asyncio.AbstractEventLoop] = None + loop: Optional[asyncio.AbstractEventLoop] = None, ) -> None: self._protocol = protocol self._low_water = limit @@ -119,15 +122,15 @@ def __init__( self._loop = loop self._size = 0 self._cursor = 0 - self._http_chunk_splits = None # type: Optional[List[int]] - self._buffer = collections.deque() # type: Deque[bytes] + self._http_chunk_splits: Optional[List[int]] = None + self._buffer: Deque[bytes] = collections.deque() self._buffer_offset = 0 self._eof = False - self._waiter = None # type: Optional[asyncio.Future[None]] - self._eof_waiter = None # type: Optional[asyncio.Future[None]] - self._exception = None # type: Optional[BaseException] - self._timer = timer - self._eof_callbacks = [] # type: List[Callable[[], None]] + self._waiter: Optional[asyncio.Future[None]] = None + self._eof_waiter: Optional[asyncio.Future[None]] = None + self._exception: Optional[BaseException] = None + self._timer = TimerNoop() if timer is None else timer + self._eof_callbacks: List[Callable[[], None]] = [] def __repr__(self) -> str: info = [self.__class__.__name__] @@ -135,7 +138,7 @@ def __repr__(self) -> str: info.append("%d bytes" % self._size) if self._eof: info.append("eof") - if self._low_water != 2 ** 16: # default limit + if self._low_water != 2**16: # default limit info.append("low=%d high=%d" % (self._low_water, self._high_water)) if self._waiter: info.append("w=%r" % self._waiter) @@ -149,19 +152,23 @@ def get_read_buffer_limits(self) -> Tuple[int, int]: def exception(self) -> Optional[BaseException]: return self._exception - def set_exception(self, exc: BaseException) -> None: + def set_exception( + self, + exc: BaseException, + exc_cause: BaseException = _EXC_SENTINEL, + ) -> None: self._exception = exc self._eof_callbacks.clear() waiter = self._waiter if waiter is not None: self._waiter = None - set_exception(waiter, exc) + set_exception(waiter, exc, exc_cause) waiter = self._eof_waiter if waiter is not None: self._eof_waiter = None - set_exception(waiter, exc) + set_exception(waiter, exc, exc_cause) def on_eof(self, callback: Callable[[], None]) -> None: if self._eof: @@ -268,7 +275,7 @@ def end_http_chunk_receiving(self) -> None: # self._http_chunk_splits contains logical byte offsets from start of # the body transfer. Each offset is the offset of the end of a chunk. # "Logical" means bytes, accessible for a user. - # If no chunks containig logical data were received, current position + # If no chunks containing logical data were received, current position # is difinitely zero. pos = self._http_chunk_splits[-1] if self._http_chunk_splits else 0 @@ -301,43 +308,49 @@ async def _wait(self, func_name: str) -> None: waiter = self._waiter = self._loop.create_future() try: - if self._timer: - with self._timer: - await waiter - else: + with self._timer: await waiter finally: self._waiter = None async def readline(self) -> bytes: + return await self.readuntil() + + async def readuntil(self, separator: bytes = b"\n") -> bytes: + seplen = len(separator) + if seplen == 0: + raise ValueError("Separator should be at least one-byte string") + if self._exception is not None: raise self._exception - line = [] - line_size = 0 + chunk = b"" + chunk_size = 0 not_enough = True while not_enough: while self._buffer and not_enough: offset = self._buffer_offset - ichar = self._buffer[0].find(b"\n", offset) + 1 - # Read from current offset to found b'\n' or to the end. - data = self._read_nowait_chunk(ichar - offset if ichar else -1) - line.append(data) - line_size += len(data) + ichar = self._buffer[0].find(separator, offset) + 1 + # Read from current offset to found separator or to the end. + data = self._read_nowait_chunk( + ichar - offset + seplen - 1 if ichar else -1 + ) + chunk += data + chunk_size += len(data) if ichar: not_enough = False - if line_size > self._high_water: - raise ValueError("Line is too long") + if chunk_size > self._high_water: + raise ValueError("Chunk too big") if self._eof: break if not_enough: - await self._wait("readline") + await self._wait("readuntil") - return b"".join(line) + return chunk async def read(self, n: int = -1) -> bytes: if self._exception is not None: @@ -394,7 +407,9 @@ async def readany(self) -> bytes: return self._read_nowait(-1) async def readchunk(self) -> Tuple[bytes, bool]: - """Returns a tuple of (data, end_of_http_chunk). When chunked transfer + """Returns a tuple of (data, end_of_http_chunk). + + When chunked transfer encoding is used, end_of_http_chunk is a boolean indicating if the end of the data corresponds to the end of a HTTP chunk , otherwise it is always False. @@ -429,7 +444,7 @@ async def readexactly(self, n: int) -> bytes: if self._exception is not None: raise self._exception - blocks = [] # type: List[bytes] + blocks: List[bytes] = [] while n > 0: block = await self.read(n) if not block: @@ -483,9 +498,10 @@ def _read_nowait_chunk(self, n: int) -> bytes: return data def _read_nowait(self, n: int) -> bytes: - """ Read not more than n bytes, or whole buffer if n == -1 """ - chunks = [] + """Read not more than n bytes, or whole buffer if n == -1""" + self._timer.assert_timeout() + chunks = [] while self._buffer: chunk = self._read_nowait_chunk(n) chunks.append(chunk) @@ -497,11 +513,21 @@ def _read_nowait(self, n: int) -> bytes: return b"".join(chunks) if chunks else b"" -class EmptyStreamReader(AsyncStreamReaderMixin): +class EmptyStreamReader(StreamReader): # lgtm [py/missing-call-to-init] + def __init__(self) -> None: + self._read_eof_chunk = False + + def __repr__(self) -> str: + return "<%s>" % self.__class__.__name__ + def exception(self) -> Optional[BaseException]: return None - def set_exception(self, exc: BaseException) -> None: + def set_exception( + self, + exc: BaseException, + exc_cause: BaseException = _EXC_SENTINEL, + ) -> None: pass def on_eof(self, callback: Callable[[], None]) -> None: @@ -531,20 +557,26 @@ async def readline(self) -> bytes: async def read(self, n: int = -1) -> bytes: return b"" + # TODO add async def readuntil + async def readany(self) -> bytes: return b"" async def readchunk(self) -> Tuple[bytes, bool]: + if not self._read_eof_chunk: + self._read_eof_chunk = True + return (b"", False) + return (b"", True) async def readexactly(self, n: int) -> bytes: raise asyncio.IncompleteReadError(b"", n) - def read_nowait(self) -> bytes: + def read_nowait(self, n: int = -1) -> bytes: return b"" -EMPTY_PAYLOAD = EmptyStreamReader() +EMPTY_PAYLOAD: Final[StreamReader] = EmptyStreamReader() class DataQueue(Generic[_T]): @@ -553,10 +585,10 @@ class DataQueue(Generic[_T]): def __init__(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop self._eof = False - self._waiter = None # type: Optional[asyncio.Future[None]] - self._exception = None # type: Optional[BaseException] + self._waiter: Optional[asyncio.Future[None]] = None + self._exception: Optional[BaseException] = None self._size = 0 - self._buffer = collections.deque() # type: Deque[Tuple[_T, int]] + self._buffer: Deque[Tuple[_T, int]] = collections.deque() def __len__(self) -> int: return len(self._buffer) @@ -570,14 +602,18 @@ def at_eof(self) -> bool: def exception(self) -> Optional[BaseException]: return self._exception - def set_exception(self, exc: BaseException) -> None: + def set_exception( + self, + exc: BaseException, + exc_cause: BaseException = _EXC_SENTINEL, + ) -> None: self._eof = True self._exception = exc waiter = self._waiter if waiter is not None: self._waiter = None - set_exception(waiter, exc) + set_exception(waiter, exc, exc_cause) def feed_data(self, data: _T, size: int = 0) -> None: self._size += size @@ -623,7 +659,8 @@ def __aiter__(self) -> AsyncStreamIterator[_T]: class FlowControlDataQueue(DataQueue[_T]): """FlowControlDataQueue resumes and pauses an underlying stream. - It is a destination for parsed data.""" + It is a destination for parsed data. + """ def __init__( self, protocol: BaseProtocol, limit: int, *, loop: asyncio.AbstractEventLoop diff --git a/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py b/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py index 0e1dbf16..88b24422 100644 --- a/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py +++ b/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py @@ -15,7 +15,6 @@ def tcp_keepalive(transport: asyncio.Transport) -> None: if sock is not None: sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - else: def tcp_keepalive(transport: asyncio.Transport) -> None: # pragma: no cover diff --git a/dist/ba_data/python-site-packages/aiohttp/test_utils.py b/dist/ba_data/python-site-packages/aiohttp/test_utils.py index 7a9ca7dd..a36e8599 100644 --- a/dist/ba_data/python-site-packages/aiohttp/test_utils.py +++ b/dist/ba_data/python-site-packages/aiohttp/test_utils.py @@ -2,27 +2,34 @@ import asyncio import contextlib -import functools import gc import inspect +import ipaddress import os import socket import sys -import unittest +import warnings from abc import ABC, abstractmethod from types import TracebackType -from typing import TYPE_CHECKING, Any, Callable, Iterator, List, Optional, Type, Union -from unittest import mock +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Iterator, + List, + Optional, + Type, + Union, + cast, +) +from unittest import IsolatedAsyncioTestCase, mock +from aiosignal import Signal from multidict import CIMultiDict, CIMultiDictProxy from yarl import URL import aiohttp -from aiohttp.client import ( - ClientResponse, - _RequestContextManager, - _WSRequestContextManager, -) +from aiohttp.client import _RequestContextManager, _WSRequestContextManager from . import ClientSession, hdrs from .abc import AbstractCookieJar @@ -30,7 +37,7 @@ from .client_ws import ClientWebSocketResponse from .helpers import sentinel from .http import HttpVersion, RawRequestMessage -from .signals import Signal +from .typedefs import StrOrURL from .web import ( Application, AppRunner, @@ -43,21 +50,24 @@ ) from .web_protocol import _RequestHandler -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from ssl import SSLContext else: SSLContext = None - REUSE_ADDRESS = os.name == "posix" and sys.platform != "cygwin" -def get_unused_port_socket(host: str) -> socket.socket: - return get_port_socket(host, 0) +def get_unused_port_socket( + host: str, family: socket.AddressFamily = socket.AF_INET +) -> socket.socket: + return get_port_socket(host, 0, family) -def get_port_socket(host: str, port: int) -> socket.socket: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +def get_port_socket( + host: str, port: int, family: socket.AddressFamily +) -> socket.socket: + s = socket.socket(family, socket.SOCK_STREAM) if REUSE_ADDRESS: # Windows has different semantics for SO_REUSEADDR, # so don't set it. Ref: @@ -71,7 +81,7 @@ def unused_port() -> int: """Return a port that is unused on the current host.""" with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind(("127.0.0.1", 0)) - return s.getsockname()[1] + return cast(int, s.getsockname()[1]) class BaseTestServer(ABC): @@ -85,16 +95,20 @@ def __init__( host: str = "127.0.0.1", port: Optional[int] = None, skip_url_asserts: bool = False, + socket_factory: Callable[ + [str, int, socket.AddressFamily], socket.socket + ] = get_port_socket, **kwargs: Any, ) -> None: self._loop = loop - self.runner = None # type: Optional[BaseRunner] - self._root = None # type: Optional[URL] + self.runner: Optional[BaseRunner] = None + self._root: Optional[URL] = None self.host = host self.port = port self._closed = False self.scheme = scheme self.skip_url_asserts = skip_url_asserts + self.socket_factory = socket_factory async def start_server( self, loop: Optional[asyncio.AbstractEventLoop] = None, **kwargs: Any @@ -103,17 +117,22 @@ async def start_server( return self._loop = loop self._ssl = kwargs.pop("ssl", None) - self.runner = await self._make_runner(**kwargs) + self.runner = await self._make_runner(handler_cancellation=True, **kwargs) await self.runner.setup() if not self.port: self.port = 0 - _sock = get_port_socket(self.host, self.port) + try: + version = ipaddress.ip_address(self.host).version + except ValueError: + version = 4 + family = socket.AF_INET6 if version == 6 else socket.AF_INET + _sock = self.socket_factory(self.host, self.port, family) self.host, self.port = _sock.getsockname()[:2] site = SockSite(self.runner, sock=_sock, ssl_context=self._ssl) await site.start() server = site._server assert server is not None - sockets = server.sockets + sockets = server.sockets # type: ignore[attr-defined] assert sockets is not None self.port = sockets[0].getsockname()[1] if self.scheme is sentinel: @@ -128,14 +147,14 @@ async def start_server( async def _make_runner(self, **kwargs: Any) -> BaseRunner: pass - def make_url(self, path: str) -> URL: + def make_url(self, path: StrOrURL) -> URL: assert self._root is not None url = URL(path) if not self.skip_url_asserts: assert not url.is_absolute() return self._root.join(url) else: - return URL(str(self._root) + path) + return URL(str(self._root) + str(path)) @property def started(self) -> bool: @@ -261,8 +280,8 @@ def __init__( cookie_jar = aiohttp.CookieJar(unsafe=True, loop=loop) self._session = ClientSession(loop=loop, cookie_jar=cookie_jar, **kwargs) self._closed = False - self._responses = [] # type: List[ClientResponse] - self._websockets = [] # type: List[ClientWebSocketResponse] + self._responses: List[ClientResponse] = [] + self._websockets: List[ClientWebSocketResponse] = [] async def start_server(self) -> None: await self._server.start_server(loop=self._loop) @@ -280,8 +299,8 @@ def server(self) -> BaseTestServer: return self._server @property - def app(self) -> Application: - return getattr(self._server, "app", None) + def app(self) -> Optional[Application]: + return cast(Optional[Application], getattr(self._server, "app", None)) @property def session(self) -> ClientSession: @@ -294,16 +313,20 @@ def session(self) -> ClientSession: """ return self._session - def make_url(self, path: str) -> URL: + def make_url(self, path: StrOrURL) -> URL: return self._server.make_url(path) - async def _request(self, method: str, path: str, **kwargs: Any) -> ClientResponse: + async def _request( + self, method: str, path: StrOrURL, **kwargs: Any + ) -> ClientResponse: resp = await self._session.request(method, self.make_url(path), **kwargs) # save it to close later self._responses.append(resp) return resp - def request(self, method: str, path: str, **kwargs: Any) -> _RequestContextManager: + def request( + self, method: str, path: StrOrURL, **kwargs: Any + ) -> _RequestContextManager: """Routes a request to tested http server. The interface is identical to aiohttp.ClientSession.request, @@ -313,35 +336,35 @@ def request(self, method: str, path: str, **kwargs: Any) -> _RequestContextManag """ return _RequestContextManager(self._request(method, path, **kwargs)) - def get(self, path: str, **kwargs: Any) -> _RequestContextManager: + def get(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP GET request.""" return _RequestContextManager(self._request(hdrs.METH_GET, path, **kwargs)) - def post(self, path: str, **kwargs: Any) -> _RequestContextManager: + def post(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP POST request.""" return _RequestContextManager(self._request(hdrs.METH_POST, path, **kwargs)) - def options(self, path: str, **kwargs: Any) -> _RequestContextManager: + def options(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP OPTIONS request.""" return _RequestContextManager(self._request(hdrs.METH_OPTIONS, path, **kwargs)) - def head(self, path: str, **kwargs: Any) -> _RequestContextManager: + def head(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP HEAD request.""" return _RequestContextManager(self._request(hdrs.METH_HEAD, path, **kwargs)) - def put(self, path: str, **kwargs: Any) -> _RequestContextManager: + def put(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP PUT request.""" return _RequestContextManager(self._request(hdrs.METH_PUT, path, **kwargs)) - def patch(self, path: str, **kwargs: Any) -> _RequestContextManager: + def patch(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP PATCH request.""" return _RequestContextManager(self._request(hdrs.METH_PATCH, path, **kwargs)) - def delete(self, path: str, **kwargs: Any) -> _RequestContextManager: + def delete(self, path: StrOrURL, **kwargs: Any) -> _RequestContextManager: """Perform an HTTP PATCH request.""" return _RequestContextManager(self._request(hdrs.METH_DELETE, path, **kwargs)) - def ws_connect(self, path: str, **kwargs: Any) -> _WSRequestContextManager: + def ws_connect(self, path: StrOrURL, **kwargs: Any) -> _WSRequestContextManager: """Initiate websocket connection. The api corresponds to aiohttp.ClientSession.ws_connect. @@ -349,7 +372,9 @@ def ws_connect(self, path: str, **kwargs: Any) -> _WSRequestContextManager: """ return _WSRequestContextManager(self._ws_connect(path, **kwargs)) - async def _ws_connect(self, path: str, **kwargs: Any) -> ClientWebSocketResponse: + async def _ws_connect( + self, path: StrOrURL, **kwargs: Any + ) -> ClientWebSocketResponse: ws = await self._session.ws_connect(self.make_url(path), **kwargs) self._websockets.append(ws) return ws @@ -400,9 +425,8 @@ async def __aexit__( await self.close() -class AioHTTPTestCase(unittest.TestCase): - """A base class to allow for unittest web applications using - aiohttp. +class AioHTTPTestCase(IsolatedAsyncioTestCase): + """A base class to allow for unittest web applications using aiohttp. Provides the following: @@ -417,43 +441,37 @@ class AioHTTPTestCase(unittest.TestCase): """ async def get_application(self) -> Application: - """ + """Get application. + This method should be overridden to return the aiohttp.web.Application object to test. - """ return self.get_app() def get_app(self) -> Application: """Obsolete method used to constructing web application. - Use .get_application() coroutine instead - + Use .get_application() coroutine instead. """ raise RuntimeError("Did you forget to define get_application()?") - def setUp(self) -> None: - self.loop = setup_test_loop() - - self.app = self.loop.run_until_complete(self.get_application()) - self.server = self.loop.run_until_complete(self.get_server(self.app)) - self.client = self.loop.run_until_complete(self.get_client(self.server)) - - self.loop.run_until_complete(self.client.start_server()) - - self.loop.run_until_complete(self.setUpAsync()) + async def asyncSetUp(self) -> None: + self.loop = asyncio.get_running_loop() + return await self.setUpAsync() async def setUpAsync(self) -> None: - pass + self.app = await self.get_application() + self.server = await self.get_server(self.app) + self.client = await self.get_client(self.server) - def tearDown(self) -> None: - self.loop.run_until_complete(self.tearDownAsync()) - self.loop.run_until_complete(self.client.close()) - teardown_test_loop(self.loop) + await self.client.start_server() + + async def asyncTearDown(self) -> None: + return await self.tearDownAsync() async def tearDownAsync(self) -> None: - pass + await self.client.close() async def get_server(self, app: Application) -> TestServer: """Return a TestServer instance.""" @@ -465,18 +483,17 @@ async def get_client(self, server: TestServer) -> TestClient: def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any: - """A decorator dedicated to use with asynchronous methods of an - AioHTTPTestCase. - - Handles executing an asynchronous function, using - the self.loop of the AioHTTPTestCase. """ + A decorator dedicated to use with asynchronous AioHTTPTestCase test methods. - @functools.wraps(func, *args, **kwargs) - def new_func(self: Any, *inner_args: Any, **inner_kwargs: Any) -> Any: - return self.loop.run_until_complete(func(self, *inner_args, **inner_kwargs)) - - return new_func + In 3.8+, this does nothing. + """ + warnings.warn( + "Decorator `@unittest_run_loop` is no longer needed in aiohttp 3.8+", + DeprecationWarning, + stacklevel=2, + ) + return func _LOOP_FACTORY = Callable[[], asyncio.AbstractEventLoop] @@ -498,34 +515,18 @@ def loop_context( def setup_test_loop( loop_factory: _LOOP_FACTORY = asyncio.new_event_loop, ) -> asyncio.AbstractEventLoop: - """Create and return an asyncio.BaseEventLoop - instance. + """Create and return an asyncio.BaseEventLoop instance. The caller should also call teardown_test_loop, once they are done with the loop. """ loop = loop_factory() - try: - module = loop.__class__.__module__ - skip_watcher = "uvloop" in module - except AttributeError: # pragma: no cover - # Just in case - skip_watcher = True asyncio.set_event_loop(loop) - if sys.platform != "win32" and not skip_watcher: - policy = asyncio.get_event_loop_policy() - watcher = asyncio.SafeChildWatcher() - watcher.attach_loop(loop) - with contextlib.suppress(NotImplementedError): - policy.set_child_watcher(watcher) return loop def teardown_test_loop(loop: asyncio.AbstractEventLoop, fast: bool = False) -> None: - """Teardown and cleanup an event_loop created - by setup_test_loop. - - """ + """Teardown and cleanup an event_loop created by setup_test_loop.""" closed = loop.is_closed() if not closed: loop.call_soon(loop.stop) @@ -545,7 +546,7 @@ def get_dict(app: Any, key: str) -> Any: def set_dict(app: Any, key: str, value: Any) -> None: app.__app_dict[key] = value - app = mock.MagicMock() + app = mock.MagicMock(spec=Application) app.__app_dict = {} app.__getitem__ = get_dict app.__setitem__ = set_dict @@ -583,20 +584,25 @@ def make_mocked_request( transport: Any = sentinel, payload: Any = sentinel, sslcontext: Optional[SSLContext] = None, - client_max_size: int = 1024 ** 2, + client_max_size: int = 1024**2, loop: Any = ..., ) -> Request: """Creates mocked web.Request testing purposes. Useful in unit tests, when spinning full web server is overkill or specific conditions and errors are hard to trigger. - """ - task = mock.Mock() if loop is ...: - loop = mock.Mock() - loop.create_future.return_value = () + # no loop passed, try to get the current one if + # its is running as we need a real loop to create + # executor jobs to be able to do testing + # with a real executor + try: + loop = asyncio.get_running_loop() + except RuntimeError: + loop = mock.Mock() + loop.create_future.return_value = () if version < HttpVersion(1, 1): closing = True @@ -619,7 +625,7 @@ def make_mocked_request( headers, raw_hdrs, closing, - False, + None, False, chunked, URL(path), diff --git a/dist/ba_data/python-site-packages/aiohttp/tracing.py b/dist/ba_data/python-site-packages/aiohttp/tracing.py index 7ae7948f..62847a0b 100644 --- a/dist/ba_data/python-site-packages/aiohttp/tracing.py +++ b/dist/ba_data/python-site-packages/aiohttp/tracing.py @@ -1,16 +1,14 @@ from types import SimpleNamespace -from typing import TYPE_CHECKING, Awaitable, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Awaitable, Optional, Protocol, Type, TypeVar import attr +from aiosignal import Signal from multidict import CIMultiDict from yarl import URL from .client_reqrep import ClientResponse -from .signals import Signal - -if TYPE_CHECKING: # pragma: no cover - from typing_extensions import Protocol +if TYPE_CHECKING: from .client import ClientSession _ParamT_contra = TypeVar("_ParamT_contra", contravariant=True) @@ -42,68 +40,71 @@ def __call__( "TraceRequestRedirectParams", "TraceRequestChunkSentParams", "TraceResponseChunkReceivedParams", + "TraceRequestHeadersSentParams", ) class TraceConfig: - """First-class used to trace requests launched via ClientSession - objects.""" + """First-class used to trace requests launched via ClientSession objects.""" def __init__( self, trace_config_ctx_factory: Type[SimpleNamespace] = SimpleNamespace ) -> None: - self._on_request_start = Signal( - self - ) # type: Signal[_SignalCallback[TraceRequestStartParams]] - self._on_request_chunk_sent = Signal( - self - ) # type: Signal[_SignalCallback[TraceRequestChunkSentParams]] - self._on_response_chunk_received = Signal( - self - ) # type: Signal[_SignalCallback[TraceResponseChunkReceivedParams]] - self._on_request_end = Signal( - self - ) # type: Signal[_SignalCallback[TraceRequestEndParams]] - self._on_request_exception = Signal( - self - ) # type: Signal[_SignalCallback[TraceRequestExceptionParams]] - self._on_request_redirect = Signal( - self - ) # type: Signal[_SignalCallback[TraceRequestRedirectParams]] - self._on_connection_queued_start = Signal( - self - ) # type: Signal[_SignalCallback[TraceConnectionQueuedStartParams]] - self._on_connection_queued_end = Signal( - self - ) # type: Signal[_SignalCallback[TraceConnectionQueuedEndParams]] - self._on_connection_create_start = Signal( + self._on_request_start: Signal[ + _SignalCallback[TraceRequestStartParams] + ] = Signal(self) + self._on_request_chunk_sent: Signal[ + _SignalCallback[TraceRequestChunkSentParams] + ] = Signal(self) + self._on_response_chunk_received: Signal[ + _SignalCallback[TraceResponseChunkReceivedParams] + ] = Signal(self) + self._on_request_end: Signal[_SignalCallback[TraceRequestEndParams]] = Signal( self - ) # type: Signal[_SignalCallback[TraceConnectionCreateStartParams]] - self._on_connection_create_end = Signal( - self - ) # type: Signal[_SignalCallback[TraceConnectionCreateEndParams]] - self._on_connection_reuseconn = Signal( - self - ) # type: Signal[_SignalCallback[TraceConnectionReuseconnParams]] - self._on_dns_resolvehost_start = Signal( - self - ) # type: Signal[_SignalCallback[TraceDnsResolveHostStartParams]] - self._on_dns_resolvehost_end = Signal( - self - ) # type: Signal[_SignalCallback[TraceDnsResolveHostEndParams]] - self._on_dns_cache_hit = Signal( - self - ) # type: Signal[_SignalCallback[TraceDnsCacheHitParams]] - self._on_dns_cache_miss = Signal( - self - ) # type: Signal[_SignalCallback[TraceDnsCacheMissParams]] + ) + self._on_request_exception: Signal[ + _SignalCallback[TraceRequestExceptionParams] + ] = Signal(self) + self._on_request_redirect: Signal[ + _SignalCallback[TraceRequestRedirectParams] + ] = Signal(self) + self._on_connection_queued_start: Signal[ + _SignalCallback[TraceConnectionQueuedStartParams] + ] = Signal(self) + self._on_connection_queued_end: Signal[ + _SignalCallback[TraceConnectionQueuedEndParams] + ] = Signal(self) + self._on_connection_create_start: Signal[ + _SignalCallback[TraceConnectionCreateStartParams] + ] = Signal(self) + self._on_connection_create_end: Signal[ + _SignalCallback[TraceConnectionCreateEndParams] + ] = Signal(self) + self._on_connection_reuseconn: Signal[ + _SignalCallback[TraceConnectionReuseconnParams] + ] = Signal(self) + self._on_dns_resolvehost_start: Signal[ + _SignalCallback[TraceDnsResolveHostStartParams] + ] = Signal(self) + self._on_dns_resolvehost_end: Signal[ + _SignalCallback[TraceDnsResolveHostEndParams] + ] = Signal(self) + self._on_dns_cache_hit: Signal[ + _SignalCallback[TraceDnsCacheHitParams] + ] = Signal(self) + self._on_dns_cache_miss: Signal[ + _SignalCallback[TraceDnsCacheMissParams] + ] = Signal(self) + self._on_request_headers_sent: Signal[ + _SignalCallback[TraceRequestHeadersSentParams] + ] = Signal(self) self._trace_config_ctx_factory = trace_config_ctx_factory def trace_config_ctx( self, trace_request_ctx: Optional[SimpleNamespace] = None ) -> SimpleNamespace: - """ Return a new trace_config_ctx instance """ + """Return a new trace_config_ctx instance""" return self._trace_config_ctx_factory(trace_request_ctx=trace_request_ctx) def freeze(self) -> None: @@ -122,6 +123,7 @@ def freeze(self) -> None: self._on_dns_resolvehost_end.freeze() self._on_dns_cache_hit.freeze() self._on_dns_cache_miss.freeze() + self._on_request_headers_sent.freeze() @property def on_request_start(self) -> "Signal[_SignalCallback[TraceRequestStartParams]]": @@ -205,10 +207,16 @@ def on_dns_cache_hit(self) -> "Signal[_SignalCallback[TraceDnsCacheHitParams]]": def on_dns_cache_miss(self) -> "Signal[_SignalCallback[TraceDnsCacheMissParams]]": return self._on_dns_cache_miss + @property + def on_request_headers_sent( + self, + ) -> "Signal[_SignalCallback[TraceRequestHeadersSentParams]]": + return self._on_request_headers_sent + @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceRequestStartParams: - """ Parameters sent by the `on_request_start` signal""" + """Parameters sent by the `on_request_start` signal""" method: str url: URL @@ -217,7 +225,7 @@ class TraceRequestStartParams: @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceRequestChunkSentParams: - """ Parameters sent by the `on_request_chunk_sent` signal""" + """Parameters sent by the `on_request_chunk_sent` signal""" method: str url: URL @@ -226,7 +234,7 @@ class TraceRequestChunkSentParams: @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceResponseChunkReceivedParams: - """ Parameters sent by the `on_response_chunk_received` signal""" + """Parameters sent by the `on_response_chunk_received` signal""" method: str url: URL @@ -235,7 +243,7 @@ class TraceResponseChunkReceivedParams: @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceRequestEndParams: - """ Parameters sent by the `on_request_end` signal""" + """Parameters sent by the `on_request_end` signal""" method: str url: URL @@ -245,7 +253,7 @@ class TraceRequestEndParams: @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceRequestExceptionParams: - """ Parameters sent by the `on_request_exception` signal""" + """Parameters sent by the `on_request_exception` signal""" method: str url: URL @@ -255,7 +263,7 @@ class TraceRequestExceptionParams: @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceRequestRedirectParams: - """ Parameters sent by the `on_request_redirect` signal""" + """Parameters sent by the `on_request_redirect` signal""" method: str url: URL @@ -265,60 +273,72 @@ class TraceRequestRedirectParams: @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceConnectionQueuedStartParams: - """ Parameters sent by the `on_connection_queued_start` signal""" + """Parameters sent by the `on_connection_queued_start` signal""" @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceConnectionQueuedEndParams: - """ Parameters sent by the `on_connection_queued_end` signal""" + """Parameters sent by the `on_connection_queued_end` signal""" @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceConnectionCreateStartParams: - """ Parameters sent by the `on_connection_create_start` signal""" + """Parameters sent by the `on_connection_create_start` signal""" @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceConnectionCreateEndParams: - """ Parameters sent by the `on_connection_create_end` signal""" + """Parameters sent by the `on_connection_create_end` signal""" @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceConnectionReuseconnParams: - """ Parameters sent by the `on_connection_reuseconn` signal""" + """Parameters sent by the `on_connection_reuseconn` signal""" @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceDnsResolveHostStartParams: - """ Parameters sent by the `on_dns_resolvehost_start` signal""" + """Parameters sent by the `on_dns_resolvehost_start` signal""" host: str @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceDnsResolveHostEndParams: - """ Parameters sent by the `on_dns_resolvehost_end` signal""" + """Parameters sent by the `on_dns_resolvehost_end` signal""" host: str @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceDnsCacheHitParams: - """ Parameters sent by the `on_dns_cache_hit` signal""" + """Parameters sent by the `on_dns_cache_hit` signal""" host: str @attr.s(auto_attribs=True, frozen=True, slots=True) class TraceDnsCacheMissParams: - """ Parameters sent by the `on_dns_cache_miss` signal""" + """Parameters sent by the `on_dns_cache_miss` signal""" host: str +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestHeadersSentParams: + """Parameters sent by the `on_request_headers_sent` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + + class Trace: - """Internal class used to keep together the main dependencies used - at the moment of send a signal.""" + """Internal dependency holder class. + + Used to keep together the main dependencies used + at the moment of send a signal. + """ def __init__( self, @@ -440,3 +460,12 @@ async def send_dns_cache_miss(self, host: str) -> None: return await self._trace_config.on_dns_cache_miss.send( self._session, self._trace_config_ctx, TraceDnsCacheMissParams(host) ) + + async def send_request_headers( + self, method: str, url: URL, headers: "CIMultiDict[str]" + ) -> None: + return await self._trace_config._on_request_headers_sent.send( + self._session, + self._trace_config_ctx, + TraceRequestHeadersSentParams(method, url, headers), + ) diff --git a/dist/ba_data/python-site-packages/aiohttp/typedefs.py b/dist/ba_data/python-site-packages/aiohttp/typedefs.py index 1b68a242..5e963e1a 100644 --- a/dist/ba_data/python-site-packages/aiohttp/typedefs.py +++ b/dist/ba_data/python-site-packages/aiohttp/typedefs.py @@ -1,8 +1,15 @@ import json import os -import pathlib -import sys -from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping, Tuple, Union +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Iterable, + Mapping, + Tuple, + Union, +) from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, istr from yarl import URL @@ -10,12 +17,14 @@ DEFAULT_JSON_ENCODER = json.dumps DEFAULT_JSON_DECODER = json.loads -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: _CIMultiDict = CIMultiDict[str] _CIMultiDictProxy = CIMultiDictProxy[str] _MultiDict = MultiDict[str] _MultiDictProxy = MultiDictProxy[str] from http.cookies import BaseCookie, Morsel + + from .web import Request, StreamResponse else: _CIMultiDict = CIMultiDict _CIMultiDictProxy = CIMultiDictProxy @@ -39,8 +48,7 @@ "BaseCookie[str]", ] +Handler = Callable[["Request"], Awaitable["StreamResponse"]] +Middleware = Callable[["Request", Handler], Awaitable["StreamResponse"]] -if sys.version_info >= (3, 6): - PathLike = Union[str, "os.PathLike[str]"] -else: - PathLike = Union[str, pathlib.PurePath] +PathLike = Union[str, "os.PathLike[str]"] diff --git a/dist/ba_data/python-site-packages/aiohttp/web.py b/dist/ba_data/python-site-packages/aiohttp/web.py index 557e3c3b..e9116507 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web.py +++ b/dist/ba_data/python-site-packages/aiohttp/web.py @@ -1,26 +1,32 @@ import asyncio import logging +import os import socket import sys +import warnings from argparse import ArgumentParser from collections.abc import Iterable +from contextlib import suppress +from functools import partial from importlib import import_module from typing import ( - Any as Any, - Awaitable as Awaitable, - Callable as Callable, + Any, + Awaitable, + Callable, Iterable as TypingIterable, - List as List, - Optional as Optional, - Set as Set, - Type as Type, - Union as Union, - cast as cast, + List, + Optional, + Set, + Type, + Union, + cast, ) +from weakref import WeakSet from .abc import AbstractAccessLogger -from .helpers import all_tasks +from .helpers import AppKey as AppKey from .log import access_logger +from .typedefs import PathLike from .web_app import Application as Application, CleanupError as CleanupError from .web_exceptions import ( HTTPAccepted as HTTPAccepted, @@ -42,6 +48,7 @@ HTTPLengthRequired as HTTPLengthRequired, HTTPMethodNotAllowed as HTTPMethodNotAllowed, HTTPMisdirectedRequest as HTTPMisdirectedRequest, + HTTPMove as HTTPMove, HTTPMovedPermanently as HTTPMovedPermanently, HTTPMultipleChoices as HTTPMultipleChoices, HTTPNetworkAuthenticationRequired as HTTPNetworkAuthenticationRequired, @@ -80,6 +87,7 @@ HTTPUseProxy as HTTPUseProxy, HTTPVariantAlsoNegotiates as HTTPVariantAlsoNegotiates, HTTPVersionNotSupported as HTTPVersionNotSupported, + NotAppKeyWarning as NotAppKeyWarning, ) from .web_fileresponse import FileResponse as FileResponse from .web_log import AccessLogger @@ -136,6 +144,7 @@ AbstractRoute as AbstractRoute, DynamicResource as DynamicResource, PlainResource as PlainResource, + PrefixedSubAppResource as PrefixedSubAppResource, Resource as Resource, ResourceRoute as ResourceRoute, StaticResource as StaticResource, @@ -151,9 +160,11 @@ __all__ = ( # web_app + "AppKey", "Application", "CleanupError", # web_exceptions + "NotAppKeyWarning", "HTTPAccepted", "HTTPBadGateway", "HTTPBadRequest", @@ -173,6 +184,7 @@ "HTTPLengthRequired", "HTTPMethodNotAllowed", "HTTPMisdirectedRequest", + "HTTPMove", "HTTPMovedPermanently", "HTTPMultipleChoices", "HTTPNetworkAuthenticationRequired", @@ -261,6 +273,7 @@ "AbstractRoute", "DynamicResource", "PlainResource", + "PrefixedSubAppResource", "Resource", "ResourceRoute", "StaticResource", @@ -279,7 +292,10 @@ try: from ssl import SSLContext except ImportError: # pragma: no cover - SSLContext = Any # type: ignore + SSLContext = Any # type: ignore[misc,assignment] + +# Only display warning when using -Wdefault, -We, -X dev or similar. +warnings.filterwarnings("ignore", category=NotAppKeyWarning, append=True) HostSequence = TypingIterable[str] @@ -289,11 +305,12 @@ async def _run_app( *, host: Optional[Union[str, HostSequence]] = None, port: Optional[int] = None, - path: Optional[str] = None, - sock: Optional[socket.socket] = None, + path: Union[PathLike, TypingIterable[PathLike], None] = None, + sock: Optional[Union[socket.socket, TypingIterable[socket.socket]]] = None, shutdown_timeout: float = 60.0, + keepalive_timeout: float = 75.0, ssl_context: Optional[SSLContext] = None, - print: Callable[..., None] = print, + print: Optional[Callable[..., None]] = print, backlog: int = 128, access_log_class: Type[AbstractAccessLogger] = AccessLogger, access_log_format: str = AccessLogger.LOG_FORMAT, @@ -301,10 +318,28 @@ async def _run_app( handle_signals: bool = True, reuse_address: Optional[bool] = None, reuse_port: Optional[bool] = None, + handler_cancellation: bool = False, ) -> None: - # A internal functio to actually do all dirty job for application running + async def wait( + starting_tasks: "WeakSet[asyncio.Task[object]]", shutdown_timeout: float + ) -> None: + # Wait for pending tasks for a given time limit. + t = asyncio.current_task() + assert t is not None + starting_tasks.add(t) + with suppress(asyncio.TimeoutError): + await asyncio.wait_for(_wait(starting_tasks), timeout=shutdown_timeout) + + async def _wait(exclude: "WeakSet[asyncio.Task[object]]") -> None: + t = asyncio.current_task() + assert t is not None + exclude.add(t) + while tasks := asyncio.all_tasks().difference(exclude): + await asyncio.wait(tasks) + + # An internal function to actually do all dirty job for application running if asyncio.iscoroutine(app): - app = await app # type: ignore + app = await app app = cast(Application, app) @@ -314,11 +349,20 @@ async def _run_app( access_log_class=access_log_class, access_log_format=access_log_format, access_log=access_log, + keepalive_timeout=keepalive_timeout, + shutdown_timeout=shutdown_timeout, + handler_cancellation=handler_cancellation, ) await runner.setup() + # On shutdown we want to avoid waiting on tasks which run forever. + # It's very likely that all tasks which run forever will have been created by + # the time we have completed the application startup (in runner.setup()), + # so we just record all running tasks here and exclude them later. + starting_tasks: "WeakSet[asyncio.Task[object]]" = WeakSet(asyncio.all_tasks()) + runner.shutdown_callback = partial(wait, starting_tasks, shutdown_timeout) - sites = [] # type: List[BaseSite] + sites: List[BaseSite] = [] try: if host is not None: @@ -328,7 +372,6 @@ async def _run_app( runner, host, port, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, reuse_address=reuse_address, @@ -342,7 +385,6 @@ async def _run_app( runner, h, port, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, reuse_address=reuse_address, @@ -354,7 +396,6 @@ async def _run_app( TCPSite( runner, port=port, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, reuse_address=reuse_address, @@ -363,12 +404,11 @@ async def _run_app( ) if path is not None: - if isinstance(path, (str, bytes, bytearray, memoryview)): + if isinstance(path, (str, os.PathLike)): sites.append( UnixSite( runner, path, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, ) @@ -379,7 +419,6 @@ async def _run_app( UnixSite( runner, p, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, ) @@ -391,7 +430,6 @@ async def _run_app( SockSite( runner, sock, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, ) @@ -402,7 +440,6 @@ async def _run_app( SockSite( runner, s, - shutdown_timeout=shutdown_timeout, ssl_context=ssl_context, backlog=backlog, ) @@ -418,15 +455,8 @@ async def _run_app( ) # sleep forever by 1 hour intervals, - # on Windows before Python 3.8 wake up every 1 second to handle - # Ctrl+C smoothly - if sys.platform == "win32" and sys.version_info < (3, 8): - delay = 1 - else: - delay = 3600 - while True: - await asyncio.sleep(delay) + await asyncio.sleep(3600) finally: await runner.cleanup() @@ -440,9 +470,7 @@ def _cancel_tasks( for task in to_cancel: task.cancel() - loop.run_until_complete( - asyncio.gather(*to_cancel, loop=loop, return_exceptions=True) - ) + loop.run_until_complete(asyncio.gather(*to_cancel, return_exceptions=True)) for task in to_cancel: if task.cancelled(): @@ -462,11 +490,12 @@ def run_app( *, host: Optional[Union[str, HostSequence]] = None, port: Optional[int] = None, - path: Optional[str] = None, - sock: Optional[socket.socket] = None, + path: Union[PathLike, TypingIterable[PathLike], None] = None, + sock: Optional[Union[socket.socket, TypingIterable[socket.socket]]] = None, shutdown_timeout: float = 60.0, + keepalive_timeout: float = 75.0, ssl_context: Optional[SSLContext] = None, - print: Callable[..., None] = print, + print: Optional[Callable[..., None]] = print, backlog: int = 128, access_log_class: Type[AbstractAccessLogger] = AccessLogger, access_log_format: str = AccessLogger.LOG_FORMAT, @@ -474,9 +503,12 @@ def run_app( handle_signals: bool = True, reuse_address: Optional[bool] = None, reuse_port: Optional[bool] = None, + handler_cancellation: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, ) -> None: """Run an app locally""" - loop = asyncio.get_event_loop() + if loop is None: + loop = asyncio.new_event_loop() # Configure if and only if in debugging mode and using the default logger if loop.get_debug() and access_log and access_log.name == "aiohttp.access": @@ -485,34 +517,37 @@ def run_app( if not access_log.hasHandlers(): access_log.addHandler(logging.StreamHandler()) - try: - main_task = loop.create_task( - _run_app( - app, - host=host, - port=port, - path=path, - sock=sock, - shutdown_timeout=shutdown_timeout, - ssl_context=ssl_context, - print=print, - backlog=backlog, - access_log_class=access_log_class, - access_log_format=access_log_format, - access_log=access_log, - handle_signals=handle_signals, - reuse_address=reuse_address, - reuse_port=reuse_port, - ) + main_task = loop.create_task( + _run_app( + app, + host=host, + port=port, + path=path, + sock=sock, + shutdown_timeout=shutdown_timeout, + keepalive_timeout=keepalive_timeout, + ssl_context=ssl_context, + print=print, + backlog=backlog, + access_log_class=access_log_class, + access_log_format=access_log_format, + access_log=access_log, + handle_signals=handle_signals, + reuse_address=reuse_address, + reuse_port=reuse_port, + handler_cancellation=handler_cancellation, ) + ) + + try: + asyncio.set_event_loop(loop) loop.run_until_complete(main_task) except (GracefulExit, KeyboardInterrupt): # pragma: no cover pass finally: _cancel_tasks({main_task}, loop) - _cancel_tasks(all_tasks(loop), loop) - if sys.version_info >= (3, 6): # don't use PY_36 to pass mypy - loop.run_until_complete(loop.shutdown_asyncgens()) + _cancel_tasks(asyncio.all_tasks(loop), loop) + loop.run_until_complete(loop.shutdown_asyncgens()) loop.close() diff --git a/dist/ba_data/python-site-packages/aiohttp/web_app.py b/dist/ba_data/python-site-packages/aiohttp/web_app.py index 14f2937a..91bf5fda 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_app.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_app.py @@ -18,10 +18,15 @@ Sequence, Tuple, Type, + TypeVar, Union, cast, + overload, ) +from aiosignal import Signal +from frozenlist import FrozenList + from . import hdrs from .abc import ( AbstractAccessLogger, @@ -29,12 +34,12 @@ AbstractRouter, AbstractStreamWriter, ) -from .frozenlist import FrozenList -from .helpers import DEBUG +from .helpers import DEBUG, AppKey from .http_parser import RawRequestMessage from .log import web_logger -from .signals import Signal from .streams import StreamReader +from .typedefs import Middleware +from .web_exceptions import NotAppKeyWarning from .web_log import AccessLogger from .web_middlewares import _fix_request_current_app from .web_protocol import RequestHandler @@ -55,29 +60,25 @@ __all__ = ("Application", "CleanupError") -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: _AppSignal = Signal[Callable[["Application"], Awaitable[None]]] _RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]] - _Handler = Callable[[Request], Awaitable[StreamResponse]] - _Middleware = Union[ - Callable[[Request, _Handler], Awaitable[StreamResponse]], - Callable[["Application", _Handler], Awaitable[_Handler]], # old-style - ] - _Middlewares = FrozenList[_Middleware] - _MiddlewaresHandlers = Optional[Sequence[Tuple[_Middleware, bool]]] + _Middlewares = FrozenList[Middleware] + _MiddlewaresHandlers = Optional[Sequence[Tuple[Middleware, bool]]] _Subapps = List["Application"] else: # No type checker mode, skip types _AppSignal = Signal _RespPrepareSignal = Signal - _Handler = Callable - _Middleware = Callable _Middlewares = FrozenList _MiddlewaresHandlers = Optional[Sequence] _Subapps = List +_T = TypeVar("_T") +_U = TypeVar("_U") + -class Application(MutableMapping[str, Any]): +class Application(MutableMapping[Union[str, AppKey[Any]], Any]): ATTRS = frozenset( [ "logger", @@ -106,9 +107,9 @@ def __init__( *, logger: logging.Logger = web_logger, router: Optional[UrlDispatcher] = None, - middlewares: Iterable[_Middleware] = (), + middlewares: Iterable[Middleware] = (), handler_args: Optional[Mapping[str, Any]] = None, - client_max_size: int = 1024 ** 2, + client_max_size: int = 1024**2, loop: Optional[asyncio.AbstractEventLoop] = None, debug: Any = ..., # mypy doesn't support ellipsis ) -> None: @@ -130,27 +131,27 @@ def __init__( "debug argument is deprecated", DeprecationWarning, stacklevel=2 ) self._debug = debug - self._router = router # type: UrlDispatcher + self._router: UrlDispatcher = router self._loop = loop self._handler_args = handler_args self.logger = logger - self._middlewares = FrozenList(middlewares) # type: _Middlewares + self._middlewares: _Middlewares = FrozenList(middlewares) # initialized on freezing - self._middlewares_handlers = None # type: _MiddlewaresHandlers + self._middlewares_handlers: _MiddlewaresHandlers = None # initialized on freezing - self._run_middlewares = None # type: Optional[bool] + self._run_middlewares: Optional[bool] = None - self._state = {} # type: Dict[str, Any] + self._state: Dict[Union[AppKey[Any], str], object] = {} self._frozen = False self._pre_frozen = False - self._subapps = [] # type: _Subapps + self._subapps: _Subapps = [] - self._on_response_prepare = Signal(self) # type: _RespPrepareSignal - self._on_startup = Signal(self) # type: _AppSignal - self._on_shutdown = Signal(self) # type: _AppSignal - self._on_cleanup = Signal(self) # type: _AppSignal + self._on_response_prepare: _RespPrepareSignal = Signal(self) + self._on_startup: _AppSignal = Signal(self) + self._on_shutdown: _AppSignal = Signal(self) + self._on_cleanup: _AppSignal = Signal(self) self._cleanup_ctx = CleanupContext() self._on_startup.append(self._cleanup_ctx._on_startup) self._on_cleanup.append(self._cleanup_ctx._on_cleanup) @@ -161,7 +162,7 @@ def __init_subclass__(cls: Type["Application"]) -> None: "Inheritance class {} from web.Application " "is discouraged".format(cls.__name__), DeprecationWarning, - stacklevel=2, + stacklevel=3, ) if DEBUG: # pragma: no cover @@ -181,7 +182,15 @@ def __setattr__(self, name: str, val: Any) -> None: def __eq__(self, other: object) -> bool: return self is other + @overload # type: ignore[override] + def __getitem__(self, key: AppKey[_T]) -> _T: + ... + + @overload def __getitem__(self, key: str) -> Any: + ... + + def __getitem__(self, key: Union[str, AppKey[_T]]) -> Any: return self._state[key] def _check_frozen(self) -> None: @@ -192,26 +201,57 @@ def _check_frozen(self) -> None: stacklevel=3, ) + @overload # type: ignore[override] + def __setitem__(self, key: AppKey[_T], value: _T) -> None: + ... + + @overload def __setitem__(self, key: str, value: Any) -> None: + ... + + def __setitem__(self, key: Union[str, AppKey[_T]], value: Any) -> None: self._check_frozen() + if not isinstance(key, AppKey): + warnings.warn( + "It is recommended to use web.AppKey instances for keys.\n" + + "https://docs.aiohttp.org/en/stable/web_advanced.html" + + "#application-s-config", + category=NotAppKeyWarning, + stacklevel=2, + ) self._state[key] = value - def __delitem__(self, key: str) -> None: + def __delitem__(self, key: Union[str, AppKey[_T]]) -> None: self._check_frozen() del self._state[key] def __len__(self) -> int: return len(self._state) - def __iter__(self) -> Iterator[str]: + def __iter__(self) -> Iterator[Union[str, AppKey[Any]]]: return iter(self._state) + @overload # type: ignore[override] + def get(self, key: AppKey[_T], default: None = ...) -> Optional[_T]: + ... + + @overload + def get(self, key: AppKey[_T], default: _U) -> Union[_T, _U]: + ... + + @overload + def get(self, key: str, default: Any = ...) -> Any: + ... + + def get(self, key: Union[str, AppKey[_T]], default: Any = None) -> Any: + return self._state.get(key, default) + ######## @property def loop(self) -> asyncio.AbstractEventLoop: # Technically the loop can be None # but we mask it by explicit type cast - # to provide more convinient type annotation + # to provide more convenient type annotation warnings.warn("loop property is deprecated", DeprecationWarning, stacklevel=2) return cast(asyncio.AbstractEventLoop, self._loop) @@ -278,7 +318,7 @@ def freeze(self) -> None: @property def debug(self) -> bool: warnings.warn("debug property is deprecated", DeprecationWarning, stacklevel=2) - return self._debug + return self._debug # type: ignore[no-any-return] def _reg_subapp_signals(self, subapp: "Application") -> None: def reg_handler(signame: str) -> None: @@ -323,7 +363,7 @@ def add_domain(self, domain: str, subapp: "Application") -> AbstractResource: if not isinstance(domain, str): raise TypeError("Domain must be str") elif "*" in domain: - rule = MaskDomain(domain) # type: Domain + rule: Domain = MaskDomain(domain) else: rule = Domain(domain) factory = partial(MatchedSubAppResource, rule, subapp) @@ -384,7 +424,7 @@ def _make_handler( kwargs[k] = v return Server( - self._handle, # type: ignore + self._handle, # type: ignore[arg-type] request_factory=self._make_request, loop=self._loop, **kwargs, @@ -427,7 +467,11 @@ async def cleanup(self) -> None: Should be called after shutdown() """ - await self.on_cleanup.send(self) + if self.on_cleanup.frozen: + await self.on_cleanup.send(self) + else: + # If an exception occurs in startup, ensure cleanup contexts are completed. + await self._cleanup_ctx._on_cleanup(self) def _make_request( self, @@ -448,7 +492,7 @@ def _make_request( client_max_size=self._client_max_size, ) - def _prepare_middleware(self) -> Iterator[Tuple[_Middleware, bool]]: + def _prepare_middleware(self) -> Iterator[Tuple[Middleware, bool]]: for m in reversed(self._middlewares): if getattr(m, "__middleware_version__", None) == 1: yield m, True @@ -477,7 +521,7 @@ async def _handle(self, request: Request) -> StreamResponse: match_info.freeze() resp = None - request._match_info = match_info # type: ignore + request._match_info = match_info expect = request.headers.get(hdrs.EXPECT) if expect: resp = await match_info.expect_handler(request) @@ -488,13 +532,13 @@ async def _handle(self, request: Request) -> StreamResponse: if self._run_middlewares: for app in match_info.apps[::-1]: - for m, new_style in app._middlewares_handlers: # type: ignore + for m, new_style in app._middlewares_handlers: # type: ignore[union-attr] if new_style: handler = update_wrapper( partial(m, handler=handler), handler ) else: - handler = await m(app, handler) # type: ignore + handler = await m(app, handler) # type: ignore[arg-type,assignment] resp = await handler(request) @@ -505,7 +549,7 @@ def __call__(self) -> "Application": return self def __repr__(self) -> str: - return "".format(id(self)) + return f"" def __bool__(self) -> bool: return True @@ -514,10 +558,10 @@ def __bool__(self) -> bool: class CleanupError(RuntimeError): @property def exceptions(self) -> List[BaseException]: - return self.args[1] + return cast(List[BaseException], self.args[1]) -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: _CleanupContextBase = FrozenList[Callable[[Application], AsyncIterator[None]]] else: _CleanupContextBase = FrozenList @@ -526,7 +570,7 @@ def exceptions(self) -> List[BaseException]: class CleanupContext(_CleanupContextBase): def __init__(self) -> None: super().__init__() - self._exits = [] # type: List[AsyncIterator[None]] + self._exits: List[AsyncIterator[None]] = [] async def _on_startup(self, app: Application) -> None: for cb in self: diff --git a/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py b/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py index 2eadca03..ee2c1e72 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py @@ -18,6 +18,7 @@ "HTTPNoContent", "HTTPResetContent", "HTTPPartialContent", + "HTTPMove", "HTTPMultipleChoices", "HTTPMovedPermanently", "HTTPFound", @@ -67,6 +68,10 @@ ) +class NotAppKeyWarning(UserWarning): + """Warning when not using AppKey in Application.""" + + ############################################################ # HTTP Exceptions ############################################################ @@ -160,7 +165,7 @@ class HTTPPartialContent(HTTPSuccessful): ############################################################ -class _HTTPMove(HTTPRedirection): +class HTTPMove(HTTPRedirection): def __init__( self, location: StrOrURL, @@ -184,21 +189,21 @@ def __init__( self.location = location -class HTTPMultipleChoices(_HTTPMove): +class HTTPMultipleChoices(HTTPMove): status_code = 300 -class HTTPMovedPermanently(_HTTPMove): +class HTTPMovedPermanently(HTTPMove): status_code = 301 -class HTTPFound(_HTTPMove): +class HTTPFound(HTTPMove): status_code = 302 # This one is safe after a POST (the redirected location will be # retrieved with GET): -class HTTPSeeOther(_HTTPMove): +class HTTPSeeOther(HTTPMove): status_code = 303 @@ -208,16 +213,16 @@ class HTTPNotModified(HTTPRedirection): empty_body = True -class HTTPUseProxy(_HTTPMove): +class HTTPUseProxy(HTTPMove): # Not a move, but looks a little like one status_code = 305 -class HTTPTemporaryRedirect(_HTTPMove): +class HTTPTemporaryRedirect(HTTPMove): status_code = 307 -class HTTPPermanentRedirect(_HTTPMove): +class HTTPPermanentRedirect(HTTPMove): status_code = 308 @@ -273,7 +278,7 @@ def __init__( content_type=content_type, ) self.headers["Allow"] = allow - self.allowed_methods = set(allowed_methods) # type: Set[str] + self.allowed_methods: Set[str] = set(allowed_methods) self.method = method.upper() @@ -366,7 +371,7 @@ class HTTPUnavailableForLegalReasons(HTTPClientError): def __init__( self, - link: str, + link: Optional[StrOrURL], *, headers: Optional[LooseHeaders] = None, reason: Optional[str] = None, @@ -381,8 +386,14 @@ def __init__( text=text, content_type=content_type, ) - self.headers["Link"] = '<%s>; rel="blocked-by"' % link - self.link = link + self._link = None + if link: + self._link = URL(link) + self.headers["Link"] = f'<{str(self._link)}>; rel="blocked-by"' + + @property + def link(self) -> Optional[URL]: + return self._link ############################################################ diff --git a/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py b/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py index 0737c4f4..7dbe50f0 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py @@ -2,22 +2,25 @@ import mimetypes import os import pathlib -import sys from typing import ( # noqa IO, TYPE_CHECKING, Any, Awaitable, Callable, + Final, + Iterator, List, Optional, + Tuple, Union, cast, ) from . import hdrs from .abc import AbstractStreamWriter -from .typedefs import LooseHeaders +from .helpers import ETAG_ANY, ETag, must_be_empty_body +from .typedefs import LooseHeaders, PathLike from .web_exceptions import ( HTTPNotModified, HTTPPartialContent, @@ -28,14 +31,14 @@ __all__ = ("FileResponse",) -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_request import BaseRequest _T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] -NOSENDFILE = bool(os.environ.get("AIOHTTP_NOSENDFILE")) +NOSENDFILE: Final[bool] = bool(os.environ.get("AIOHTTP_NOSENDFILE")) class FileResponse(StreamResponse): @@ -43,7 +46,7 @@ class FileResponse(StreamResponse): def __init__( self, - path: Union[str, pathlib.Path], + path: PathLike, chunk_size: int = 256 * 1024, status: int = 200, reason: Optional[str] = None, @@ -51,10 +54,7 @@ def __init__( ) -> None: super().__init__(status=status, reason=reason, headers=headers) - if isinstance(path, str): - path = pathlib.Path(path) - - self._path = path + self._path = pathlib.Path(path) self._chunk_size = chunk_size async def _sendfile_fallback( @@ -85,7 +85,7 @@ async def _sendfile( writer = await super().prepare(request) assert writer is not None - if NOSENDFILE or sys.version_info < (3, 7) or self.compression: + if NOSENDFILE or self.compression: return await self._sendfile_fallback(writer, fobj, offset, count) loop = request._loop @@ -100,32 +100,87 @@ async def _sendfile( await super().write_eof() return writer - async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]: + @staticmethod + def _strong_etag_match(etag_value: str, etags: Tuple[ETag, ...]) -> bool: + if len(etags) == 1 and etags[0].value == ETAG_ANY: + return True + return any(etag.value == etag_value for etag in etags if not etag.is_weak) + + async def _not_modified( + self, request: "BaseRequest", etag_value: str, last_modified: float + ) -> Optional[AbstractStreamWriter]: + self.set_status(HTTPNotModified.status_code) + self._length_check = False + self.etag = etag_value # type: ignore[assignment] + self.last_modified = last_modified # type: ignore[assignment] + # Delete any Content-Length headers provided by user. HTTP 304 + # should always have empty response body + return await super().prepare(request) + + async def _precondition_failed( + self, request: "BaseRequest" + ) -> Optional[AbstractStreamWriter]: + self.set_status(HTTPPreconditionFailed.status_code) + self.content_length = 0 + return await super().prepare(request) + + def _get_file_path_stat_and_gzip( + self, check_for_gzipped_file: bool + ) -> Tuple[pathlib.Path, os.stat_result, bool]: + """Return the file path, stat result, and gzip status. + + This method should be called from a thread executor + since it calls os.stat which may block. + """ filepath = self._path - - gzip = False - if "gzip" in request.headers.get(hdrs.ACCEPT_ENCODING, ""): + if check_for_gzipped_file: gzip_path = filepath.with_name(filepath.name + ".gz") + try: + return gzip_path, gzip_path.stat(), True + except OSError: + # Fall through and try the non-gzipped file + pass - if gzip_path.is_file(): - filepath = gzip_path - gzip = True + return filepath, filepath.stat(), False + async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]: loop = asyncio.get_event_loop() - st = await loop.run_in_executor(None, filepath.stat) - - modsince = request.if_modified_since - if modsince is not None and st.st_mtime <= modsince.timestamp(): - self.set_status(HTTPNotModified.status_code) - self._length_check = False - # Delete any Content-Length headers provided by user. HTTP 304 - # should always have empty response body - return await super().prepare(request) + # Encoding comparisons should be case-insensitive + # https://www.rfc-editor.org/rfc/rfc9110#section-8.4.1 + check_for_gzipped_file = ( + "gzip" in request.headers.get(hdrs.ACCEPT_ENCODING, "").lower() + ) + filepath, st, gzip = await loop.run_in_executor( + None, self._get_file_path_stat_and_gzip, check_for_gzipped_file + ) + + etag_value = f"{st.st_mtime_ns:x}-{st.st_size:x}" + last_modified = st.st_mtime + + # https://tools.ietf.org/html/rfc7232#section-6 + ifmatch = request.if_match + if ifmatch is not None and not self._strong_etag_match(etag_value, ifmatch): + return await self._precondition_failed(request) unmodsince = request.if_unmodified_since - if unmodsince is not None and st.st_mtime > unmodsince.timestamp(): - self.set_status(HTTPPreconditionFailed.status_code) - return await super().prepare(request) + if ( + unmodsince is not None + and ifmatch is None + and st.st_mtime > unmodsince.timestamp() + ): + return await self._precondition_failed(request) + + ifnonematch = request.if_none_match + if ifnonematch is not None and self._strong_etag_match(etag_value, ifnonematch): + return await self._not_modified(request, etag_value, last_modified) + + modsince = request.if_modified_since + if ( + modsince is not None + and ifnonematch is None + and st.st_mtime <= modsince.timestamp() + ): + return await self._not_modified(request, etag_value, last_modified) if hdrs.CONTENT_TYPE not in self.headers: ct, encoding = mimetypes.guess_type(str(filepath)) @@ -211,12 +266,18 @@ async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter self.set_status(status) if should_set_ct: - self.content_type = ct # type: ignore + self.content_type = ct # type: ignore[assignment] if encoding: self.headers[hdrs.CONTENT_ENCODING] = encoding if gzip: self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING - self.last_modified = st.st_mtime # type: ignore + # Disable compression if we are already sending + # a compressed file since we don't want to double + # compress. + self._compression = False + + self.etag = etag_value # type: ignore[assignment] + self.last_modified = st.st_mtime # type: ignore[assignment] self.content_length = count self.headers[hdrs.ACCEPT_RANGES] = "bytes" @@ -228,7 +289,8 @@ async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter real_start, real_start + count - 1, file_size ) - if request.method == hdrs.METH_HEAD or self.status in [204, 304]: + # If we are sending 0 bytes calling sendfile() will throw a ValueError + if count == 0 or must_be_empty_body(request.method, self.status): return await super().prepare(request) fobj = await loop.run_in_executor(None, filepath.open, "rb") @@ -240,4 +302,4 @@ async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter try: return await self._sendfile(request, fobj, offset, count) finally: - await loop.run_in_executor(None, fobj.close) + await asyncio.shield(loop.run_in_executor(None, fobj.close)) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_log.py b/dist/ba_data/python-site-packages/aiohttp/web_log.py index 4cfa5792..633e9e3a 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_log.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_log.py @@ -3,6 +3,7 @@ import logging import os import re +import time as time_mod from collections import namedtuple from typing import Any, Callable, Dict, Iterable, List, Tuple # noqa @@ -57,7 +58,7 @@ class AccessLogger(AbstractAccessLogger): LOG_FORMAT = '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' FORMAT_RE = re.compile(r"%(\{([A-Za-z0-9\-_]+)\}([ioe])|[atPrsbOD]|Tf?)") CLEANUP_RE = re.compile(r"(%[^s])") - _FORMAT_CACHE = {} # type: Dict[str, Tuple[str, List[KeyMethod]]] + _FORMAT_CACHE: Dict[str, Tuple[str, List[KeyMethod]]] = {} def __init__(self, logger: logging.Logger, log_format: str = LOG_FORMAT) -> None: """Initialise the logger. @@ -142,9 +143,10 @@ def _format_a(request: BaseRequest, response: StreamResponse, time: float) -> st @staticmethod def _format_t(request: BaseRequest, response: StreamResponse, time: float) -> str: - now = datetime.datetime.utcnow() + tz = datetime.timezone(datetime.timedelta(seconds=-time_mod.timezone)) + now = datetime.datetime.now(tz) start_time = now - datetime.timedelta(seconds=time) - return start_time.strftime("[%d/%b/%Y:%H:%M:%S +0000]") + return start_time.strftime("[%d/%b/%Y:%H:%M:%S %z]") @staticmethod def _format_P(request: BaseRequest, response: StreamResponse, time: float) -> str: @@ -187,6 +189,9 @@ def _format_line( return [(key, method(request, response, time)) for key, method in self._methods] def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None: + if not self.logger.isEnabledFor(logging.INFO): + # Avoid formatting the log line if it will not be emitted. + return try: fmt_info = self._format_line(request, response, time) @@ -198,10 +203,10 @@ def log(self, request: BaseRequest, response: StreamResponse, time: float) -> No if key.__class__ is str: extra[key] = value else: - k1, k2 = key # type: ignore - dct = extra.get(k1, {}) # type: ignore - dct[k2] = value # type: ignore - extra[k1] = dct # type: ignore + k1, k2 = key # type: ignore[misc] + dct = extra.get(k1, {}) # type: ignore[var-annotated,has-type] + dct[k2] = value # type: ignore[index,has-type] + extra[k1] = dct # type: ignore[has-type,assignment] self.logger.info(self._log_format % tuple(values), extra=extra) except Exception: diff --git a/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py b/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py index 8a8967e8..5da1533c 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py @@ -1,7 +1,8 @@ import re -from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar +from typing import TYPE_CHECKING, Tuple, Type, TypeVar -from .web_exceptions import HTTPPermanentRedirect, _HTTPMove +from .typedefs import Handler, Middleware +from .web_exceptions import HTTPMove, HTTPPermanentRedirect from .web_request import Request from .web_response import StreamResponse from .web_urldispatcher import SystemRoute @@ -11,7 +12,7 @@ "normalize_path_middleware", ) -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_app import Application _Func = TypeVar("_Func") @@ -21,7 +22,7 @@ async def _check_request_resolves(request: Request, path: str) -> Tuple[bool, Re alt_request = request.clone(rel_url=path) match_info = await request.app.router.resolve(alt_request) - alt_request._match_info = match_info # type: ignore + alt_request._match_info = match_info if match_info.http_exception is None: return True, alt_request @@ -30,25 +31,20 @@ async def _check_request_resolves(request: Request, path: str) -> Tuple[bool, Re def middleware(f: _Func) -> _Func: - f.__middleware_version__ = 1 # type: ignore + f.__middleware_version__ = 1 # type: ignore[attr-defined] return f -_Handler = Callable[[Request], Awaitable[StreamResponse]] -_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]] - - def normalize_path_middleware( *, append_slash: bool = True, remove_slash: bool = False, merge_slashes: bool = True, - redirect_class: Type[_HTTPMove] = HTTPPermanentRedirect -) -> _Middleware: - """ - Middleware factory which produces a middleware that normalizes - the path of a request. By normalizing it means: + redirect_class: Type[HTTPMove] = HTTPPermanentRedirect, +) -> Middleware: + """Factory for producing a middleware that normalizes the path of a request. + Normalizing means: - Add or remove a trailing slash to the path. - Double slashes are replaced by one. @@ -74,12 +70,11 @@ def normalize_path_middleware( If merge_slashes is True, merge multiple consecutive slashes in the path into one. """ - correct_configuration = not (append_slash and remove_slash) assert correct_configuration, "Cannot both remove and append slash" @middleware - async def impl(request: Request, handler: _Handler) -> StreamResponse: + async def impl(request: Request, handler: Handler) -> StreamResponse: if isinstance(request.match_info.route, SystemRoute): paths_to_check = [] if "?" in request.raw_path: @@ -112,9 +107,9 @@ async def impl(request: Request, handler: _Handler) -> StreamResponse: return impl -def _fix_request_current_app(app: "Application") -> _Middleware: +def _fix_request_current_app(app: "Application") -> Middleware: @middleware - async def impl(request: Request, handler: _Handler) -> StreamResponse: + async def impl(request: Request, handler: Handler) -> StreamResponse: with request.match_info.set_current_app(app): return await handler(request) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_protocol.py b/dist/ba_data/python-site-packages/aiohttp/web_protocol.py index 8e02bc4a..f083b13e 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_protocol.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_protocol.py @@ -7,13 +7,26 @@ from html import escape as html_escape from http import HTTPStatus from logging import Logger -from typing import TYPE_CHECKING, Any, Awaitable, Callable, Optional, Tuple, Type, cast +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Deque, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import attr import yarl from .abc import AbstractAccessLogger, AbstractStreamWriter from .base_protocol import BaseProtocol -from .helpers import CeilTimeout, current_task +from .helpers import ceil_timeout, set_exception from .http import ( HttpProcessingError, HttpRequestParser, @@ -31,7 +44,7 @@ __all__ = ("RequestHandler", "RequestPayloadError", "PayloadAccessError") -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_server import Server @@ -48,9 +61,17 @@ _RequestHandler = Callable[[BaseRequest], Awaitable[StreamResponse]] - ERROR = RawRequestMessage( - "UNKNOWN", "/", HttpVersion10, {}, {}, True, False, False, False, yarl.URL("/") + "UNKNOWN", + "/", + HttpVersion10, + {}, # type: ignore[arg-type] + {}, # type: ignore[arg-type] + True, + None, + False, + False, + yarl.URL("/"), ) @@ -62,6 +83,16 @@ class PayloadAccessError(Exception): """Payload was accessed after response was sent.""" +@attr.s(auto_attribs=True, frozen=True, slots=True) +class _ErrInfo: + status: int + exc: BaseException + message: str + + +_MsgType = Tuple[Union[RawRequestMessage, _ErrInfo], StreamReader] + + class RequestHandler(BaseProtocol): """HTTP protocol implementation. @@ -73,32 +104,32 @@ class RequestHandler(BaseProtocol): status line, bad headers or incomplete payload. If any error occurs, connection gets closed. - :param keepalive_timeout: number of seconds before closing - keep-alive connection - :type keepalive_timeout: int or None + keepalive_timeout -- number of seconds before closing + keep-alive connection - :param bool tcp_keepalive: TCP keep-alive is on, default is on + tcp_keepalive -- TCP keep-alive is on, default is on - :param bool debug: enable debug mode + debug -- enable debug mode - :param logger: custom logger object - :type logger: aiohttp.log.server_logger + logger -- custom logger object - :param access_log_class: custom class for access_logger - :type access_log_class: aiohttp.abc.AbstractAccessLogger + access_log_class -- custom class for access_logger - :param access_log: custom logging object - :type access_log: aiohttp.log.server_logger + access_log -- custom logging object - :param str access_log_format: access log format string + access_log_format -- access log format string - :param loop: Optional event loop + loop -- Optional event loop - :param int max_line_size: Optional maximum header line size + max_line_size -- Optional maximum header line size - :param int max_field_size: Optional maximum header field size + max_field_size -- Optional maximum header field size - :param int max_headers: Optional maximum header size + max_headers -- Optional maximum header size + + timeout_ceil_threshold -- Optional value to specify + threshold to ceil() timeout + values """ @@ -118,7 +149,6 @@ class RequestHandler(BaseProtocol): "_messages", "_message_tail", "_waiter", - "_error_handler", "_task_handler", "_upgrade", "_payload_parser", @@ -131,6 +161,7 @@ class RequestHandler(BaseProtocol): "_close", "_force_close", "_current_request", + "_timeout_ceil_threshold", ) def __init__( @@ -149,39 +180,35 @@ def __init__( max_headers: int = 32768, max_field_size: int = 8190, lingering_time: float = 10.0, - read_bufsize: int = 2 ** 16, + read_bufsize: int = 2**16, + auto_decompress: bool = True, + timeout_ceil_threshold: float = 5, ): - super().__init__(loop) self._request_count = 0 self._keepalive = False - self._current_request = None # type: Optional[BaseRequest] - self._manager = manager # type: Optional[Server] - self._request_handler = ( - manager.request_handler - ) # type: Optional[_RequestHandler] - self._request_factory = ( - manager.request_factory - ) # type: Optional[_RequestFactory] + self._current_request: Optional[BaseRequest] = None + self._manager: Optional[Server] = manager + self._request_handler: Optional[_RequestHandler] = manager.request_handler + self._request_factory: Optional[_RequestFactory] = manager.request_factory self._tcp_keepalive = tcp_keepalive # placeholder to be replaced on keepalive timeout setup self._keepalive_time = 0.0 - self._keepalive_handle = None # type: Optional[asyncio.Handle] + self._keepalive_handle: Optional[asyncio.Handle] = None self._keepalive_timeout = keepalive_timeout self._lingering_time = float(lingering_time) - self._messages = deque() # type: Any # Python 3.5 has no typing.Deque + self._messages: Deque[_MsgType] = deque() self._message_tail = b"" - self._waiter = None # type: Optional[asyncio.Future[None]] - self._error_handler = None # type: Optional[asyncio.Task[None]] - self._task_handler = None # type: Optional[asyncio.Task[None]] + self._waiter: Optional[asyncio.Future[None]] = None + self._task_handler: Optional[asyncio.Task[None]] = None self._upgrade = False - self._payload_parser = None # type: Any - self._request_parser = HttpRequestParser( + self._payload_parser: Any = None + self._request_parser: Optional[HttpRequestParser] = HttpRequestParser( self, loop, read_bufsize, @@ -189,15 +216,22 @@ def __init__( max_field_size=max_field_size, max_headers=max_headers, payload_exception=RequestPayloadError, - ) # type: Optional[HttpRequestParser] + auto_decompress=auto_decompress, + ) + + self._timeout_ceil_threshold: float = 5 + try: + self._timeout_ceil_threshold = float(timeout_ceil_threshold) + except (TypeError, ValueError): + pass self.logger = logger self.debug = debug self.access_log = access_log if access_log: - self.access_logger = access_log_class( + self.access_logger: Optional[AbstractAccessLogger] = access_log_class( access_log, access_log_format - ) # type: Optional[AbstractAccessLogger] + ) else: self.access_logger = None @@ -215,9 +249,11 @@ def keepalive_timeout(self) -> float: return self._keepalive_timeout async def shutdown(self, timeout: Optional[float] = 15.0) -> None: - """Worker process is about to exit, we need cleanup everything and - stop accepting requests. It is especially important for keep-alive - connections.""" + """Do worker process exit preparations. + + We need to clean up everything and stop accepting requests. + It is especially important for keep-alive connections. + """ self._force_close = True if self._keepalive_handle is not None: @@ -228,10 +264,7 @@ async def shutdown(self, timeout: Optional[float] = 15.0) -> None: # wait for handlers with suppress(asyncio.CancelledError, asyncio.TimeoutError): - with CeilTimeout(timeout, loop=self._loop): - if self._error_handler is not None and not self._error_handler.done(): - await self._error_handler - + async with ceil_timeout(timeout): if self._current_request is not None: self._current_request._cancel(asyncio.CancelledError()) @@ -264,6 +297,9 @@ def connection_lost(self, exc: Optional[BaseException]) -> None: super().connection_lost(exc) + # Grab value before setting _manager to None. + handler_cancellation = self._manager.handler_cancellation + self._manager = None self._force_close = True self._request_factory = None @@ -278,13 +314,12 @@ def connection_lost(self, exc: Optional[BaseException]) -> None: exc = ConnectionResetError("Connection lost") self._current_request._cancel(exc) - if self._error_handler is not None: - self._error_handler.cancel() - if self._task_handler is not None: - self._task_handler.cancel() if self._waiter is not None: self._waiter.cancel() + if handler_cancellation and self._task_handler is not None: + self._task_handler.cancel() + self._task_handler = None if self._payload_parser is not None: @@ -308,40 +343,30 @@ def data_received(self, data: bytes) -> None: if self._force_close or self._close: return # parse http messages + messages: Sequence[_MsgType] if self._payload_parser is None and not self._upgrade: assert self._request_parser is not None try: messages, upgraded, tail = self._request_parser.feed_data(data) except HttpProcessingError as exc: - # something happened during parsing - self._error_handler = self._loop.create_task( - self.handle_parse_error( - StreamWriter(self, self._loop), 400, exc, exc.message - ) - ) - self.close() - except Exception as exc: - # 500: internal error - self._error_handler = self._loop.create_task( - self.handle_parse_error(StreamWriter(self, self._loop), 500, exc) - ) - self.close() - else: - if messages: - # sometimes the parser returns no messages - for (msg, payload) in messages: - self._request_count += 1 - self._messages.append((msg, payload)) - - waiter = self._waiter - if waiter is not None: - if not waiter.done(): - # don't set result twice - waiter.set_result(None) - - self._upgrade = upgraded - if upgraded and tail: - self._message_tail = tail + messages = [ + (_ErrInfo(status=400, exc=exc, message=exc.message), EMPTY_PAYLOAD) + ] + upgraded = False + tail = b"" + + for msg, payload in messages or (): + self._request_count += 1 + self._messages.append((msg, payload)) + + waiter = self._waiter + if messages and waiter is not None and not waiter.done(): + # don't set result twice + waiter.set_result(None) + + self._upgrade = upgraded + if upgraded and tail: + self._message_tail = tail # no parser, just store elif self._payload_parser is None and self._upgrade and data: @@ -364,14 +389,17 @@ def keep_alive(self, val: bool) -> None: self._keepalive_handle = None def close(self) -> None: - """Stop accepting new pipelinig messages and close - connection when handlers done processing messages""" + """Close connection. + + Stop accepting new pipelining messages and close + connection when handlers done processing messages. + """ self._close = True if self._waiter: self._waiter.cancel() def force_close(self) -> None: - """Force close connection""" + """Forcefully close connection.""" self._force_close = True if self._waiter: self._waiter.cancel() @@ -407,25 +435,25 @@ def _process_keepalive(self) -> None: # not all request handlers are done, # reschedule itself to next second self._keepalive_handle = self._loop.call_later( - self.KEEPALIVE_RESCHEDULE_DELAY, self._process_keepalive + self.KEEPALIVE_RESCHEDULE_DELAY, + self._process_keepalive, ) async def _handle_request( self, request: BaseRequest, start_time: float, + request_handler: Callable[[BaseRequest], Awaitable[StreamResponse]], ) -> Tuple[StreamResponse, bool]: assert self._request_handler is not None try: try: self._current_request = request - resp = await self._request_handler(request) + resp = await request_handler(request) finally: self._current_request = None except HTTPException as exc: - resp = Response( - status=exc.status, reason=exc.reason, text=exc.text, headers=exc.headers - ) + resp = exc reset = await self.finish_response(request, resp, start_time) except asyncio.CancelledError: raise @@ -437,6 +465,15 @@ async def _handle_request( resp = self.handle_error(request, 500, exc) reset = await self.finish_response(request, resp, start_time) else: + # Deprecation warning (See #2415) + if getattr(resp, "__http_exception__", False): + warnings.warn( + "returning HTTPException object is deprecated " + "(#2415) and will be removed, " + "please raise the exception instead", + DeprecationWarning, + ) + reset = await self.finish_response(request, resp, start_time) return resp, reset @@ -477,23 +514,24 @@ async def start(self) -> None: manager.requests_count += 1 writer = StreamWriter(self, loop) + if isinstance(message, _ErrInfo): + # make request_factory work + request_handler = self._make_error_handler(message) + message = ERROR + else: + request_handler = self._request_handler + request = self._request_factory(message, payload, self, writer, handler) try: # a new task is used for copy context vars (#3406) - task = self._loop.create_task(self._handle_request(request, start)) + task = self._loop.create_task( + self._handle_request(request, start, request_handler) + ) try: resp, reset = await task except (asyncio.CancelledError, ConnectionError): self.log_debug("Ignored premature client disconnection") break - # Deprecation warning (See #2415) - if getattr(resp, "__http_exception__", False): - warnings.warn( - "returning HTTPException object is deprecated " - "(#2415) and will be removed, " - "please raise the exception instead", - DeprecationWarning, - ) # Drop the processed task from asyncio.Task.all_tasks() early del task @@ -517,7 +555,7 @@ async def start(self) -> None: with suppress(asyncio.TimeoutError, asyncio.CancelledError): while not payload.is_eof() and now < end_t: - with CeilTimeout(end_t - now, loop=loop): + async with ceil_timeout(end_t - now): # read and ignore await payload.readany() now = loop.time() @@ -527,7 +565,7 @@ async def start(self) -> None: self.log_debug("Uncompleted request.") self.close() - payload.set_exception(PayloadAccessError()) + set_exception(payload, PayloadAccessError()) except asyncio.CancelledError: self.log_debug("Ignored premature client disconnection ") @@ -558,14 +596,15 @@ async def start(self) -> None: # remove handler, close transport if no handlers left if not self._force_close: self._task_handler = None - if self.transport is not None and self._error_handler is None: + if self.transport is not None: self.transport.close() async def finish_response( self, request: BaseRequest, resp: StreamResponse, start_time: float ) -> bool: - """ - Prepare the response and write_eof, then log access. This has to + """Prepare the response and write_eof, then log access. + + This has to be called within the context of any exception so the access logger can get exception information. Returns True if the client disconnects prematurely. @@ -607,9 +646,17 @@ def handle_error( """Handle errors. Returns HTTP response with specific status code. Logs additional - information. It always closes current connection.""" + information. It always closes current connection. + """ self.log_exception("Error handling request", exc_info=exc) + # some data already got sent, connection is broken + if request.writer.output_size > 0: + raise ConnectionError( + "Response is sent already, cannot send another response " + "with the error message" + ) + ct = "text/plain" if status == HTTPStatus.INTERNAL_SERVER_ERROR: title = "{0.value} {0.phrase}".format(HTTPStatus.INTERNAL_SERVER_ERROR) @@ -638,30 +685,14 @@ def handle_error( resp = Response(status=status, text=message, content_type=ct) resp.force_close() - # some data already got sent, connection is broken - if request.writer.output_size > 0 or self.transport is None: - self.force_close() - return resp - async def handle_parse_error( - self, - writer: AbstractStreamWriter, - status: int, - exc: Optional[BaseException] = None, - message: Optional[str] = None, - ) -> None: - task = current_task() - assert task is not None - request = BaseRequest( - ERROR, EMPTY_PAYLOAD, self, writer, task, self._loop # type: ignore - ) - - resp = self.handle_error(request, status, exc, message) - await resp.prepare(request) - await resp.write_eof() - - if self.transport is not None: - self.transport.close() + def _make_error_handler( + self, err_info: _ErrInfo + ) -> Callable[[BaseRequest], Awaitable[StreamResponse]]: + async def handler(request: BaseRequest) -> StreamResponse: + return self.handle_error( + request, err_info.status, err_info.exc, err_info.message + ) - self._error_handler = None + return handler diff --git a/dist/ba_data/python-site-packages/aiohttp/web_request.py b/dist/ba_data/python-site-packages/aiohttp/web_request.py index f11e7be4..4bc670a7 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_request.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_request.py @@ -7,17 +7,18 @@ import tempfile import types import warnings -from email.utils import parsedate from http.cookies import SimpleCookie from types import MappingProxyType from typing import ( TYPE_CHECKING, Any, Dict, + Final, Iterator, Mapping, MutableMapping, Optional, + Pattern, Tuple, Union, cast, @@ -25,12 +26,30 @@ from urllib.parse import parse_qsl import attr -from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy +from multidict import ( + CIMultiDict, + CIMultiDictProxy, + MultiDict, + MultiDictProxy, + MultiMapping, +) from yarl import URL from . import hdrs from .abc import AbstractStreamWriter -from .helpers import DEBUG, ChainMapProxy, HeadersMixin, reify, sentinel +from .helpers import ( + _SENTINEL, + DEBUG, + ETAG_ANY, + LIST_QUOTED_ETAG_RE, + ChainMapProxy, + ETag, + HeadersMixin, + parse_http_date, + reify, + sentinel, + set_exception, +) from .http_parser import RawRequestMessage from .http_writer import HttpVersion from .multipart import BodyPartReader, MultipartReader @@ -48,7 +67,7 @@ __all__ = ("BaseRequest", "FileField", "Request") -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_app import Application from .web_protocol import RequestHandler from .web_urldispatcher import UrlMappingMatchInfo @@ -63,31 +82,33 @@ class FileField: headers: "CIMultiDictProxy[str]" -_TCHAR = string.digits + string.ascii_letters + r"!#$%&'*+.^_`|~-" +_TCHAR: Final[str] = string.digits + string.ascii_letters + r"!#$%&'*+.^_`|~-" # '-' at the end to prevent interpretation as range in a char class -_TOKEN = fr"[{_TCHAR}]+" +_TOKEN: Final[str] = rf"[{_TCHAR}]+" -_QDTEXT = r"[{}]".format( +_QDTEXT: Final[str] = r"[{}]".format( r"".join(chr(c) for c in (0x09, 0x20, 0x21) + tuple(range(0x23, 0x7F))) ) # qdtext includes 0x5C to escape 0x5D ('\]') # qdtext excludes obs-text (because obsoleted, and encoding not specified) -_QUOTED_PAIR = r"\\[\t !-~]" +_QUOTED_PAIR: Final[str] = r"\\[\t !-~]" -_QUOTED_STRING = r'"(?:{quoted_pair}|{qdtext})*"'.format( +_QUOTED_STRING: Final[str] = r'"(?:{quoted_pair}|{qdtext})*"'.format( qdtext=_QDTEXT, quoted_pair=_QUOTED_PAIR ) -_FORWARDED_PAIR = r"({token})=({token}|{quoted_string})(:\d{{1,4}})?".format( +_FORWARDED_PAIR: Final[ + str +] = r"({token})=({token}|{quoted_string})(:\d{{1,4}})?".format( token=_TOKEN, quoted_string=_QUOTED_STRING ) -_QUOTED_PAIR_REPLACE_RE = re.compile(r"\\([\t !-~])") +_QUOTED_PAIR_REPLACE_RE: Final[Pattern[str]] = re.compile(r"\\([\t !-~])") # same pattern as _QUOTED_PAIR but contains a capture group -_FORWARDED_PAIR_RE = re.compile(_FORWARDED_PAIR) +_FORWARDED_PAIR_RE: Final[Pattern[str]] = re.compile(_FORWARDED_PAIR) ############################################################ # HTTP Request @@ -135,7 +156,7 @@ def __init__( task: "asyncio.Task[None]", loop: asyncio.AbstractEventLoop, *, - client_max_size: int = 1024 ** 2, + client_max_size: int = 1024**2, state: Optional[Dict[str, Any]] = None, scheme: Optional[str] = None, host: Optional[str] = None, @@ -151,14 +172,22 @@ def __init__( self._headers = message.headers self._method = message.method self._version = message.version - self._rel_url = message.url - self._post = ( - None - ) # type: Optional[MultiDictProxy[Union[str, bytes, FileField]]] - self._read_bytes = None # type: Optional[bytes] + self._cache: Dict[str, Any] = {} + url = message.url + if url.is_absolute(): + # absolute URL is given, + # override auto-calculating url, host, and scheme + # all other properties should be good + self._cache["url"] = url + self._cache["host"] = url.host + self._cache["scheme"] = url.scheme + self._rel_url = url.relative() + else: + self._rel_url = message.url + self._post: Optional[MultiDictProxy[Union[str, bytes, FileField]]] = None + self._read_bytes: Optional[bytes] = None self._state = state - self._cache = {} # type: Dict[str, Any] self._task = task self._client_max_size = client_max_size self._loop = loop @@ -178,29 +207,28 @@ def __init__( def clone( self, *, - method: str = sentinel, - rel_url: StrOrURL = sentinel, - headers: LooseHeaders = sentinel, - scheme: str = sentinel, - host: str = sentinel, - remote: str = sentinel, + method: Union[str, _SENTINEL] = sentinel, + rel_url: Union[StrOrURL, _SENTINEL] = sentinel, + headers: Union[LooseHeaders, _SENTINEL] = sentinel, + scheme: Union[str, _SENTINEL] = sentinel, + host: Union[str, _SENTINEL] = sentinel, + remote: Union[str, _SENTINEL] = sentinel, + client_max_size: Union[int, _SENTINEL] = sentinel, ) -> "BaseRequest": """Clone itself with replacement some attributes. Creates and returns a new instance of Request object. If no parameters are given, an exact copy is returned. If a parameter is not passed, it will reuse the one from the current request object. - """ - if self._read_bytes: raise RuntimeError("Cannot clone request " "after reading its content") - dct = {} # type: Dict[str, Any] + dct: Dict[str, Any] = {} if method is not sentinel: dct["method"] = method if rel_url is not sentinel: - new_url = URL(rel_url) + new_url: URL = URL(rel_url) dct["url"] = new_url dct["path"] = str(new_url) if headers is not sentinel: @@ -219,6 +247,8 @@ def clone( kwargs["host"] = host if remote is not sentinel: kwargs["remote"] = remote + if client_max_size is sentinel: + client_max_size = self._client_max_size return self.__class__( message, @@ -227,7 +257,7 @@ def clone( self._payload_writer, self._task, self._loop, - client_max_size=self._client_max_size, + client_max_size=client_max_size, state=self._state.copy(), **kwargs, ) @@ -250,6 +280,10 @@ def transport(self) -> Optional[asyncio.Transport]: def writer(self) -> AbstractStreamWriter: return self._payload_writer + @property + def client_max_size(self) -> int: + return self._client_max_size + @reify def message(self) -> RawRequestMessage: warnings.warn("Request.message is deprecated", DeprecationWarning, stacklevel=3) @@ -315,7 +349,7 @@ def forwarded(self) -> Tuple[Mapping[str, str], ...]: length = len(field_value) pos = 0 need_separator = False - elem = {} # type: Dict[str, str] + elem: Dict[str, str] = {} elems.append(types.MappingProxyType(elem)) while 0 <= pos < length: match = _FORWARDED_PAIR_RE.match(field_value, pos) @@ -396,8 +430,7 @@ def host(self) -> str: host = self._message.headers.get(hdrs.HOST) if host is not None: return host - else: - return socket.getfqdn() + return socket.getfqdn() @reify def remote(self) -> Optional[str]: @@ -408,10 +441,11 @@ def remote(self) -> Optional[str]: - overridden value by .clone(remote=new_remote) call. - peername of opened socket """ + if self._transport_peername is None: + return None if isinstance(self._transport_peername, (list, tuple)): - return self._transport_peername[0] - else: - return self._transport_peername + return str(self._transport_peername[0]) + return str(self._transport_peername) @reify def url(self) -> URL: @@ -437,6 +471,7 @@ def path_qs(self) -> str: @reify def raw_path(self) -> str: """The URL including raw *PATH INFO* without the host or scheme. + Warning, the path is unquoted and may contains non valid URL characters E.g., ``/my%2Fpath%7Cwith%21some%25strange%24characters`` @@ -444,9 +479,9 @@ def raw_path(self) -> str: return self._message.path @reify - def query(self) -> "MultiDictProxy[str]": + def query(self) -> "MultiMapping[str]": """A multidict with all the variables in the query string.""" - return self._rel_url.query + return MultiDictProxy(self._rel_url.query) @reify def query_string(self) -> str: @@ -457,7 +492,7 @@ def query_string(self) -> str: return self._rel_url.query_string @reify - def headers(self) -> "CIMultiDictProxy[str]": + def headers(self) -> "MultiMapping[str]": """A case-insensitive multidict proxy with all headers.""" return self._headers @@ -466,22 +501,13 @@ def raw_headers(self) -> RawHeaders: """A sequence of pairs for all headers.""" return self._message.raw_headers - @staticmethod - def _http_date(_date_str: Optional[str]) -> Optional[datetime.datetime]: - """Process a date string, return a datetime object""" - if _date_str is not None: - timetuple = parsedate(_date_str) - if timetuple is not None: - return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) - return None - @reify def if_modified_since(self) -> Optional[datetime.datetime]: """The value of If-Modified-Since HTTP header, or None. This header is represented as a `datetime` object. """ - return self._http_date(self.headers.get(hdrs.IF_MODIFIED_SINCE)) + return parse_http_date(self.headers.get(hdrs.IF_MODIFIED_SINCE)) @reify def if_unmodified_since(self) -> Optional[datetime.datetime]: @@ -489,7 +515,53 @@ def if_unmodified_since(self) -> Optional[datetime.datetime]: This header is represented as a `datetime` object. """ - return self._http_date(self.headers.get(hdrs.IF_UNMODIFIED_SINCE)) + return parse_http_date(self.headers.get(hdrs.IF_UNMODIFIED_SINCE)) + + @staticmethod + def _etag_values(etag_header: str) -> Iterator[ETag]: + """Extract `ETag` objects from raw header.""" + if etag_header == ETAG_ANY: + yield ETag( + is_weak=False, + value=ETAG_ANY, + ) + else: + for match in LIST_QUOTED_ETAG_RE.finditer(etag_header): + is_weak, value, garbage = match.group(2, 3, 4) + # Any symbol captured by 4th group means + # that the following sequence is invalid. + if garbage: + break + + yield ETag( + is_weak=bool(is_weak), + value=value, + ) + + @classmethod + def _if_match_or_none_impl( + cls, header_value: Optional[str] + ) -> Optional[Tuple[ETag, ...]]: + if not header_value: + return None + + return tuple(cls._etag_values(header_value)) + + @reify + def if_match(self) -> Optional[Tuple[ETag, ...]]: + """The value of If-Match HTTP header, or None. + + This header is represented as a `tuple` of `ETag` objects. + """ + return self._if_match_or_none_impl(self.headers.get(hdrs.IF_MATCH)) + + @reify + def if_none_match(self) -> Optional[Tuple[ETag, ...]]: + """The value of If-None-Match HTTP header, or None. + + This header is represented as a `tuple` of `ETag` objects. + """ + return self._if_match_or_none_impl(self.headers.get(hdrs.IF_NONE_MATCH)) @reify def if_range(self) -> Optional[datetime.datetime]: @@ -497,7 +569,7 @@ def if_range(self) -> Optional[datetime.datetime]: This header is represented as a `datetime` object. """ - return self._http_date(self.headers.get(hdrs.IF_RANGE)) + return parse_http_date(self.headers.get(hdrs.IF_RANGE)) @reify def keep_alive(self) -> bool: @@ -511,7 +583,7 @@ def cookies(self) -> Mapping[str, str]: A read-only dictionary-like object. """ raw = self.headers.get(hdrs.COOKIE, "") - parsed = SimpleCookie(raw) # type: SimpleCookie[str] + parsed = SimpleCookie(raw) return MappingProxyType({key: val.value for key, val in parsed.items()}) @reify @@ -634,7 +706,7 @@ async def post(self) -> "MultiDictProxy[Union[str, bytes, FileField]]": self._post = MultiDictProxy(MultiDict()) return self._post - out = MultiDict() # type: MultiDict[Union[str, bytes, FileField]] + out: MultiDict[Union[str, bytes, FileField]] = MultiDict() if content_type == "multipart/form-data": multipart = await self.multipart() @@ -654,18 +726,21 @@ async def post(self) -> "MultiDictProxy[Union[str, bytes, FileField]]": # https://tools.ietf.org/html/rfc7578#section-4.4 if field.filename: # store file in temp file - tmp = tempfile.TemporaryFile() - chunk = await field.read_chunk(size=2 ** 16) + tmp = await self._loop.run_in_executor( + None, tempfile.TemporaryFile + ) + chunk = await field.read_chunk(size=2**16) while chunk: chunk = field.decode(chunk) - tmp.write(chunk) + await self._loop.run_in_executor(None, tmp.write, chunk) size += len(chunk) if 0 < max_size < size: + await self._loop.run_in_executor(None, tmp.close) raise HTTPRequestEntityTooLarge( max_size=max_size, actual_size=size ) - chunk = await field.read_chunk(size=2 ** 16) - tmp.seek(0) + chunk = await field.read_chunk(size=2**16) + await self._loop.run_in_executor(None, tmp.seek, 0) if field_ct is None: field_ct = "application/octet-stream" @@ -742,7 +817,7 @@ async def _prepare_hook(self, response: StreamResponse) -> None: return def _cancel(self, exc: BaseException) -> None: - self._payload.set_exception(exc) + set_exception(self._payload, exc) class Request(BaseRequest): @@ -756,7 +831,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: # or information about traversal lookup # initialized after route resolving - self._match_info = None # type: Optional[UrlMappingMatchInfo] + self._match_info: Optional[UrlMappingMatchInfo] = None if DEBUG: @@ -773,12 +848,13 @@ def __setattr__(self, name: str, val: Any) -> None: def clone( self, *, - method: str = sentinel, - rel_url: StrOrURL = sentinel, - headers: LooseHeaders = sentinel, - scheme: str = sentinel, - host: str = sentinel, - remote: str = sentinel, + method: Union[str, _SENTINEL] = sentinel, + rel_url: Union[StrOrURL, _SENTINEL] = sentinel, + headers: Union[LooseHeaders, _SENTINEL] = sentinel, + scheme: Union[str, _SENTINEL] = sentinel, + host: Union[str, _SENTINEL] = sentinel, + remote: Union[str, _SENTINEL] = sentinel, + client_max_size: Union[int, _SENTINEL] = sentinel, ) -> "Request": ret = super().clone( method=method, @@ -787,6 +863,7 @@ def clone( scheme=scheme, host=host, remote=remote, + client_max_size=client_max_size, ) new_ret = cast(Request, ret) new_ret._match_info = self._match_info diff --git a/dist/ba_data/python-site-packages/aiohttp/web_response.py b/dist/ba_data/python-site-packages/aiohttp/web_response.py index f34b00e2..40d6f01e 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_response.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_response.py @@ -6,19 +6,16 @@ import math import time import warnings -import zlib from concurrent.futures import Executor -from email.utils import parsedate -from http.cookies import Morsel, SimpleCookie +from http import HTTPStatus +from http.cookies import SimpleCookie from typing import ( TYPE_CHECKING, Any, Dict, Iterator, - Mapping, MutableMapping, Optional, - Tuple, Union, cast, ) @@ -27,15 +24,27 @@ from . import hdrs, payload from .abc import AbstractStreamWriter -from .helpers import PY_38, HeadersMixin, rfc822_formatted_time, sentinel -from .http import RESPONSES, SERVER_SOFTWARE, HttpVersion10, HttpVersion11 +from .compression_utils import ZLibCompressor +from .helpers import ( + ETAG_ANY, + QUOTED_ETAG_RE, + ETag, + HeadersMixin, + must_be_empty_body, + parse_http_date, + rfc822_formatted_time, + sentinel, + should_remove_content_length, + validate_etag_value, +) +from .http import SERVER_SOFTWARE, HttpVersion10, HttpVersion11 from .payload import Payload from .typedefs import JSONEncoder, LooseHeaders __all__ = ("ContentCoding", "StreamResponse", "Response", "json_response") -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_request import BaseRequest BaseClass = MutableMapping[str, Any] @@ -43,12 +52,6 @@ BaseClass = collections.abc.MutableMapping -if not PY_38: - # allow samesite to be used in python < 3.8 - # already permitted in python 3.8, see https://bugs.python.org/issue29613 - Morsel._reserved["samesite"] = "SameSite" # type: ignore - - class ContentCoding(enum.Enum): # The content codings that we have support for. # @@ -76,20 +79,21 @@ def __init__( headers: Optional[LooseHeaders] = None, ) -> None: self._body = None - self._keep_alive = None # type: Optional[bool] + self._keep_alive: Optional[bool] = None self._chunked = False self._compression = False - self._compression_force = None # type: Optional[ContentCoding] - self._cookies = SimpleCookie() # type: SimpleCookie[str] + self._compression_force: Optional[ContentCoding] = None + self._cookies = SimpleCookie() - self._req = None # type: Optional[BaseRequest] - self._payload_writer = None # type: Optional[AbstractStreamWriter] + self._req: Optional[BaseRequest] = None + self._payload_writer: Optional[AbstractStreamWriter] = None self._eof_sent = False + self._must_be_empty_body: Optional[bool] = None self._body_length = 0 - self._state = {} # type: Dict[str, Any] + self._state: Dict[str, Any] = {} if headers is not None: - self._headers = CIMultiDict(headers) # type: CIMultiDict[str] + self._headers: CIMultiDict[str] = CIMultiDict(headers) else: self._headers = CIMultiDict() @@ -100,8 +104,11 @@ def prepared(self) -> bool: return self._payload_writer is not None @property - def task(self) -> "asyncio.Task[None]": - return getattr(self._req, "task", None) + def task(self) -> "Optional[asyncio.Task[None]]": + if self._req: + return self._req.task + else: + return None @property def status(self) -> int: @@ -123,7 +130,6 @@ def set_status( self, status: int, reason: Optional[str] = None, - _RESPONSES: Mapping[int, Tuple[str, str]] = RESPONSES, ) -> None: assert not self.prepared, ( "Cannot change the response status code after " "the headers have been sent" @@ -131,8 +137,8 @@ def set_status( self._status = int(status) if reason is None: try: - reason = _RESPONSES[self._status][0] - except Exception: + reason = HTTPStatus(self._status).phrase + except ValueError: reason = "" self._reason = reason @@ -187,7 +193,7 @@ def headers(self) -> "CIMultiDict[str]": return self._headers @property - def cookies(self) -> "SimpleCookie[str]": + def cookies(self) -> SimpleCookie: return self._cookies def set_cookie( @@ -209,7 +215,6 @@ def set_cookie( Sets new cookie or updates existent with new value. Also updates only those params which are not None. """ - old = self._cookies.get(name) if old is not None and old.coded_value == "": # deleted cookie @@ -314,12 +319,7 @@ def last_modified(self) -> Optional[datetime.datetime]: This header is represented as a `datetime` object. """ - httpdate = self._headers.get(hdrs.LAST_MODIFIED) - if httpdate is not None: - timetuple = parsedate(httpdate) - if timetuple is not None: - return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) - return None + return parse_http_date(self._headers.get(hdrs.LAST_MODIFIED)) @last_modified.setter def last_modified( @@ -338,6 +338,43 @@ def last_modified( elif isinstance(value, str): self._headers[hdrs.LAST_MODIFIED] = value + @property + def etag(self) -> Optional[ETag]: + quoted_value = self._headers.get(hdrs.ETAG) + if not quoted_value: + return None + elif quoted_value == ETAG_ANY: + return ETag(value=ETAG_ANY) + match = QUOTED_ETAG_RE.fullmatch(quoted_value) + if not match: + return None + is_weak, value = match.group(1, 2) + return ETag( + is_weak=bool(is_weak), + value=value, + ) + + @etag.setter + def etag(self, value: Optional[Union[ETag, str]]) -> None: + if value is None: + self._headers.pop(hdrs.ETAG, None) + elif (isinstance(value, str) and value == ETAG_ANY) or ( + isinstance(value, ETag) and value.value == ETAG_ANY + ): + self._headers[hdrs.ETAG] = ETAG_ANY + elif isinstance(value, str): + validate_etag_value(value) + self._headers[hdrs.ETAG] = f'"{value}"' + elif isinstance(value, ETag) and isinstance(value.value, str): + validate_etag_value(value.value) + hdr_value = f'W/"{value.value}"' if value.is_weak else f'"{value.value}"' + self._headers[hdrs.ETAG] = hdr_value + else: + raise ValueError( + f"Unsupported etag type: {type(value)}. " + f"etag must be str, ETag or None" + ) + def _generate_content_type_header( self, CONTENT_TYPE: istr = hdrs.CONTENT_TYPE ) -> None: @@ -363,6 +400,8 @@ async def _start_compression(self, request: "BaseRequest") -> None: if self._compression_force: await self._do_start_compression(self._compression_force) else: + # Encoding comparisons should be case-insensitive + # https://www.rfc-editor.org/rfc/rfc9110#section-8.4.1 accept_encoding = request.headers.get(hdrs.ACCEPT_ENCODING, "").lower() for coding in ContentCoding: if coding.value in accept_encoding: @@ -374,7 +413,7 @@ async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter return None if self._payload_writer is not None: return self._payload_writer - + self._must_be_empty_body = must_be_empty_body(request.method, self.status) return await self._start(request) async def _start(self, request: "BaseRequest") -> AbstractStreamWriter: @@ -413,26 +452,34 @@ async def _prepare_headers(self) -> None: "Using chunked encoding is forbidden " "for HTTP/{0.major}.{0.minor}".format(request.version) ) - writer.enable_chunking() - headers[hdrs.TRANSFER_ENCODING] = "chunked" + if not self._must_be_empty_body: + writer.enable_chunking() + headers[hdrs.TRANSFER_ENCODING] = "chunked" if hdrs.CONTENT_LENGTH in headers: del headers[hdrs.CONTENT_LENGTH] elif self._length_check: writer.length = self.content_length if writer.length is None: if version >= HttpVersion11: - writer.enable_chunking() - headers[hdrs.TRANSFER_ENCODING] = "chunked" - if hdrs.CONTENT_LENGTH in headers: - del headers[hdrs.CONTENT_LENGTH] - else: + if not self._must_be_empty_body: + writer.enable_chunking() + headers[hdrs.TRANSFER_ENCODING] = "chunked" + elif not self._must_be_empty_body: keep_alive = False - # HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2 - # HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4 - elif version >= HttpVersion11 and self.status in (100, 101, 102, 103, 204): - del headers[hdrs.CONTENT_LENGTH] - headers.setdefault(hdrs.CONTENT_TYPE, "application/octet-stream") + # HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2 + # HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4 + if self._must_be_empty_body: + if hdrs.CONTENT_LENGTH in headers and should_remove_content_length( + request.method, self.status + ): + del headers[hdrs.CONTENT_LENGTH] + # https://datatracker.ietf.org/doc/html/rfc9112#section-6.1-10 + # https://datatracker.ietf.org/doc/html/rfc9112#section-6.1-13 + if hdrs.TRANSFER_ENCODING in headers: + del headers[hdrs.TRANSFER_ENCODING] + else: + headers.setdefault(hdrs.CONTENT_TYPE, "application/octet-stream") headers.setdefault(hdrs.DATE, rfc822_formatted_time()) headers.setdefault(hdrs.SERVER, SERVER_SOFTWARE) @@ -545,7 +592,7 @@ def __init__( raise ValueError("body and text are not allowed together") if headers is None: - real_headers = CIMultiDict() # type: CIMultiDict[str] + real_headers: CIMultiDict[str] = CIMultiDict() elif not isinstance(headers, CIMultiDict): real_headers = CIMultiDict(headers) else: @@ -594,7 +641,7 @@ def __init__( else: self.body = body - self._compressed_body = None # type: Optional[bytes] + self._compressed_body: Optional[bytes] = None self._zlib_executor_size = zlib_executor_size self._zlib_executor = zlib_executor @@ -603,15 +650,10 @@ def body(self) -> Optional[Union[bytes, Payload]]: return self._body @body.setter - def body( - self, - body: bytes, - CONTENT_TYPE: istr = hdrs.CONTENT_TYPE, - CONTENT_LENGTH: istr = hdrs.CONTENT_LENGTH, - ) -> None: + def body(self, body: bytes) -> None: if body is None: - self._body = None # type: Optional[bytes] - self._body_payload = False # type: bool + self._body: Optional[bytes] = None + self._body_payload: bool = False elif isinstance(body, (bytes, bytearray)): self._body = body self._body_payload = False @@ -625,15 +667,9 @@ def body( headers = self._headers - # set content-length header if needed - if not self._chunked and CONTENT_LENGTH not in headers: - size = body.size - if size is not None: - headers[CONTENT_LENGTH] = str(size) - # set content-type - if CONTENT_TYPE not in headers: - headers[CONTENT_TYPE] = body.content_type + if hdrs.CONTENT_TYPE not in headers: + headers[hdrs.CONTENT_TYPE] = body.content_type # copy payload headers if body.headers: @@ -691,14 +727,14 @@ async def write_eof(self, data: bytes = b"") -> None: if self._eof_sent: return if self._compressed_body is None: - body = self._body # type: Optional[Union[bytes, Payload]] + body: Optional[Union[bytes, Payload]] = self._body else: body = self._compressed_body assert not data, f"data arg is not supported, got {data!r}" assert self._req is not None assert self._payload_writer is not None if body is not None: - if self._req._method == hdrs.METH_HEAD or self._status in [204, 304]: + if self._must_be_empty_body: await super().write_eof() elif self._body_payload: payload = cast(Payload, body) @@ -710,22 +746,24 @@ async def write_eof(self, data: bytes = b"") -> None: await super().write_eof() async def _start(self, request: "BaseRequest") -> AbstractStreamWriter: - if not self._chunked and hdrs.CONTENT_LENGTH not in self._headers: - if not self._body_payload: - if self._body is not None: - self._headers[hdrs.CONTENT_LENGTH] = str(len(self._body)) - else: - self._headers[hdrs.CONTENT_LENGTH] = "0" + if should_remove_content_length(request.method, self.status): + if hdrs.CONTENT_LENGTH in self._headers: + del self._headers[hdrs.CONTENT_LENGTH] + elif not self._chunked and hdrs.CONTENT_LENGTH not in self._headers: + if self._body_payload: + size = cast(Payload, self._body).size + if size is not None: + self._headers[hdrs.CONTENT_LENGTH] = str(size) + else: + body_len = len(self._body) if self._body else "0" + # https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6-7 + if body_len != "0" or ( + self.status != 304 and request.method.upper() != hdrs.METH_HEAD + ): + self._headers[hdrs.CONTENT_LENGTH] = str(body_len) return await super()._start(request) - def _compress_body(self, zlib_mode: int) -> None: - assert zlib_mode > 0 - compressobj = zlib.compressobj(wbits=zlib_mode) - body_in = self._body - assert body_in is not None - self._compressed_body = compressobj.compress(body_in) + compressobj.flush() - async def _do_start_compression(self, coding: ContentCoding) -> None: if self._body_payload or self._chunked: return await super()._do_start_compression(coding) @@ -733,26 +771,26 @@ async def _do_start_compression(self, coding: ContentCoding) -> None: if coding != ContentCoding.identity: # Instead of using _payload_writer.enable_compression, # compress the whole body - zlib_mode = ( - 16 + zlib.MAX_WBITS if coding == ContentCoding.gzip else zlib.MAX_WBITS + compressor = ZLibCompressor( + encoding=str(coding.value), + max_sync_chunk_size=self._zlib_executor_size, + executor=self._zlib_executor, ) - body_in = self._body - assert body_in is not None - if ( - self._zlib_executor_size is not None - and len(body_in) > self._zlib_executor_size - ): - await asyncio.get_event_loop().run_in_executor( - self._zlib_executor, self._compress_body, zlib_mode + assert self._body is not None + if self._zlib_executor_size is None and len(self._body) > 1024 * 1024: + warnings.warn( + "Synchronous compression of large response bodies " + f"({len(self._body)} bytes) might block the async event loop. " + "Consider providing a custom value to zlib_executor_size/" + "zlib_executor response properties or disabling compression on it." ) - else: - self._compress_body(zlib_mode) - - body_out = self._compressed_body - assert body_out is not None + self._compressed_body = ( + await compressor.compress(self._body) + compressor.flush() + ) + assert self._compressed_body is not None self._headers[hdrs.CONTENT_ENCODING] = coding.value - self._headers[hdrs.CONTENT_LENGTH] = str(len(body_out)) + self._headers[hdrs.CONTENT_LENGTH] = str(len(self._compressed_body)) def json_response( diff --git a/dist/ba_data/python-site-packages/aiohttp/web_routedef.py b/dist/ba_data/python-site-packages/aiohttp/web_routedef.py index 18852510..d79cd32a 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_routedef.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_routedef.py @@ -3,7 +3,6 @@ from typing import ( TYPE_CHECKING, Any, - Awaitable, Callable, Dict, Iterator, @@ -19,9 +18,9 @@ from . import hdrs from .abc import AbstractView -from .typedefs import PathLike +from .typedefs import Handler, PathLike -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_request import Request from .web_response import StreamResponse from .web_urldispatcher import AbstractRoute, UrlDispatcher @@ -53,8 +52,7 @@ def register(self, router: UrlDispatcher) -> List[AbstractRoute]: pass # pragma: no cover -_SimpleHandler = Callable[[Request], Awaitable[StreamResponse]] -_HandlerType = Union[Type[AbstractView], _SimpleHandler] +_HandlerType = Union[Type[AbstractView], Handler] @attr.s(auto_attribs=True, frozen=True, repr=False, slots=True) @@ -158,10 +156,10 @@ class RouteTableDef(Sequence[AbstractRouteDef]): """Route definition table""" def __init__(self) -> None: - self._items = [] # type: List[AbstractRouteDef] + self._items: List[AbstractRouteDef] = [] def __repr__(self) -> str: - return "".format(len(self._items)) + return f"" @overload def __getitem__(self, index: int) -> AbstractRouteDef: @@ -171,7 +169,7 @@ def __getitem__(self, index: int) -> AbstractRouteDef: def __getitem__(self, index: slice) -> List[AbstractRouteDef]: ... - def __getitem__(self, index): # type: ignore + def __getitem__(self, index): # type: ignore[no-untyped-def] return self._items[index] def __iter__(self) -> Iterator[AbstractRouteDef]: @@ -208,6 +206,9 @@ def patch(self, path: str, **kwargs: Any) -> _Deco: def delete(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_DELETE, path, **kwargs) + def options(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_OPTIONS, path, **kwargs) + def view(self, path: str, **kwargs: Any) -> _Deco: return self.route(hdrs.METH_ANY, path, **kwargs) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_runner.py b/dist/ba_data/python-site-packages/aiohttp/web_runner.py index 25ac28a7..19a44416 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_runner.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_runner.py @@ -1,18 +1,20 @@ import asyncio import signal import socket +import warnings from abc import ABC, abstractmethod -from typing import Any, List, Optional, Set +from typing import Any, Awaitable, Callable, List, Optional, Set from yarl import URL +from .typedefs import PathLike from .web_app import Application from .web_server import Server try: from ssl import SSLContext except ImportError: - SSLContext = object # type: ignore + SSLContext = object # type: ignore[misc,assignment] __all__ = ( @@ -37,7 +39,7 @@ def _raise_graceful_exit() -> None: class BaseSite(ABC): - __slots__ = ("_runner", "_shutdown_timeout", "_ssl_context", "_backlog", "_server") + __slots__ = ("_runner", "_ssl_context", "_backlog", "_server") def __init__( self, @@ -49,11 +51,14 @@ def __init__( ) -> None: if runner.server is None: raise RuntimeError("Call runner.setup() before making a site") + if shutdown_timeout != 60.0: + msg = "shutdown_timeout should be set on BaseRunner" + warnings.warn(msg, DeprecationWarning, stacklevel=2) + runner._shutdown_timeout = shutdown_timeout self._runner = runner - self._shutdown_timeout = shutdown_timeout self._ssl_context = ssl_context self._backlog = backlog - self._server = None # type: Optional[asyncio.AbstractServer] + self._server: Optional[asyncio.AbstractServer] = None @property @abstractmethod @@ -66,16 +71,9 @@ async def start(self) -> None: async def stop(self) -> None: self._runner._check_site(self) - if self._server is None: - self._runner._unreg_site(self) - return # not started yet - self._server.close() - # named pipes do not have wait_closed property - if hasattr(self._server, "wait_closed"): - await self._server.wait_closed() - await self._runner.shutdown() - assert self._runner.server - await self._runner.server.shutdown(self._shutdown_timeout) + if self._server is not None: # Maybe not started yet + self._server.close() + self._runner._unreg_site(self) @@ -135,7 +133,7 @@ class UnixSite(BaseSite): def __init__( self, runner: "BaseRunner", - path: str, + path: PathLike, *, shutdown_timeout: float = 60.0, ssl_context: Optional[SSLContext] = None, @@ -160,7 +158,10 @@ async def start(self) -> None: server = self._runner.server assert server is not None self._server = await loop.create_unix_server( - server, self._path, ssl=self._ssl_context, backlog=self._backlog + server, + self._path, + ssl=self._ssl_context, + backlog=self._backlog, ) @@ -171,7 +172,9 @@ def __init__( self, runner: "BaseRunner", path: str, *, shutdown_timeout: float = 60.0 ) -> None: loop = asyncio.get_event_loop() - if not isinstance(loop, asyncio.ProactorEventLoop): # type: ignore + if not isinstance( + loop, asyncio.ProactorEventLoop # type: ignore[attr-defined] + ): raise RuntimeError( "Named Pipes only available in proactor" "loop under windows" ) @@ -187,7 +190,9 @@ async def start(self) -> None: loop = asyncio.get_event_loop() server = self._runner.server assert server is not None - _server = await loop.start_serving_pipe(server, self._path) # type: ignore + _server = await loop.start_serving_pipe( # type: ignore[attr-defined] + server, self._path + ) self._server = _server[0] @@ -233,13 +238,28 @@ async def start(self) -> None: class BaseRunner(ABC): - __slots__ = ("_handle_signals", "_kwargs", "_server", "_sites") + __slots__ = ( + "shutdown_callback", + "_handle_signals", + "_kwargs", + "_server", + "_sites", + "_shutdown_timeout", + ) - def __init__(self, *, handle_signals: bool = False, **kwargs: Any) -> None: + def __init__( + self, + *, + handle_signals: bool = False, + shutdown_timeout: float = 60.0, + **kwargs: Any, + ) -> None: + self.shutdown_callback: Optional[Callable[[], Awaitable[None]]] = None self._handle_signals = handle_signals self._kwargs = kwargs - self._server = None # type: Optional[Server] - self._sites = [] # type: List[BaseSite] + self._server: Optional[Server] = None + self._sites: List[BaseSite] = [] + self._shutdown_timeout = shutdown_timeout @property def server(self) -> Optional[Server]: @@ -247,11 +267,11 @@ def server(self) -> Optional[Server]: @property def addresses(self) -> List[Any]: - ret = [] # type: List[Any] + ret: List[Any] = [] for site in self._sites: server = site._server if server is not None: - sockets = server.sockets + sockets = server.sockets # type: ignore[attr-defined] if sockets is not None: for sock in sockets: ret.append(sock.getsockname()) @@ -276,24 +296,32 @@ async def setup(self) -> None: @abstractmethod async def shutdown(self) -> None: - pass # pragma: no cover + """Call any shutdown hooks to help server close gracefully.""" async def cleanup(self) -> None: - loop = asyncio.get_event_loop() - - if self._server is None: - # no started yet, do nothing - return - # The loop over sites is intentional, an exception on gather() # leaves self._sites in unpredictable state. # The loop guaranties that a site is either deleted on success or # still present on failure for site in list(self._sites): await site.stop() + + if self._server: # If setup succeeded + # Yield to event loop to ensure incoming requests prior to stopping the sites + # have all started to be handled before we proceed to close idle connections. + await asyncio.sleep(0) + self._server.pre_shutdown() + await self.shutdown() + + if self.shutdown_callback: + await self.shutdown_callback() + + await self._server.shutdown(self._shutdown_timeout) await self._cleanup_server() + self._server = None if self._handle_signals: + loop = asyncio.get_running_loop() try: loop.remove_signal_handler(signal.SIGINT) loop.remove_signal_handler(signal.SIGTERM) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_server.py b/dist/ba_data/python-site-packages/aiohttp/web_server.py index 5657ed9c..52faacb1 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_server.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_server.py @@ -18,15 +18,17 @@ def __init__( handler: _RequestHandler, *, request_factory: Optional[_RequestFactory] = None, + handler_cancellation: bool = False, loop: Optional[asyncio.AbstractEventLoop] = None, **kwargs: Any ) -> None: self._loop = get_running_loop(loop) - self._connections = {} # type: Dict[RequestHandler, asyncio.Transport] + self._connections: Dict[RequestHandler, asyncio.Transport] = {} self._kwargs = kwargs self.requests_count = 0 self.request_handler = handler self.request_factory = request_factory or self._make_request + self.handler_cancellation = handler_cancellation @property def connections(self) -> List[RequestHandler]: @@ -53,10 +55,23 @@ def _make_request( ) -> BaseRequest: return BaseRequest(message, payload, protocol, writer, task, self._loop) + def pre_shutdown(self) -> None: + for conn in self._connections: + conn.close() + async def shutdown(self, timeout: Optional[float] = None) -> None: - coros = [conn.shutdown(timeout) for conn in self._connections] + coros = (conn.shutdown(timeout) for conn in self._connections) await asyncio.gather(*coros) self._connections.clear() def __call__(self) -> RequestHandler: - return RequestHandler(self, loop=self._loop, **self._kwargs) + try: + return RequestHandler(self, loop=self._loop, **self._kwargs) + except TypeError: + # Failsafe creation: remove all custom handler_args + kwargs = { + k: v + for k, v in self._kwargs.items() + if k in ["debug", "access_log_class"] + } + return RequestHandler(self, loop=self._loop, **kwargs) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py b/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py index 2afd72f1..954291f6 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py @@ -1,7 +1,9 @@ import abc import asyncio import base64 +import functools import hashlib +import html import inspect import keyword import os @@ -18,29 +20,31 @@ Callable, Container, Dict, + Final, Generator, Iterable, Iterator, List, Mapping, + NoReturn, Optional, Pattern, Set, Sized, Tuple, Type, + TypedDict, Union, cast, ) -from typing_extensions import TypedDict -from yarl import URL, __version__ as yarl_version # type: ignore +from yarl import URL, __version__ as yarl_version # type: ignore[attr-defined] from . import hdrs from .abc import AbstractMatchInfo, AbstractRouter, AbstractView from .helpers import DEBUG from .http import HttpVersion11 -from .typedefs import PathLike +from .typedefs import Handler, PathLike from .web_exceptions import ( HTTPException, HTTPExpectationFailed, @@ -67,23 +71,28 @@ ) -if TYPE_CHECKING: # pragma: no cover +if TYPE_CHECKING: from .web_app import Application BaseDict = Dict[str, str] else: BaseDict = dict -YARL_VERSION = tuple(map(int, yarl_version.split(".")[:2])) +YARL_VERSION: Final[Tuple[int, ...]] = tuple(map(int, yarl_version.split(".")[:2])) -HTTP_METHOD_RE = re.compile(r"^[0-9A-Za-z!#\$%&'\*\+\-\.\^_`\|~]+$") -ROUTE_RE = re.compile(r"(\{[_a-zA-Z][^{}]*(?:\{[^{}]*\}[^{}]*)*\})") -PATH_SEP = re.escape("/") +HTTP_METHOD_RE: Final[Pattern[str]] = re.compile( + r"^[0-9A-Za-z!#\$%&'\*\+\-\.\^_`\|~]+$" +) +ROUTE_RE: Final[Pattern[str]] = re.compile( + r"(\{[_a-zA-Z][^{}]*(?:\{[^{}]*\}[^{}]*)*\})" +) +PATH_SEP: Final[str] = re.escape("/") -_WebHandler = Callable[[Request], Awaitable[StreamResponse]] -_ExpectHandler = Callable[[Request], Awaitable[None]] -_Resolve = Tuple[Optional[AbstractMatchInfo], Set[str]] +_ExpectHandler = Callable[[Request], Awaitable[Optional[StreamResponse]]] +_Resolve = Tuple[Optional["UrlMappingMatchInfo"], Set[str]] + +html_escape = functools.partial(html.escape, quote=True) class _InfoDict(TypedDict, total=False): @@ -128,16 +137,16 @@ def url_for(self, **kwargs: str) -> URL: @abc.abstractmethod # pragma: no branch async def resolve(self, request: Request) -> _Resolve: - """Resolve resource + """Resolve resource. - Return (UrlMappingMatchInfo, allowed_methods) pair.""" + Return (UrlMappingMatchInfo, allowed_methods) pair. + """ @abc.abstractmethod def add_prefix(self, prefix: str) -> None: """Add a prefix to processed URLs. Required for subapplications support. - """ @abc.abstractmethod @@ -156,7 +165,7 @@ class AbstractRoute(abc.ABC): def __init__( self, method: str, - handler: Union[_WebHandler, Type[AbstractView]], + handler: Union[Handler, Type[AbstractView]], *, expect_handler: Optional[_ExpectHandler] = None, resource: Optional[AbstractResource] = None, @@ -192,8 +201,9 @@ def __init__( async def handler_wrapper(request: Request) -> StreamResponse: result = old_handler(request) if asyncio.iscoroutine(result): - return await result - return result # type: ignore + result = await result + assert isinstance(result, StreamResponse) + return result old_handler = handler handler = handler_wrapper @@ -208,7 +218,7 @@ def method(self) -> str: return self._method @property - def handler(self) -> _WebHandler: + def handler(self) -> Handler: return self._handler @property @@ -228,20 +238,20 @@ def get_info(self) -> _InfoDict: def url_for(self, *args: str, **kwargs: str) -> URL: """Construct url for route with additional params.""" - async def handle_expect_header(self, request: Request) -> None: - await self._expect_handler(request) + async def handle_expect_header(self, request: Request) -> Optional[StreamResponse]: + return await self._expect_handler(request) class UrlMappingMatchInfo(BaseDict, AbstractMatchInfo): def __init__(self, match_dict: Dict[str, str], route: AbstractRoute): super().__init__(match_dict) self._route = route - self._apps = [] # type: List[Application] - self._current_app = None # type: Optional[Application] + self._apps: List[Application] = [] + self._current_app: Optional[Application] = None self._frozen = False @property - def handler(self) -> _WebHandler: + def handler(self) -> Handler: return self._route.handler @property @@ -256,7 +266,7 @@ def expect_handler(self) -> _ExpectHandler: def http_exception(self) -> Optional[HTTPException]: return None - def get_info(self) -> _InfoDict: # type: ignore + def get_info(self) -> _InfoDict: # type: ignore[override] return self._route.get_info() @property @@ -331,12 +341,12 @@ async def _default_expect_handler(request: Request) -> None: class Resource(AbstractResource): def __init__(self, *, name: Optional[str] = None) -> None: super().__init__(name=name) - self._routes = [] # type: List[ResourceRoute] + self._routes: List[ResourceRoute] = [] def add_route( self, method: str, - handler: Union[Type[AbstractView], _WebHandler], + handler: Union[Type[AbstractView], Handler], *, expect_handler: Optional[_ExpectHandler] = None, ) -> "ResourceRoute": @@ -360,7 +370,7 @@ def register_route(self, route: "ResourceRoute") -> None: self._routes.append(route) async def resolve(self, request: Request) -> _Resolve: - allowed_methods = set() # type: Set[str] + allowed_methods: Set[str] = set() match_dict = self._match(request.rel_url.raw_path) if match_dict is None: @@ -382,7 +392,7 @@ def _match(self, path: str) -> Optional[Dict[str, str]]: def __len__(self) -> int: return len(self._routes) - def __iter__(self) -> Iterator[AbstractRoute]: + def __iter__(self) -> Iterator["ResourceRoute"]: return iter(self._routes) # TODO: implement all abstract methods @@ -421,7 +431,7 @@ def raw_match(self, path: str) -> bool: def get_info(self) -> _InfoDict: return {"path": self._path} - def url_for(self) -> URL: # type: ignore + def url_for(self) -> URL: # type: ignore[override] return URL.build(path=self._path, encoded=True) def __repr__(self) -> str: @@ -511,6 +521,7 @@ def __init__(self, prefix: str, *, name: Optional[str] = None) -> None: assert prefix in ("", "/") or not prefix.endswith("/"), prefix super().__init__(name=name) self._prefix = _requote_path(prefix) + self._prefix2 = self._prefix + "/" @property def canonical(self) -> str: @@ -521,6 +532,7 @@ def add_prefix(self, prefix: str) -> None: assert not prefix.endswith("/") assert len(prefix) > 1 self._prefix = prefix + self._prefix + self._prefix2 = self._prefix + "/" def raw_match(self, prefix: str) -> bool: return False @@ -569,17 +581,15 @@ def __init__( ), } - def url_for( # type: ignore + def url_for( # type: ignore[override] self, *, - filename: Union[str, Path], + filename: PathLike, append_version: Optional[bool] = None, ) -> URL: if append_version is None: append_version = self._append_version - if isinstance(filename, Path): - filename = str(filename) - filename = filename.lstrip("/") + filename = str(filename).lstrip("/") url = URL.build(path=self._prefix, encoded=True) # filename is not encoded @@ -589,9 +599,14 @@ def url_for( # type: ignore url = url / filename if append_version: + unresolved_path = self._directory.joinpath(filename) try: - filepath = self._directory.joinpath(filename).resolve() - if not self._follow_symlinks: + if self._follow_symlinks: + normalized_path = Path(os.path.normpath(unresolved_path)) + normalized_path.relative_to(self._directory) + filepath = normalized_path.resolve() + else: + filepath = unresolved_path.resolve() filepath.relative_to(self._directory) except (ValueError, FileNotFoundError): # ValueError for case when path point to symlink @@ -621,7 +636,7 @@ def get_info(self) -> _InfoDict: "routes": self._routes, } - def set_options_route(self, handler: _WebHandler) -> None: + def set_options_route(self, handler: Handler) -> None: if "OPTIONS" in self._routes: raise RuntimeError("OPTIONS route was set already") self._routes["OPTIONS"] = ResourceRoute( @@ -632,7 +647,7 @@ async def resolve(self, request: Request) -> _Resolve: path = request.rel_url.raw_path method = request.method allowed_methods = set(self._routes) - if not path.startswith(self._prefix): + if not path.startswith(self._prefix2) and path != self._prefix: return None, set() if method not in allowed_methods: @@ -656,8 +671,13 @@ async def _handle(self, request: Request) -> StreamResponse: # /static/\\machine_name\c$ or /static/D:\path # where the static dir is totally different raise HTTPForbidden() - filepath = self._directory.joinpath(filename).resolve() - if not self._follow_symlinks: + unresolved_path = self._directory.joinpath(filename) + if self._follow_symlinks: + normalized_path = Path(os.path.normpath(unresolved_path)) + normalized_path.relative_to(self._directory) + filepath = normalized_path.resolve() + else: + filepath = unresolved_path.resolve() filepath.relative_to(self._directory) except (ValueError, FileNotFoundError) as error: # relatively safe @@ -692,7 +712,7 @@ def _directory_as_html(self, filepath: Path) -> str: assert filepath.is_dir() relative_path_to_dir = filepath.relative_to(self._directory).as_posix() - index_of = f"Index of /{relative_path_to_dir}" + index_of = f"Index of /{html_escape(relative_path_to_dir)}" h1 = f"

{index_of}

" index_list = [] @@ -700,7 +720,7 @@ def _directory_as_html(self, filepath: Path) -> str: for _file in sorted(dir_index): # show file url as relative to static path rel_path = _file.relative_to(self._directory).as_posix() - file_url = self._prefix + "/" + rel_path + quoted_file_url = _quote_path(f"{self._prefix}/{rel_path}") # if file is a directory, add '/' to the end of the name if _file.is_dir(): @@ -709,9 +729,7 @@ def _directory_as_html(self, filepath: Path) -> str: file_name = _file.name index_list.append( - '
  • {name}
  • '.format( - url=file_url, name=file_name - ) + f'
  • {html_escape(file_name)}
  • ' ) ul = "
      \n{}\n
    ".format("\n".join(index_list)) body = f"\n{h1}\n{ul}\n" @@ -748,7 +766,7 @@ def get_info(self) -> _InfoDict: async def resolve(self, request: Request) -> _Resolve: if ( - not request.url.raw_path.startswith(self._prefix + "/") + not request.url.raw_path.startswith(self._prefix2) and request.url.raw_path != self._prefix ): return None, set() @@ -878,7 +896,7 @@ class ResourceRoute(AbstractRoute): def __init__( self, method: str, - handler: Union[_WebHandler, Type[AbstractView]], + handler: Union[Handler, Type[AbstractView]], resource: AbstractResource, *, expect_handler: Optional[_ExpectHandler] = None, @@ -942,16 +960,18 @@ class View(AbstractView): async def _iter(self) -> StreamResponse: if self.request.method not in hdrs.METH_ALL: self._raise_allowed_methods() + method: Optional[Callable[[], Awaitable[StreamResponse]]] method = getattr(self, self.request.method.lower(), None) if method is None: self._raise_allowed_methods() - resp = await method() - return resp + ret = await method() + assert isinstance(ret, StreamResponse) + return ret def __await__(self) -> Generator[Any, None, StreamResponse]: return self._iter().__await__() - def _raise_allowed_methods(self) -> None: + def _raise_allowed_methods(self) -> NoReturn: allowed_methods = {m for m in hdrs.METH_ALL if hasattr(self, m.lower())} raise HTTPMethodNotAllowed(self.request.method, allowed_methods) @@ -972,7 +992,7 @@ def __contains__(self, resource: object) -> bool: class RoutesView(Sized, Iterable[AbstractRoute], Container[AbstractRoute]): def __init__(self, resources: List[AbstractResource]): - self._routes = [] # type: List[AbstractRoute] + self._routes: List[AbstractRoute] = [] for resource in resources: for route in resource: self._routes.append(route) @@ -993,12 +1013,12 @@ class UrlDispatcher(AbstractRouter, Mapping[str, AbstractResource]): def __init__(self) -> None: super().__init__() - self._resources = [] # type: List[AbstractResource] - self._named_resources = {} # type: Dict[str, AbstractResource] + self._resources: List[AbstractResource] = [] + self._named_resources: Dict[str, AbstractResource] = {} - async def resolve(self, request: Request) -> AbstractMatchInfo: + async def resolve(self, request: Request) -> UrlMappingMatchInfo: method = request.method - allowed_methods = set() # type: Set[str] + allowed_methods: Set[str] = set() for resource in self._resources: match_dict, allowed = await resource.resolve(request) @@ -1006,11 +1026,11 @@ async def resolve(self, request: Request) -> AbstractMatchInfo: return match_dict else: allowed_methods |= allowed + + if allowed_methods: + return MatchInfoError(HTTPMethodNotAllowed(method, allowed_methods)) else: - if allowed_methods: - return MatchInfoError(HTTPMethodNotAllowed(method, allowed_methods)) - else: - return MatchInfoError(HTTPNotFound()) + return MatchInfoError(HTTPNotFound()) def __iter__(self) -> Iterator[str]: return iter(self._named_resources) @@ -1086,7 +1106,7 @@ def add_route( self, method: str, path: str, - handler: Union[_WebHandler, Type[AbstractView]], + handler: Union[Handler, Type[AbstractView]], *, name: Optional[str] = None, expect_handler: Optional[_ExpectHandler] = None, @@ -1128,72 +1148,53 @@ def add_static( self.register_resource(resource) return resource - def add_head(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute: - """ - Shortcut for add_route with method HEAD - """ + def add_head(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method HEAD.""" return self.add_route(hdrs.METH_HEAD, path, handler, **kwargs) - def add_options( - self, path: str, handler: _WebHandler, **kwargs: Any - ) -> AbstractRoute: - """ - Shortcut for add_route with method OPTIONS - """ + def add_options(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method OPTIONS.""" return self.add_route(hdrs.METH_OPTIONS, path, handler, **kwargs) def add_get( self, path: str, - handler: _WebHandler, + handler: Handler, *, name: Optional[str] = None, allow_head: bool = True, **kwargs: Any, ) -> AbstractRoute: - """ - Shortcut for add_route with method GET, if allow_head is true another - route is added allowing head requests to the same endpoint + """Shortcut for add_route with method GET. + + If allow_head is true, another + route is added allowing head requests to the same endpoint. """ resource = self.add_resource(path, name=name) if allow_head: resource.add_route(hdrs.METH_HEAD, handler, **kwargs) return resource.add_route(hdrs.METH_GET, handler, **kwargs) - def add_post(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute: - """ - Shortcut for add_route with method POST - """ + def add_post(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method POST.""" return self.add_route(hdrs.METH_POST, path, handler, **kwargs) - def add_put(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute: - """ - Shortcut for add_route with method PUT - """ + def add_put(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method PUT.""" return self.add_route(hdrs.METH_PUT, path, handler, **kwargs) - def add_patch( - self, path: str, handler: _WebHandler, **kwargs: Any - ) -> AbstractRoute: - """ - Shortcut for add_route with method PATCH - """ + def add_patch(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method PATCH.""" return self.add_route(hdrs.METH_PATCH, path, handler, **kwargs) - def add_delete( - self, path: str, handler: _WebHandler, **kwargs: Any - ) -> AbstractRoute: - """ - Shortcut for add_route with method DELETE - """ + def add_delete(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute: + """Shortcut for add_route with method DELETE.""" return self.add_route(hdrs.METH_DELETE, path, handler, **kwargs) def add_view( self, path: str, handler: Type[AbstractView], **kwargs: Any ) -> AbstractRoute: - """ - Shortcut for add_route with ANY methods for a class-based view - """ + """Shortcut for add_route with ANY methods for a class-based view.""" return self.add_route(hdrs.METH_ANY, path, handler, **kwargs) def freeze(self) -> None: diff --git a/dist/ba_data/python-site-packages/aiohttp/web_ws.py b/dist/ba_data/python-site-packages/aiohttp/web_ws.py index da7ce6df..9fe66527 100644 --- a/dist/ba_data/python-site-packages/aiohttp/web_ws.py +++ b/dist/ba_data/python-site-packages/aiohttp/web_ws.py @@ -3,15 +3,15 @@ import binascii import hashlib import json -from typing import Any, Iterable, Optional, Tuple +import sys +from typing import Any, Final, Iterable, Optional, Tuple, cast -import async_timeout import attr from multidict import CIMultiDict from . import hdrs from .abc import AbstractStreamWriter -from .helpers import call_later, set_result +from .helpers import call_later, set_exception, set_result from .http import ( WS_CLOSED_MESSAGE, WS_CLOSING_MESSAGE, @@ -19,6 +19,7 @@ WebSocketError, WebSocketReader, WebSocketWriter, + WSCloseCode, WSMessage, WSMsgType as WSMsgType, ws_ext_gen, @@ -31,13 +32,18 @@ from .web_request import BaseRequest from .web_response import StreamResponse +if sys.version_info >= (3, 11): + import asyncio as async_timeout +else: + import async_timeout + __all__ = ( "WebSocketResponse", "WebSocketReady", "WSMsgType", ) -THRESHOLD_CONNLOST_ACCESS = 5 +THRESHOLD_CONNLOST_ACCESS: Final[int] = 5 @attr.s(auto_attribs=True, frozen=True, slots=True) @@ -67,25 +73,25 @@ def __init__( ) -> None: super().__init__(status=101) self._protocols = protocols - self._ws_protocol = None # type: Optional[str] - self._writer = None # type: Optional[WebSocketWriter] - self._reader = None # type: Optional[FlowControlDataQueue[WSMessage]] + self._ws_protocol: Optional[str] = None + self._writer: Optional[WebSocketWriter] = None + self._reader: Optional[FlowControlDataQueue[WSMessage]] = None self._closed = False self._closing = False self._conn_lost = 0 - self._close_code = None # type: Optional[int] - self._loop = None # type: Optional[asyncio.AbstractEventLoop] - self._waiting = None # type: Optional[asyncio.Future[bool]] - self._exception = None # type: Optional[BaseException] + self._close_code: Optional[int] = None + self._loop: Optional[asyncio.AbstractEventLoop] = None + self._waiting: Optional[asyncio.Future[bool]] = None + self._exception: Optional[BaseException] = None self._timeout = timeout self._receive_timeout = receive_timeout self._autoclose = autoclose self._autoping = autoping self._heartbeat = heartbeat - self._heartbeat_cb = None + self._heartbeat_cb: Optional[asyncio.TimerHandle] = None if heartbeat is not None: self._pong_heartbeat = heartbeat / 2.0 - self._pong_response_cb = None + self._pong_response_cb: Optional[asyncio.TimerHandle] = None self._compress = compress self._max_msg_size = max_msg_size @@ -102,29 +108,40 @@ def _reset_heartbeat(self) -> None: self._cancel_heartbeat() if self._heartbeat is not None: + assert self._loop is not None self._heartbeat_cb = call_later( - self._send_heartbeat, self._heartbeat, self._loop + self._send_heartbeat, + self._heartbeat, + self._loop, + timeout_ceil_threshold=self._req._protocol._timeout_ceil_threshold + if self._req is not None + else 5, ) def _send_heartbeat(self) -> None: if self._heartbeat is not None and not self._closed: + assert self._loop is not None # fire-and-forget a task is not perfect but maybe ok for # sending ping. Otherwise we need a long-living heartbeat # task in the class. - self._loop.create_task(self._writer.ping()) # type: ignore + self._loop.create_task(self._writer.ping()) # type: ignore[union-attr] if self._pong_response_cb is not None: self._pong_response_cb.cancel() self._pong_response_cb = call_later( - self._pong_not_received, self._pong_heartbeat, self._loop + self._pong_not_received, + self._pong_heartbeat, + self._loop, + timeout_ceil_threshold=self._req._protocol._timeout_ceil_threshold + if self._req is not None + else 5, ) def _pong_not_received(self) -> None: if self._req is not None and self._req.transport is not None: self._closed = True - self._close_code = 1006 + self._set_code_close_transport(WSCloseCode.ABNORMAL_CLOSURE) self._exception = asyncio.TimeoutError() - self._req.transport.close() async def prepare(self, request: BaseRequest) -> AbstractStreamWriter: # make pre-check to don't hide it by do_handshake() exceptions @@ -193,9 +210,9 @@ def _handshake( accept_val = base64.b64encode( hashlib.sha1(key.encode() + WS_KEY).digest() ).decode() - response_headers = CIMultiDict( # type: ignore + response_headers = CIMultiDict( { - hdrs.UPGRADE: "websocket", # type: ignore + hdrs.UPGRADE: "websocket", hdrs.CONNECTION: "upgrade", hdrs.SEC_WEBSOCKET_ACCEPT: accept_val, } @@ -216,7 +233,12 @@ def _handshake( if protocol: response_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = protocol - return (response_headers, protocol, compress, notakeover) # type: ignore + return ( + response_headers, + protocol, + compress, + notakeover, + ) # type: ignore[return-value] def _pre_start(self, request: BaseRequest) -> Tuple[str, WebSocketWriter]: self._loop = request._loop @@ -245,7 +267,7 @@ def _post_start( loop = self._loop assert loop is not None - self._reader = FlowControlDataQueue(request._protocol, 2 ** 16, loop=loop) + self._reader = FlowControlDataQueue(request._protocol, 2**16, loop=loop) request.protocol.set_parser( WebSocketReader(self._reader, self._max_msg_size, compress=self._compress) ) @@ -278,6 +300,19 @@ def ws_protocol(self) -> Optional[str]: def compress(self) -> bool: return self._compress + def get_extra_info(self, name: str, default: Any = None) -> Any: + """Get optional transport information. + + If no value associated with ``name`` is found, ``default`` is returned. + """ + writer = self._writer + if writer is None: + return default + transport = writer.transport + if transport is None: + return default + return transport.get_extra_info(name, default) + def exception(self) -> Optional[BaseException]: return self._exception @@ -315,7 +350,7 @@ async def send_json( ) -> None: await self.send_str(dumps(data), compress=compress) - async def write_eof(self) -> None: # type: ignore + async def write_eof(self) -> None: # type: ignore[override] if self._eof_sent: return if self._payload_writer is None: @@ -324,7 +359,10 @@ async def write_eof(self) -> None: # type: ignore await self.close() self._eof_sent = True - async def close(self, *, code: int = 1000, message: bytes = b"") -> bool: + async def close( + self, *, code: int = WSCloseCode.OK, message: bytes = b"", drain: bool = True + ) -> bool: + """Close websocket connection.""" if self._writer is None: raise RuntimeError("Call .prepare() first") @@ -338,46 +376,63 @@ async def close(self, *, code: int = 1000, message: bytes = b"") -> bool: reader.feed_data(WS_CLOSING_MESSAGE, 0) await self._waiting - if not self._closed: - self._closed = True - try: - await self._writer.close(code, message) - writer = self._payload_writer - assert writer is not None - await writer.drain() - except (asyncio.CancelledError, asyncio.TimeoutError): - self._close_code = 1006 - raise - except Exception as exc: - self._close_code = 1006 - self._exception = exc - return True + if self._closed: + return False - if self._closing: - return True + self._closed = True + try: + await self._writer.close(code, message) + writer = self._payload_writer + assert writer is not None + if drain: + await writer.drain() + except (asyncio.CancelledError, asyncio.TimeoutError): + self._set_code_close_transport(WSCloseCode.ABNORMAL_CLOSURE) + raise + except Exception as exc: + self._exception = exc + self._set_code_close_transport(WSCloseCode.ABNORMAL_CLOSURE) + return True - reader = self._reader - assert reader is not None - try: - with async_timeout.timeout(self._timeout, loop=self._loop): - msg = await reader.read() - except asyncio.CancelledError: - self._close_code = 1006 - raise - except Exception as exc: - self._close_code = 1006 - self._exception = exc - return True + if self._closing: + self._close_transport() + return True - if msg.type == WSMsgType.CLOSE: - self._close_code = msg.data - return True + reader = self._reader + assert reader is not None + try: + async with async_timeout.timeout(self._timeout): + msg = await reader.read() + except asyncio.CancelledError: + self._set_code_close_transport(WSCloseCode.ABNORMAL_CLOSURE) + raise + except Exception as exc: + self._exception = exc + self._set_code_close_transport(WSCloseCode.ABNORMAL_CLOSURE) + return True - self._close_code = 1006 - self._exception = asyncio.TimeoutError() + if msg.type == WSMsgType.CLOSE: + self._set_code_close_transport(msg.data) return True - else: - return False + + self._set_code_close_transport(WSCloseCode.ABNORMAL_CLOSURE) + self._exception = asyncio.TimeoutError() + return True + + def _set_closing(self, code: WSCloseCode) -> None: + """Set the close code and mark the connection as closing.""" + self._closing = True + self._close_code = code + + def _set_code_close_transport(self, code: WSCloseCode) -> None: + """Set the close code and close the transport.""" + self._close_code = code + self._close_transport() + + def _close_transport(self) -> None: + """Close the transport.""" + if self._req is not None and self._req.transport is not None: + self._req.transport.close() async def receive(self, timeout: Optional[float] = None) -> WSMessage: if self._reader is None: @@ -400,20 +455,17 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage: try: self._waiting = loop.create_future() try: - with async_timeout.timeout( - timeout or self._receive_timeout, loop=self._loop - ): + async with async_timeout.timeout(timeout or self._receive_timeout): msg = await self._reader.read() self._reset_heartbeat() finally: waiter = self._waiting set_result(waiter, True) self._waiting = None - except (asyncio.CancelledError, asyncio.TimeoutError): - self._close_code = 1006 + except asyncio.TimeoutError: raise except EofStream: - self._close_code = 1000 + self._close_code = WSCloseCode.OK await self.close() return WSMessage(WSMsgType.CLOSED, None, None) except WebSocketError as exc: @@ -422,18 +474,21 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage: return WSMessage(WSMsgType.ERROR, exc, None) except Exception as exc: self._exception = exc - self._closing = True - self._close_code = 1006 + self._set_closing(WSCloseCode.ABNORMAL_CLOSURE) await self.close() return WSMessage(WSMsgType.ERROR, exc, None) if msg.type == WSMsgType.CLOSE: - self._closing = True - self._close_code = msg.data + self._set_closing(msg.data) + # Could be closed while awaiting reader. if not self._closed and self._autoclose: - await self.close() + # The client is likely going to close the + # connection out from under us so we do not + # want to drain any pending writes as it will + # likely result writing to a broken pipe. + await self.close(drain=False) elif msg.type == WSMsgType.CLOSING: - self._closing = True + self._set_closing(WSCloseCode.OK) elif msg.type == WSMsgType.PING and self._autoping: await self.pong(msg.data) continue @@ -450,13 +505,13 @@ async def receive_str(self, *, timeout: Optional[float] = None) -> str: msg.type, msg.data ) ) - return msg.data + return cast(str, msg.data) async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes: msg = await self.receive(timeout) if msg.type != WSMsgType.BINARY: raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes") - return msg.data + return cast(bytes, msg.data) async def receive_json( self, *, loads: JSONDecoder = json.loads, timeout: Optional[float] = None @@ -477,5 +532,8 @@ async def __anext__(self) -> WSMessage: return msg def _cancel(self, exc: BaseException) -> None: + # web_protocol calls this from connection_lost + # or when the server is shutting down. + self._closing = True if self._reader is not None: - self._reader.set_exception(exc) + set_exception(self._reader, exc) diff --git a/dist/ba_data/python-site-packages/aiohttp/worker.py b/dist/ba_data/python-site-packages/aiohttp/worker.py index 67b244bb..9b307697 100644 --- a/dist/ba_data/python-site-packages/aiohttp/worker.py +++ b/dist/ba_data/python-site-packages/aiohttp/worker.py @@ -22,14 +22,14 @@ SSLContext = ssl.SSLContext except ImportError: # pragma: no cover - ssl = None # type: ignore - SSLContext = object # type: ignore + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] -__all__ = ("GunicornWebWorker", "GunicornUVLoopWebWorker", "GunicornTokioWebWorker") +__all__ = ("GunicornWebWorker", "GunicornUVLoopWebWorker") -class GunicornWebWorker(base.Worker): +class GunicornWebWorker(base.Worker): # type: ignore[misc,no-any-unimported] DEFAULT_AIOHTTP_LOG_FORMAT = AccessLogger.LOG_FORMAT DEFAULT_GUNICORN_LOG_FORMAT = GunicornAccessLogFormat.default @@ -37,9 +37,9 @@ class GunicornWebWorker(base.Worker): def __init__(self, *args: Any, **kw: Any) -> None: # pragma: no cover super().__init__(*args, **kw) - self._task = None # type: Optional[asyncio.Task[None]] + self._task: Optional[asyncio.Task[None]] = None self.exit_code = 0 - self._notify_waiter = None # type: Optional[asyncio.Future[bool]] + self._notify_waiter: Optional[asyncio.Future[bool]] = None def init_process(self) -> None: # create new event_loop after fork @@ -57,30 +57,40 @@ def run(self) -> None: self.loop.run_until_complete(self._task) except Exception: self.log.exception("Exception in gunicorn worker") - if sys.version_info >= (3, 6): - self.loop.run_until_complete(self.loop.shutdown_asyncgens()) + self.loop.run_until_complete(self.loop.shutdown_asyncgens()) self.loop.close() sys.exit(self.exit_code) async def _run(self) -> None: + runner = None if isinstance(self.wsgi, Application): app = self.wsgi elif asyncio.iscoroutinefunction(self.wsgi): - app = await self.wsgi() + wsgi = await self.wsgi() + if isinstance(wsgi, web.AppRunner): + runner = wsgi + app = runner.app + else: + app = wsgi else: raise RuntimeError( "wsgi app should be either Application or " "async function returning Application, got {}".format(self.wsgi) ) - access_log = self.log.access_log if self.cfg.accesslog else None - runner = web.AppRunner( - app, - logger=self.log, - keepalive_timeout=self.cfg.keepalive, - access_log=access_log, - access_log_format=self._get_valid_log_format(self.cfg.access_log_format), - ) + + if runner is None: + access_log = self.log.access_log if self.cfg.accesslog else None + runner = web.AppRunner( + app, + logger=self.log, + keepalive_timeout=self.cfg.keepalive, + access_log=access_log, + access_log_format=self._get_valid_log_format( + self.cfg.access_log_format + ), + shutdown_timeout=self.cfg.graceful_timeout / 100 * 95, + ) await runner.setup() ctx = self._create_ssl_context(self.cfg) if self.cfg.is_ssl else None @@ -94,18 +104,17 @@ async def _run(self) -> None: runner, sock, ssl_context=ctx, - shutdown_timeout=self.cfg.graceful_timeout / 100 * 95, ) await site.start() # If our parent changed then we shut down. pid = os.getpid() try: - while self.alive: # type: ignore + while self.alive: # type: ignore[has-type] self.notify() cnt = server.requests_count - if self.cfg.max_requests and cnt > self.cfg.max_requests: + if self.max_requests and cnt > self.max_requests: self.alive = False self.log.info("Max requests, shutting down: %s", self) @@ -171,8 +180,10 @@ def init_signals(self) -> None: # by interrupting system calls signal.siginterrupt(signal.SIGTERM, False) signal.siginterrupt(signal.SIGUSR1, False) + # Reset signals so Gunicorn doesn't swallow subprocess return codes + # See: https://github.com/aio-libs/aiohttp/issues/6130 - def handle_quit(self, sig: int, frame: FrameType) -> None: + def handle_quit(self, sig: int, frame: Optional[FrameType]) -> None: self.alive = False # worker_int callback @@ -181,7 +192,7 @@ def handle_quit(self, sig: int, frame: FrameType) -> None: # wakeup closing process self._notify_waiter_done() - def handle_abort(self, sig: int, frame: FrameType) -> None: + def handle_abort(self, sig: int, frame: Optional[FrameType]) -> None: self.alive = False self.exit_code = 1 self.cfg.worker_abort(self) @@ -234,19 +245,3 @@ def init_process(self) -> None: asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) super().init_process() - - -class GunicornTokioWebWorker(GunicornWebWorker): - def init_process(self) -> None: # pragma: no cover - import tokio - - # Close any existing event loop before setting a - # new policy. - asyncio.get_event_loop().close() - - # Setup tokio policy, so that every - # asyncio.get_event_loop() will create an instance - # of tokio event loop. - asyncio.set_event_loop_policy(tokio.EventLoopPolicy()) - - super().init_process() diff --git a/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/INSTALLER b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/LICENSE b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/LICENSE new file mode 100644 index 00000000..7082a2d5 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013-2019 Nikolay Kim and Andrew Svetlov + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/METADATA b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/METADATA new file mode 100644 index 00000000..fc964525 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/METADATA @@ -0,0 +1,128 @@ +Metadata-Version: 2.1 +Name: aiosignal +Version: 1.3.1 +Summary: aiosignal: a list of registered asynchronous callbacks +Home-page: https://github.com/aio-libs/aiosignal +Maintainer: aiohttp team +Maintainer-email: team@aiohttp.org +License: Apache 2.0 +Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby +Project-URL: CI: GitHub Actions, https://github.com/aio-libs/aiosignal/actions +Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiosignal +Project-URL: Docs: RTD, https://docs.aiosignal.org +Project-URL: GitHub: issues, https://github.com/aio-libs/aiosignal/issues +Project-URL: GitHub: repo, https://github.com/aio-libs/aiosignal +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Development Status :: 5 - Production/Stable +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Framework :: AsyncIO +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: frozenlist (>=1.1.0) + +========= +aiosignal +========= + +.. image:: https://github.com/aio-libs/aiosignal/workflows/CI/badge.svg + :target: https://github.com/aio-libs/aiosignal/actions?query=workflow%3ACI + :alt: GitHub status for master branch + +.. image:: https://codecov.io/gh/aio-libs/aiosignal/branch/master/graph/badge.svg + :target: https://codecov.io/gh/aio-libs/aiosignal + :alt: codecov.io status for master branch + +.. image:: https://badge.fury.io/py/aiosignal.svg + :target: https://pypi.org/project/aiosignal + :alt: Latest PyPI package version + +.. image:: https://readthedocs.org/projects/aiosignal/badge/?version=latest + :target: https://aiosignal.readthedocs.io/ + :alt: Latest Read The Docs + +.. image:: https://img.shields.io/discourse/topics?server=https%3A%2F%2Faio-libs.discourse.group%2F + :target: https://aio-libs.discourse.group/ + :alt: Discourse group for io-libs + +.. image:: https://badges.gitter.im/Join%20Chat.svg + :target: https://gitter.im/aio-libs/Lobby + :alt: Chat on Gitter + +Introduction +============ + +A project to manage callbacks in `asyncio` projects. + +``Signal`` is a list of registered asynchronous callbacks. + +The signal's life-cycle has two stages: after creation its content +could be filled by using standard list operations: ``sig.append()`` +etc. + +After you call ``sig.freeze()`` the signal is *frozen*: adding, removing +and dropping callbacks is forbidden. + +The only available operation is calling the previously registered +callbacks by using ``await sig.send(data)``. + +For concrete usage examples see the `Signals + +section of the `Web Server Advanced +` chapter of the `aiohttp +documentation`_. + + +Installation +------------ + +:: + + $ pip install aiosignal + +The library requires Python 3.6 or newer. + + +Documentation +============= + +https://aiosignal.readthedocs.io/ + +Communication channels +====================== + +*gitter chat* https://gitter.im/aio-libs/Lobby + +Requirements +============ + +- Python >= 3.6 +- frozenlist >= 1.0.0 + +License +======= + +``aiosignal`` is offered under the Apache 2 license. + +Source code +=========== + +The project is hosted on GitHub_ + +Please file an issue in the `bug tracker +`_ if you have found a bug +or have some suggestions to improve the library. + +.. _GitHub: https://github.com/aio-libs/aiosignal +.. _aiohttp documentation: https://docs.aiohttp.org/ diff --git a/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/RECORD b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/RECORD new file mode 100644 index 00000000..6d9ffa25 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/RECORD @@ -0,0 +1,10 @@ +aiosignal-1.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +aiosignal-1.3.1.dist-info/LICENSE,sha256=b9UkPpLdf5jsacesN3co50kFcJ_1J6W_mNbQJjwE9bY,11332 +aiosignal-1.3.1.dist-info/METADATA,sha256=c0HRnlYzfXKztZPTFDlPfygizTherhG5WdwXlvco0Ug,4008 +aiosignal-1.3.1.dist-info/RECORD,, +aiosignal-1.3.1.dist-info/WHEEL,sha256=ZL1lC_LiPDNRgDnOl2taCMc83aPEUZgHHv2h-LDgdiM,92 +aiosignal-1.3.1.dist-info/top_level.txt,sha256=z45aNOKGDdrI1roqZY3BGXQ22kJFPHBmVdwtLYLtXC0,10 +aiosignal/__init__.py,sha256=zQNfFYRSd84bswvpFv8ZWjEr5DeYwV3LXbMSyo2222s,867 +aiosignal/__init__.pyi,sha256=xeCddYSS8fZAkz8S4HuKSR2IDe3N7RW_LKcXDPPA1Xk,311 +aiosignal/__pycache__/__init__.cpython-312.pyc,, +aiosignal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/WHEEL b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/WHEEL new file mode 100644 index 00000000..5e1f087c --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.38.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/top_level.txt b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/top_level.txt new file mode 100644 index 00000000..ac6df3af --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal-1.3.1.dist-info/top_level.txt @@ -0,0 +1 @@ +aiosignal diff --git a/dist/ba_data/python-site-packages/aiosignal/__init__.py b/dist/ba_data/python-site-packages/aiosignal/__init__.py new file mode 100644 index 00000000..3d288e6e --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal/__init__.py @@ -0,0 +1,36 @@ +from frozenlist import FrozenList + +__version__ = "1.3.1" + +__all__ = ("Signal",) + + +class Signal(FrozenList): + """Coroutine-based signal implementation. + + To connect a callback to a signal, use any list method. + + Signals are fired using the send() coroutine, which takes named + arguments. + """ + + __slots__ = ("_owner",) + + def __init__(self, owner): + super().__init__() + self._owner = owner + + def __repr__(self): + return "".format( + self._owner, self.frozen, list(self) + ) + + async def send(self, *args, **kwargs): + """ + Sends data to all registered receivers. + """ + if not self.frozen: + raise RuntimeError("Cannot send non-frozen signal.") + + for receiver in self: + await receiver(*args, **kwargs) # type: ignore diff --git a/dist/ba_data/python-site-packages/aiosignal/__init__.pyi b/dist/ba_data/python-site-packages/aiosignal/__init__.pyi new file mode 100644 index 00000000..d4e3416d --- /dev/null +++ b/dist/ba_data/python-site-packages/aiosignal/__init__.pyi @@ -0,0 +1,12 @@ +from typing import Any, Generic, TypeVar + +from frozenlist import FrozenList + +__all__ = ("Signal",) + +_T = TypeVar("_T") + +class Signal(FrozenList[_T], Generic[_T]): + def __init__(self, owner: Any) -> None: ... + def __repr__(self) -> str: ... + async def send(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/dist/ba_data/python-site-packages/chardet/metadata/__init__.py b/dist/ba_data/python-site-packages/aiosignal/py.typed similarity index 100% rename from dist/ba_data/python-site-packages/chardet/metadata/__init__.py rename to dist/ba_data/python-site-packages/aiosignal/py.typed diff --git a/dist/ba_data/python-site-packages/async_timeout/__init__.py b/dist/ba_data/python-site-packages/async_timeout/__init__.py deleted file mode 100644 index dcc55f0c..00000000 --- a/dist/ba_data/python-site-packages/async_timeout/__init__.py +++ /dev/null @@ -1,115 +0,0 @@ -import asyncio -import sys - -from types import TracebackType -from typing import Optional, Type, Any # noqa - - -__version__ = '3.0.1' - -PY_37 = sys.version_info >= (3, 7) - - -class timeout: - """timeout context manager. - - Useful in cases when you want to apply timeout logic around block - of code or in cases when asyncio.wait_for is not suitable. For example: - - >>> with timeout(0.001): - ... async with aiohttp.get('https://github.com') as r: - ... await r.text() - - - timeout - value in seconds or None to disable timeout logic - loop - asyncio compatible event loop - """ - def __init__(self, timeout: Optional[float], - *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: - self._timeout = timeout - if loop is None: - loop = asyncio.get_event_loop() - self._loop = loop - self._task = None # type: Optional[asyncio.Task[Any]] - self._cancelled = False - self._cancel_handler = None # type: Optional[asyncio.Handle] - self._cancel_at = None # type: Optional[float] - - def __enter__(self) -> 'timeout': - return self._do_enter() - - def __exit__(self, - exc_type: Type[BaseException], - exc_val: BaseException, - exc_tb: TracebackType) -> Optional[bool]: - self._do_exit(exc_type) - return None - - async def __aenter__(self) -> 'timeout': - return self._do_enter() - - async def __aexit__(self, - exc_type: Type[BaseException], - exc_val: BaseException, - exc_tb: TracebackType) -> None: - self._do_exit(exc_type) - - @property - def expired(self) -> bool: - return self._cancelled - - @property - def remaining(self) -> Optional[float]: - if self._cancel_at is not None: - return max(self._cancel_at - self._loop.time(), 0.0) - else: - return None - - def _do_enter(self) -> 'timeout': - # Support Tornado 5- without timeout - # Details: https://github.com/python/asyncio/issues/392 - if self._timeout is None: - return self - - self._task = current_task(self._loop) - if self._task is None: - raise RuntimeError('Timeout context manager should be used ' - 'inside a task') - - if self._timeout <= 0: - self._loop.call_soon(self._cancel_task) - return self - - self._cancel_at = self._loop.time() + self._timeout - self._cancel_handler = self._loop.call_at( - self._cancel_at, self._cancel_task) - return self - - def _do_exit(self, exc_type: Type[BaseException]) -> None: - if exc_type is asyncio.CancelledError and self._cancelled: - self._cancel_handler = None - self._task = None - raise asyncio.TimeoutError - if self._timeout is not None and self._cancel_handler is not None: - self._cancel_handler.cancel() - self._cancel_handler = None - self._task = None - return None - - def _cancel_task(self) -> None: - if self._task is not None: - self._task.cancel() - self._cancelled = True - - -def current_task(loop: asyncio.AbstractEventLoop) -> 'asyncio.Task[Any]': - if PY_37: - task = asyncio.current_task(loop=loop) # type: ignore - else: - task = asyncio.Task.current_task(loop=loop) - if task is None: - # this should be removed, tokio must use register_task and family API - if hasattr(loop, 'current_task'): - task = loop.current_task() # type: ignore - - return task diff --git a/dist/ba_data/python-site-packages/async_timeout/py.typed b/dist/ba_data/python-site-packages/async_timeout/py.typed deleted file mode 100644 index f6e0339a..00000000 --- a/dist/ba_data/python-site-packages/async_timeout/py.typed +++ /dev/null @@ -1 +0,0 @@ -Placeholder \ No newline at end of file diff --git a/dist/ba_data/python-site-packages/attr/__init__.py b/dist/ba_data/python-site-packages/attr/__init__.py index b1ce7fe2..9226258a 100644 --- a/dist/ba_data/python-site-packages/attr/__init__.py +++ b/dist/ba_data/python-site-packages/attr/__init__.py @@ -1,11 +1,15 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT -import sys +""" +Classes Without Boilerplate +""" from functools import partial +from typing import Callable from . import converters, exceptions, filters, setters, validators from ._cmp import cmp_using +from ._compat import Protocol from ._config import get_run_validators, set_run_validators from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types from ._make import ( @@ -19,31 +23,22 @@ make_class, validate, ) +from ._next_gen import define, field, frozen, mutable from ._version_info import VersionInfo -__version__ = "21.2.0" -__version_info__ = VersionInfo._from_version_string(__version__) - -__title__ = "attrs" -__description__ = "Classes Without Boilerplate" -__url__ = "https://www.attrs.org/" -__uri__ = __url__ -__doc__ = __description__ + " <" + __uri__ + ">" - -__author__ = "Hynek Schlawack" -__email__ = "hs@ox.cx" - -__license__ = "MIT" -__copyright__ = "Copyright (c) 2015 Hynek Schlawack" - - s = attributes = attrs ib = attr = attrib dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + +class AttrsInstance(Protocol): + pass + + __all__ = [ "Attribute", + "AttrsInstance", "Factory", "NOTHING", "asdict", @@ -55,15 +50,19 @@ "attrs", "cmp_using", "converters", + "define", "evolve", "exceptions", + "field", "fields", "fields_dict", "filters", + "frozen", "get_run_validators", "has", "ib", "make_class", + "mutable", "resolve_types", "s", "set_run_validators", @@ -72,7 +71,64 @@ "validators", ] -if sys.version_info[:2] >= (3, 6): - from ._next_gen import define, field, frozen, mutable - __all__.extend((define, field, frozen, mutable)) +def _make_getattr(mod_name: str) -> Callable: + """ + Create a metadata proxy for packaging information that uses *mod_name* in + its warnings and errors. + """ + + def __getattr__(name: str) -> str: + dunder_to_metadata = { + "__title__": "Name", + "__copyright__": "", + "__version__": "version", + "__version_info__": "version", + "__description__": "summary", + "__uri__": "", + "__url__": "", + "__author__": "", + "__email__": "", + "__license__": "license", + } + if name not in dunder_to_metadata: + msg = f"module {mod_name} has no attribute {name}" + raise AttributeError(msg) + + import sys + import warnings + + if sys.version_info < (3, 8): + from importlib_metadata import metadata + else: + from importlib.metadata import metadata + + if name not in ("__version__", "__version_info__"): + warnings.warn( + f"Accessing {mod_name}.{name} is deprecated and will be " + "removed in a future release. Use importlib.metadata directly " + "to query for attrs's packaging metadata.", + DeprecationWarning, + stacklevel=2, + ) + + meta = metadata("attrs") + if name == "__license__": + return "MIT" + if name == "__copyright__": + return "Copyright (c) 2015 Hynek Schlawack" + if name in ("__uri__", "__url__"): + return meta["Project-URL"].split(" ", 1)[-1] + if name == "__version_info__": + return VersionInfo._from_version_string(meta["version"]) + if name == "__author__": + return meta["Author-email"].rsplit(" ", 1)[0] + if name == "__email__": + return meta["Author-email"].rsplit("<", 1)[1][:-1] + + return meta[dunder_to_metadata[name]] + + return __getattr__ + + +__getattr__ = _make_getattr(__name__) diff --git a/dist/ba_data/python-site-packages/attr/__init__.pyi b/dist/ba_data/python-site-packages/attr/__init__.pyi index 3503b073..37a20873 100644 --- a/dist/ba_data/python-site-packages/attr/__init__.pyi +++ b/dist/ba_data/python-site-packages/attr/__init__.pyi @@ -1,3 +1,4 @@ +import enum import sys from typing import ( @@ -8,6 +9,7 @@ from typing import ( List, Mapping, Optional, + Protocol, Sequence, Tuple, Type, @@ -22,8 +24,19 @@ from . import exceptions as exceptions from . import filters as filters from . import setters as setters from . import validators as validators +from ._cmp import cmp_using as cmp_using +from ._typing_compat import AttrsInstance_ from ._version_info import VersionInfo +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + from typing_extensions import TypeGuard + +if sys.version_info >= (3, 11): + from typing import dataclass_transform +else: + from typing_extensions import dataclass_transform __version__: str __version_info__: VersionInfo @@ -40,31 +53,39 @@ _T = TypeVar("_T") _C = TypeVar("_C", bound=type) _EqOrderType = Union[bool, Callable[[Any], Any]] -_ValidatorType = Callable[[Any, Attribute[_T], _T], Any] +_ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any] _ConverterType = Callable[[Any], Any] -_FilterType = Callable[[Attribute[_T], _T], bool] +_FilterType = Callable[["Attribute[_T]", _T], bool] _ReprType = Callable[[Any], str] _ReprArgType = Union[bool, _ReprType] -_OnSetAttrType = Callable[[Any, Attribute[Any], Any], Any] +_OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any] _OnSetAttrArgType = Union[ _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType ] -_FieldTransformer = Callable[[type, List[Attribute[Any]]], List[Attribute[Any]]] +_FieldTransformer = Callable[ + [type, List["Attribute[Any]"]], List["Attribute[Any]"] +] # FIXME: in reality, if multiple validators are passed they must be in a list # or tuple, but those are invariant and so would prevent subtypes of # _ValidatorType from working when passed in a list or tuple. _ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] -# _make -- +# We subclass this here to keep the protocol's qualified name clean. +class AttrsInstance(AttrsInstance_, Protocol): + pass -NOTHING: object +_A = TypeVar("_A", bound=type[AttrsInstance]) + +class _Nothing(enum.Enum): + NOTHING = enum.auto() + +NOTHING = _Nothing.NOTHING # NOTE: Factory lies about its return type to make this possible: # `x: List[int] # = Factory(list)` # Work around mypy issue #4554 in the common case by using an overload. if sys.version_info >= (3, 8): from typing import Literal - @overload def Factory(factory: Callable[[], _T]) -> _T: ... @overload @@ -77,6 +98,7 @@ if sys.version_info >= (3, 8): factory: Callable[[], _T], takes_self: Literal[False], ) -> _T: ... + else: @overload def Factory(factory: Callable[[], _T]) -> _T: ... @@ -86,22 +108,6 @@ else: takes_self: bool = ..., ) -> _T: ... -# Static type inference support via __dataclass_transform__ implemented as per: -# https://github.com/microsoft/pyright/blob/1.1.135/specs/dataclass_transforms.md -# This annotation must be applied to all overloads of "define" and "attrs" -# -# NOTE: This is a typing construct and does not exist at runtime. Extensions -# wrapping attrs decorators should declare a separate __dataclass_transform__ -# signature in the extension module using the specification linked above to -# provide pyright support. -def __dataclass_transform__( - *, - eq_default: bool = True, - order_default: bool = False, - kw_only_default: bool = False, - field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()), -) -> Callable[[_T], _T]: ... - class Attribute(Generic[_T]): name: str default: Optional[_T] @@ -117,6 +123,7 @@ class Attribute(Generic[_T]): type: Optional[Type[_T]] kw_only: bool on_setattr: _OnSetAttrType + alias: Optional[str] def evolve(self, **changes: Any) -> "Attribute[Any]": ... @@ -160,6 +167,7 @@ def attrib( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., ) -> Any: ... # This form catches an explicit None or no default and infers the type from the @@ -180,6 +188,7 @@ def attrib( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., ) -> _T: ... # This form catches an explicit default argument. @@ -199,6 +208,7 @@ def attrib( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., ) -> _T: ... # This form covers type=non-Type: e.g. forward references (str), Any @@ -218,6 +228,7 @@ def attrib( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., ) -> Any: ... @overload def field( @@ -234,6 +245,8 @@ def field( eq: Optional[bool] = ..., order: Optional[bool] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., ) -> Any: ... # This form catches an explicit None or no default and infers the type from the @@ -253,6 +266,8 @@ def field( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., ) -> _T: ... # This form catches an explicit default argument. @@ -271,6 +286,8 @@ def field( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., ) -> _T: ... # This form covers type=non-Type: e.g. forward references (str), Any @@ -289,9 +306,11 @@ def field( eq: Optional[_EqOrderType] = ..., order: Optional[_EqOrderType] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., ) -> Any: ... @overload -@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +@dataclass_transform(order_default=True, field_specifiers=(attrib, field)) def attrs( maybe_cls: _C, these: Optional[Dict[str, Any]] = ..., @@ -315,9 +334,11 @@ def attrs( getstate_setstate: Optional[bool] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., + unsafe_hash: Optional[bool] = ..., ) -> _C: ... @overload -@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +@dataclass_transform(order_default=True, field_specifiers=(attrib, field)) def attrs( maybe_cls: None = ..., these: Optional[Dict[str, Any]] = ..., @@ -341,14 +362,17 @@ def attrs( getstate_setstate: Optional[bool] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., + unsafe_hash: Optional[bool] = ..., ) -> Callable[[_C], _C]: ... @overload -@__dataclass_transform__(field_descriptors=(attrib, field)) +@dataclass_transform(field_specifiers=(attrib, field)) def define( maybe_cls: _C, *, these: Optional[Dict[str, Any]] = ..., repr: bool = ..., + unsafe_hash: Optional[bool] = ..., hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., @@ -365,14 +389,16 @@ def define( getstate_setstate: Optional[bool] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., ) -> _C: ... @overload -@__dataclass_transform__(field_descriptors=(attrib, field)) +@dataclass_transform(field_specifiers=(attrib, field)) def define( maybe_cls: None = ..., *, these: Optional[Dict[str, Any]] = ..., repr: bool = ..., + unsafe_hash: Optional[bool] = ..., hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., @@ -389,24 +415,73 @@ def define( getstate_setstate: Optional[bool] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., ) -> Callable[[_C], _C]: ... mutable = define -frozen = define # they differ only in their defaults -# TODO: add support for returning NamedTuple from the mypy plugin -class _Fields(Tuple[Attribute[Any], ...]): - def __getattr__(self, name: str) -> Attribute[Any]: ... - -def fields(cls: type) -> _Fields: ... -def fields_dict(cls: type) -> Dict[str, Attribute[Any]]: ... -def validate(inst: Any) -> None: ... +@overload +@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) +def frozen( + maybe_cls: _C, + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + unsafe_hash: Optional[bool] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) +def frozen( + maybe_cls: None = ..., + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + unsafe_hash: Optional[bool] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... +def fields(cls: Type[AttrsInstance]) -> Any: ... +def fields_dict(cls: Type[AttrsInstance]) -> Dict[str, Attribute[Any]]: ... +def validate(inst: AttrsInstance) -> None: ... def resolve_types( - cls: _C, + cls: _A, globalns: Optional[Dict[str, Any]] = ..., localns: Optional[Dict[str, Any]] = ..., attribs: Optional[List[Attribute[Any]]] = ..., -) -> _C: ... + include_extras: bool = ..., +) -> _A: ... # TODO: add support for returning a proper attrs class from the mypy plugin # we use Any instead of _CountingAttr so that e.g. `make_class('Foo', @@ -415,6 +490,7 @@ def make_class( name: str, attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]], bases: Tuple[type, ...] = ..., + class_body: Optional[Dict[str, Any]] = ..., repr_ns: Optional[str] = ..., repr: bool = ..., cmp: Optional[_EqOrderType] = ..., @@ -442,24 +518,28 @@ def make_class( # these: # https://github.com/python/mypy/issues/4236 # https://github.com/python/typing/issues/253 +# XXX: remember to fix attrs.asdict/astuple too! def asdict( - inst: Any, + inst: AttrsInstance, recurse: bool = ..., filter: Optional[_FilterType[Any]] = ..., dict_factory: Type[Mapping[Any, Any]] = ..., retain_collection_types: bool = ..., - value_serializer: Optional[Callable[[type, Attribute[Any], Any], Any]] = ..., + value_serializer: Optional[ + Callable[[type, Attribute[Any], Any], Any] + ] = ..., + tuple_keys: Optional[bool] = ..., ) -> Dict[str, Any]: ... # TODO: add support for returning NamedTuple from the mypy plugin def astuple( - inst: Any, + inst: AttrsInstance, recurse: bool = ..., filter: Optional[_FilterType[Any]] = ..., tuple_factory: Type[Sequence[Any]] = ..., retain_collection_types: bool = ..., ) -> Tuple[Any, ...]: ... -def has(cls: type) -> bool: ... +def has(cls: type) -> TypeGuard[Type[AttrsInstance]]: ... def assoc(inst: _T, **changes: Any) -> _T: ... def evolve(inst: _T, **changes: Any) -> _T: ... diff --git a/dist/ba_data/python-site-packages/attr/_cmp.py b/dist/ba_data/python-site-packages/attr/_cmp.py index b747b603..a4a35e08 100644 --- a/dist/ba_data/python-site-packages/attr/_cmp.py +++ b/dist/ba_data/python-site-packages/attr/_cmp.py @@ -1,8 +1,9 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT + import functools +import types -from ._compat import new_class from ._make import _make_ne @@ -19,22 +20,22 @@ def cmp_using( class_name="Comparable", ): """ - Create a class that can be passed into `attr.ib`'s ``eq``, ``order``, and - ``cmp`` arguments to customize field comparison. - - The resulting class will have a full set of ordering methods if - at least one of ``{lt, le, gt, ge}`` and ``eq`` are provided. - - :param Optional[callable] eq: `callable` used to evaluate equality - of two objects. - :param Optional[callable] lt: `callable` used to evaluate whether - one object is less than another object. - :param Optional[callable] le: `callable` used to evaluate whether - one object is less than or equal to another object. - :param Optional[callable] gt: `callable` used to evaluate whether - one object is greater than another object. - :param Optional[callable] ge: `callable` used to evaluate whether - one object is greater than or equal to another object. + Create a class that can be passed into `attrs.field`'s ``eq``, ``order``, + and ``cmp`` arguments to customize field comparison. + + The resulting class will have a full set of ordering methods if at least + one of ``{lt, le, gt, ge}`` and ``eq`` are provided. + + :param Optional[callable] eq: `callable` used to evaluate equality of two + objects. + :param Optional[callable] lt: `callable` used to evaluate whether one + object is less than another object. + :param Optional[callable] le: `callable` used to evaluate whether one + object is less than or equal to another object. + :param Optional[callable] gt: `callable` used to evaluate whether one + object is greater than another object. + :param Optional[callable] ge: `callable` used to evaluate whether one + object is greater than or equal to another object. :param bool require_same_type: When `True`, equality and ordering methods will return `NotImplemented` if objects are not of the same type. @@ -78,7 +79,9 @@ def cmp_using( num_order_functions += 1 body["__ge__"] = _make_operator("ge", ge) - type_ = new_class(class_name, (object,), {}, lambda ns: ns.update(body)) + type_ = types.new_class( + class_name, (object,), {}, lambda ns: ns.update(body) + ) # Add same type requirement. if require_same_type: @@ -89,10 +92,8 @@ def cmp_using( if not has_eq_function: # functools.total_ordering requires __eq__ to be defined, # so raise early error here to keep a nice stack. - raise ValueError( - "eq must be define is order to complete ordering from " - "lt, le, gt, ge." - ) + msg = "eq must be define is order to complete ordering from lt, le, gt, ge." + raise ValueError(msg) type_ = functools.total_ordering(type_) return type_ @@ -127,9 +128,9 @@ def method(self, other): return result - method.__name__ = "__%s__" % (name,) - method.__doc__ = "Return a %s b. Computed by attrs." % ( - _operation_names[name], + method.__name__ = f"__{name}__" + method.__doc__ = ( + f"Return a {_operation_names[name]} b. Computed by attrs." ) return method @@ -139,10 +140,7 @@ def _is_comparable_to(self, other): """ Check whether `other` is comparable to `self`. """ - for func in self._requirements: - if not func(self, other): - return False - return True + return all(func(self, other) for func in self._requirements) def _check_same_type(self, other): diff --git a/dist/ba_data/python-site-packages/attr/_cmp.pyi b/dist/ba_data/python-site-packages/attr/_cmp.pyi index 7093550f..f3dcdc1a 100644 --- a/dist/ba_data/python-site-packages/attr/_cmp.pyi +++ b/dist/ba_data/python-site-packages/attr/_cmp.pyi @@ -1,14 +1,13 @@ -from typing import Type - -from . import _CompareWithType +from typing import Any, Callable, Optional, Type +_CompareWithType = Callable[[Any, Any], bool] def cmp_using( - eq: Optional[_CompareWithType], - lt: Optional[_CompareWithType], - le: Optional[_CompareWithType], - gt: Optional[_CompareWithType], - ge: Optional[_CompareWithType], - require_same_type: bool, - class_name: str, + eq: Optional[_CompareWithType] = ..., + lt: Optional[_CompareWithType] = ..., + le: Optional[_CompareWithType] = ..., + gt: Optional[_CompareWithType] = ..., + ge: Optional[_CompareWithType] = ..., + require_same_type: bool = ..., + class_name: str = ..., ) -> Type: ... diff --git a/dist/ba_data/python-site-packages/attr/_compat.py b/dist/ba_data/python-site-packages/attr/_compat.py index 6939f338..46b05ca4 100644 --- a/dist/ba_data/python-site-packages/attr/_compat.py +++ b/dist/ba_data/python-site-packages/attr/_compat.py @@ -1,242 +1,87 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT +import inspect import platform import sys -import types -import warnings +import threading + +from collections.abc import Mapping, Sequence # noqa: F401 +from typing import _GenericAlias -PY2 = sys.version_info[0] == 2 PYPY = platform.python_implementation() == "PyPy" +PY_3_8_PLUS = sys.version_info[:2] >= (3, 8) +PY_3_9_PLUS = sys.version_info[:2] >= (3, 9) +PY310 = sys.version_info[:2] >= (3, 10) +PY_3_12_PLUS = sys.version_info[:2] >= (3, 12) -if PYPY or sys.version_info[:2] >= (3, 6): - ordered_dict = dict +if sys.version_info < (3, 8): + try: + from typing_extensions import Protocol + except ImportError: # pragma: no cover + Protocol = object else: - from collections import OrderedDict - - ordered_dict = OrderedDict - + from typing import Protocol # noqa: F401 -if PY2: - from collections import Mapping, Sequence - from UserDict import IterableUserDict - - # We 'bundle' isclass instead of using inspect as importing inspect is - # fairly expensive (order of 10-15 ms for a modern machine in 2016) - def isclass(klass): - return isinstance(klass, (type, types.ClassType)) - - def new_class(name, bases, kwds, exec_body): - """ - A minimal stub of types.new_class that we need for make_class. - """ - ns = {} - exec_body(ns) - - return type(name, bases, ns) +class _AnnotationExtractor: + """ + Extract type annotations from a callable, returning None whenever there + is none. + """ - # TYPE is used in exceptions, repr(int) is different on Python 2 and 3. - TYPE = "type" + __slots__ = ["sig"] - def iteritems(d): - return d.iteritems() + def __init__(self, callable): + try: + self.sig = inspect.signature(callable) + except (ValueError, TypeError): # inspect failed + self.sig = None - # Python 2 is bereft of a read-only dict proxy, so we make one! - class ReadOnlyDict(IterableUserDict): + def get_first_param_type(self): """ - Best-effort read-only dict wrapper. - """ - - def __setitem__(self, key, val): - # We gently pretend we're a Python 3 mappingproxy. - raise TypeError( - "'mappingproxy' object does not support item assignment" - ) - - def update(self, _): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'update'" - ) - - def __delitem__(self, _): - # We gently pretend we're a Python 3 mappingproxy. - raise TypeError( - "'mappingproxy' object does not support item deletion" - ) - - def clear(self): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'clear'" - ) - - def pop(self, key, default=None): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'pop'" - ) - - def popitem(self): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'popitem'" - ) - - def setdefault(self, key, default=None): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'setdefault'" - ) - - def __repr__(self): - # Override to be identical to the Python 3 version. - return "mappingproxy(" + repr(self.data) + ")" - - def metadata_proxy(d): - res = ReadOnlyDict() - res.data.update(d) # We blocked update, so we have to do it like this. - return res - - def just_warn(*args, **kw): # pragma: no cover - """ - We only warn on Python 3 because we are not aware of any concrete - consequences of not setting the cell on Python 2. + Return the type annotation of the first argument if it's not empty. """ + if not self.sig: + return None + params = list(self.sig.parameters.values()) + if params and params[0].annotation is not inspect.Parameter.empty: + return params[0].annotation -else: # Python 3 and later. - from collections.abc import Mapping, Sequence # noqa + return None - def just_warn(*args, **kw): + def get_return_type(self): """ - We only warn on Python 3 because we are not aware of any concrete - consequences of not setting the cell on Python 2. + Return the return type if it's not empty. """ - warnings.warn( - "Running interpreter doesn't sufficiently support code object " - "introspection. Some features like bare super() or accessing " - "__class__ will not work with slotted classes.", - RuntimeWarning, - stacklevel=2, - ) - - def isclass(klass): - return isinstance(klass, type) - - TYPE = "class" - - def iteritems(d): - return d.items() - - new_class = types.new_class - - def metadata_proxy(d): - return types.MappingProxyType(dict(d)) - - -def make_set_closure_cell(): - """Return a function of two arguments (cell, value) which sets - the value stored in the closure cell `cell` to `value`. - """ - # pypy makes this easy. (It also supports the logic below, but - # why not do the easy/fast thing?) - if PYPY: - - def set_closure_cell(cell, value): - cell.__setstate__((value,)) - - return set_closure_cell - - # Otherwise gotta do it the hard way. - - # Create a function that will set its first cellvar to `value`. - def set_first_cellvar_to(value): - x = value - return - - # This function will be eliminated as dead code, but - # not before its reference to `x` forces `x` to be - # represented as a closure cell rather than a local. - def force_x_to_be_a_cell(): # pragma: no cover - return x - - try: - # Extract the code object and make sure our assumptions about - # the closure behavior are correct. - if PY2: - co = set_first_cellvar_to.func_code - else: - co = set_first_cellvar_to.__code__ - if co.co_cellvars != ("x",) or co.co_freevars != (): - raise AssertionError # pragma: no cover - - # Convert this code object to a code object that sets the - # function's first _freevar_ (not cellvar) to the argument. - if sys.version_info >= (3, 8): - # CPython 3.8+ has an incompatible CodeType signature - # (added a posonlyargcount argument) but also added - # CodeType.replace() to do this without counting parameters. - set_first_freevar_code = co.replace( - co_cellvars=co.co_freevars, co_freevars=co.co_cellvars - ) - else: - args = [co.co_argcount] - if not PY2: - args.append(co.co_kwonlyargcount) - args.extend( - [ - co.co_nlocals, - co.co_stacksize, - co.co_flags, - co.co_code, - co.co_consts, - co.co_names, - co.co_varnames, - co.co_filename, - co.co_name, - co.co_firstlineno, - co.co_lnotab, - # These two arguments are reversed: - co.co_cellvars, - co.co_freevars, - ] - ) - set_first_freevar_code = types.CodeType(*args) - - def set_closure_cell(cell, value): - # Create a function using the set_first_freevar_code, - # whose first closure cell is `cell`. Calling it will - # change the value of that cell. - setter = types.FunctionType( - set_first_freevar_code, {}, "setter", (), (cell,) - ) - # And call it to set the cell. - setter(value) - - # Make sure it works on this interpreter: - def make_func_with_cell(): - x = None - - def func(): - return x # pragma: no cover - - return func - - if PY2: - cell = make_func_with_cell().func_closure[0] - else: - cell = make_func_with_cell().__closure__[0] - set_closure_cell(cell, 100) - if cell.cell_contents != 100: - raise AssertionError # pragma: no cover - - except Exception: - return just_warn - else: - return set_closure_cell - - -set_closure_cell = make_set_closure_cell() + if ( + self.sig + and self.sig.return_annotation is not inspect.Signature.empty + ): + return self.sig.return_annotation + + return None + + +# Thread-local global to track attrs instances which are already being repr'd. +# This is needed because there is no other (thread-safe) way to pass info +# about the instances that are already being repr'd through the call stack +# in order to ensure we don't perform infinite recursion. +# +# For instance, if an instance contains a dict which contains that instance, +# we need to know that we're already repr'ing the outside instance from within +# the dict's repr() call. +# +# This lives here rather than in _make.py so that the functions in _make.py +# don't have a direct reference to the thread-local in their globals dict. +# If they have such a reference, it breaks cloudpickle. +repr_context = threading.local() + + +def get_generic_base(cl): + """If this is a generic class (A[str]), return the generic base for it.""" + if cl.__class__ is _GenericAlias: + return cl.__origin__ + return None diff --git a/dist/ba_data/python-site-packages/attr/_config.py b/dist/ba_data/python-site-packages/attr/_config.py index 8ec92096..9c245b14 100644 --- a/dist/ba_data/python-site-packages/attr/_config.py +++ b/dist/ba_data/python-site-packages/attr/_config.py @@ -1,5 +1,4 @@ -from __future__ import absolute_import, division, print_function - +# SPDX-License-Identifier: MIT __all__ = ["set_run_validators", "get_run_validators"] @@ -9,9 +8,14 @@ def set_run_validators(run): """ Set whether or not validators are run. By default, they are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.set_disabled()` + instead. """ if not isinstance(run, bool): - raise TypeError("'run' must be bool.") + msg = "'run' must be bool." + raise TypeError(msg) global _run_validators _run_validators = run @@ -19,5 +23,9 @@ def set_run_validators(run): def get_run_validators(): """ Return whether or not validators are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.get_disabled()` + instead. """ return _run_validators diff --git a/dist/ba_data/python-site-packages/attr/_funcs.py b/dist/ba_data/python-site-packages/attr/_funcs.py index fda508c5..a888991d 100644 --- a/dist/ba_data/python-site-packages/attr/_funcs.py +++ b/dist/ba_data/python-site-packages/attr/_funcs.py @@ -1,8 +1,9 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT + import copy -from ._compat import iteritems +from ._compat import PY_3_9_PLUS, get_generic_base from ._make import NOTHING, _obj_setattr, fields from .exceptions import AttrsAttributeNotFoundError @@ -16,16 +17,16 @@ def asdict( value_serializer=None, ): """ - Return the ``attrs`` attribute values of *inst* as a dict. + Return the *attrs* attribute values of *inst* as a dict. - Optionally recurse into other ``attrs``-decorated classes. + Optionally recurse into other *attrs*-decorated classes. - :param inst: Instance of an ``attrs``-decorated class. + :param inst: Instance of an *attrs*-decorated class. :param bool recurse: Recurse into classes that are also - ``attrs``-decorated. + *attrs*-decorated. :param callable filter: A callable whose return code determines whether an attribute or element is included (``True``) or dropped (``False``). Is - called with the `attr.Attribute` as the first argument and the + called with the `attrs.Attribute` as the first argument and the value as the second argument. :param callable dict_factory: A callable to produce dictionaries from. For example, to produce ordered dictionaries instead of normal Python @@ -40,12 +41,14 @@ def asdict( :rtype: return type of *dict_factory* - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class. .. versionadded:: 16.0.0 *dict_factory* .. versionadded:: 16.1.0 *retain_collection_types* .. versionadded:: 20.3.0 *value_serializer* + .. versionadded:: 21.3.0 If a dict has a collection for a key, it is + serialized as a tuple. """ attrs = fields(inst.__class__) rv = dict_factory() @@ -61,46 +64,55 @@ def asdict( if has(v.__class__): rv[a.name] = asdict( v, - True, - filter, - dict_factory, - retain_collection_types, - value_serializer, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ) elif isinstance(v, (tuple, list, set, frozenset)): cf = v.__class__ if retain_collection_types is True else list - rv[a.name] = cf( - [ - _asdict_anything( - i, - filter, - dict_factory, - retain_collection_types, - value_serializer, - ) - for i in v - ] - ) + items = [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in v + ] + try: + rv[a.name] = cf(items) + except TypeError: + if not issubclass(cf, tuple): + raise + # Workaround for TypeError: cf.__new__() missing 1 required + # positional argument (which appears, for a namedturle) + rv[a.name] = cf(*items) elif isinstance(v, dict): df = dict_factory rv[a.name] = df( ( _asdict_anything( kk, - filter, - df, - retain_collection_types, - value_serializer, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ), _asdict_anything( vv, - filter, - df, - retain_collection_types, - value_serializer, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ), ) - for kk, vv in iteritems(v) + for kk, vv in v.items() ) else: rv[a.name] = v @@ -111,6 +123,7 @@ def asdict( def _asdict_anything( val, + is_key, filter, dict_factory, retain_collection_types, @@ -123,22 +136,29 @@ def _asdict_anything( # Attrs class. rv = asdict( val, - True, - filter, - dict_factory, - retain_collection_types, - value_serializer, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ) elif isinstance(val, (tuple, list, set, frozenset)): - cf = val.__class__ if retain_collection_types is True else list + if retain_collection_types is True: + cf = val.__class__ + elif is_key: + cf = tuple + else: + cf = list + rv = cf( [ _asdict_anything( i, - filter, - dict_factory, - retain_collection_types, - value_serializer, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ) for i in val ] @@ -148,13 +168,23 @@ def _asdict_anything( rv = df( ( _asdict_anything( - kk, filter, df, retain_collection_types, value_serializer + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ), _asdict_anything( - vv, filter, df, retain_collection_types, value_serializer + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, ), ) - for kk, vv in iteritems(val) + for kk, vv in val.items() ) else: rv = val @@ -172,16 +202,16 @@ def astuple( retain_collection_types=False, ): """ - Return the ``attrs`` attribute values of *inst* as a tuple. + Return the *attrs* attribute values of *inst* as a tuple. - Optionally recurse into other ``attrs``-decorated classes. + Optionally recurse into other *attrs*-decorated classes. - :param inst: Instance of an ``attrs``-decorated class. + :param inst: Instance of an *attrs*-decorated class. :param bool recurse: Recurse into classes that are also - ``attrs``-decorated. + *attrs*-decorated. :param callable filter: A callable whose return code determines whether an attribute or element is included (``True``) or dropped (``False``). Is - called with the `attr.Attribute` as the first argument and the + called with the `attrs.Attribute` as the first argument and the value as the second argument. :param callable tuple_factory: A callable to produce tuples from. For example, to produce lists instead of tuples. @@ -192,7 +222,7 @@ def astuple( :rtype: return type of *tuple_factory* - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class. .. versionadded:: 16.2.0 @@ -217,22 +247,26 @@ def astuple( ) elif isinstance(v, (tuple, list, set, frozenset)): cf = v.__class__ if retain is True else list - rv.append( - cf( - [ - astuple( - j, - recurse=True, - filter=filter, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(j.__class__) - else j - for j in v - ] + items = [ + astuple( + j, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, ) - ) + if has(j.__class__) + else j + for j in v + ] + try: + rv.append(cf(items)) + except TypeError: + if not issubclass(cf, tuple): + raise + # Workaround for TypeError: cf.__new__() missing 1 required + # positional argument (which appears, for a namedturle) + rv.append(cf(*items)) elif isinstance(v, dict): df = v.__class__ if retain is True else dict rv.append( @@ -253,7 +287,7 @@ def astuple( if has(vv.__class__) else vv, ) - for kk, vv in iteritems(v) + for kk, vv in v.items() ) ) else: @@ -266,84 +300,128 @@ def astuple( def has(cls): """ - Check whether *cls* is a class with ``attrs`` attributes. + Check whether *cls* is a class with *attrs* attributes. :param type cls: Class to introspect. :raise TypeError: If *cls* is not a class. :rtype: bool """ - return getattr(cls, "__attrs_attrs__", None) is not None + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is not None: + return True + + # No attrs, maybe it's a specialized generic (A[str])? + generic_base = get_generic_base(cls) + if generic_base is not None: + generic_attrs = getattr(generic_base, "__attrs_attrs__", None) + if generic_attrs is not None: + # Stick it on here for speed next time. + cls.__attrs_attrs__ = generic_attrs + return generic_attrs is not None + return False def assoc(inst, **changes): """ Copy *inst* and apply *changes*. - :param inst: Instance of a class with ``attrs`` attributes. + This is different from `evolve` that applies the changes to the arguments + that create the new instance. + + `evolve`'s behavior is preferable, but there are `edge cases`_ where it + doesn't work. Therefore `assoc` is deprecated, but will not be removed. + + .. _`edge cases`: https://github.com/python-attrs/attrs/issues/251 + + :param inst: Instance of a class with *attrs* attributes. :param changes: Keyword changes in the new copy. :return: A copy of inst with *changes* incorporated. - :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't - be found on *cls*. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.AttrsAttributeNotFoundError: If *attr_name* + couldn't be found on *cls*. + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class. .. deprecated:: 17.1.0 - Use `evolve` instead. + Use `attrs.evolve` instead if you can. + This function will not be removed du to the slightly different approach + compared to `attrs.evolve`. """ - import warnings - - warnings.warn( - "assoc is deprecated and will be removed after 2018/01.", - DeprecationWarning, - stacklevel=2, - ) new = copy.copy(inst) attrs = fields(inst.__class__) - for k, v in iteritems(changes): + for k, v in changes.items(): a = getattr(attrs, k, NOTHING) if a is NOTHING: - raise AttrsAttributeNotFoundError( - "{k} is not an attrs attribute on {cl}.".format( - k=k, cl=new.__class__ - ) - ) + msg = f"{k} is not an attrs attribute on {new.__class__}." + raise AttrsAttributeNotFoundError(msg) _obj_setattr(new, k, v) return new -def evolve(inst, **changes): +def evolve(*args, **changes): """ - Create a new instance, based on *inst* with *changes* applied. + Create a new instance, based on the first positional argument with + *changes* applied. - :param inst: Instance of a class with ``attrs`` attributes. + :param inst: Instance of a class with *attrs* attributes. :param changes: Keyword changes in the new copy. :return: A copy of inst with *changes* incorporated. :raise TypeError: If *attr_name* couldn't be found in the class ``__init__``. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class. - .. versionadded:: 17.1.0 + .. versionadded:: 17.1.0 + .. deprecated:: 23.1.0 + It is now deprecated to pass the instance using the keyword argument + *inst*. It will raise a warning until at least April 2024, after which + it will become an error. Always pass the instance as a positional + argument. """ + # Try to get instance by positional argument first. + # Use changes otherwise and warn it'll break. + if args: + try: + (inst,) = args + except ValueError: + msg = f"evolve() takes 1 positional argument, but {len(args)} were given" + raise TypeError(msg) from None + else: + try: + inst = changes.pop("inst") + except KeyError: + msg = "evolve() missing 1 required positional argument: 'inst'" + raise TypeError(msg) from None + + import warnings + + warnings.warn( + "Passing the instance per keyword argument is deprecated and " + "will stop working in, or after, April 2024.", + DeprecationWarning, + stacklevel=2, + ) + cls = inst.__class__ attrs = fields(cls) for a in attrs: if not a.init: continue attr_name = a.name # To deal with private attributes. - init_name = attr_name if attr_name[0] != "_" else attr_name[1:] + init_name = a.alias if init_name not in changes: changes[init_name] = getattr(inst, attr_name) return cls(**changes) -def resolve_types(cls, globalns=None, localns=None, attribs=None): +def resolve_types( + cls, globalns=None, localns=None, attribs=None, include_extras=True +): """ Resolve any strings and forward annotations in type annotations. @@ -362,34 +440,44 @@ def resolve_types(cls, globalns=None, localns=None, attribs=None): :param Optional[dict] localns: Dictionary containing local variables. :param Optional[list] attribs: List of attribs for the given class. This is necessary when calling from inside a ``field_transformer`` - since *cls* is not an ``attrs`` class yet. + since *cls* is not an *attrs* class yet. + :param bool include_extras: Resolve more accurately, if possible. + Pass ``include_extras`` to ``typing.get_hints``, if supported by the + typing module. On supported Python versions (3.9+), this resolves the + types more accurately. :raise TypeError: If *cls* is not a class. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class and you didn't pass any attribs. :raise NameError: If types cannot be resolved because of missing variables. :returns: *cls* so you can use this function also as a class decorator. - Please note that you have to apply it **after** `attr.s`. That means - the decorator has to come in the line **before** `attr.s`. + Please note that you have to apply it **after** `attrs.define`. That + means the decorator has to come in the line **before** `attrs.define`. .. versionadded:: 20.1.0 .. versionadded:: 21.1.0 *attribs* + .. versionadded:: 23.1.0 *include_extras* """ - try: - # Since calling get_type_hints is expensive we cache whether we've - # done it already. - cls.__attrs_types_resolved__ - except AttributeError: + # Since calling get_type_hints is expensive we cache whether we've + # done it already. + if getattr(cls, "__attrs_types_resolved__", None) != cls: import typing - hints = typing.get_type_hints(cls, globalns=globalns, localns=localns) + kwargs = {"globalns": globalns, "localns": localns} + + if PY_3_9_PLUS: + kwargs["include_extras"] = include_extras + + hints = typing.get_type_hints(cls, **kwargs) for field in fields(cls) if attribs is None else attribs: if field.name in hints: # Since fields have been frozen we must work around it. _obj_setattr(field, "type", hints[field.name]) - cls.__attrs_types_resolved__ = True + # We store the class we resolved so that subclasses know they haven't + # been resolved. + cls.__attrs_types_resolved__ = cls # Return the class so you can use it as a decorator too. return cls diff --git a/dist/ba_data/python-site-packages/attr/_make.py b/dist/ba_data/python-site-packages/attr/_make.py index a1912b12..10b4eca7 100644 --- a/dist/ba_data/python-site-packages/attr/_make.py +++ b/dist/ba_data/python-site-packages/attr/_make.py @@ -1,46 +1,39 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT +import contextlib import copy +import enum +import functools import inspect +import itertools import linecache import sys -import threading -import uuid -import warnings +import types +import typing from operator import itemgetter -from . import _config, setters +# We need to import _compat itself in addition to the _compat members to avoid +# having the thread-local in the globals here. +from . import _compat, _config, setters from ._compat import ( - PY2, - PYPY, - isclass, - iteritems, - metadata_proxy, - new_class, - ordered_dict, - set_closure_cell, + PY310, + PY_3_8_PLUS, + _AnnotationExtractor, + get_generic_base, ) from .exceptions import ( DefaultAlreadySetError, FrozenInstanceError, NotAnAttrsClassError, - PythonTooOldError, UnannotatedAttributeError, ) -if not PY2: - import typing - - # This is used at least twice, so cache it here. _obj_setattr = object.__setattr__ _init_converter_pat = "__attr_converter_%s" -_init_factory_pat = "__attr_factory_{}" -_tuple_property_pat = ( - " {attr_name} = _attrs_property(_attrs_itemgetter({index}))" -) +_init_factory_pat = "__attr_factory_%s" _classvar_prefixes = ( "typing.ClassVar", "t.ClassVar", @@ -52,27 +45,26 @@ # (when slots=True) _hash_cache_field = "_attrs_cached_hash" -_empty_metadata_singleton = metadata_proxy({}) +_empty_metadata_singleton = types.MappingProxyType({}) # Unique object for unequivocal getattr() defaults. _sentinel = object() +_ng_default_on_setattr = setters.pipe(setters.convert, setters.validate) -class _Nothing(object): + +class _Nothing(enum.Enum): """ - Sentinel class to indicate the lack of a value when ``None`` is ambiguous. + Sentinel to indicate the lack of a value when ``None`` is ambiguous. - ``_Nothing`` is a singleton. There is only ever one of it. + If extending attrs, you can use ``typing.Literal[NOTHING]`` to show + that a value may be ``NOTHING``. .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. + .. versionchanged:: 22.2.0 ``NOTHING`` is now an ``enum.Enum`` variant. """ - _singleton = None - - def __new__(cls): - if _Nothing._singleton is None: - _Nothing._singleton = super(_Nothing, cls).__new__(cls) - return _Nothing._singleton + NOTHING = enum.auto() def __repr__(self): return "NOTHING" @@ -80,11 +72,8 @@ def __repr__(self): def __bool__(self): return False - def __len__(self): - return 0 # __bool__ for Python 2 - -NOTHING = _Nothing() +NOTHING = _Nothing.NOTHING """ Sentinel to indicate the lack of a value when ``None`` is ambiguous. """ @@ -102,17 +91,8 @@ class _CacheHashWrapper(int): See GH #613 for more details. """ - if PY2: - # For some reason `type(None)` isn't callable in Python 2, but we don't - # actually need a constructor for None objects, we just need any - # available function that returns None. - def __reduce__(self, _none_constructor=getattr, _args=(0, "", None)): - return _none_constructor, _args - - else: - - def __reduce__(self, _none_constructor=type(None), _args=()): - return _none_constructor, _args + def __reduce__(self, _none_constructor=type(None), _args=()): # noqa: B008 + return _none_constructor, _args def attrib( @@ -130,113 +110,130 @@ def attrib( eq=None, order=None, on_setattr=None, + alias=None, ): """ Create a new attribute on a class. .. warning:: - Does *not* do anything unless the class is also decorated with - `attr.s`! + Does *not* do anything unless the class is also decorated with `attr.s` + / `attrs.define` / and so on! + + Please consider using `attrs.field` in new code (``attr.ib`` will *never* + go away, though). - :param default: A value that is used if an ``attrs``-generated ``__init__`` + :param default: A value that is used if an *attrs*-generated ``__init__`` is used and no value is passed while instantiating or the attribute is excluded using ``init=False``. - If the value is an instance of `Factory`, its callable will be + If the value is an instance of `attrs.Factory`, its callable will be used to construct a new value (useful for mutable data types like lists or dicts). - If a default is not set (or set manually to `attr.NOTHING`), a value - *must* be supplied when instantiating; otherwise a `TypeError` - will be raised. + If a default is not set (or set manually to `attrs.NOTHING`), a value + *must* be supplied when instantiating; otherwise a `TypeError` will be + raised. The default can also be set using decorator notation as shown below. - :type default: Any value + .. seealso:: `defaults` :param callable factory: Syntactic sugar for ``default=attr.Factory(factory)``. - :param validator: `callable` that is called by ``attrs``-generated + :param validator: `callable` that is called by *attrs*-generated ``__init__`` methods after the instance has been initialized. They - receive the initialized instance, the `Attribute`, and the + receive the initialized instance, the :func:`~attrs.Attribute`, and the passed value. The return value is *not* inspected so the validator has to throw an exception itself. - If a `list` is passed, its items are treated as validators and must - all pass. + If a `list` is passed, its items are treated as validators and must all + pass. Validators can be globally disabled and re-enabled using - `get_run_validators`. + `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. The validator can also be set using decorator notation as shown below. + .. seealso:: :ref:`validators` + :type validator: `callable` or a `list` of `callable`\\ s. - :param repr: Include this attribute in the generated ``__repr__`` - method. If ``True``, include the attribute; if ``False``, omit it. By - default, the built-in ``repr()`` function is used. To override how the - attribute value is formatted, pass a ``callable`` that takes a single - value and returns a string. Note that the resulting string is used - as-is, i.e. it will be used directly *instead* of calling ``repr()`` - (the default). + :param repr: Include this attribute in the generated ``__repr__`` method. + If ``True``, include the attribute; if ``False``, omit it. By default, + the built-in ``repr()`` function is used. To override how the attribute + value is formatted, pass a ``callable`` that takes a single value and + returns a string. Note that the resulting string is used as-is, i.e. it + will be used directly *instead* of calling ``repr()`` (the default). :type repr: a `bool` or a `callable` to use a custom function. - :param eq: If ``True`` (default), include this attribute in the - generated ``__eq__`` and ``__ne__`` methods that check two instances - for equality. To override how the attribute value is compared, - pass a ``callable`` that takes a single value and returns the value - to be compared. + :param eq: If ``True`` (default), include this attribute in the generated + ``__eq__`` and ``__ne__`` methods that check two instances for + equality. To override how the attribute value is compared, pass a + ``callable`` that takes a single value and returns the value to be + compared. + + .. seealso:: `comparison` :type eq: a `bool` or a `callable`. :param order: If ``True`` (default), include this attributes in the - generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. - To override how the attribute value is ordered, - pass a ``callable`` that takes a single value and returns the value - to be ordered. + generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To + override how the attribute value is ordered, pass a ``callable`` that + takes a single value and returns the value to be ordered. + + .. seealso:: `comparison` :type order: a `bool` or a `callable`. :param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the same value. Must not be mixed with *eq* or *order*. + + .. seealso:: `comparison` :type cmp: a `bool` or a `callable`. - :param Optional[bool] hash: Include this attribute in the generated + :param bool | None hash: Include this attribute in the generated ``__hash__`` method. If ``None`` (default), mirror *eq*'s value. This is the correct behavior according the Python spec. Setting this value to anything else than ``None`` is *discouraged*. + + .. seealso:: `hashing` :param bool init: Include this attribute in the generated ``__init__`` method. It is possible to set this to ``False`` and set a default value. In that case this attributed is unconditionally initialized with the specified default value or factory. - :param callable converter: `callable` that is called by - ``attrs``-generated ``__init__`` methods to convert attribute's value - to the desired format. It is given the passed-in value, and the - returned value will be used as the new value of the attribute. The - value is converted before being passed to the validator, if any. - :param metadata: An arbitrary mapping, to be used by third-party - components. See `extending_metadata`. - :param type: The type of the attribute. In Python 3.6 or greater, the - preferred method to specify the type is using a variable annotation - (see `PEP 526 `_). - This argument is provided for backward compatibility. - Regardless of the approach used, the type will be stored on - ``Attribute.type``. - - Please note that ``attrs`` doesn't do anything with this metadata by - itself. You can use it as part of your own code or for - `static type checking `. - :param kw_only: Make this attribute keyword-only (Python 3+) - in the generated ``__init__`` (if ``init`` is ``False``, this - parameter is ignored). + + .. seealso:: `init` + :param callable converter: `callable` that is called by *attrs*-generated + ``__init__`` methods to convert attribute's value to the desired + format. It is given the passed-in value, and the returned value will + be used as the new value of the attribute. The value is converted + before being passed to the validator, if any. + + .. seealso:: :ref:`converters` + :param dict | None metadata: An arbitrary mapping, to be used by + third-party components. See `extending-metadata`. + + :param type: The type of the attribute. Nowadays, the preferred method to + specify the type is using a variable annotation (see :pep:`526`). This + argument is provided for backward compatibility. Regardless of the + approach used, the type will be stored on ``Attribute.type``. + + Please note that *attrs* doesn't do anything with this metadata by + itself. You can use it as part of your own code or for `static type + checking `. + :param bool kw_only: Make this attribute keyword-only in the generated + ``__init__`` (if ``init`` is ``False``, this parameter is ignored). :param on_setattr: Allows to overwrite the *on_setattr* setting from `attr.s`. If left `None`, the *on_setattr* value from `attr.s` is used. - Set to `attr.setters.NO_OP` to run **no** `setattr` hooks for this + Set to `attrs.setters.NO_OP` to run **no** `setattr` hooks for this attribute -- regardless of the setting in `attr.s`. :type on_setattr: `callable`, or a list of callables, or `None`, or - `attr.setters.NO_OP` + `attrs.setters.NO_OP` + :param str | None alias: Override this attribute's parameter name in the + generated ``__init__`` method. If left `None`, default to ``name`` + stripped of leading underscores. See `private-attributes`. .. versionadded:: 15.2.0 *convert* .. versionadded:: 16.3.0 *metadata* @@ -259,24 +256,25 @@ def attrib( .. versionchanged:: 21.1.0 *eq*, *order*, and *cmp* also accept a custom callable .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 22.2.0 *alias* """ eq, eq_key, order, order_key = _determine_attrib_eq_order( cmp, eq, order, True ) if hash is not None and hash is not True and hash is not False: - raise TypeError( - "Invalid value for hash. Must be True, False, or None." - ) + msg = "Invalid value for hash. Must be True, False, or None." + raise TypeError(msg) if factory is not None: if default is not NOTHING: - raise ValueError( - "The `default` and `factory` arguments are mutually " - "exclusive." + msg = ( + "The `default` and `factory` arguments are mutually exclusive." ) + raise ValueError(msg) if not callable(factory): - raise ValueError("The `factory` argument must be a callable.") + msg = "The `factory` argument must be a callable." + raise ValueError(msg) default = Factory(factory) if metadata is None: @@ -308,6 +306,7 @@ def attrib( order=order, order_key=order_key, on_setattr=on_setattr, + alias=alias, ) @@ -319,24 +318,31 @@ def _compile_and_eval(script, globs, locs=None, filename=""): eval(bytecode, globs, locs) -def _make_method(name, script, filename, globs=None): +def _make_method(name, script, filename, globs): """ Create the method with the script given and return the method object. """ locs = {} - if globs is None: - globs = {} - - _compile_and_eval(script, globs, locs, filename) # In order of debuggers like PDB being able to step through the code, # we add a fake linecache entry. - linecache.cache[filename] = ( - len(script), - None, - script.splitlines(True), - filename, - ) + count = 1 + base_filename = filename + while True: + linecache_tuple = ( + len(script), + None, + script.splitlines(True), + filename, + ) + old_val = linecache.cache.setdefault(filename, linecache_tuple) + if old_val == linecache_tuple: + break + + filename = f"{base_filename[:-1]}-{count}>" + count += 1 + + _compile_and_eval(script, globs, locs, filename) return locs[name] @@ -351,15 +357,15 @@ class MyClassAttributes(tuple): __slots__ = () x = property(itemgetter(0)) """ - attr_class_name = "{}Attributes".format(cls_name) + attr_class_name = f"{cls_name}Attributes" attr_class_template = [ - "class {}(tuple):".format(attr_class_name), + f"class {attr_class_name}(tuple):", " __slots__ = ()", ] if attr_names: for i, attr_name in enumerate(attr_names): attr_class_template.append( - _tuple_property_pat.format(index=i, attr_name=attr_name) + f" {attr_name} = _attrs_property(_attrs_itemgetter({i}))" ) else: attr_class_template.append(" pass") @@ -403,8 +409,6 @@ def _is_class_var(annot): def _has_own_attribute(cls, attrib_name): """ Check whether *cls* defines *attrib_name* (and doesn't just inherit it). - - Requires Python 3. """ attr = getattr(cls, attrib_name, _sentinel) if attr is _sentinel: @@ -428,13 +432,6 @@ def _get_annotations(cls): return {} -def _counter_getter(e): - """ - Key function for sorting to avoid re-creating a lambda for every class. - """ - return e[1].counter - - def _collect_base_attrs(cls, taken_attr_names): """ Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. @@ -448,7 +445,7 @@ def _collect_base_attrs(cls, taken_attr_names): if a.inherited or a.name in taken_attr_names: continue - a = a.evolve(inherited=True) + a = a.evolve(inherited=True) # noqa: PLW2901 base_attrs.append(a) base_attr_map[a.name] = base_cls @@ -486,7 +483,7 @@ def _collect_base_attrs_broken(cls, taken_attr_names): if a.name in taken_attr_names: continue - a = a.evolve(inherited=True) + a = a.evolve(inherited=True) # noqa: PLW2901 taken_attr_names.add(a.name) base_attrs.append(a) base_attr_map[a.name] = base_cls @@ -511,10 +508,7 @@ def _transform_attrs( anns = _get_annotations(cls) if these is not None: - ca_list = [(name, ca) for name, ca in iteritems(these)] - - if not isinstance(these, ordered_dict): - ca_list.sort(key=_counter_getter) + ca_list = list(these.items()) elif auto_attribs is True: ca_names = { name @@ -530,10 +524,7 @@ def _transform_attrs( a = cd.get(attr_name, NOTHING) if not isinstance(a, _CountingAttr): - if a is NOTHING: - a = attrib() - else: - a = attrib(default=a) + a = attrib() if a is NOTHING else attrib(default=a) ca_list.append((attr_name, a)) unannotated = ca_names - annot_names @@ -571,15 +562,11 @@ def _transform_attrs( cls, {a.name for a in own_attrs} ) - attr_names = [a.name for a in base_attrs + own_attrs] - - AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) - if kw_only: own_attrs = [a.evolve(kw_only=True) for a in own_attrs] base_attrs = [a.evolve(kw_only=True) for a in base_attrs] - attrs = AttrsClass(base_attrs + own_attrs) + attrs = base_attrs + own_attrs # Mandatory vs non-mandatory attr order only matters when they are part of # the __init__ signature and when they aren't kw_only (which are moved to @@ -588,42 +575,100 @@ def _transform_attrs( had_default = False for a in (a for a in attrs if a.init is not False and a.kw_only is False): if had_default is True and a.default is NOTHING: - raise ValueError( - "No mandatory attributes allowed after an attribute with a " - "default value or factory. Attribute in question: %r" % (a,) - ) + msg = f"No mandatory attributes allowed after an attribute with a default value or factory. Attribute in question: {a!r}" + raise ValueError(msg) if had_default is False and a.default is not NOTHING: had_default = True if field_transformer is not None: attrs = field_transformer(cls, attrs) - return _Attributes((attrs, base_attrs, base_attr_map)) + # Resolve default field alias after executing field_transformer. + # This allows field_transformer to differentiate between explicit vs + # default aliases and supply their own defaults. + attrs = [ + a.evolve(alias=_default_init_alias_for(a.name)) if not a.alias else a + for a in attrs + ] -if PYPY: + # Create AttrsClass *after* applying the field_transformer since it may + # add or remove attributes! + attr_names = [a.name for a in attrs] + AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) - def _frozen_setattrs(self, name, value): - """ - Attached to frozen classes as __setattr__. - """ - if isinstance(self, BaseException) and name in ( - "__cause__", - "__context__", - ): - BaseException.__setattr__(self, name, value) - return + return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map)) - raise FrozenInstanceError() +def _make_cached_property_getattr( + cached_properties, + original_getattr, + cls, +): + lines = [ + # Wrapped to get `__class__` into closure cell for super() + # (It will be replaced with the newly constructed class after construction). + "def wrapper():", + " __class__ = _cls", + " def __getattr__(self, item, cached_properties=cached_properties, original_getattr=original_getattr, _cached_setattr_get=_cached_setattr_get):", + " func = cached_properties.get(item)", + " if func is not None:", + " result = func(self)", + " _setter = _cached_setattr_get(self)", + " _setter(item, result)", + " return result", + ] + if original_getattr is not None: + lines.append( + " return original_getattr(self, item)", + ) + else: + lines.extend( + [ + " if hasattr(super(), '__getattr__'):", + " return super().__getattr__(item)", + " original_error = f\"'{self.__class__.__name__}' object has no attribute '{item}'\"", + " raise AttributeError(original_error)", + ] + ) + + lines.extend( + [ + " return __getattr__", + "__getattr__ = wrapper()", + ] + ) -else: + unique_filename = _generate_unique_filename(cls, "getattr") - def _frozen_setattrs(self, name, value): - """ - Attached to frozen classes as __setattr__. - """ - raise FrozenInstanceError() + glob = { + "cached_properties": cached_properties, + "_cached_setattr_get": _obj_setattr.__get__, + "_cls": cls, + "original_getattr": original_getattr, + } + + return _make_method( + "__getattr__", + "\n".join(lines), + unique_filename, + glob, + ) + + +def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + if isinstance(self, BaseException) and name in ( + "__cause__", + "__context__", + "__traceback__", + ): + BaseException.__setattr__(self, name, value) + return + + raise FrozenInstanceError() def _frozen_delattrs(self, name): @@ -633,7 +678,7 @@ def _frozen_delattrs(self, name): raise FrozenInstanceError() -class _ClassBuilder(object): +class _ClassBuilder: """ Iteratively build *one* class. """ @@ -649,12 +694,13 @@ class _ClassBuilder(object): "_delete_attribs", "_frozen", "_has_pre_init", + "_pre_init_has_args", "_has_post_init", "_is_exc", "_on_setattr", "_slots", "_weakref_slot", - "_has_own_setattr", + "_wrote_own_setattr", "_has_custom_setattr", ) @@ -687,7 +733,7 @@ def __init__( self._cls = cls self._cls_dict = dict(cls.__dict__) if slots else {} self._attrs = attrs - self._base_names = set(a.name for a in base_attrs) + self._base_names = {a.name for a in base_attrs} self._base_attr_map = base_map self._attr_names = tuple(a.name for a in attrs) self._slots = slots @@ -695,13 +741,20 @@ def __init__( self._weakref_slot = weakref_slot self._cache_hash = cache_hash self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) + self._pre_init_has_args = False + if self._has_pre_init: + # Check if the pre init method has more arguments than just `self` + # We want to pass arguments if pre init expects arguments + pre_init_func = cls.__attrs_pre_init__ + pre_init_signature = inspect.signature(pre_init_func) + self._pre_init_has_args = len(pre_init_signature.parameters) > 1 self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) self._delete_attribs = not bool(these) self._is_exc = is_exc self._on_setattr = on_setattr self._has_custom_setattr = has_custom_setattr - self._has_own_setattr = False + self._wrote_own_setattr = False self._cls_dict["__attrs_attrs__"] = self._attrs @@ -709,7 +762,33 @@ def __init__( self._cls_dict["__setattr__"] = _frozen_setattrs self._cls_dict["__delattr__"] = _frozen_delattrs - self._has_own_setattr = True + self._wrote_own_setattr = True + elif on_setattr in ( + _ng_default_on_setattr, + setters.validate, + setters.convert, + ): + has_validator = has_converter = False + for a in attrs: + if a.validator is not None: + has_validator = True + if a.converter is not None: + has_converter = True + + if has_validator and has_converter: + break + if ( + ( + on_setattr == _ng_default_on_setattr + and not (has_validator or has_converter) + ) + or (on_setattr == setters.validate and not has_validator) + or (on_setattr == setters.convert and not has_converter) + ): + # If class-level on_setattr is set to convert + validate, but + # there's no field to convert or validate, pretend like there's + # no on_setattr. + self._on_setattr = None if getstate_setstate: ( @@ -718,17 +797,35 @@ def __init__( ) = self._make_getstate_setstate() def __repr__(self): - return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__) + return f"<_ClassBuilder(cls={self._cls.__name__})>" - def build_class(self): - """ - Finalize class based on the accumulated configuration. + if PY310: + import abc + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + return self._create_slots_class() + + return self.abc.update_abstractmethods( + self._patch_original_class() + ) + + else: + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + return self._create_slots_class() - Builder cannot be used after calling this method. - """ - if self._slots is True: - return self._create_slots_class() - else: return self._patch_original_class() def _patch_original_class(self): @@ -745,13 +842,11 @@ def _patch_original_class(self): name not in base_names and getattr(cls, name, _sentinel) is not _sentinel ): - try: + # An AttributeError can happen if a base class defines a + # class variable and we want to set an attribute with the + # same name by using only a type annotation. + with contextlib.suppress(AttributeError): delattr(cls, name) - except AttributeError: - # This can happen if a base class defines a class - # variable and we want to set an attribute with the - # same name by using only a type annotation. - pass # Attach our dunder methods. for name, value in self._cls_dict.items(): @@ -759,13 +854,13 @@ def _patch_original_class(self): # If we've inherited an attrs __setattr__ and don't write our own, # reset it to object's. - if not self._has_own_setattr and getattr( + if not self._wrote_own_setattr and getattr( cls, "__attrs_own_setattr__", False ): cls.__attrs_own_setattr__ = False if not self._has_custom_setattr: - cls.__setattr__ = object.__setattr__ + cls.__setattr__ = _obj_setattr return cls @@ -775,8 +870,8 @@ def _create_slots_class(self): """ cd = { k: v - for k, v in iteritems(self._cls_dict) - if k not in tuple(self._attr_names) + ("__dict__", "__weakref__") + for k, v in self._cls_dict.items() + if k not in (*tuple(self._attr_names), "__dict__", "__weakref__") } # If our class doesn't have its own implementation of __setattr__ @@ -787,18 +882,18 @@ def _create_slots_class(self): # XXX: a non-attrs class and subclass the resulting class with an attrs # XXX: class. See `test_slotted_confused` for details. For now that's # XXX: OK with us. - if not self._has_own_setattr: + if not self._wrote_own_setattr: cd["__attrs_own_setattr__"] = False if not self._has_custom_setattr: for base_cls in self._cls.__bases__: if base_cls.__dict__.get("__attrs_own_setattr__", False): - cd["__setattr__"] = object.__setattr__ + cd["__setattr__"] = _obj_setattr break # Traverse the MRO to collect existing slots # and check for an existing __weakref__. - existing_slots = dict() + existing_slots = {} weakref_inherited = False for base_cls in self._cls.__mro__[1:-1]: if base_cls.__dict__.get("__weakref__", None) is not None: @@ -821,38 +916,76 @@ def _create_slots_class(self): ): names += ("__weakref__",) + if PY_3_8_PLUS: + cached_properties = { + name: cached_property.func + for name, cached_property in cd.items() + if isinstance(cached_property, functools.cached_property) + } + else: + # `functools.cached_property` was introduced in 3.8. + # So can't be used before this. + cached_properties = {} + + # Collect methods with a `__class__` reference that are shadowed in the new class. + # To know to update them. + additional_closure_functions_to_update = [] + if cached_properties: + # Add cached properties to names for slotting. + names += tuple(cached_properties.keys()) + + for name in cached_properties: + # Clear out function from class to avoid clashing. + del cd[name] + + class_annotations = _get_annotations(self._cls) + for name, func in cached_properties.items(): + annotation = inspect.signature(func).return_annotation + if annotation is not inspect.Parameter.empty: + class_annotations[name] = annotation + + original_getattr = cd.get("__getattr__") + if original_getattr is not None: + additional_closure_functions_to_update.append(original_getattr) + + cd["__getattr__"] = _make_cached_property_getattr( + cached_properties, original_getattr, self._cls + ) + # We only add the names of attributes that aren't inherited. # Setting __slots__ to inherited attributes wastes memory. slot_names = [name for name in names if name not in base_names] + # There are slots for attributes from current class # that are defined in parent classes. - # As their descriptors may be overriden by a child class, + # As their descriptors may be overridden by a child class, # we collect them here and update the class dict reused_slots = { slot: slot_descriptor - for slot, slot_descriptor in iteritems(existing_slots) + for slot, slot_descriptor in existing_slots.items() if slot in slot_names } slot_names = [name for name in slot_names if name not in reused_slots] cd.update(reused_slots) if self._cache_hash: slot_names.append(_hash_cache_field) + cd["__slots__"] = tuple(slot_names) - qualname = getattr(self._cls, "__qualname__", None) - if qualname is not None: - cd["__qualname__"] = qualname + cd["__qualname__"] = self._cls.__qualname__ # Create new class based on old class and our methods. cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) # The following is a fix for - # https://github.com/python-attrs/attrs/issues/102. On Python 3, - # if a method mentions `__class__` or uses the no-arg super(), the + # . + # If a method mentions `__class__` or uses the no-arg super(), the # compiler will bake a reference to the class in the method itself # as `method.__closure__`. Since we replace the class with a # clone, we rewrite these references so it keeps working. - for item in cls.__dict__.values(): + for item in itertools.chain( + cls.__dict__.values(), additional_closure_functions_to_update + ): if isinstance(item, (classmethod, staticmethod)): # Class- and staticmethods hide their functions inside. # These might need to be rewritten as well. @@ -869,26 +1002,25 @@ def _create_slots_class(self): for cell in closure_cells: try: match = cell.cell_contents is self._cls - except ValueError: # ValueError: Cell is empty + except ValueError: # noqa: PERF203 + # ValueError: Cell is empty pass else: if match: - set_closure_cell(cell, cls) - + cell.cell_contents = cls return cls def add_repr(self, ns): self._cls_dict["__repr__"] = self._add_method_dunders( - _make_repr(self._attrs, ns=ns) + _make_repr(self._attrs, ns, self._cls) ) return self def add_str(self): repr = self._cls_dict.get("__repr__") if repr is None: - raise ValueError( - "__str__ can only be generated if a __repr__ exists." - ) + msg = "__str__ can only be generated if a __repr__ exists." + raise ValueError(msg) def __str__(self): return self.__repr__() @@ -909,7 +1041,7 @@ def slots_getstate(self): """ Automatically created by attrs. """ - return tuple(getattr(self, name) for name in state_attr_names) + return {name: getattr(self, name) for name in state_attr_names} hash_caching_enabled = self._cache_hash @@ -917,9 +1049,16 @@ def slots_setstate(self, state): """ Automatically created by attrs. """ - __bound_setattr = _obj_setattr.__get__(self, Attribute) - for name, value in zip(state_attr_names, state): - __bound_setattr(name, value) + __bound_setattr = _obj_setattr.__get__(self) + if isinstance(state, tuple): + # Backward compatibility with attrs instances pickled with + # attrs versions before v22.2.0 which stored tuples. + for name, value in zip(state_attr_names, state): + __bound_setattr(name, value) + else: + for name in state_attr_names: + if name in state: + __bound_setattr(name, state[name]) # The hash code cache is not included when the object is # serialized, but it still needs to be initialized to None to @@ -952,34 +1091,41 @@ def add_init(self): self._cls, self._attrs, self._has_pre_init, + self._pre_init_has_args, self._has_post_init, self._frozen, self._slots, self._cache_hash, self._base_attr_map, self._is_exc, - self._on_setattr is not None - and self._on_setattr is not setters.NO_OP, + self._on_setattr, attrs_init=False, ) ) return self + def add_match_args(self): + self._cls_dict["__match_args__"] = tuple( + field.name + for field in self._attrs + if field.init and not field.kw_only + ) + def add_attrs_init(self): self._cls_dict["__attrs_init__"] = self._add_method_dunders( _make_init( self._cls, self._attrs, self._has_pre_init, + self._pre_init_has_args, self._has_post_init, self._frozen, self._slots, self._cache_hash, self._base_attr_map, self._is_exc, - self._on_setattr is not None - and self._on_setattr is not setters.NO_OP, + self._on_setattr, attrs_init=True, ) ) @@ -1021,9 +1167,8 @@ def add_setattr(self): if self._has_custom_setattr: # We need to write a __setattr__ but there already is one! - raise ValueError( - "Can't combine custom __setattr__ with on_setattr hooks." - ) + msg = "Can't combine custom __setattr__ with on_setattr hooks." + raise ValueError(msg) # docstring comes from _add_method_dunders def __setattr__(self, name, val): @@ -1038,7 +1183,7 @@ def __setattr__(self, name, val): self._cls_dict["__attrs_own_setattr__"] = True self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) - self._has_own_setattr = True + self._wrote_own_setattr = True return self @@ -1046,41 +1191,29 @@ def _add_method_dunders(self, method): """ Add __module__ and __qualname__ to a *method* if possible. """ - try: + with contextlib.suppress(AttributeError): method.__module__ = self._cls.__module__ - except AttributeError: - pass - try: - method.__qualname__ = ".".join( - (self._cls.__qualname__, method.__name__) - ) - except AttributeError: - pass + with contextlib.suppress(AttributeError): + method.__qualname__ = f"{self._cls.__qualname__}.{method.__name__}" - try: - method.__doc__ = "Method generated by attrs for class %s." % ( - self._cls.__qualname__, + with contextlib.suppress(AttributeError): + method.__doc__ = ( + "Method generated by attrs for class " + f"{self._cls.__qualname__}." ) - except AttributeError: - pass return method -_CMP_DEPRECATION = ( - "The usage of `cmp` is deprecated and will be removed on or after " - "2021-06-01. Please use `eq` and `order` instead." -) - - def _determine_attrs_eq_order(cmp, eq, order, default_eq): """ Validate the combination of *cmp*, *eq*, and *order*. Derive the effective values of eq and order. If *eq* is None, set it to *default_eq*. """ if cmp is not None and any((eq is not None, order is not None)): - raise ValueError("Don't mix `cmp` with `eq' and `order`.") + msg = "Don't mix `cmp` with `eq' and `order`." + raise ValueError(msg) # cmp takes precedence due to bw-compatibility. if cmp is not None: @@ -1095,7 +1228,8 @@ def _determine_attrs_eq_order(cmp, eq, order, default_eq): order = eq if eq is False and order is True: - raise ValueError("`order` can only be True if `eq` is True too.") + msg = "`order` can only be True if `eq` is True too." + raise ValueError(msg) return eq, order @@ -1106,7 +1240,8 @@ def _determine_attrib_eq_order(cmp, eq, order, default_eq): values of eq and order. If *eq* is None, set it to *default_eq*. """ if cmp is not None and any((eq is not None, order is not None)): - raise ValueError("Don't mix `cmp` with `eq' and `order`.") + msg = "Don't mix `cmp` with `eq' and `order`." + raise ValueError(msg) def decide_callable_or_boolean(value): """ @@ -1136,7 +1271,8 @@ def decide_callable_or_boolean(value): order, order_key = decide_callable_or_boolean(order) if eq is False and order is True: - raise ValueError("`order` can only be True if `eq` is True too.") + msg = "`order` can only be True if `eq` is True too." + raise ValueError(msg) return eq, eq_key, order, order_key @@ -1152,8 +1288,6 @@ def _determine_whether_to_implement( whose presence signal that the user has implemented it themselves. Return *default* if no reason for either for or against is found. - - auto_detect must be False on Python 2. """ if flag is True or flag is False: return flag @@ -1192,24 +1326,25 @@ def attrs( getstate_setstate=None, on_setattr=None, field_transformer=None, + match_args=True, + unsafe_hash=None, ): r""" - A class decorator that adds `dunder - `_\ -methods according to the + A class decorator that adds :term:`dunder methods` according to the specified attributes using `attr.ib` or the *these* argument. - :param these: A dictionary of name to `attr.ib` mappings. This is - useful to avoid the definition of your attributes within the class body + Please consider using `attrs.define` / `attrs.frozen` in new code + (``attr.s`` will *never* go away, though). + + :param these: A dictionary of name to `attr.ib` mappings. This is useful + to avoid the definition of your attributes within the class body because you can't (e.g. if you want to add ``__repr__`` methods to Django models) or don't want to. - If *these* is not ``None``, ``attrs`` will *not* search the class body + If *these* is not ``None``, *attrs* will *not* search the class body for attributes and will *not* remove any attributes from it. - If *these* is an ordered dict (`dict` on Python 3.6+, - `collections.OrderedDict` otherwise), the order is deduced from - the order of the attributes inside *these*. Otherwise the order - of the definition of the attributes is used. + The order is deduced from the order of the attributes inside *these*. :type these: `dict` of `str` to `attr.ib` @@ -1222,79 +1357,89 @@ def attrs( arguments is implemented in the *current* class (i.e. it is *not* inherited from some base class). - So for example by implementing ``__eq__`` on a class yourself, - ``attrs`` will deduce ``eq=False`` and will create *neither* - ``__eq__`` *nor* ``__ne__`` (but Python classes come with a sensible - ``__ne__`` by default, so it *should* be enough to only implement - ``__eq__`` in most cases). + So for example by implementing ``__eq__`` on a class yourself, *attrs* + will deduce ``eq=False`` and will create *neither* ``__eq__`` *nor* + ``__ne__`` (but Python classes come with a sensible ``__ne__`` by + default, so it *should* be enough to only implement ``__eq__`` in most + cases). .. warning:: - If you prevent ``attrs`` from creating the ordering methods for you + If you prevent *attrs* from creating the ordering methods for you (``order=False``, e.g. by implementing ``__le__``), it becomes *your* responsibility to make sure its ordering is sound. The best way is to use the `functools.total_ordering` decorator. - Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*, - *cmp*, or *hash* overrides whatever *auto_detect* would determine. - - *auto_detect* requires Python 3. Setting it ``True`` on Python 2 raises - a `PythonTooOldError`. + Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*, *cmp*, + or *hash* overrides whatever *auto_detect* would determine. :param bool repr: Create a ``__repr__`` method with a human readable - representation of ``attrs`` attributes.. + representation of *attrs* attributes.. :param bool str: Create a ``__str__`` method that is identical to - ``__repr__``. This is usually not necessary except for - `Exception`\ s. - :param Optional[bool] eq: If ``True`` or ``None`` (default), add ``__eq__`` + ``__repr__``. This is usually not necessary except for `Exception`\ s. + :param bool | None eq: If ``True`` or ``None`` (default), add ``__eq__`` and ``__ne__`` methods that check two instances for equality. - They compare the instances as if they were tuples of their ``attrs`` + They compare the instances as if they were tuples of their *attrs* attributes if and only if the types of both classes are *identical*! - :param Optional[bool] order: If ``True``, add ``__lt__``, ``__le__``, + + .. seealso:: `comparison` + :param bool | None order: If ``True``, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` methods that behave like *eq* above and allow instances to be ordered. If ``None`` (default) mirror value of *eq*. - :param Optional[bool] cmp: Setting *cmp* is equivalent to setting *eq* - and *order* to the same value. Must not be mixed with *eq* or *order*. - :param Optional[bool] hash: If ``None`` (default), the ``__hash__`` method - is generated according how *eq* and *frozen* are set. - 1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you. + .. seealso:: `comparison` + :param bool | None cmp: Setting *cmp* is equivalent to setting *eq* and + *order* to the same value. Must not be mixed with *eq* or *order*. + + .. seealso:: `comparison` + :param bool | None unsafe_hash: If ``None`` (default), the ``__hash__`` + method is generated according how *eq* and *frozen* are set. + + 1. If *both* are True, *attrs* will generate a ``__hash__`` for you. 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set to None, marking it unhashable (which it is). 3. If *eq* is False, ``__hash__`` will be left untouched meaning the ``__hash__`` method of the base class will be used (if base class is ``object``, this means it will fall back to id-based hashing.). - Although not recommended, you can decide for yourself and force - ``attrs`` to create one (e.g. if the class is immutable even though you - didn't freeze it programmatically) by passing ``True`` or not. Both of - these cases are rather special and should be used carefully. - - See our documentation on `hashing`, Python's documentation on - `object.__hash__`, and the `GitHub issue that led to the default \ - behavior `_ for more - details. - :param bool init: Create a ``__init__`` method that initializes the - ``attrs`` attributes. Leading underscores are stripped for the argument - name. If a ``__attrs_pre_init__`` method exists on the class, it will - be called before the class is initialized. If a ``__attrs_post_init__`` - method exists on the class, it will be called after the class is fully + Although not recommended, you can decide for yourself and force *attrs* + to create one (e.g. if the class is immutable even though you didn't + freeze it programmatically) by passing ``True`` or not. Both of these + cases are rather special and should be used carefully. + + .. seealso:: + + - Our documentation on `hashing`, + - Python's documentation on `object.__hash__`, + - and the `GitHub issue that led to the default \ + behavior `_ for + more details. + + :param bool | None hash: Alias for *unsafe_hash*. *unsafe_hash* takes + precedence. + :param bool init: Create a ``__init__`` method that initializes the *attrs* + attributes. Leading underscores are stripped for the argument name. If + a ``__attrs_pre_init__`` method exists on the class, it will be called + before the class is initialized. If a ``__attrs_post_init__`` method + exists on the class, it will be called after the class is fully initialized. - If ``init`` is ``False``, an ``__attrs_init__`` method will be - injected instead. This allows you to define a custom ``__init__`` - method that can do pre-init work such as ``super().__init__()``, - and then call ``__attrs_init__()`` and ``__attrs_post_init__()``. - :param bool slots: Create a `slotted class ` that's more - memory-efficient. Slotted classes are generally superior to the default - dict classes, but have some gotchas you should know about, so we - encourage you to read the `glossary entry `. + If ``init`` is ``False``, an ``__attrs_init__`` method will be injected + instead. This allows you to define a custom ``__init__`` method that + can do pre-init work such as ``super().__init__()``, and then call + ``__attrs_init__()`` and ``__attrs_post_init__()``. + + .. seealso:: `init` + :param bool slots: Create a :term:`slotted class ` that's + more memory-efficient. Slotted classes are generally superior to the + default dict classes, but have some gotchas you should know about, so + we encourage you to read the :term:`glossary entry `. :param bool frozen: Make instances immutable after initialization. If someone attempts to modify a frozen instance, - `attr.exceptions.FrozenInstanceError` is raised. + `attrs.exceptions.FrozenInstanceError` is raised. .. note:: @@ -1309,25 +1454,25 @@ def attrs( 4. If a class is frozen, you cannot modify ``self`` in ``__attrs_post_init__`` or a self-written ``__init__``. You can - circumvent that limitation by using - ``object.__setattr__(self, "attribute_name", value)``. + circumvent that limitation by using ``object.__setattr__(self, + "attribute_name", value)``. 5. Subclasses of a frozen class are frozen too. :param bool weakref_slot: Make instances weak-referenceable. This has no effect unless ``slots`` is also enabled. - :param bool auto_attribs: If ``True``, collect `PEP 526`_-annotated - attributes (Python 3.6 and later only) from the class body. + :param bool auto_attribs: If ``True``, collect :pep:`526`-annotated + attributes from the class body. - In this case, you **must** annotate every field. If ``attrs`` - encounters a field that is set to an `attr.ib` but lacks a type - annotation, an `attr.exceptions.UnannotatedAttributeError` is - raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't - want to set a type. + In this case, you **must** annotate every field. If *attrs* encounters + a field that is set to an `attr.ib` but lacks a type annotation, an + `attr.exceptions.UnannotatedAttributeError` is raised. Use + ``field_name: typing.Any = attr.ib(...)`` if you don't want to set a + type. If you assign a value to those attributes (e.g. ``x: int = 42``), that value becomes the default value like if it were passed using - ``attr.ib(default=42)``. Passing an instance of `Factory` also + ``attr.ib(default=42)``. Passing an instance of `attrs.Factory` also works as expected in most cases (see warning below). Attributes annotated as `typing.ClassVar`, and attributes that are @@ -1335,58 +1480,55 @@ def attrs( .. warning:: For features that use the attribute name to create decorators (e.g. - `validators `), you still *must* assign `attr.ib` to - them. Otherwise Python will either not find the name or try to use - the default value to call e.g. ``validator`` on it. + :ref:`validators `), you still *must* assign `attr.ib` + to them. Otherwise Python will either not find the name or try to + use the default value to call e.g. ``validator`` on it. These errors can be quite confusing and probably the most common bug report on our bug tracker. - .. _`PEP 526`: https://www.python.org/dev/peps/pep-0526/ - :param bool kw_only: Make all attributes keyword-only (Python 3+) - in the generated ``__init__`` (if ``init`` is ``False``, this - parameter is ignored). - :param bool cache_hash: Ensure that the object's hash code is computed - only once and stored on the object. If this is set to ``True``, - hashing must be either explicitly or implicitly enabled for this - class. If the hash code is cached, avoid any reassignments of - fields involved in hash code computation or mutations of the objects - those fields point to after object creation. If such changes occur, - the behavior of the object's hash code is undefined. - :param bool auto_exc: If the class subclasses `BaseException` - (which implicitly includes any subclass of any exception), the - following happens to behave like a well-behaved Python exceptions - class: + :param bool kw_only: Make all attributes keyword-only in the generated + ``__init__`` (if ``init`` is ``False``, this parameter is ignored). + :param bool cache_hash: Ensure that the object's hash code is computed only + once and stored on the object. If this is set to ``True``, hashing + must be either explicitly or implicitly enabled for this class. If the + hash code is cached, avoid any reassignments of fields involved in hash + code computation or mutations of the objects those fields point to + after object creation. If such changes occur, the behavior of the + object's hash code is undefined. + :param bool auto_exc: If the class subclasses `BaseException` (which + implicitly includes any subclass of any exception), the following + happens to behave like a well-behaved Python exceptions class: - the values for *eq*, *order*, and *hash* are ignored and the - instances compare and hash by the instance's ids (N.B. ``attrs`` will + instances compare and hash by the instance's ids (N.B. *attrs* will *not* remove existing implementations of ``__hash__`` or the equality methods. It just won't add own ones.), - all attributes that are either passed into ``__init__`` or have a default value are additionally available as a tuple in the ``args`` attribute, - the value of *str* is ignored leaving ``__str__`` to base classes. - :param bool collect_by_mro: Setting this to `True` fixes the way ``attrs`` + :param bool collect_by_mro: Setting this to `True` fixes the way *attrs* collects attributes from base classes. The default behavior is incorrect in certain cases of multiple inheritance. It should be on by - default but is kept off for backward-compatability. + default but is kept off for backward-compatibility. - See issue `#428 `_ for - more details. + .. seealso:: + Issue `#428 `_ - :param Optional[bool] getstate_setstate: + :param bool | None getstate_setstate: .. note:: This is usually only interesting for slotted classes and you should probably just set *auto_detect* to `True`. - If `True`, ``__getstate__`` and - ``__setstate__`` are generated and attached to the class. This is - necessary for slotted classes to be pickleable. If left `None`, it's - `True` by default for slotted classes and ``False`` for dict classes. + If `True`, ``__getstate__`` and ``__setstate__`` are generated and + attached to the class. This is necessary for slotted classes to be + pickleable. If left `None`, it's `True` by default for slotted classes + and ``False`` for dict classes. - If *auto_detect* is `True`, and *getstate_setstate* is left `None`, - and **either** ``__getstate__`` or ``__setstate__`` is detected directly - on the class (i.e. not inherited), it is set to `False` (this is usually + If *auto_detect* is `True`, and *getstate_setstate* is left `None`, and + **either** ``__getstate__`` or ``__setstate__`` is detected directly on + the class (i.e. not inherited), it is set to `False` (this is usually what you want). :param on_setattr: A callable that is run whenever the user attempts to set @@ -1399,13 +1541,23 @@ def attrs( the callable. If a list of callables is passed, they're automatically wrapped in an - `attr.setters.pipe`. + `attrs.setters.pipe`. + :type on_setattr: `callable`, or a list of callables, or `None`, or + `attrs.setters.NO_OP` + + :param callable | None field_transformer: + A function that is called with the original class object and all fields + right before *attrs* finalizes the class. You can use this, e.g., to + automatically add converters or validators to fields based on their + types. - :param Optional[callable] field_transformer: - A function that is called with the original class object and all - fields right before ``attrs`` finalizes the class. You can use - this, e.g., to automatically add converters or validators to - fields based on their types. See `transform-fields` for more details. + .. seealso:: `transform-fields` + + :param bool match_args: + If `True` (default), set ``__match_args__`` on the class to support + :pep:`634` (Structural Pattern Matching). It is a tuple of all + non-keyword-only ``__init__`` parameter names on Python 3.10 and later. + Ignored on older Python versions. .. versionadded:: 16.0.0 *slots* .. versionadded:: 16.1.0 *frozen* @@ -1440,23 +1592,20 @@ def attrs( ``init=False`` injects ``__attrs_init__`` .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 21.3.0 *match_args* + .. versionadded:: 22.2.0 + *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). """ - if auto_detect and PY2: - raise PythonTooOldError( - "auto_detect only works on Python 3 and later." - ) - eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) - hash_ = hash # work around the lack of nonlocal + + # unsafe_hash takes precedence due to PEP 681. + if unsafe_hash is not None: + hash = unsafe_hash if isinstance(on_setattr, (list, tuple)): on_setattr = setters.pipe(*on_setattr) def wrap(cls): - - if getattr(cls, "__class__", None) is None: - raise TypeError("attrs only works with new-style classes.") - is_frozen = frozen or _has_frozen_base_class(cls) is_exc = auto_exc is True and issubclass(cls, BaseException) has_own_setattr = auto_detect and _has_own_attribute( @@ -1464,7 +1613,8 @@ def wrap(cls): ) if has_own_setattr and is_frozen: - raise ValueError("Can't freeze a class with a custom __setattr__.") + msg = "Can't freeze a class with a custom __setattr__." + raise ValueError(msg) builder = _ClassBuilder( cls, @@ -1507,28 +1657,25 @@ def wrap(cls): builder.add_setattr() + nonlocal hash if ( - hash_ is None + hash is None and auto_detect is True and _has_own_attribute(cls, "__hash__") ): hash = False - else: - hash = hash_ + if hash is not True and hash is not False and hash is not None: # Can't use `hash in` because 1 == True for example. - raise TypeError( - "Invalid value for hash. Must be True, False, or None." - ) - elif hash is False or (hash is None and eq is False) or is_exc: + msg = "Invalid value for hash. Must be True, False, or None." + raise TypeError(msg) + + if hash is False or (hash is None and eq is False) or is_exc: # Don't do anything. Should fall back to __object__'s __hash__ # which is by id. if cache_hash: - raise TypeError( - "Invalid value for cache_hash. To use hash caching," - " hashing must be either explicitly or implicitly " - "enabled." - ) + msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled." + raise TypeError(msg) elif hash is True or ( hash is None and eq is True and is_frozen is True ): @@ -1537,11 +1684,8 @@ def wrap(cls): else: # Raise TypeError on attempts to hash. if cache_hash: - raise TypeError( - "Invalid value for cache_hash. To use hash caching," - " hashing must be either explicitly or implicitly " - "enabled." - ) + msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled." + raise TypeError(msg) builder.make_unhashable() if _determine_whether_to_implement( @@ -1551,10 +1695,15 @@ def wrap(cls): else: builder.add_attrs_init() if cache_hash: - raise TypeError( - "Invalid value for cache_hash. To use hash caching," - " init must be True." - ) + msg = "Invalid value for cache_hash. To use hash caching, init must be True." + raise TypeError(msg) + + if ( + PY310 + and match_args + and not _has_own_attribute(cls, "__match_args__") + ): + builder.add_match_args() return builder.build_class() @@ -1562,8 +1711,8 @@ def wrap(cls): # if it's used as `@attrs` but ``None`` if used as `@attrs()`. if maybe_cls is None: return wrap - else: - return wrap(maybe_cls) + + return wrap(maybe_cls) _attrs = attrs @@ -1573,58 +1722,22 @@ def wrap(cls): """ -if PY2: - - def _has_frozen_base_class(cls): - """ - Check whether *cls* has a frozen ancestor by looking at its - __setattr__. - """ - return ( - getattr(cls.__setattr__, "__module__", None) - == _frozen_setattrs.__module__ - and cls.__setattr__.__name__ == _frozen_setattrs.__name__ - ) - - -else: - - def _has_frozen_base_class(cls): - """ - Check whether *cls* has a frozen ancestor by looking at its - __setattr__. - """ - return cls.__setattr__ == _frozen_setattrs +def _has_frozen_base_class(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return cls.__setattr__ is _frozen_setattrs def _generate_unique_filename(cls, func_name): """ Create a "filename" suitable for a function being generated. """ - unique_id = uuid.uuid4() - extra = "" - count = 1 - - while True: - unique_filename = "".format( - func_name, - cls.__module__, - getattr(cls, "__qualname__", cls.__name__), - extra, - ) - # To handle concurrency we essentially "reserve" our spot in - # the linecache with a dummy line. The caller can then - # set this value correctly. - cache_line = (1, None, (str(unique_id),), unique_filename) - if ( - linecache.cache.setdefault(unique_filename, cache_line) - == cache_line - ): - return unique_filename - - # Looks like this spot is taken. Try again. - count += 1 - extra = "-{0}".format(count) + return ( + f"" + ) def _make_hash(cls, attrs, frozen, cache_hash): @@ -1636,6 +1749,8 @@ def _make_hash(cls, attrs, frozen, cache_hash): unique_filename = _generate_unique_filename(cls, "hash") type_hash = hash(unique_filename) + # If eq is custom generated, we need to include the functions in globs + globs = {} hash_def = "def __hash__(self" hash_func = "hash((" @@ -1643,13 +1758,9 @@ def _make_hash(cls, attrs, frozen, cache_hash): if not cache_hash: hash_def += "):" else: - if not PY2: - hash_def += ", *" + hash_def += ", *" - hash_def += ( - ", _cache_wrapper=" - + "__import__('attr._make')._make._CacheHashWrapper):" - ) + hash_def += ", _cache_wrapper=__import__('attr._make')._make._CacheHashWrapper):" hash_func = "_cache_wrapper(" + hash_func closing_braces += ")" @@ -1665,32 +1776,39 @@ def append_hash_computation_lines(prefix, indent): method_lines.extend( [ indent + prefix + hash_func, - indent + " %d," % (type_hash,), + indent + f" {type_hash},", ] ) for a in attrs: - method_lines.append(indent + " self.%s," % a.name) + if a.eq_key: + cmp_name = f"_{a.name}_key" + globs[cmp_name] = a.eq_key + method_lines.append( + indent + f" {cmp_name}(self.{a.name})," + ) + else: + method_lines.append(indent + f" self.{a.name},") method_lines.append(indent + " " + closing_braces) if cache_hash: - method_lines.append(tab + "if self.%s is None:" % _hash_cache_field) + method_lines.append(tab + f"if self.{_hash_cache_field} is None:") if frozen: append_hash_computation_lines( - "object.__setattr__(self, '%s', " % _hash_cache_field, tab * 2 + f"object.__setattr__(self, '{_hash_cache_field}', ", tab * 2 ) method_lines.append(tab * 2 + ")") # close __setattr__ else: append_hash_computation_lines( - "self.%s = " % _hash_cache_field, tab * 2 + f"self.{_hash_cache_field} = ", tab * 2 ) - method_lines.append(tab + "return self.%s" % _hash_cache_field) + method_lines.append(tab + f"return self.{_hash_cache_field}") else: append_hash_computation_lines("return ", tab) script = "\n".join(method_lines) - return _make_method("__hash__", script, unique_filename) + return _make_method("__hash__", script, unique_filename, globs) def _add_hash(cls, attrs): @@ -1741,29 +1859,17 @@ def _make_eq(cls, attrs): others = [" ) == ("] for a in attrs: if a.eq_key: - cmp_name = "_%s_key" % (a.name,) + cmp_name = f"_{a.name}_key" # Add the key function to the global namespace # of the evaluated function. globs[cmp_name] = a.eq_key - lines.append( - " %s(self.%s)," - % ( - cmp_name, - a.name, - ) - ) - others.append( - " %s(other.%s)," - % ( - cmp_name, - a.name, - ) - ) + lines.append(f" {cmp_name}(self.{a.name}),") + others.append(f" {cmp_name}(other.{a.name}),") else: - lines.append(" self.%s," % (a.name,)) - others.append(" other.%s," % (a.name,)) + lines.append(f" self.{a.name},") + others.append(f" other.{a.name},") - lines += others + [" )"] + lines += [*others, " )"] else: lines.append(" return True") @@ -1841,66 +1947,61 @@ def _add_eq(cls, attrs=None): return cls -_already_repring = threading.local() - - -def _make_repr(attrs, ns): - """ - Make a repr method that includes relevant *attrs*, adding *ns* to the full - name. - """ - +def _make_repr(attrs, ns, cls): + unique_filename = _generate_unique_filename(cls, "repr") # Figure out which attributes to include, and which function to use to - # format them. The a.repr value can be either bool or a custom callable. + # format them. The a.repr value can be either bool or a custom + # callable. attr_names_with_reprs = tuple( - (a.name, repr if a.repr is True else a.repr) + (a.name, (repr if a.repr is True else a.repr), a.init) for a in attrs if a.repr is not False ) + globs = { + name + "_repr": r for name, r, _ in attr_names_with_reprs if r != repr + } + globs["_compat"] = _compat + globs["AttributeError"] = AttributeError + globs["NOTHING"] = NOTHING + attribute_fragments = [] + for name, r, i in attr_names_with_reprs: + accessor = ( + "self." + name if i else 'getattr(self, "' + name + '", NOTHING)' + ) + fragment = ( + "%s={%s!r}" % (name, accessor) + if r == repr + else "%s={%s_repr(%s)}" % (name, name, accessor) + ) + attribute_fragments.append(fragment) + repr_fragment = ", ".join(attribute_fragments) - def __repr__(self): - """ - Automatically created by attrs. - """ - try: - working_set = _already_repring.working_set - except AttributeError: - working_set = set() - _already_repring.working_set = working_set - - if id(self) in working_set: - return "..." - real_cls = self.__class__ - if ns is None: - qualname = getattr(real_cls, "__qualname__", None) - if qualname is not None: - class_name = qualname.rsplit(">.", 1)[-1] - else: - class_name = real_cls.__name__ - else: - class_name = ns + "." + real_cls.__name__ - - # Since 'self' remains on the stack (i.e.: strongly referenced) for the - # duration of this call, it's safe to depend on id(...) stability, and - # not need to track the instance and therefore worry about properties - # like weakref- or hash-ability. - working_set.add(id(self)) - try: - result = [class_name, "("] - first = True - for name, attr_repr in attr_names_with_reprs: - if first: - first = False - else: - result.append(", ") - result.extend( - (name, "=", attr_repr(getattr(self, name, NOTHING))) - ) - return "".join(result) + ")" - finally: - working_set.remove(id(self)) + if ns is None: + cls_name_fragment = '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}' + else: + cls_name_fragment = ns + ".{self.__class__.__name__}" - return __repr__ + lines = [ + "def __repr__(self):", + " try:", + " already_repring = _compat.repr_context.already_repring", + " except AttributeError:", + " already_repring = {id(self),}", + " _compat.repr_context.already_repring = already_repring", + " else:", + " if id(self) in already_repring:", + " return '...'", + " else:", + " already_repring.add(id(self))", + " try:", + f" return f'{cls_name_fragment}({repr_fragment})'", + " finally:", + " already_repring.remove(id(self))", + ] + + return _make_method( + "__repr__", "\n".join(lines), unique_filename, globs=globs + ) def _add_repr(cls, ns=None, attrs=None): @@ -1910,13 +2011,13 @@ def _add_repr(cls, ns=None, attrs=None): if attrs is None: attrs = cls.__attrs_attrs__ - cls.__repr__ = _make_repr(attrs, ns) + cls.__repr__ = _make_repr(attrs, ns, cls) return cls def fields(cls): """ - Return the tuple of ``attrs`` attributes for a class. + Return the tuple of *attrs* attributes for a class. The tuple also allows accessing the fields by their names (see below for examples). @@ -1924,50 +2025,61 @@ def fields(cls): :param type cls: Class to introspect. :raise TypeError: If *cls* is not a class. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class. - :rtype: tuple (with name accessors) of `attr.Attribute` + :rtype: tuple (with name accessors) of `attrs.Attribute` - .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields - by name. + .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields + by name. + .. versionchanged:: 23.1.0 Add support for generic classes. """ - if not isclass(cls): - raise TypeError("Passed object must be a class.") + generic_base = get_generic_base(cls) + + if generic_base is None and not isinstance(cls, type): + msg = "Passed object must be a class." + raise TypeError(msg) + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: - raise NotAnAttrsClassError( - "{cls!r} is not an attrs-decorated class.".format(cls=cls) - ) + if generic_base is not None: + attrs = getattr(generic_base, "__attrs_attrs__", None) + if attrs is not None: + # Even though this is global state, stick it on here to speed + # it up. We rely on `cls` being cached for this to be + # efficient. + cls.__attrs_attrs__ = attrs + return attrs + msg = f"{cls!r} is not an attrs-decorated class." + raise NotAnAttrsClassError(msg) + return attrs def fields_dict(cls): """ - Return an ordered dictionary of ``attrs`` attributes for a class, whose + Return an ordered dictionary of *attrs* attributes for a class, whose keys are the attribute names. :param type cls: Class to introspect. :raise TypeError: If *cls* is not a class. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* class. - :rtype: an ordered dict where keys are attribute names and values are - `attr.Attribute`\\ s. This will be a `dict` if it's - naturally ordered like on Python 3.6+ or an - :class:`~collections.OrderedDict` otherwise. + :rtype: dict .. versionadded:: 18.1.0 """ - if not isclass(cls): - raise TypeError("Passed object must be a class.") + if not isinstance(cls, type): + msg = "Passed object must be a class." + raise TypeError(msg) attrs = getattr(cls, "__attrs_attrs__", None) if attrs is None: - raise NotAnAttrsClassError( - "{cls!r} is not an attrs-decorated class.".format(cls=cls) - ) - return ordered_dict(((a.name, a) for a in attrs)) + msg = f"{cls!r} is not an attrs-decorated class." + raise NotAnAttrsClassError(msg) + return {a.name: a for a in attrs} def validate(inst): @@ -1976,7 +2088,7 @@ def validate(inst): Leaves all exceptions through. - :param inst: Instance of a class with ``attrs`` attributes. + :param inst: Instance of a class with *attrs* attributes. """ if _config._run_validators is False: return @@ -2002,17 +2114,23 @@ def _make_init( cls, attrs, pre_init, + pre_init_has_args, post_init, frozen, slots, cache_hash, base_attr_map, is_exc, - has_global_on_setattr, + cls_on_setattr, attrs_init, ): - if frozen and has_global_on_setattr: - raise ValueError("Frozen classes can't use on_setattr.") + has_cls_on_setattr = ( + cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP + ) + + if frozen and has_cls_on_setattr: + msg = "Frozen classes can't use on_setattr." + raise ValueError(msg) needs_cached_setattr = cache_hash or frozen filtered_attrs = [] @@ -2026,12 +2144,11 @@ def _make_init( if a.on_setattr is not None: if frozen is True: - raise ValueError("Frozen classes can't use on_setattr.") + msg = "Frozen classes can't use on_setattr." + raise ValueError(msg) needs_cached_setattr = True - elif ( - has_global_on_setattr and a.on_setattr is not setters.NO_OP - ) or _is_slot_attr(a.name, base_attr_map): + elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP: needs_cached_setattr = True unique_filename = _generate_unique_filename(cls, "init") @@ -2041,12 +2158,13 @@ def _make_init( frozen, slots, pre_init, + pre_init_has_args, post_init, cache_hash, base_attr_map, is_exc, needs_cached_setattr, - has_global_on_setattr, + has_cls_on_setattr, attrs_init, ) if cls.__module__ in sys.modules: @@ -2058,7 +2176,7 @@ def _make_init( if needs_cached_setattr: # Save the lookup overhead in __init__ if we need to circumvent # setattr hooks. - globs["_cached_setattr"] = _obj_setattr + globs["_cached_setattr_get"] = _obj_setattr.__get__ init = _make_method( "__attrs_init__" if attrs_init else "__init__", @@ -2075,7 +2193,7 @@ def _setattr(attr_name, value_var, has_on_setattr): """ Use the cached object.setattr to set *attr_name* to *value_var*. """ - return "_setattr('%s', %s)" % (attr_name, value_var) + return f"_setattr('{attr_name}', {value_var})" def _setattr_with_converter(attr_name, value_var, has_on_setattr): @@ -2098,7 +2216,7 @@ def _assign(attr_name, value, has_on_setattr): if has_on_setattr: return _setattr(attr_name, value, True) - return "self.%s = %s" % (attr_name, value) + return f"self.{attr_name} = {value}" def _assign_with_converter(attr_name, value_var, has_on_setattr): @@ -2116,74 +2234,18 @@ def _assign_with_converter(attr_name, value_var, has_on_setattr): ) -if PY2: - - def _unpack_kw_only_py2(attr_name, default=None): - """ - Unpack *attr_name* from _kw_only dict. - """ - if default is not None: - arg_default = ", %s" % default - else: - arg_default = "" - return "%s = _kw_only.pop('%s'%s)" % ( - attr_name, - attr_name, - arg_default, - ) - - def _unpack_kw_only_lines_py2(kw_only_args): - """ - Unpack all *kw_only_args* from _kw_only dict and handle errors. - - Given a list of strings "{attr_name}" and "{attr_name}={default}" - generates list of lines of code that pop attrs from _kw_only dict and - raise TypeError similar to builtin if required attr is missing or - extra key is passed. - - >>> print("\n".join(_unpack_kw_only_lines_py2(["a", "b=42"]))) - try: - a = _kw_only.pop('a') - b = _kw_only.pop('b', 42) - except KeyError as _key_error: - raise TypeError( - ... - if _kw_only: - raise TypeError( - ... - """ - lines = ["try:"] - lines.extend( - " " + _unpack_kw_only_py2(*arg.split("=")) - for arg in kw_only_args - ) - lines += """\ -except KeyError as _key_error: - raise TypeError( - '__init__() missing required keyword-only argument: %s' % _key_error - ) -if _kw_only: - raise TypeError( - '__init__() got an unexpected keyword argument %r' - % next(iter(_kw_only)) - ) -""".split( - "\n" - ) - return lines - - def _attrs_to_init_script( attrs, frozen, slots, pre_init, + pre_init_has_args, post_init, cache_hash, base_attr_map, is_exc, needs_cached_setattr, - has_global_on_setattr, + has_cls_on_setattr, attrs_init, ): """ @@ -2203,7 +2265,7 @@ def _attrs_to_init_script( # Circumvent the __setattr__ descriptor to save one lookup per # assignment. # Note _setattr will be used again below if cache_hash is True - "_setattr = _cached_setattr.__get__(self, self.__class__)" + "_setattr = _cached_setattr_get(self)" ) if frozen is True: @@ -2221,7 +2283,7 @@ def fmt_setter(attr_name, value_var, has_on_setattr): if _is_slot_attr(attr_name, base_attr_map): return _setattr(attr_name, value_var, has_on_setattr) - return "_inst_dict['%s'] = %s" % (attr_name, value_var) + return f"_inst_dict['{attr_name}'] = {value_var}" def fmt_setter_with_converter( attr_name, value_var, has_on_setattr @@ -2257,24 +2319,23 @@ def fmt_setter_with_converter( attr_name = a.name has_on_setattr = a.on_setattr is not None or ( - a.on_setattr is not setters.NO_OP and has_global_on_setattr + a.on_setattr is not setters.NO_OP and has_cls_on_setattr ) - arg_name = a.name.lstrip("_") + # a.alias is set to maybe-mangled attr_name in _ClassBuilder if not + # explicitly provided + arg_name = a.alias has_factory = isinstance(a.default, Factory) - if has_factory and a.default.takes_self: - maybe_self = "self" - else: - maybe_self = "" + maybe_self = "self" if has_factory and a.default.takes_self else "" if a.init is False: if has_factory: - init_factory_name = _init_factory_pat.format(a.name) + init_factory_name = _init_factory_pat % (a.name,) if a.converter is not None: lines.append( fmt_setter_with_converter( attr_name, - init_factory_name + "(%s)" % (maybe_self,), + init_factory_name + f"({maybe_self})", has_on_setattr, ) ) @@ -2284,32 +2345,31 @@ def fmt_setter_with_converter( lines.append( fmt_setter( attr_name, - init_factory_name + "(%s)" % (maybe_self,), + init_factory_name + f"({maybe_self})", has_on_setattr, ) ) names_for_globals[init_factory_name] = a.default.factory - else: - if a.converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, - "attr_dict['%s'].default" % (attr_name,), - has_on_setattr, - ) + elif a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + f"attr_dict['{attr_name}'].default", + has_on_setattr, ) - conv_name = _init_converter_pat % (a.name,) - names_for_globals[conv_name] = a.converter - else: - lines.append( - fmt_setter( - attr_name, - "attr_dict['%s'].default" % (attr_name,), - has_on_setattr, - ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + f"attr_dict['{attr_name}'].default", + has_on_setattr, ) + ) elif a.default is not NOTHING and not has_factory: - arg = "%s=attr_dict['%s'].default" % (arg_name, attr_name) + arg = f"{arg_name}=attr_dict['{attr_name}'].default" if a.kw_only: kw_only_args.append(arg) else: @@ -2328,14 +2388,14 @@ def fmt_setter_with_converter( lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) elif has_factory: - arg = "%s=NOTHING" % (arg_name,) + arg = f"{arg_name}=NOTHING" if a.kw_only: kw_only_args.append(arg) else: args.append(arg) - lines.append("if %s is not NOTHING:" % (arg_name,)) + lines.append(f"if {arg_name} is not NOTHING:") - init_factory_name = _init_factory_pat.format(a.name) + init_factory_name = _init_factory_pat % (a.name,) if a.converter is not None: lines.append( " " @@ -2390,21 +2450,11 @@ def fmt_setter_with_converter( if a.init is True: if a.type is not None and a.converter is None: annotations[arg_name] = a.type - elif a.converter is not None and not PY2: + elif a.converter is not None: # Try to get the type from the converter. - sig = None - try: - sig = inspect.signature(a.converter) - except (ValueError, TypeError): # inspect failed - pass - if sig: - sig_params = list(sig.parameters.values()) - if ( - sig_params - and sig_params[0].annotation - is not inspect.Parameter.empty - ): - annotations[arg_name] = sig_params[0].annotation + t = _AnnotationExtractor(a.converter).get_first_param_type() + if t: + annotations[arg_name] = t if attrs_to_validate: # we can skip this if there are no validators. names_for_globals["_config"] = _config @@ -2412,23 +2462,21 @@ def fmt_setter_with_converter( for a in attrs_to_validate: val_name = "__attr_validator_" + a.name attr_name = "__attr_" + a.name - lines.append( - " %s(self, %s, self.%s)" % (val_name, attr_name, a.name) - ) + lines.append(f" {val_name}(self, {attr_name}, self.{a.name})") names_for_globals[val_name] = a.validator names_for_globals[attr_name] = a if post_init: lines.append("self.__attrs_post_init__()") - # because this is set only after __attrs_post_init is called, a crash + # because this is set only after __attrs_post_init__ is called, a crash # will result if post-init tries to access the hash code. This seemed # preferable to setting this beforehand, in which case alteration to # field values during post-init combined with post-init accessing the # hash code would result in silent bugs. if cache_hash: if frozen: - if slots: + if slots: # noqa: SIM108 # if frozen and slots, then _setattr defined above init_hash_cache = "_setattr('%s', %s)" else: @@ -2441,58 +2489,92 @@ def fmt_setter_with_converter( # For exceptions we rely on BaseException.__init__ for proper # initialization. if is_exc: - vals = ",".join("self." + a.name for a in attrs if a.init) + vals = ",".join(f"self.{a.name}" for a in attrs if a.init) - lines.append("BaseException.__init__(self, %s)" % (vals,)) + lines.append(f"BaseException.__init__(self, {vals})") args = ", ".join(args) + pre_init_args = args if kw_only_args: - if PY2: - lines = _unpack_kw_only_lines_py2(kw_only_args) + lines + args += "%s*, %s" % ( + ", " if args else "", # leading comma + ", ".join(kw_only_args), # kw_only args + ) + pre_init_kw_only_args = ", ".join( + ["%s=%s" % (kw_arg, kw_arg) for kw_arg in kw_only_args] + ) + pre_init_args += ( + ", " if pre_init_args else "" + ) # handle only kwargs and no regular args + pre_init_args += pre_init_kw_only_args + + if pre_init and pre_init_has_args: + # If pre init method has arguments, pass same arguments as `__init__` + lines[0] = "self.__attrs_pre_init__(%s)" % pre_init_args - args += "%s**_kw_only" % (", " if args else "",) # leading comma - else: - args += "%s*, %s" % ( - ", " if args else "", # leading comma - ", ".join(kw_only_args), # kw_only args - ) return ( - """\ -def {init_name}(self, {args}): - {lines} -""".format( - init_name=("__attrs_init__" if attrs_init else "__init__"), - args=args, - lines="\n ".join(lines) if lines else "pass", + "def %s(self, %s):\n %s\n" + % ( + ("__attrs_init__" if attrs_init else "__init__"), + args, + "\n ".join(lines) if lines else "pass", ), names_for_globals, annotations, ) -class Attribute(object): +def _default_init_alias_for(name: str) -> str: + """ + The default __init__ parameter name for a field. + + This performs private-name adjustment via leading-unscore stripping, + and is the default value of Attribute.alias if not provided. + """ + + return name.lstrip("_") + + +class Attribute: """ *Read-only* representation of an attribute. + .. warning:: + + You should never instantiate this class yourself. + + The class has *all* arguments of `attr.ib` (except for ``factory`` + which is only syntactic sugar for ``default=Factory(...)`` plus the + following: + + - ``name`` (`str`): The name of the attribute. + - ``alias`` (`str`): The __init__ parameter name of the attribute, after + any explicit overrides and default private-attribute-name handling. + - ``inherited`` (`bool`): Whether or not that attribute has been inherited + from a base class. + - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The callables + that are used for comparing and ordering objects by this attribute, + respectively. These are set by passing a callable to `attr.ib`'s ``eq``, + ``order``, or ``cmp`` arguments. See also :ref:`comparison customization + `. + Instances of this class are frequently used for introspection purposes like: - `fields` returns a tuple of them. - Validators get them passed as the first argument. - - The *field transformer* hook receives a list of them. + - The :ref:`field transformer ` hook receives a list of + them. + - The ``alias`` property exposes the __init__ parameter name of the field, + with any overrides and default private-attribute handling applied. - :attribute name: The name of the attribute. - :attribute inherited: Whether or not that attribute has been inherited from - a base class. - - Plus *all* arguments of `attr.ib` (except for ``factory`` - which is only syntactic sugar for ``default=Factory(...)``. .. versionadded:: 20.1.0 *inherited* .. versionadded:: 20.1.0 *on_setattr* .. versionchanged:: 20.2.0 *inherited* is not taken into account for equality checks and hashing anymore. .. versionadded:: 21.1.0 *eq_key* and *order_key* + .. versionadded:: 22.2.0 *alias* For the full version history of the fields, see `attr.ib`. """ @@ -2514,6 +2596,7 @@ class Attribute(object): "kw_only", "inherited", "on_setattr", + "alias", ) def __init__( @@ -2535,13 +2618,14 @@ def __init__( order=None, order_key=None, on_setattr=None, + alias=None, ): eq, eq_key, order, order_key = _determine_attrib_eq_order( cmp, eq_key or eq, order_key or order, True ) # Cache this descriptor here to speed things up later. - bound_setattr = _obj_setattr.__get__(self, Attribute) + bound_setattr = _obj_setattr.__get__(self) # Despite the big red warning, people *do* instantiate `Attribute` # themselves. @@ -2559,7 +2643,7 @@ def __init__( bound_setattr( "metadata", ( - metadata_proxy(metadata) + types.MappingProxyType(dict(metadata)) # Shallow copy if metadata else _empty_metadata_singleton ), @@ -2568,6 +2652,7 @@ def __init__( bound_setattr("kw_only", kw_only) bound_setattr("inherited", inherited) bound_setattr("on_setattr", on_setattr) + bound_setattr("alias", alias) def __setattr__(self, name, value): raise FrozenInstanceError() @@ -2578,9 +2663,8 @@ def from_counting_attr(cls, name, ca, type=None): if type is None: type = ca.type elif ca.type is not None: - raise ValueError( - "Type annotation and type argument cannot both be present" - ) + msg = "Type annotation and type argument cannot both be present" + raise ValueError(msg) inst_dict = { k: getattr(ca, k) for k in Attribute.__slots__ @@ -2600,25 +2684,16 @@ def from_counting_attr(cls, name, ca, type=None): type=type, cmp=None, inherited=False, - **inst_dict + **inst_dict, ) - @property - def cmp(self): - """ - Simulate the presence of a cmp attribute and warn. - """ - warnings.warn(_CMP_DEPRECATION, DeprecationWarning, stacklevel=2) - - return self.eq and self.order - - # Don't use attr.evolve since fields(Attribute) doesn't work + # Don't use attrs.evolve since fields(Attribute) doesn't work def evolve(self, **changes): """ Copy *self* and apply *changes*. - This works similarly to `attr.evolve` but that function does not work - with ``Attribute``. + This works similarly to `attrs.evolve` but that function does not work + with `Attribute`. It is mainly meant to be used for `transform-fields`. @@ -2647,14 +2722,14 @@ def __setstate__(self, state): self._setattrs(zip(self.__slots__, state)) def _setattrs(self, name_values_pairs): - bound_setattr = _obj_setattr.__get__(self, Attribute) + bound_setattr = _obj_setattr.__get__(self) for name, value in name_values_pairs: if name != "metadata": bound_setattr(name, value) else: bound_setattr( name, - metadata_proxy(value) + types.MappingProxyType(dict(value)) if value else _empty_metadata_singleton, ) @@ -2672,6 +2747,7 @@ def _setattrs(self, name_values_pairs): hash=(name != "metadata"), init=True, inherited=False, + alias=_default_init_alias_for(name), ) for name in Attribute.__slots__ ] @@ -2685,7 +2761,7 @@ def _setattrs(self, name_values_pairs): ) -class _CountingAttr(object): +class _CountingAttr: """ Intermediate representation of attributes that uses a counter to preserve the order in which the attributes have been defined. @@ -2710,37 +2786,42 @@ class _CountingAttr(object): "type", "kw_only", "on_setattr", + "alias", ) - __attrs_attrs__ = tuple( - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - hash=True, - init=True, - kw_only=False, - eq=True, - eq_key=None, - order=False, - order_key=None, - inherited=False, - on_setattr=None, - ) - for name in ( - "counter", - "_default", - "repr", - "eq", - "order", - "hash", - "init", - "on_setattr", - ) - ) + ( + __attrs_attrs__ = ( + *tuple( + Attribute( + name=name, + alias=_default_init_alias_for(name), + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=True, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ) + for name in ( + "counter", + "_default", + "repr", + "eq", + "order", + "hash", + "init", + "on_setattr", + "alias", + ) + ), Attribute( name="metadata", + alias="metadata", default=None, validator=None, repr=True, @@ -2775,6 +2856,7 @@ def __init__( order, order_key, on_setattr, + alias, ): _CountingAttr.cls_counter += 1 self.counter = _CountingAttr.cls_counter @@ -2792,6 +2874,7 @@ def __init__( self.type = type self.kw_only = kw_only self.on_setattr = on_setattr + self.alias = alias def validator(self, meth): """ @@ -2828,11 +2911,11 @@ def default(self, meth): _CountingAttr = _add_eq(_add_repr(_CountingAttr)) -class Factory(object): +class Factory: """ Stores a factory callable. - If passed as the default value to `attr.ib`, the factory is used to + If passed as the default value to `attrs.field`, the factory is used to generate a new value. :param callable factory: A callable that takes either none or exactly one @@ -2846,10 +2929,6 @@ class Factory(object): __slots__ = ("factory", "takes_self") def __init__(self, factory, takes_self=False): - """ - `Factory` is part of the default machinery so if we want a default - value here, we have to implement it ourselves. - """ self.factory = factory self.takes_self = takes_self @@ -2886,23 +2965,26 @@ def __setstate__(self, state): Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) -def make_class(name, attrs, bases=(object,), **attributes_arguments): - """ +def make_class( + name, attrs, bases=(object,), class_body=None, **attributes_arguments +): + r""" A quick way to create a new class called *name* with *attrs*. :param str name: The name for the new class. :param attrs: A list of names or a dictionary of mappings of names to - attributes. + `attr.ib`\ s / `attrs.field`\ s. - If *attrs* is a list or an ordered dict (`dict` on Python 3.6+, - `collections.OrderedDict` otherwise), the order is deduced from - the order of the names or attributes inside *attrs*. Otherwise the - order of the definition of the attributes is used. + The order is deduced from the order of the names or attributes inside + *attrs*. Otherwise the order of the definition of the attributes is + used. :type attrs: `list` or `dict` :param tuple bases: Classes that the new class will subclass. + :param dict class_body: An optional dictionary of class attributes for the new class. + :param attributes_arguments: Passed unmodified to `attr.s`. :return: A new class with *attrs*. @@ -2910,19 +2992,23 @@ def make_class(name, attrs, bases=(object,), **attributes_arguments): .. versionadded:: 17.1.0 *bases* .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. + .. versionchanged:: 23.2.0 *class_body* """ if isinstance(attrs, dict): cls_dict = attrs elif isinstance(attrs, (list, tuple)): - cls_dict = dict((a, attrib()) for a in attrs) + cls_dict = {a: attrib() for a in attrs} else: - raise TypeError("attrs argument must be a dict or a list.") + msg = "attrs argument must be a dict or a list." + raise TypeError(msg) pre_init = cls_dict.pop("__attrs_pre_init__", None) post_init = cls_dict.pop("__attrs_post_init__", None) user_init = cls_dict.pop("__init__", None) body = {} + if class_body is not None: + body.update(class_body) if pre_init is not None: body["__attrs_pre_init__"] = pre_init if post_init is not None: @@ -2930,18 +3016,16 @@ def make_class(name, attrs, bases=(object,), **attributes_arguments): if user_init is not None: body["__init__"] = user_init - type_ = new_class(name, bases, {}, lambda ns: ns.update(body)) + type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body)) # For pickling to work, the __module__ variable needs to be set to the # frame where the class is created. Bypass this step in environments where # sys._getframe is not defined (Jython for example) or sys._getframe is not # defined for arguments greater than 0 (IronPython). - try: + with contextlib.suppress(AttributeError, ValueError): type_.__module__ = sys._getframe(1).f_globals.get( "__name__", "__main__" ) - except (AttributeError, ValueError): - pass # We do it here for proper warnings with meaningful stacklevel. cmp = attributes_arguments.pop("cmp", None) @@ -2963,7 +3047,7 @@ def make_class(name, attrs, bases=(object,), **attributes_arguments): @attrs(slots=True, hash=True) -class _AndValidator(object): +class _AndValidator: """ Compose many validators to a single one. """ @@ -3017,36 +3101,19 @@ def pipe_converter(val): return val - if not PY2: - if not converters: - # If the converter list is empty, pipe_converter is the identity. - A = typing.TypeVar("A") - pipe_converter.__annotations__ = {"val": A, "return": A} - else: - # Get parameter type. - sig = None - try: - sig = inspect.signature(converters[0]) - except (ValueError, TypeError): # inspect failed - pass - if sig: - params = list(sig.parameters.values()) - if ( - params - and params[0].annotation is not inspect.Parameter.empty - ): - pipe_converter.__annotations__["val"] = params[ - 0 - ].annotation - # Get return type. - sig = None - try: - sig = inspect.signature(converters[-1]) - except (ValueError, TypeError): # inspect failed - pass - if sig and sig.return_annotation is not inspect.Signature().empty: - pipe_converter.__annotations__[ - "return" - ] = sig.return_annotation + if not converters: + # If the converter list is empty, pipe_converter is the identity. + A = typing.TypeVar("A") + pipe_converter.__annotations__ = {"val": A, "return": A} + else: + # Get parameter type from first converter. + t = _AnnotationExtractor(converters[0]).get_first_param_type() + if t: + pipe_converter.__annotations__["val"] = t + + # Get return type from last converter. + rt = _AnnotationExtractor(converters[-1]).get_return_type() + if rt: + pipe_converter.__annotations__["return"] = rt return pipe_converter diff --git a/dist/ba_data/python-site-packages/attr/_next_gen.py b/dist/ba_data/python-site-packages/attr/_next_gen.py index fab0af96..1fb9f259 100644 --- a/dist/ba_data/python-site-packages/attr/_next_gen.py +++ b/dist/ba_data/python-site-packages/attr/_next_gen.py @@ -1,14 +1,24 @@ +# SPDX-License-Identifier: MIT + """ -These are Python 3.6+-only and keyword-only APIs that call `attr.s` and -`attr.ib` with different default values. +These are keyword-only APIs that call `attr.s` and `attr.ib` with different +default values. """ -from functools import partial -from attr.exceptions import UnannotatedAttributeError +from functools import partial from . import setters -from ._make import NOTHING, _frozen_setattrs, attrib, attrs +from ._funcs import asdict as _asdict +from ._funcs import astuple as _astuple +from ._make import ( + NOTHING, + _frozen_setattrs, + _ng_default_on_setattr, + attrib, + attrs, +) +from .exceptions import UnannotatedAttributeError def define( @@ -16,6 +26,7 @@ def define( *, these=None, repr=None, + unsafe_hash=None, hash=None, init=None, slots=True, @@ -32,22 +43,47 @@ def define( getstate_setstate=None, on_setattr=None, field_transformer=None, + match_args=True, ): r""" - The only behavioral differences are the handling of the *auto_attribs* - option: + Define an *attrs* class. + + Differences to the classic `attr.s` that it uses underneath: + + - Automatically detect whether or not *auto_attribs* should be `True` (c.f. + *auto_attribs* parameter). + - Converters and validators run when attributes are set by default -- if + *frozen* is `False`. + - *slots=True* + + .. caution:: + + Usually this has only upsides and few visible effects in everyday + programming. But it *can* lead to some surprising behaviors, so please + make sure to read :term:`slotted classes`. + - *auto_exc=True* + - *auto_detect=True* + - *order=False* + - Some options that were only relevant on Python 2 or were kept around for + backwards-compatibility have been removed. + + Please note that these are all defaults and you can change them as you + wish. :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves exactly like `attr.s`. If left `None`, `attr.s` will try to guess: - 1. If any attributes are annotated and no unannotated `attr.ib`\ s + 1. If any attributes are annotated and no unannotated `attrs.fields`\ s are found, it assumes *auto_attribs=True*. 2. Otherwise it assumes *auto_attribs=False* and tries to collect - `attr.ib`\ s. + `attrs.fields`\ s. - and that mutable classes (``frozen=False``) validate on ``__setattr__``. + For now, please refer to `attr.s` for the rest of the parameters. .. versionadded:: 20.1.0 + .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. + .. versionadded:: 22.2.0 + *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). """ def do_it(cls, auto_attribs): @@ -56,6 +92,7 @@ def do_it(cls, auto_attribs): these=these, repr=repr, hash=hash, + unsafe_hash=unsafe_hash, init=init, slots=slots, frozen=frozen, @@ -72,6 +109,7 @@ def do_it(cls, auto_attribs): getstate_setstate=getstate_setstate, on_setattr=on_setattr, field_transformer=field_transformer, + match_args=match_args, ) def wrap(cls): @@ -84,19 +122,17 @@ def wrap(cls): had_on_setattr = on_setattr not in (None, setters.NO_OP) - # By default, mutable classes validate on setattr. + # By default, mutable classes convert & validate on setattr. if frozen is False and on_setattr is None: - on_setattr = setters.validate + on_setattr = _ng_default_on_setattr # However, if we subclass a frozen class, we inherit the immutability # and disable on_setattr. for base_cls in cls.__bases__: if base_cls.__setattr__ is _frozen_setattrs: if had_on_setattr: - raise ValueError( - "Frozen classes can't use on_setattr " - "(frozen-ness was inherited)." - ) + msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)." + raise ValueError(msg) on_setattr = setters.NO_OP break @@ -113,8 +149,8 @@ def wrap(cls): # if it's used as `@attrs` but ``None`` if used as `@attrs()`. if maybe_cls is None: return wrap - else: - return wrap(maybe_cls) + + return wrap(maybe_cls) mutable = define @@ -129,17 +165,22 @@ def field( hash=None, init=True, metadata=None, + type=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None, + alias=None, ): """ Identical to `attr.ib`, except keyword-only and with some arguments removed. + .. versionadded:: 23.1.0 + The *type* parameter has been re-added; mostly for `attrs.make_class`. + Please note that type checkers ignore this metadata. .. versionadded:: 20.1.0 """ return attrib( @@ -149,10 +190,40 @@ def field( hash=hash, init=init, metadata=metadata, + type=type, converter=converter, factory=factory, kw_only=kw_only, eq=eq, order=order, on_setattr=on_setattr, + alias=alias, + ) + + +def asdict(inst, *, recurse=True, filter=None, value_serializer=None): + """ + Same as `attr.asdict`, except that collections types are always retained + and dict is always used as *dict_factory*. + + .. versionadded:: 21.3.0 + """ + return _asdict( + inst=inst, + recurse=recurse, + filter=filter, + value_serializer=value_serializer, + retain_collection_types=True, + ) + + +def astuple(inst, *, recurse=True, filter=None): + """ + Same as `attr.astuple`, except that collections types are always retained + and `tuple` is always used as the *tuple_factory*. + + .. versionadded:: 21.3.0 + """ + return _astuple( + inst=inst, recurse=recurse, filter=filter, retain_collection_types=True ) diff --git a/dist/ba_data/python-site-packages/attr/_typing_compat.pyi b/dist/ba_data/python-site-packages/attr/_typing_compat.pyi new file mode 100644 index 00000000..ca7b71e9 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_typing_compat.pyi @@ -0,0 +1,15 @@ +from typing import Any, ClassVar, Protocol + +# MYPY is a special constant in mypy which works the same way as `TYPE_CHECKING`. +MYPY = False + +if MYPY: + # A protocol to be able to statically accept an attrs class. + class AttrsInstance_(Protocol): + __attrs_attrs__: ClassVar[Any] + +else: + # For type checkers without plug-in support use an empty protocol that + # will (hopefully) be combined into a union. + class AttrsInstance_(Protocol): + pass diff --git a/dist/ba_data/python-site-packages/attr/_version_info.py b/dist/ba_data/python-site-packages/attr/_version_info.py index 014e78a1..51a1312f 100644 --- a/dist/ba_data/python-site-packages/attr/_version_info.py +++ b/dist/ba_data/python-site-packages/attr/_version_info.py @@ -1,4 +1,5 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT + from functools import total_ordering @@ -8,7 +9,7 @@ @total_ordering @attrs(eq=False, order=False, slots=True, frozen=True) -class VersionInfo(object): +class VersionInfo: """ A version object that can be compared to tuple of length 1--4: diff --git a/dist/ba_data/python-site-packages/attr/converters.py b/dist/ba_data/python-site-packages/attr/converters.py index 2777db6d..2bf4c902 100644 --- a/dist/ba_data/python-site-packages/attr/converters.py +++ b/dist/ba_data/python-site-packages/attr/converters.py @@ -1,22 +1,21 @@ +# SPDX-License-Identifier: MIT + """ Commonly useful converters. """ -from __future__ import absolute_import, division, print_function - -from ._compat import PY2 -from ._make import NOTHING, Factory, pipe +import typing -if not PY2: - import inspect - import typing +from ._compat import _AnnotationExtractor +from ._make import NOTHING, Factory, pipe __all__ = [ - "pipe", - "optional", "default_if_none", + "optional", + "pipe", + "to_bool", ] @@ -39,22 +38,15 @@ def optional_converter(val): return None return converter(val) - if not PY2: - sig = None - try: - sig = inspect.signature(converter) - except (ValueError, TypeError): # inspect failed - pass - if sig: - params = list(sig.parameters.values()) - if params and params[0].annotation is not inspect.Parameter.empty: - optional_converter.__annotations__["val"] = typing.Optional[ - params[0].annotation - ] - if sig.return_annotation is not inspect.Signature.empty: - optional_converter.__annotations__["return"] = typing.Optional[ - sig.return_annotation - ] + xtr = _AnnotationExtractor(converter) + + t = xtr.get_first_param_type() + if t: + optional_converter.__annotations__["val"] = typing.Optional[t] + + rt = xtr.get_return_type() + if rt: + optional_converter.__annotations__["return"] = typing.Optional[rt] return optional_converter @@ -65,34 +57,33 @@ def default_if_none(default=NOTHING, factory=None): result of *factory*. :param default: Value to be used if ``None`` is passed. Passing an instance - of `attr.Factory` is supported, however the ``takes_self`` option + of `attrs.Factory` is supported, however the ``takes_self`` option is *not*. :param callable factory: A callable that takes no parameters whose result is used if ``None`` is passed. :raises TypeError: If **neither** *default* or *factory* is passed. :raises TypeError: If **both** *default* and *factory* are passed. - :raises ValueError: If an instance of `attr.Factory` is passed with + :raises ValueError: If an instance of `attrs.Factory` is passed with ``takes_self=True``. .. versionadded:: 18.2.0 """ if default is NOTHING and factory is None: - raise TypeError("Must pass either `default` or `factory`.") + msg = "Must pass either `default` or `factory`." + raise TypeError(msg) if default is not NOTHING and factory is not None: - raise TypeError( - "Must pass either `default` or `factory` but not both." - ) + msg = "Must pass either `default` or `factory` but not both." + raise TypeError(msg) if factory is not None: default = Factory(factory) if isinstance(default, Factory): if default.takes_self: - raise ValueError( - "`takes_self` is not supported by default_if_none." - ) + msg = "`takes_self` is not supported by default_if_none." + raise ValueError(msg) def default_if_none_converter(val): if val is not None: @@ -109,3 +100,45 @@ def default_if_none_converter(val): return default return default_if_none_converter + + +def to_bool(val): + """ + Convert "boolean" strings (e.g., from env. vars.) to real booleans. + + Values mapping to :code:`True`: + + - :code:`True` + - :code:`"true"` / :code:`"t"` + - :code:`"yes"` / :code:`"y"` + - :code:`"on"` + - :code:`"1"` + - :code:`1` + + Values mapping to :code:`False`: + + - :code:`False` + - :code:`"false"` / :code:`"f"` + - :code:`"no"` / :code:`"n"` + - :code:`"off"` + - :code:`"0"` + - :code:`0` + + :raises ValueError: for any other value. + + .. versionadded:: 21.3.0 + """ + if isinstance(val, str): + val = val.lower() + truthy = {True, "true", "t", "yes", "y", "on", "1", 1} + falsy = {False, "false", "f", "no", "n", "off", "0", 0} + try: + if val in truthy: + return True + if val in falsy: + return False + except TypeError: + # Raised when "val" is not hashable (e.g., lists) + pass + msg = f"Cannot convert value to bool: {val}" + raise ValueError(msg) diff --git a/dist/ba_data/python-site-packages/attr/converters.pyi b/dist/ba_data/python-site-packages/attr/converters.pyi index 84a57590..5abb49f6 100644 --- a/dist/ba_data/python-site-packages/attr/converters.pyi +++ b/dist/ba_data/python-site-packages/attr/converters.pyi @@ -1,8 +1,7 @@ -from typing import Callable, Optional, TypeVar, overload +from typing import Callable, TypeVar, overload from . import _ConverterType - _T = TypeVar("_T") def pipe(*validators: _ConverterType) -> _ConverterType: ... @@ -11,3 +10,4 @@ def optional(converter: _ConverterType) -> _ConverterType: ... def default_if_none(default: _T) -> _ConverterType: ... @overload def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... +def to_bool(val: str) -> bool: ... diff --git a/dist/ba_data/python-site-packages/attr/exceptions.py b/dist/ba_data/python-site-packages/attr/exceptions.py index f6f9861b..3b7abb81 100644 --- a/dist/ba_data/python-site-packages/attr/exceptions.py +++ b/dist/ba_data/python-site-packages/attr/exceptions.py @@ -1,4 +1,8 @@ -from __future__ import absolute_import, division, print_function +# SPDX-License-Identifier: MIT + +from __future__ import annotations + +from typing import ClassVar class FrozenError(AttributeError): @@ -13,7 +17,7 @@ class FrozenError(AttributeError): """ msg = "can't set attribute" - args = [msg] + args: ClassVar[tuple[str]] = [msg] class FrozenInstanceError(FrozenError): @@ -34,7 +38,7 @@ class FrozenAttributeError(FrozenError): class AttrsAttributeNotFoundError(ValueError): """ - An ``attrs`` function couldn't find an attribute that the user asked for. + An *attrs* function couldn't find an attribute that the user asked for. .. versionadded:: 16.2.0 """ @@ -42,7 +46,7 @@ class AttrsAttributeNotFoundError(ValueError): class NotAnAttrsClassError(ValueError): """ - A non-``attrs`` class has been passed into an ``attrs`` function. + A non-*attrs* class has been passed into an *attrs* function. .. versionadded:: 16.2.0 """ @@ -50,7 +54,7 @@ class NotAnAttrsClassError(ValueError): class DefaultAlreadySetError(RuntimeError): """ - A default has been set using ``attr.ib()`` and is attempted to be reset + A default has been set when defining the field and is attempted to be reset using the decorator. .. versionadded:: 17.1.0 @@ -59,8 +63,7 @@ class DefaultAlreadySetError(RuntimeError): class UnannotatedAttributeError(RuntimeError): """ - A class with ``auto_attribs=True`` has an ``attr.ib()`` without a type - annotation. + A class with ``auto_attribs=True`` has a field without a type annotation. .. versionadded:: 17.3.0 """ @@ -68,7 +71,7 @@ class UnannotatedAttributeError(RuntimeError): class PythonTooOldError(RuntimeError): """ - It was attempted to use an ``attrs`` feature that requires a newer Python + It was attempted to use an *attrs* feature that requires a newer Python version. .. versionadded:: 18.2.0 @@ -77,8 +80,8 @@ class PythonTooOldError(RuntimeError): class NotCallableError(TypeError): """ - A ``attr.ib()`` requiring a callable has been set with a value - that is not callable. + A field requiring a callable has been set with a value that is not + callable. .. versionadded:: 19.2.0 """ diff --git a/dist/ba_data/python-site-packages/attr/exceptions.pyi b/dist/ba_data/python-site-packages/attr/exceptions.pyi index a800fb26..f2680118 100644 --- a/dist/ba_data/python-site-packages/attr/exceptions.pyi +++ b/dist/ba_data/python-site-packages/attr/exceptions.pyi @@ -1,6 +1,5 @@ from typing import Any - class FrozenError(AttributeError): msg: str = ... diff --git a/dist/ba_data/python-site-packages/attr/filters.py b/dist/ba_data/python-site-packages/attr/filters.py index dc47e8fa..a1e40c98 100644 --- a/dist/ba_data/python-site-packages/attr/filters.py +++ b/dist/ba_data/python-site-packages/attr/filters.py @@ -1,10 +1,9 @@ +# SPDX-License-Identifier: MIT + """ Commonly useful filters for `attr.asdict`. """ -from __future__ import absolute_import, division, print_function - -from ._compat import isclass from ._make import Attribute @@ -13,40 +12,55 @@ def _split_what(what): Returns a tuple of `frozenset`s of classes and attributes. """ return ( - frozenset(cls for cls in what if isclass(cls)), + frozenset(cls for cls in what if isinstance(cls, type)), + frozenset(cls for cls in what if isinstance(cls, str)), frozenset(cls for cls in what if isinstance(cls, Attribute)), ) def include(*what): """ - Whitelist *what*. + Include *what*. - :param what: What to whitelist. - :type what: `list` of `type` or `attr.Attribute`\\ s + :param what: What to include. + :type what: `list` of classes `type`, field names `str` or + `attrs.Attribute`\\ s :rtype: `callable` + + .. versionchanged:: 23.1.0 Accept strings with field names. """ - cls, attrs = _split_what(what) + cls, names, attrs = _split_what(what) def include_(attribute, value): - return value.__class__ in cls or attribute in attrs + return ( + value.__class__ in cls + or attribute.name in names + or attribute in attrs + ) return include_ def exclude(*what): """ - Blacklist *what*. + Exclude *what*. - :param what: What to blacklist. - :type what: `list` of classes or `attr.Attribute`\\ s. + :param what: What to exclude. + :type what: `list` of classes `type`, field names `str` or + `attrs.Attribute`\\ s. :rtype: `callable` + + .. versionchanged:: 23.3.0 Accept field name string as input argument """ - cls, attrs = _split_what(what) + cls, names, attrs = _split_what(what) def exclude_(attribute, value): - return value.__class__ not in cls and attribute not in attrs + return not ( + value.__class__ in cls + or attribute.name in names + or attribute in attrs + ) return exclude_ diff --git a/dist/ba_data/python-site-packages/attr/filters.pyi b/dist/ba_data/python-site-packages/attr/filters.pyi index f7b63f1b..8a02fa0f 100644 --- a/dist/ba_data/python-site-packages/attr/filters.pyi +++ b/dist/ba_data/python-site-packages/attr/filters.pyi @@ -2,6 +2,5 @@ from typing import Any, Union from . import Attribute, _FilterType - -def include(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... -def exclude(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... +def include(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ... +def exclude(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ... diff --git a/dist/ba_data/python-site-packages/attr/setters.py b/dist/ba_data/python-site-packages/attr/setters.py index 240014b3..12ed6750 100644 --- a/dist/ba_data/python-site-packages/attr/setters.py +++ b/dist/ba_data/python-site-packages/attr/setters.py @@ -1,8 +1,9 @@ +# SPDX-License-Identifier: MIT + """ Commonly used hooks for on_setattr. """ -from __future__ import absolute_import, division, print_function from . import _config from .exceptions import FrozenAttributeError @@ -67,11 +68,6 @@ def convert(instance, attrib, new_value): return new_value +# Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. +# autodata stopped working, so the docstring is inlined in the API docs. NO_OP = object() -""" -Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. - -Does not work in `pipe` or within lists. - -.. versionadded:: 20.1.0 -""" diff --git a/dist/ba_data/python-site-packages/attr/setters.pyi b/dist/ba_data/python-site-packages/attr/setters.pyi index a921e07d..72f7ce47 100644 --- a/dist/ba_data/python-site-packages/attr/setters.pyi +++ b/dist/ba_data/python-site-packages/attr/setters.pyi @@ -1,8 +1,7 @@ -from typing import Any, NewType, NoReturn, TypeVar, cast +from typing import Any, NewType, NoReturn, TypeVar from . import Attribute, _OnSetAttrType - _T = TypeVar("_T") def frozen( diff --git a/dist/ba_data/python-site-packages/attr/validators.py b/dist/ba_data/python-site-packages/attr/validators.py index b9a73054..34d6b761 100644 --- a/dist/ba_data/python-site-packages/attr/validators.py +++ b/dist/ba_data/python-site-packages/attr/validators.py @@ -1,12 +1,19 @@ +# SPDX-License-Identifier: MIT + """ Commonly useful validators. """ -from __future__ import absolute_import, division, print_function +import operator import re +from contextlib import contextmanager +from re import Pattern + +from ._config import get_run_validators, set_run_validators from ._make import _AndValidator, and_, attrib, attrs +from .converters import default_if_none from .exceptions import NotCallableError @@ -14,17 +21,75 @@ "and_", "deep_iterable", "deep_mapping", + "disabled", + "ge", + "get_disabled", + "gt", "in_", "instance_of", "is_callable", + "le", + "lt", "matches_re", + "max_len", + "min_len", + "not_", "optional", "provides", + "set_disabled", ] +def set_disabled(disabled): + """ + Globally disable or enable running validators. + + By default, they are run. + + :param disabled: If ``True``, disable running all validators. + :type disabled: bool + + .. warning:: + + This function is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(not disabled) + + +def get_disabled(): + """ + Return a bool indicating whether validators are currently disabled or not. + + :return: ``True`` if validators are currently disabled. + :rtype: bool + + .. versionadded:: 21.3.0 + """ + return not get_run_validators() + + +@contextmanager +def disabled(): + """ + Context manager that disables running validators within its context. + + .. warning:: + + This context manager is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(False) + try: + yield + finally: + set_run_validators(True) + + @attrs(repr=False, slots=True, hash=True) -class _InstanceOfValidator(object): +class _InstanceOfValidator: type = attrib() def __call__(self, inst, attr, value): @@ -32,23 +97,21 @@ def __call__(self, inst, attr, value): We use a callable class to be able to change the ``__repr__``. """ if not isinstance(value, self.type): + msg = "'{name}' must be {type!r} (got {value!r} that is a {actual!r}).".format( + name=attr.name, + type=self.type, + actual=value.__class__, + value=value, + ) raise TypeError( - "'{name}' must be {type!r} (got {value!r} that is a " - "{actual!r}).".format( - name=attr.name, - type=self.type, - actual=value.__class__, - value=value, - ), + msg, attr, self.type, value, ) def __repr__(self): - return "".format( - type=self.type - ) + return f"" def instance_of(type): @@ -58,19 +121,18 @@ def instance_of(type): `isinstance` therefore it's also valid to pass a tuple of types). :param type: The type to check for. - :type type: type or tuple of types + :type type: type or tuple of type :raises TypeError: With a human readable error message, the attribute - (of type `attr.Attribute`), the expected type, and the value it + (of type `attrs.Attribute`), the expected type, and the value it got. """ return _InstanceOfValidator(type) @attrs(repr=False, frozen=True, slots=True) -class _MatchesReValidator(object): - regex = attrib() - flags = attrib() +class _MatchesReValidator: + pattern = attrib() match_func = attrib() def __call__(self, inst, attr, value): @@ -78,20 +140,18 @@ def __call__(self, inst, attr, value): We use a callable class to be able to change the ``__repr__``. """ if not self.match_func(value): + msg = "'{name}' must match regex {pattern!r} ({value!r} doesn't)".format( + name=attr.name, pattern=self.pattern.pattern, value=value + ) raise ValueError( - "'{name}' must match regex {regex!r}" - " ({value!r} doesn't)".format( - name=attr.name, regex=self.regex.pattern, value=value - ), + msg, attr, - self.regex, + self.pattern, value, ) def __repr__(self): - return "".format( - regex=self.regex - ) + return f"" def matches_re(regex, flags=0, func=None): @@ -99,48 +159,46 @@ def matches_re(regex, flags=0, func=None): A validator that raises `ValueError` if the initializer is called with a string that doesn't match *regex*. - :param str regex: a regex string to match against + :param regex: a regex string or precompiled pattern to match against :param int flags: flags that will be passed to the underlying re function (default 0) - :param callable func: which underlying `re` function to call (options - are `re.fullmatch`, `re.search`, `re.match`, default - is ``None`` which means either `re.fullmatch` or an emulation of - it on Python 2). For performance reasons, they won't be used directly - but on a pre-`re.compile`\ ed pattern. + :param callable func: which underlying `re` function to call. Valid options + are `re.fullmatch`, `re.search`, and `re.match`; the default ``None`` + means `re.fullmatch`. For performance reasons, the pattern is always + precompiled using `re.compile`. .. versionadded:: 19.2.0 + .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern. """ - fullmatch = getattr(re, "fullmatch", None) - valid_funcs = (fullmatch, None, re.search, re.match) + valid_funcs = (re.fullmatch, None, re.search, re.match) if func not in valid_funcs: - raise ValueError( - "'func' must be one of %s." - % ( - ", ".join( - sorted( - e and e.__name__ or "None" for e in set(valid_funcs) - ) - ), + msg = "'func' must be one of {}.".format( + ", ".join( + sorted(e and e.__name__ or "None" for e in set(valid_funcs)) ) ) + raise ValueError(msg) + + if isinstance(regex, Pattern): + if flags: + msg = "'flags' can only be used with a string pattern; pass flags to re.compile() instead" + raise TypeError(msg) + pattern = regex + else: + pattern = re.compile(regex, flags) - pattern = re.compile(regex, flags) if func is re.match: match_func = pattern.match elif func is re.search: match_func = pattern.search else: - if fullmatch: - match_func = pattern.fullmatch - else: - pattern = re.compile(r"(?:{})\Z".format(regex), flags) - match_func = pattern.match + match_func = pattern.fullmatch - return _MatchesReValidator(pattern, flags, match_func) + return _MatchesReValidator(pattern, match_func) @attrs(repr=False, slots=True, hash=True) -class _ProvidesValidator(object): +class _ProvidesValidator: interface = attrib() def __call__(self, inst, attr, value): @@ -148,20 +206,18 @@ def __call__(self, inst, attr, value): We use a callable class to be able to change the ``__repr__``. """ if not self.interface.providedBy(value): + msg = "'{name}' must provide {interface!r} which {value!r} doesn't.".format( + name=attr.name, interface=self.interface, value=value + ) raise TypeError( - "'{name}' must provide {interface!r} which {value!r} " - "doesn't.".format( - name=attr.name, interface=self.interface, value=value - ), + msg, attr, self.interface, value, ) def __repr__(self): - return "".format( - interface=self.interface - ) + return f"" def provides(interface): @@ -175,14 +231,24 @@ def provides(interface): :type interface: ``zope.interface.Interface`` :raises TypeError: With a human readable error message, the attribute - (of type `attr.Attribute`), the expected interface, and the + (of type `attrs.Attribute`), the expected interface, and the value it got. + + .. deprecated:: 23.1.0 """ + import warnings + + warnings.warn( + "attrs's zope-interface support is deprecated and will be removed in, " + "or after, April 2024.", + DeprecationWarning, + stacklevel=2, + ) return _ProvidesValidator(interface) @attrs(repr=False, slots=True, hash=True) -class _OptionalValidator(object): +class _OptionalValidator: validator = attrib() def __call__(self, inst, attr, value): @@ -192,9 +258,7 @@ def __call__(self, inst, attr, value): self.validator(inst, attr, value) def __repr__(self): - return "".format( - what=repr(self.validator) - ) + return f"" def optional(validator): @@ -203,20 +267,21 @@ def optional(validator): which can be set to ``None`` in addition to satisfying the requirements of the sub-validator. - :param validator: A validator (or a list of validators) that is used for - non-``None`` values. - :type validator: callable or `list` of callables. + :param Callable | tuple[Callable] | list[Callable] validator: A validator + (or validators) that is used for non-``None`` values. .. versionadded:: 15.1.0 .. versionchanged:: 17.1.0 *validator* can be a list of validators. + .. versionchanged:: 23.1.0 *validator* can also be a tuple of validators. """ - if isinstance(validator, list): + if isinstance(validator, (list, tuple)): return _OptionalValidator(_AndValidator(validator)) + return _OptionalValidator(validator) @attrs(repr=False, slots=True, hash=True) -class _InValidator(object): +class _InValidator: options = attrib() def __call__(self, inst, attr, value): @@ -226,16 +291,16 @@ def __call__(self, inst, attr, value): in_options = False if not in_options: + msg = f"'{attr.name}' must be in {self.options!r} (got {value!r})" raise ValueError( - "'{name}' must be in {options!r} (got {value!r})".format( - name=attr.name, options=self.options, value=value - ) + msg, + attr, + self.options, + value, ) def __repr__(self): - return "".format( - options=self.options - ) + return f"" def in_(options): @@ -248,16 +313,20 @@ def in_(options): :type options: list, tuple, `enum.Enum`, ... :raises ValueError: With a human readable error message, the attribute (of - type `attr.Attribute`), the expected options, and the value it + type `attrs.Attribute`), the expected options, and the value it got. .. versionadded:: 17.1.0 + .. versionchanged:: 22.1.0 + The ValueError was incomplete until now and only contained the human + readable error message. Now it contains all the information that has + been promised since 17.1.0. """ return _InValidator(options) @attrs(repr=False, slots=False, hash=True) -class _IsCallableValidator(object): +class _IsCallableValidator: def __call__(self, inst, attr, value): """ We use a callable class to be able to change the ``__repr__``. @@ -280,21 +349,21 @@ def __repr__(self): def is_callable(): """ - A validator that raises a `attr.exceptions.NotCallableError` if the + A validator that raises a `attrs.exceptions.NotCallableError` if the initializer is called with a value for this particular attribute that is not callable. .. versionadded:: 19.1.0 - :raises `attr.exceptions.NotCallableError`: With a human readable error - message containing the attribute (`attr.Attribute`) name, + :raises attrs.exceptions.NotCallableError: With a human readable error + message containing the attribute (`attrs.Attribute`) name, and the value it got. """ return _IsCallableValidator() @attrs(repr=False, slots=True, hash=True) -class _DeepIterable(object): +class _DeepIterable: member_validator = attrib(validator=is_callable()) iterable_validator = attrib( default=None, validator=optional(is_callable()) @@ -314,14 +383,11 @@ def __repr__(self): iterable_identifier = ( "" if self.iterable_validator is None - else " {iterable!r}".format(iterable=self.iterable_validator) + else f" {self.iterable_validator!r}" ) return ( - "" - ).format( - iterable_identifier=iterable_identifier, - member=self.member_validator, + f"" ) @@ -329,7 +395,7 @@ def deep_iterable(member_validator, iterable_validator=None): """ A validator that performs deep validation of an iterable. - :param member_validator: Validator to apply to iterable members + :param member_validator: Validator(s) to apply to iterable members :param iterable_validator: Validator to apply to iterable itself (optional) @@ -337,11 +403,13 @@ def deep_iterable(member_validator, iterable_validator=None): :raises TypeError: if any sub-validators fail """ + if isinstance(member_validator, (list, tuple)): + member_validator = and_(*member_validator) return _DeepIterable(member_validator, iterable_validator) @attrs(repr=False, slots=True, hash=True) -class _DeepMapping(object): +class _DeepMapping: key_validator = attrib(validator=is_callable()) value_validator = attrib(validator=is_callable()) mapping_validator = attrib(default=None, validator=optional(is_callable())) @@ -377,3 +445,237 @@ def deep_mapping(key_validator, value_validator, mapping_validator=None): :raises TypeError: if any sub-validators fail """ return _DeepMapping(key_validator, value_validator, mapping_validator) + + +@attrs(repr=False, frozen=True, slots=True) +class _NumberValidator: + bound = attrib() + compare_op = attrib() + compare_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.compare_func(value, self.bound): + msg = f"'{attr.name}' must be {self.compare_op} {self.bound}: {value}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def lt(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number larger or equal to *val*. + + :param val: Exclusive upper bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<", operator.lt) + + +def le(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number greater than *val*. + + :param val: Inclusive upper bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<=", operator.le) + + +def ge(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number smaller than *val*. + + :param val: Inclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">=", operator.ge) + + +def gt(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number smaller or equal to *val*. + + :param val: Exclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">", operator.gt) + + +@attrs(repr=False, frozen=True, slots=True) +class _MaxLengthValidator: + max_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) > self.max_length: + msg = f"Length of '{attr.name}' must be <= {self.max_length}: {len(value)}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def max_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is longer than *length*. + + :param int length: Maximum length of the string or iterable + + .. versionadded:: 21.3.0 + """ + return _MaxLengthValidator(length) + + +@attrs(repr=False, frozen=True, slots=True) +class _MinLengthValidator: + min_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) < self.min_length: + msg = f"Length of '{attr.name}' must be >= {self.min_length}: {len(value)}" + raise ValueError(msg) + + def __repr__(self): + return f"" + + +def min_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is shorter than *length*. + + :param int length: Minimum length of the string or iterable + + .. versionadded:: 22.1.0 + """ + return _MinLengthValidator(length) + + +@attrs(repr=False, slots=True, hash=True) +class _SubclassOfValidator: + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not issubclass(value, self.type): + msg = f"'{attr.name}' must be a subclass of {self.type!r} (got {value!r})." + raise TypeError( + msg, + attr, + self.type, + value, + ) + + def __repr__(self): + return f"" + + +def _subclass_of(type): + """ + A validator that raises a `TypeError` if the initializer is called + with a wrong type for this particular attribute (checks are performed using + `issubclass` therefore it's also valid to pass a tuple of types). + + :param type: The type to check for. + :type type: type or tuple of types + + :raises TypeError: With a human readable error message, the attribute + (of type `attrs.Attribute`), the expected type, and the value it + got. + """ + return _SubclassOfValidator(type) + + +@attrs(repr=False, slots=True, hash=True) +class _NotValidator: + validator = attrib() + msg = attrib( + converter=default_if_none( + "not_ validator child '{validator!r}' " + "did not raise a captured error" + ) + ) + exc_types = attrib( + validator=deep_iterable( + member_validator=_subclass_of(Exception), + iterable_validator=instance_of(tuple), + ), + ) + + def __call__(self, inst, attr, value): + try: + self.validator(inst, attr, value) + except self.exc_types: + pass # suppress error to invert validity + else: + raise ValueError( + self.msg.format( + validator=self.validator, + exc_types=self.exc_types, + ), + attr, + self.validator, + value, + self.exc_types, + ) + + def __repr__(self): + return ( + "" + ).format( + what=self.validator, + exc_types=self.exc_types, + ) + + +def not_(validator, *, msg=None, exc_types=(ValueError, TypeError)): + """ + A validator that wraps and logically 'inverts' the validator passed to it. + It will raise a `ValueError` if the provided validator *doesn't* raise a + `ValueError` or `TypeError` (by default), and will suppress the exception + if the provided validator *does*. + + Intended to be used with existing validators to compose logic without + needing to create inverted variants, for example, ``not_(in_(...))``. + + :param validator: A validator to be logically inverted. + :param msg: Message to raise if validator fails. + Formatted with keys ``exc_types`` and ``validator``. + :type msg: str + :param exc_types: Exception type(s) to capture. + Other types raised by child validators will not be intercepted and + pass through. + + :raises ValueError: With a human readable error message, + the attribute (of type `attrs.Attribute`), + the validator that failed to raise an exception, + the value it got, + and the expected exception types. + + .. versionadded:: 22.2.0 + """ + try: + exc_types = tuple(exc_types) + except TypeError: + exc_types = (exc_types,) + return _NotValidator(validator, msg, exc_types) diff --git a/dist/ba_data/python-site-packages/attr/validators.pyi b/dist/ba_data/python-site-packages/attr/validators.pyi index fe92aac4..d194a75a 100644 --- a/dist/ba_data/python-site-packages/attr/validators.pyi +++ b/dist/ba_data/python-site-packages/attr/validators.pyi @@ -3,11 +3,13 @@ from typing import ( AnyStr, Callable, Container, + ContextManager, Iterable, List, Mapping, Match, Optional, + Pattern, Tuple, Type, TypeVar, @@ -16,7 +18,7 @@ from typing import ( ) from . import _ValidatorType - +from . import _ValidatorArgType _T = TypeVar("_T") _T1 = TypeVar("_T1") @@ -27,6 +29,10 @@ _K = TypeVar("_K") _V = TypeVar("_V") _M = TypeVar("_M", bound=Mapping) +def set_disabled(run: bool) -> None: ... +def get_disabled() -> bool: ... +def disabled() -> ContextManager[None]: ... + # To be more precise on instance_of use some overloads. # If there are more than 3 items in the tuple then we fall back to Any @overload @@ -45,19 +51,21 @@ def instance_of( def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ... def provides(interface: Any) -> _ValidatorType[Any]: ... def optional( - validator: Union[_ValidatorType[_T], List[_ValidatorType[_T]]] + validator: Union[ + _ValidatorType[_T], List[_ValidatorType[_T]], Tuple[_ValidatorType[_T]] + ] ) -> _ValidatorType[Optional[_T]]: ... def in_(options: Container[_T]) -> _ValidatorType[_T]: ... def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... def matches_re( - regex: AnyStr, + regex: Union[Pattern[AnyStr], AnyStr], flags: int = ..., func: Optional[ Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]] ] = ..., ) -> _ValidatorType[AnyStr]: ... def deep_iterable( - member_validator: _ValidatorType[_T], + member_validator: _ValidatorArgType[_T], iterable_validator: Optional[_ValidatorType[_I]] = ..., ) -> _ValidatorType[_I]: ... def deep_mapping( @@ -66,3 +74,15 @@ def deep_mapping( mapping_validator: Optional[_ValidatorType[_M]] = ..., ) -> _ValidatorType[_M]: ... def is_callable() -> _ValidatorType[_T]: ... +def lt(val: _T) -> _ValidatorType[_T]: ... +def le(val: _T) -> _ValidatorType[_T]: ... +def ge(val: _T) -> _ValidatorType[_T]: ... +def gt(val: _T) -> _ValidatorType[_T]: ... +def max_len(length: int) -> _ValidatorType[_T]: ... +def min_len(length: int) -> _ValidatorType[_T]: ... +def not_( + validator: _ValidatorType[_T], + *, + msg: Optional[str] = None, + exc_types: Union[Type[Exception], Iterable[Type[Exception]]] = ..., +) -> _ValidatorType[_T]: ... diff --git a/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/INSTALLER b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/METADATA b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/METADATA new file mode 100644 index 00000000..c20be76c --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/METADATA @@ -0,0 +1,202 @@ +Metadata-Version: 2.1 +Name: attrs +Version: 23.2.0 +Summary: Classes Without Boilerplate +Project-URL: Documentation, https://www.attrs.org/ +Project-URL: Changelog, https://www.attrs.org/en/stable/changelog.html +Project-URL: GitHub, https://github.com/python-attrs/attrs +Project-URL: Funding, https://github.com/sponsors/hynek +Project-URL: Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi +Author-email: Hynek Schlawack +License-Expression: MIT +License-File: LICENSE +Keywords: attribute,boilerplate,class +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Typing :: Typed +Requires-Python: >=3.7 +Requires-Dist: importlib-metadata; python_version < '3.8' +Provides-Extra: cov +Requires-Dist: attrs[tests]; extra == 'cov' +Requires-Dist: coverage[toml]>=5.3; extra == 'cov' +Provides-Extra: dev +Requires-Dist: attrs[tests]; extra == 'dev' +Requires-Dist: pre-commit; extra == 'dev' +Provides-Extra: docs +Requires-Dist: furo; extra == 'docs' +Requires-Dist: myst-parser; extra == 'docs' +Requires-Dist: sphinx; extra == 'docs' +Requires-Dist: sphinx-notfound-page; extra == 'docs' +Requires-Dist: sphinxcontrib-towncrier; extra == 'docs' +Requires-Dist: towncrier; extra == 'docs' +Requires-Dist: zope-interface; extra == 'docs' +Provides-Extra: tests +Requires-Dist: attrs[tests-no-zope]; extra == 'tests' +Requires-Dist: zope-interface; extra == 'tests' +Provides-Extra: tests-mypy +Requires-Dist: mypy>=1.6; (platform_python_implementation == 'CPython' and python_version >= '3.8') and extra == 'tests-mypy' +Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.8') and extra == 'tests-mypy' +Provides-Extra: tests-no-zope +Requires-Dist: attrs[tests-mypy]; extra == 'tests-no-zope' +Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'tests-no-zope' +Requires-Dist: hypothesis; extra == 'tests-no-zope' +Requires-Dist: pympler; extra == 'tests-no-zope' +Requires-Dist: pytest-xdist[psutil]; extra == 'tests-no-zope' +Requires-Dist: pytest>=4.3.0; extra == 'tests-no-zope' +Description-Content-Type: text/markdown + +

    + + attrs + +

    + + +*attrs* is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka [dunder methods](https://www.attrs.org/en/latest/glossary.html#term-dunder-methods)). +[Trusted by NASA](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/personalizing-your-profile#list-of-qualifying-repositories-for-mars-2020-helicopter-contributor-achievement) for Mars missions since 2020! + +Its main goal is to help you to write **concise** and **correct** software without slowing down your code. + + +## Sponsors + +*attrs* would not be possible without our [amazing sponsors](https://github.com/sponsors/hynek). +Especially those generously supporting us at the *The Organization* tier and higher: + +

    + + + +

    + +

    + Please consider joining them to help make attrs’s maintenance more sustainable! +

    + + + +## Example + +*attrs* gives you a class decorator and a way to declaratively define the attributes on that class: + + + +```pycon +>>> from attrs import asdict, define, make_class, Factory + +>>> @define +... class SomeClass: +... a_number: int = 42 +... list_of_numbers: list[int] = Factory(list) +... +... def hard_math(self, another_number): +... return self.a_number + sum(self.list_of_numbers) * another_number + + +>>> sc = SomeClass(1, [1, 2, 3]) +>>> sc +SomeClass(a_number=1, list_of_numbers=[1, 2, 3]) + +>>> sc.hard_math(3) +19 +>>> sc == SomeClass(1, [1, 2, 3]) +True +>>> sc != SomeClass(2, [3, 2, 1]) +True + +>>> asdict(sc) +{'a_number': 1, 'list_of_numbers': [1, 2, 3]} + +>>> SomeClass() +SomeClass(a_number=42, list_of_numbers=[]) + +>>> C = make_class("C", ["a", "b"]) +>>> C("foo", "bar") +C(a='foo', b='bar') +``` + +After *declaring* your attributes, *attrs* gives you: + +- a concise and explicit overview of the class's attributes, +- a nice human-readable `__repr__`, +- equality-checking methods, +- an initializer, +- and much more, + +*without* writing dull boilerplate code again and again and *without* runtime performance penalties. + +**Hate type annotations**!? +No problem! +Types are entirely **optional** with *attrs*. +Simply assign `attrs.field()` to the attributes instead of annotating them with types. + +--- + +This example uses *attrs*'s modern APIs that have been introduced in version 20.1.0, and the *attrs* package import name that has been added in version 21.3.0. +The classic APIs (`@attr.s`, `attr.ib`, plus their serious-business aliases) and the `attr` package import name will remain **indefinitely**. + +Please check out [*On The Core API Names*](https://www.attrs.org/en/latest/names.html) for a more in-depth explanation. + + +## Data Classes + +On the tin, *attrs* might remind you of `dataclasses` (and indeed, `dataclasses` [are a descendant](https://hynek.me/articles/import-attrs/) of *attrs*). +In practice it does a lot more and is more flexible. +For instance it allows you to define [special handling of NumPy arrays for equality checks](https://www.attrs.org/en/stable/comparison.html#customization), allows more ways to [plug into the initialization process](https://www.attrs.org/en/stable/init.html#hooking-yourself-into-initialization), and allows for stepping through the generated methods using a debugger. + +For more details, please refer to our [comparison page](https://www.attrs.org/en/stable/why.html#data-classes). + + +## Project Information + +- [**Changelog**](https://www.attrs.org/en/stable/changelog.html) +- [**Documentation**](https://www.attrs.org/) +- [**PyPI**](https://pypi.org/project/attrs/) +- [**Source Code**](https://github.com/python-attrs/attrs) +- [**Contributing**](https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md) +- [**Third-party Extensions**](https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs) +- **Get Help**: please use the `python-attrs` tag on [StackOverflow](https://stackoverflow.com/questions/tagged/python-attrs) + + +### *attrs* for Enterprise + +Available as part of the Tidelift Subscription. + +The maintainers of *attrs* and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. +Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. +[Learn more.](https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) + +## Release Information + +### Changes + +- The type annotation for `attrs.resolve_types()` is now correct. + [#1141](https://github.com/python-attrs/attrs/issues/1141) +- Type stubs now use `typing.dataclass_transform` to decorate dataclass-like decorators, instead of the non-standard `__dataclass_transform__` special form, which is only supported by Pyright. + [#1158](https://github.com/python-attrs/attrs/issues/1158) +- Fixed serialization of namedtuple fields using `attrs.asdict/astuple()` with `retain_collection_types=True`. + [#1165](https://github.com/python-attrs/attrs/issues/1165) +- `attrs.AttrsInstance` is now a `typing.Protocol` in both type hints and code. + This allows you to subclass it along with another `Protocol`. + [#1172](https://github.com/python-attrs/attrs/issues/1172) +- If *attrs* detects that `__attrs_pre_init__` accepts more than just `self`, it will call it with the same arguments as `__init__` was called. + This allows you to, for example, pass arguments to `super().__init__()`. + [#1187](https://github.com/python-attrs/attrs/issues/1187) +- Slotted classes now transform `functools.cached_property` decorated methods to support equivalent semantics. + [#1200](https://github.com/python-attrs/attrs/issues/1200) +- Added *class_body* argument to `attrs.make_class()` to provide additional attributes for newly created classes. + It is, for example, now possible to attach methods. + [#1203](https://github.com/python-attrs/attrs/issues/1203) + + +--- + +[Full changelog](https://www.attrs.org/en/stable/changelog.html) diff --git a/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/RECORD b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/RECORD new file mode 100644 index 00000000..9708b064 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/RECORD @@ -0,0 +1,55 @@ +attr/__init__.py,sha256=WlXJN6ICB0Y_HZ0lmuTUgia0kuSdn2p67d4N6cYxNZM,3307 +attr/__init__.pyi,sha256=u08EujYHy_rSyebNn-I9Xv2S_cXmtA9xWGc0cBsyl18,16976 +attr/__pycache__/__init__.cpython-312.pyc,, +attr/__pycache__/_cmp.cpython-312.pyc,, +attr/__pycache__/_compat.cpython-312.pyc,, +attr/__pycache__/_config.cpython-312.pyc,, +attr/__pycache__/_funcs.cpython-312.pyc,, +attr/__pycache__/_make.cpython-312.pyc,, +attr/__pycache__/_next_gen.cpython-312.pyc,, +attr/__pycache__/_version_info.cpython-312.pyc,, +attr/__pycache__/converters.cpython-312.pyc,, +attr/__pycache__/exceptions.cpython-312.pyc,, +attr/__pycache__/filters.cpython-312.pyc,, +attr/__pycache__/setters.cpython-312.pyc,, +attr/__pycache__/validators.cpython-312.pyc,, +attr/_cmp.py,sha256=OQZlWdFX74z18adGEUp40Ojqm0NNu1Flqnv2JE8B2ng,4025 +attr/_cmp.pyi,sha256=sGQmOM0w3_K4-X8cTXR7g0Hqr290E8PTObA9JQxWQqc,399 +attr/_compat.py,sha256=QmRyxii295wcQfaugWqxuIumAPsNQ2-RUF82QZPqMKw,2540 +attr/_config.py,sha256=z81Vt-GeT_2taxs1XZfmHx9TWlSxjPb6eZH1LTGsS54,843 +attr/_funcs.py,sha256=VBTUFKLklsmqxys3qWSTK_Ac9Z4s0mAJWwgW9nA7Llk,17173 +attr/_make.py,sha256=LnVy2e0HygoqaZknhC19z7JmOt7qGkAadf2LZgWVJWI,101923 +attr/_next_gen.py,sha256=as1voi8siAI_o2OQG8YIiZvmn0G7-S3_j_774rnoZ_g,6203 +attr/_typing_compat.pyi,sha256=XDP54TUn-ZKhD62TOQebmzrwFyomhUCoGRpclb6alRA,469 +attr/_version_info.py,sha256=exSqb3b5E-fMSsgZAlEw9XcLpEgobPORCZpcaEglAM4,2121 +attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209 +attr/converters.py,sha256=Kyw5MY0yfnUR_RwN1Vydf0EiE---htDxOgSc_-NYL6A,3622 +attr/converters.pyi,sha256=jKlpHBEt6HVKJvgrMFJRrHq8p61GXg4-Nd5RZWKJX7M,406 +attr/exceptions.py,sha256=HRFq4iybmv7-DcZwyjl6M1euM2YeJVK_hFxuaBGAngI,1977 +attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539 +attr/filters.py,sha256=9pYvXqdg6mtLvKIIb56oALRMoHFnQTcGCO4EXTc1qyM,1470 +attr/filters.pyi,sha256=0mRCjLKxdcvAo0vD-Cr81HfRXXCp9j_cAXjOoAHtPGM,225 +attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attr/setters.py,sha256=pbCZQ-pE6ZxjDqZfWWUhUFefXtpekIU4qS_YDMLPQ50,1400 +attr/setters.pyi,sha256=pyY8TVNBu8TWhOldv_RxHzmGvdgFQH981db70r0fn5I,567 +attr/validators.py,sha256=LGVpbiNg_KGzYrKUD5JPiZkx8TMfynDZGoQoLJNCIMo,19676 +attr/validators.pyi,sha256=167Dl9nt7NUhE9wht1I-buo039qyUT1nEUT_nKjSWr4,2580 +attrs-23.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +attrs-23.2.0.dist-info/METADATA,sha256=WwvG7OHyKjEPpyFUZCCYt1n0E_CcqdRb7bliGEdcm-A,9531 +attrs-23.2.0.dist-info/RECORD,, +attrs-23.2.0.dist-info/WHEEL,sha256=mRYSEL3Ih6g5a_CVMIcwiF__0Ae4_gLYh01YFNwiq1k,87 +attrs-23.2.0.dist-info/licenses/LICENSE,sha256=iCEVyV38KvHutnFPjsbVy8q_Znyv-HKfQkINpj9xTp8,1109 +attrs/__init__.py,sha256=9_5waVbFs7rLqtXZ73tNDrxhezyZ8VZeX4BbvQ3EeJw,1039 +attrs/__init__.pyi,sha256=s_ajQ_U14DOsOz0JbmAKDOi46B3v2PcdO0UAV1MY6Ek,2168 +attrs/__pycache__/__init__.cpython-312.pyc,, +attrs/__pycache__/converters.cpython-312.pyc,, +attrs/__pycache__/exceptions.cpython-312.pyc,, +attrs/__pycache__/filters.cpython-312.pyc,, +attrs/__pycache__/setters.cpython-312.pyc,, +attrs/__pycache__/validators.cpython-312.pyc,, +attrs/converters.py,sha256=8kQljrVwfSTRu8INwEk8SI0eGrzmWftsT7rM0EqyohM,76 +attrs/exceptions.py,sha256=ACCCmg19-vDFaDPY9vFl199SPXCQMN_bENs4DALjzms,76 +attrs/filters.py,sha256=VOUMZug9uEU6dUuA0dF1jInUK0PL3fLgP0VBS5d-CDE,73 +attrs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attrs/setters.py,sha256=eL1YidYQV3T2h9_SYIZSZR1FAcHGb1TuCTy0E0Lv2SU,73 +attrs/validators.py,sha256=xcy6wD5TtTkdCG1f4XWbocPSO0faBjk5IfVJfP6SUj0,76 diff --git a/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/WHEEL b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/WHEEL new file mode 100644 index 00000000..2860816a --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.21.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/licenses/LICENSE b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/licenses/LICENSE new file mode 100644 index 00000000..2bd6453d --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs-23.2.0.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Hynek Schlawack and the attrs contributors + +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. diff --git a/dist/ba_data/python-site-packages/attrs/__init__.py b/dist/ba_data/python-site-packages/attrs/__init__.py new file mode 100644 index 00000000..0c248156 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/__init__.py @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: MIT + +from attr import ( + NOTHING, + Attribute, + AttrsInstance, + Factory, + _make_getattr, + assoc, + cmp_using, + define, + evolve, + field, + fields, + fields_dict, + frozen, + has, + make_class, + mutable, + resolve_types, + validate, +) +from attr._next_gen import asdict, astuple + +from . import converters, exceptions, filters, setters, validators + + +__all__ = [ + "__author__", + "__copyright__", + "__description__", + "__doc__", + "__email__", + "__license__", + "__title__", + "__url__", + "__version__", + "__version_info__", + "asdict", + "assoc", + "astuple", + "Attribute", + "AttrsInstance", + "cmp_using", + "converters", + "define", + "evolve", + "exceptions", + "Factory", + "field", + "fields_dict", + "fields", + "filters", + "frozen", + "has", + "make_class", + "mutable", + "NOTHING", + "resolve_types", + "setters", + "validate", + "validators", +] + +__getattr__ = _make_getattr(__name__) diff --git a/dist/ba_data/python-site-packages/attrs/__init__.pyi b/dist/ba_data/python-site-packages/attrs/__init__.pyi new file mode 100644 index 00000000..9372cfea --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/__init__.pyi @@ -0,0 +1,67 @@ +from typing import ( + Any, + Callable, + Dict, + Mapping, + Optional, + Sequence, + Tuple, + Type, +) + +# Because we need to type our own stuff, we have to make everything from +# attr explicitly public too. +from attr import __author__ as __author__ +from attr import __copyright__ as __copyright__ +from attr import __description__ as __description__ +from attr import __email__ as __email__ +from attr import __license__ as __license__ +from attr import __title__ as __title__ +from attr import __url__ as __url__ +from attr import __version__ as __version__ +from attr import __version_info__ as __version_info__ +from attr import _FilterType +from attr import assoc as assoc +from attr import Attribute as Attribute +from attr import AttrsInstance as AttrsInstance +from attr import cmp_using as cmp_using +from attr import converters as converters +from attr import define as define +from attr import evolve as evolve +from attr import exceptions as exceptions +from attr import Factory as Factory +from attr import field as field +from attr import fields as fields +from attr import fields_dict as fields_dict +from attr import filters as filters +from attr import frozen as frozen +from attr import has as has +from attr import make_class as make_class +from attr import mutable as mutable +from attr import NOTHING as NOTHING +from attr import resolve_types as resolve_types +from attr import setters as setters +from attr import validate as validate +from attr import validators as validators + +# TODO: see definition of attr.asdict/astuple +def asdict( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + dict_factory: Type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Optional[ + Callable[[type, Attribute[Any], Any], Any] + ] = ..., + tuple_keys: bool = ..., +) -> Dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + tuple_factory: Type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> Tuple[Any, ...]: ... diff --git a/dist/ba_data/python-site-packages/attrs/converters.py b/dist/ba_data/python-site-packages/attrs/converters.py new file mode 100644 index 00000000..7821f6c0 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/converters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.converters import * # noqa: F403 diff --git a/dist/ba_data/python-site-packages/attrs/exceptions.py b/dist/ba_data/python-site-packages/attrs/exceptions.py new file mode 100644 index 00000000..3323f9d2 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/exceptions.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.exceptions import * # noqa: F403 diff --git a/dist/ba_data/python-site-packages/attrs/filters.py b/dist/ba_data/python-site-packages/attrs/filters.py new file mode 100644 index 00000000..3080f483 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/filters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.filters import * # noqa: F403 diff --git a/dist/ba_root/mods/serverData/Chat Logs.log b/dist/ba_data/python-site-packages/attrs/py.typed similarity index 100% rename from dist/ba_root/mods/serverData/Chat Logs.log rename to dist/ba_data/python-site-packages/attrs/py.typed diff --git a/dist/ba_data/python-site-packages/attrs/setters.py b/dist/ba_data/python-site-packages/attrs/setters.py new file mode 100644 index 00000000..f3d73bb7 --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/setters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.setters import * # noqa: F403 diff --git a/dist/ba_data/python-site-packages/attrs/validators.py b/dist/ba_data/python-site-packages/attrs/validators.py new file mode 100644 index 00000000..037e124f --- /dev/null +++ b/dist/ba_data/python-site-packages/attrs/validators.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.validators import * # noqa: F403 diff --git a/dist/ba_data/python-site-packages/bin/flask b/dist/ba_data/python-site-packages/bin/flask new file mode 100644 index 00000000..a3eb0ec5 --- /dev/null +++ b/dist/ba_data/python-site-packages/bin/flask @@ -0,0 +1,8 @@ +#!/usr/bin/python3.12 +# -*- coding: utf-8 -*- +import re +import sys +from flask.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/INSTALLER b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/LICENSE.txt b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/LICENSE.txt new file mode 100644 index 00000000..79c9825a --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2010 Jason Kirtland + +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. diff --git a/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/METADATA b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/METADATA new file mode 100644 index 00000000..efa45f59 --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.1 +Name: blinker +Version: 1.8.2 +Summary: Fast, simple object-to-object and broadcast signaling +Author: Jason Kirtland +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Source, https://github.com/pallets-eco/blinker/ + +# Blinker + +Blinker provides a fast dispatching system that allows any number of +interested parties to subscribe to events, or "signals". + + +## Pallets Community Ecosystem + +> [!IMPORTANT]\ +> This project is part of the Pallets Community Ecosystem. Pallets is the open +> source organization that maintains Flask; Pallets-Eco enables community +> maintenance of related projects. If you are interested in helping maintain +> this project, please reach out on [the Pallets Discord server][discord]. +> +> [discord]: https://discord.gg/pallets + + +## Example + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +```pycon +>>> from blinker import signal +>>> started = signal('round-started') +>>> def each(round): +... print(f"Round {round}") +... +>>> started.connect(each) + +>>> def round_two(round): +... print("This is round two.") +... +>>> started.connect(round_two, sender=2) + +>>> for round in range(1, 4): +... started.send(round) +... +Round 1! +Round 2! +This is round two. +Round 3! +``` + diff --git a/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/RECORD b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/RECORD new file mode 100644 index 00000000..b6a6b7eb --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/RECORD @@ -0,0 +1,12 @@ +blinker-1.8.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.8.2.dist-info/LICENSE.txt,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.8.2.dist-info/METADATA,sha256=3tEx40hm9IEofyFqDPJsDPE9MAIEhtifapoSp7FqzuA,1633 +blinker-1.8.2.dist-info/RECORD,, +blinker-1.8.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +blinker/__init__.py,sha256=ymyJY_PoTgBzaPgdr4dq-RRsGh7D-sYQIGMNp8Rx4qc,1577 +blinker/__pycache__/__init__.cpython-312.pyc,, +blinker/__pycache__/_utilities.cpython-312.pyc,, +blinker/__pycache__/base.cpython-312.pyc,, +blinker/_utilities.py,sha256=0J7eeXXTUx0Ivf8asfpx0ycVkp0Eqfqnj117x2mYX9E,1675 +blinker/base.py,sha256=nIZJEtXQ8LLZZJrwVp2wQcdfCzDixvAHR9VpSWiyVcQ,22574 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/WHEEL b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/WHEEL new file mode 100644 index 00000000..3b5e64b5 --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker-1.8.2.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/dist/ba_data/python-site-packages/blinker/__init__.py b/dist/ba_data/python-site-packages/blinker/__init__.py new file mode 100644 index 00000000..c93527ec --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import typing as t + +from .base import ANY +from .base import default_namespace +from .base import NamedSignal +from .base import Namespace +from .base import Signal +from .base import signal + +__all__ = [ + "ANY", + "default_namespace", + "NamedSignal", + "Namespace", + "Signal", + "signal", +] + + +def __getattr__(name: str) -> t.Any: + import warnings + + if name == "__version__": + import importlib.metadata + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Blinker 1.9.0. Use feature detection or" + " 'importlib.metadata.version(\"blinker\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("blinker") + + if name == "receiver_connected": + from .base import _receiver_connected + + warnings.warn( + "The global 'receiver_connected' signal is deprecated and will be" + " removed in Blinker 1.9. Use 'Signal.receiver_connected' and" + " 'Signal.receiver_disconnected' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _receiver_connected + + if name == "WeakNamespace": + from .base import _WeakNamespace + + warnings.warn( + "'WeakNamespace' is deprecated and will be removed in Blinker 1.9." + " Use 'Namespace' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _WeakNamespace + + raise AttributeError(name) diff --git a/dist/ba_data/python-site-packages/blinker/_utilities.py b/dist/ba_data/python-site-packages/blinker/_utilities.py new file mode 100644 index 00000000..000c902a --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker/_utilities.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +import collections.abc as c +import inspect +import typing as t +from weakref import ref +from weakref import WeakMethod + +T = t.TypeVar("T") + + +class Symbol: + """A constant symbol, nicer than ``object()``. Repeated calls return the + same instance. + + >>> Symbol('foo') is Symbol('foo') + True + >>> Symbol('foo') + foo + """ + + symbols: t.ClassVar[dict[str, Symbol]] = {} + + def __new__(cls, name: str) -> Symbol: + if name in cls.symbols: + return cls.symbols[name] + + obj = super().__new__(cls) + cls.symbols[name] = obj + return obj + + def __init__(self, name: str) -> None: + self.name = name + + def __repr__(self) -> str: + return self.name + + def __getnewargs__(self) -> tuple[t.Any, ...]: + return (self.name,) + + +def make_id(obj: object) -> c.Hashable: + """Get a stable identifier for a receiver or sender, to be used as a dict + key or in a set. + """ + if inspect.ismethod(obj): + # The id of a bound method is not stable, but the id of the unbound + # function and instance are. + return id(obj.__func__), id(obj.__self__) + + if isinstance(obj, (str, int)): + # Instances with the same value always compare equal and have the same + # hash, even if the id may change. + return obj + + # Assume other types are not hashable but will always be the same instance. + return id(obj) + + +def make_ref(obj: T, callback: c.Callable[[ref[T]], None] | None = None) -> ref[T]: + if inspect.ismethod(obj): + return WeakMethod(obj, callback) # type: ignore[arg-type, return-value] + + return ref(obj, callback) diff --git a/dist/ba_data/python-site-packages/blinker/base.py b/dist/ba_data/python-site-packages/blinker/base.py new file mode 100644 index 00000000..ec494b14 --- /dev/null +++ b/dist/ba_data/python-site-packages/blinker/base.py @@ -0,0 +1,621 @@ +from __future__ import annotations + +import collections.abc as c +import typing as t +import warnings +import weakref +from collections import defaultdict +from contextlib import AbstractContextManager +from contextlib import contextmanager +from functools import cached_property +from inspect import iscoroutinefunction +from weakref import WeakValueDictionary + +from ._utilities import make_id +from ._utilities import make_ref +from ._utilities import Symbol + +if t.TYPE_CHECKING: + F = t.TypeVar("F", bound=c.Callable[..., t.Any]) + +ANY = Symbol("ANY") +"""Symbol for "any sender".""" + +ANY_ID = 0 + + +class Signal: + """A notification emitter. + + :param doc: The docstring for the signal. + """ + + ANY = ANY + """An alias for the :data:`~blinker.ANY` sender symbol.""" + + set_class: type[set[t.Any]] = set + """The set class to use for tracking connected receivers and senders. + Python's ``set`` is unordered. If receivers must be dispatched in the order + they were connected, an ordered set implementation can be used. + + .. versionadded:: 1.7 + """ + + @cached_property + def receiver_connected(self) -> Signal: + """Emitted at the end of each :meth:`connect` call. + + The signal sender is the signal instance, and the :meth:`connect` + arguments are passed through: ``receiver``, ``sender``, and ``weak``. + + .. versionadded:: 1.2 + """ + return Signal(doc="Emitted after a receiver connects.") + + @cached_property + def receiver_disconnected(self) -> Signal: + """Emitted at the end of each :meth:`disconnect` call. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: ``receiver`` and ``sender``. + + This signal is emitted **only** when :meth:`disconnect` is called + explicitly. This signal cannot be emitted by an automatic disconnect + when a weakly referenced receiver or sender goes out of scope, as the + instance is no longer be available to be used as the sender for this + signal. + + An alternative approach is available by subscribing to + :attr:`receiver_connected` and setting up a custom weakref cleanup + callback on weak receivers and senders. + + .. versionadded:: 1.2 + """ + return Signal(doc="Emitted after a receiver disconnects.") + + def __init__(self, doc: str | None = None) -> None: + if doc: + self.__doc__ = doc + + self.receivers: dict[ + t.Any, weakref.ref[c.Callable[..., t.Any]] | c.Callable[..., t.Any] + ] = {} + """The map of connected receivers. Useful to quickly check if any + receivers are connected to the signal: ``if s.receivers:``. The + structure and data is not part of the public API, but checking its + boolean value is. + """ + + self.is_muted: bool = False + self._by_receiver: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._by_sender: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._weak_senders: dict[t.Any, weakref.ref[t.Any]] = {} + + def connect(self, receiver: F, sender: t.Any = ANY, weak: bool = True) -> F: + """Connect ``receiver`` to be called when the signal is sent by + ``sender``. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends. + """ + receiver_id = make_id(receiver) + sender_id = ANY_ID if sender is ANY else make_id(sender) + + if weak: + self.receivers[receiver_id] = make_ref( + receiver, self._make_cleanup_receiver(receiver_id) + ) + else: + self.receivers[receiver_id] = receiver + + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + + if sender is not ANY and sender_id not in self._weak_senders: + # store a cleanup for weakref-able senders + try: + self._weak_senders[sender_id] = make_ref( + sender, self._make_cleanup_sender(sender_id) + ) + except TypeError: + pass + + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: + try: + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) + except TypeError: + # TODO no explanation or test for this + self.disconnect(receiver, sender) + raise + + if _receiver_connected.receivers and self is not _receiver_connected: + try: + _receiver_connected.send( + self, receiver_arg=receiver, sender_arg=sender, weak_arg=weak + ) + except TypeError: + self.disconnect(receiver, sender) + raise + + return receiver + + def connect_via(self, sender: t.Any, weak: bool = False) -> c.Callable[[F], F]: + """Connect the decorated function to be called when the signal is sent + by ``sender``. + + The decorated function will be called when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument along + with any extra keyword arguments. + + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends.= + + .. versionadded:: 1.1 + """ + + def decorator(fn: F) -> F: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY + ) -> c.Generator[None, None, None]: + """A context manager that temporarily connects ``receiver`` to the + signal while a ``with`` block executes. When the block exits, the + receiver is disconnected. Useful for tests. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. + + .. versionadded:: 1.1 + """ + self.connect(receiver, sender=sender, weak=False) + + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> c.Generator[None, None, None]: + """A context manager that temporarily disables the signal. No receivers + will be called if the signal is sent, until the ``with`` block exits. + Useful for tests. + """ + self.is_muted = True + + try: + yield None + finally: + self.is_muted = False + + def temporarily_connected_to( + self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY + ) -> AbstractContextManager[None]: + """Deprecated alias for :meth:`connected_to`. + + .. deprecated:: 1.1 + Renamed to ``connected_to``. Will be removed in Blinker 1.9. + + .. versionadded:: 0.9 + """ + warnings.warn( + "'temporarily_connected_to' is renamed to 'connected_to'. The old name is" + " deprecated and will be removed in Blinker 1.9.", + DeprecationWarning, + stacklevel=2, + ) + return self.connected_to(receiver, sender) + + def send( + self, + sender: t.Any | None = None, + /, + *, + _async_wrapper: c.Callable[ + [c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]]], c.Callable[..., t.Any] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Call all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _async_wrapper: Will be called on any receivers that are async + coroutines to turn them into sync callables. For example, could run + the receiver with an event loop. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionchanged:: 1.7 + Added the ``_async_wrapper`` argument. + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if iscoroutinefunction(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function.") + + result = _async_wrapper(receiver)(sender, **kwargs) + else: + result = receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + async def send_async( + self, + sender: t.Any | None = None, + /, + *, + _sync_wrapper: c.Callable[ + [c.Callable[..., t.Any]], c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Await all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _sync_wrapper: Will be called on any receivers that are sync + callables to turn them into async coroutines. For example, + could call the receiver in a thread. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionadded:: 1.7 + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if not iscoroutinefunction(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function.") + + result = await _sync_wrapper(receiver)(sender, **kwargs) + else: + result = await receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + def has_receivers_for(self, sender: t.Any) -> bool: + """Check if there is at least one receiver that will be called with the + given ``sender``. A receiver connected to :data:`ANY` will always be + called, regardless of sender. Does not check if weakly referenced + receivers are still live. See :meth:`receivers_for` for a stronger + search. + + :param sender: Check for receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + if not self.receivers: + return False + + if self._by_sender[ANY_ID]: + return True + + if sender is ANY: + return False + + return make_id(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> c.Generator[c.Callable[..., t.Any], None, None]: + """Yield each receiver to be called for ``sender``, in addition to those + to be called for :data:`ANY`. Weakly referenced receivers that are not + live will be disconnected and skipped. + + :param sender: Yield receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + # TODO: test receivers_for(ANY) + if not self.receivers: + return + + sender_id = make_id(sender) + + if sender_id in self._by_sender: + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] + else: + ids = self._by_sender[ANY_ID].copy() + + for receiver_id in ids: + receiver = self.receivers.get(receiver_id) + + if receiver is None: + continue + + if isinstance(receiver, weakref.ref): + strong = receiver() + + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + + yield strong + else: + yield receiver + + def disconnect(self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY) -> None: + """Disconnect ``receiver`` from being called when the signal is sent by + ``sender``. + + :param receiver: A connected receiver callable. + :param sender: Disconnect from only this sender. By default, disconnect + from all senders. + """ + sender_id: c.Hashable + + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = make_id(sender) + + receiver_id = make_id(receiver) + self._disconnect(receiver_id, sender_id) + + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) + + def _disconnect(self, receiver_id: c.Hashable, sender_id: c.Hashable) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, None) is not None: + for bucket in self._by_sender.values(): + bucket.discard(receiver_id) + + self.receivers.pop(receiver_id, None) + else: + self._by_sender[sender_id].discard(receiver_id) + self._by_receiver[receiver_id].discard(sender_id) + + def _make_cleanup_receiver( + self, receiver_id: c.Hashable + ) -> c.Callable[[weakref.ref[c.Callable[..., t.Any]]], None]: + """Create a callback function to disconnect a weakly referenced + receiver when it is garbage collected. + """ + + def cleanup(ref: weakref.ref[c.Callable[..., t.Any]]) -> None: + self._disconnect(receiver_id, ANY_ID) + + return cleanup + + def _make_cleanup_sender( + self, sender_id: c.Hashable + ) -> c.Callable[[weakref.ref[t.Any]], None]: + """Create a callback function to disconnect all receivers for a weakly + referenced sender when it is garbage collected. + """ + assert sender_id != ANY_ID + + def cleanup(ref: weakref.ref[t.Any]) -> None: + self._weak_senders.pop(sender_id, None) + + for receiver_id in self._by_sender.pop(sender_id, ()): + self._by_receiver[receiver_id].discard(sender_id) + + return cleanup + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leaves behind a small amount of bookkeeping + data. Typical workloads using Blinker, for example in most web apps, + Flask, CLI scripts, etc., are not adversely affected by this + bookkeeping. + + With a long-running process performing dynamic signal routing with high + volume, e.g. connecting to function closures, senders are all unique + object instances. Doing all of this over and over may cause memory usage + to grow due to extraneous bookkeeping. (An empty ``set`` for each stale + sender/receiver pair.) + + This method will prune that bookkeeping away, with the caveat that such + pruning is not threadsafe. The risk is that cleanup of a fully + disconnected receiver/sender pair occurs while another thread is + connecting that same pair. If you are in the highly dynamic, unique + receiver/sender situation that has lead you to this method, that failure + mode is perhaps not a big deal for you. + """ + for mapping in (self._by_sender, self._by_receiver): + for ident, bucket in list(mapping.items()): + if not bucket: + mapping.pop(ident, None) + + def _clear_state(self) -> None: + """Disconnect all receivers and senders. Useful for tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +_receiver_connected = Signal( + """\ +Sent by a :class:`Signal` after a receiver connects. + +:argument: the Signal that was connected to +:keyword receiver_arg: the connected receiver +:keyword sender_arg: the sender to connect to +:keyword weak_arg: true if the connection to receiver_arg is a weak reference + +.. deprecated:: 1.2 + Individual signals have their own :attr:`~Signal.receiver_connected` and + :attr:`~Signal.receiver_disconnected` signals with a slightly simplified + call signature. This global signal will be removed in Blinker 1.9. +""" +) + + +class NamedSignal(Signal): + """A named generic notification emitter. The name is not used by the signal + itself, but matches the key in the :class:`Namespace` that it belongs to. + + :param name: The name of the signal within the namespace. + :param doc: The docstring for the signal. + """ + + def __init__(self, name: str, doc: str | None = None) -> None: + super().__init__(doc) + + #: The name of this signal. + self.name: str = name + + def __repr__(self) -> str: + base = super().__repr__() + return f"{base[:-1]}; {self.name!r}>" # noqa: E702 + + +if t.TYPE_CHECKING: + + class PNamespaceSignal(t.Protocol): + def __call__(self, name: str, doc: str | None = None) -> NamedSignal: ... + + # Python < 3.9 + _NamespaceBase = dict[str, NamedSignal] # type: ignore[misc] +else: + _NamespaceBase = dict + + +class Namespace(_NamespaceBase): + """A dict mapping names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` for the given ``name``, creating it + if required. Repeated calls with the same name return the same signal. + + :param name: The name of the signal. + :param doc: The docstring of the signal. + """ + if name not in self: + self[name] = NamedSignal(name, doc) + + return self[name] + + +class _WeakNamespace(WeakValueDictionary): # type: ignore[type-arg] + """A weak mapping of names to signals. + + Automatically cleans up unused signals when the last reference goes out + of scope. This namespace implementation provides similar behavior to Blinker + <= 1.2. + + .. deprecated:: 1.3 + Will be removed in Blinker 1.9. + + .. versionadded:: 1.3 + """ + + def __init__(self) -> None: + warnings.warn( + "'WeakNamespace' is deprecated and will be removed in Blinker 1.9." + " Use 'Namespace' instead.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__() + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` for the given ``name``, creating it + if required. Repeated calls with the same name return the same signal. + + :param name: The name of the signal. + :param doc: The docstring of the signal. + """ + if name not in self: + self[name] = NamedSignal(name, doc) + + return self[name] # type: ignore[no-any-return] + + +default_namespace: Namespace = Namespace() +"""A default :class:`Namespace` for creating named signals. :func:`signal` +creates a :class:`NamedSignal` in this namespace. +""" + +signal: PNamespaceSignal = default_namespace.signal +"""Return a :class:`NamedSignal` in :data:`default_namespace` with the given +``name``, creating it if required. Repeated calls with the same name return the +same signal. +""" + + +def __getattr__(name: str) -> t.Any: + if name == "receiver_connected": + warnings.warn( + "The global 'receiver_connected' signal is deprecated and will be" + " removed in Blinker 1.9. Use 'Signal.receiver_connected' and" + " 'Signal.receiver_disconnected' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _receiver_connected + + if name == "WeakNamespace": + warnings.warn( + "'WeakNamespace' is deprecated and will be removed in Blinker 1.9." + " Use 'Namespace' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _WeakNamespace + + raise AttributeError(name) diff --git a/dist/ba_root/mods/serverData/data.json b/dist/ba_data/python-site-packages/blinker/py.typed similarity index 100% rename from dist/ba_root/mods/serverData/data.json rename to dist/ba_data/python-site-packages/blinker/py.typed diff --git a/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/INSTALLER b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/LICENSE b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/LICENSE new file mode 100644 index 00000000..62b076cd --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/LICENSE @@ -0,0 +1,20 @@ +This package contains a modified version of ca-bundle.crt: + +ca-bundle.crt -- Bundle of CA Root Certificates + +This is a bundle of X.509 certificates of public Certificate Authorities +(CA). These were automatically extracted from Mozilla's root certificates +file (certdata.txt). This file can be found in the mozilla source tree: +https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt +It contains the certificates in PEM format and therefore +can be directly used with curl / libcurl / php_curl, or with +an Apache+mod_ssl webserver for SSL client authentication. +Just configure this file as the SSLCACertificateFile.# + +***** BEGIN LICENSE BLOCK ***** +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain +one at http://mozilla.org/MPL/2.0/. + +***** END LICENSE BLOCK ***** +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/METADATA b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/METADATA new file mode 100644 index 00000000..c688a628 --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/METADATA @@ -0,0 +1,66 @@ +Metadata-Version: 2.1 +Name: certifi +Version: 2024.2.2 +Summary: Python package for providing Mozilla's CA Bundle. +Home-page: https://github.com/certifi/python-certifi +Author: Kenneth Reitz +Author-email: me@kennethreitz.com +License: MPL-2.0 +Project-URL: Source, https://github.com/certifi/python-certifi +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Requires-Python: >=3.6 +License-File: LICENSE + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> import certifi + + >>> certifi.where() + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' + +Or from the command line:: + + $ python -m certifi + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem + +Enjoy! + +.. _`Requests`: https://requests.readthedocs.io/en/master/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. diff --git a/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/RECORD b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/RECORD new file mode 100644 index 00000000..441c836a --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2024.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2024.2.2.dist-info/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989 +certifi-2024.2.2.dist-info/METADATA,sha256=1noreLRChpOgeSj0uJT1mehiBl8ngh33Guc7KdvzYYM,2170 +certifi-2024.2.2.dist-info/RECORD,, +certifi-2024.2.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 +certifi-2024.2.2.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=ljtEx-EmmPpTe2SOd5Kzsujm_lUD0fKJVnE9gzce320,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-312.pyc,, +certifi/__pycache__/__main__.cpython-312.pyc,, +certifi/__pycache__/core.cpython-312.pyc,, +certifi/cacert.pem,sha256=ejR8qP724p-CtuR4U1WmY1wX-nVeCUD2XxWqj8e9f5I,292541 +certifi/core.py,sha256=qRDDFyXVJwTB_EmoGppaXU_R9qCZvhl-EzxPMuV3nTA,4426 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/WHEEL b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/WHEEL new file mode 100644 index 00000000..98c0d20b --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/top_level.txt b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/top_level.txt new file mode 100644 index 00000000..963eac53 --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi-2024.2.2.dist-info/top_level.txt @@ -0,0 +1 @@ +certifi diff --git a/dist/ba_data/python-site-packages/certifi/__init__.py b/dist/ba_data/python-site-packages/certifi/__init__.py index a3546f12..177082e0 100644 --- a/dist/ba_data/python-site-packages/certifi/__init__.py +++ b/dist/ba_data/python-site-packages/certifi/__init__.py @@ -1,4 +1,4 @@ from .core import contents, where __all__ = ["contents", "where"] -__version__ = "2022.12.07" +__version__ = "2025.01.31" diff --git a/dist/ba_data/python-site-packages/certifi/cacert.pem b/dist/ba_data/python-site-packages/certifi/cacert.pem index df9e4e3c..860f259b 100644 --- a/dist/ba_data/python-site-packages/certifi/cacert.pem +++ b/dist/ba_data/python-site-packages/certifi/cacert.pem @@ -245,34 +245,6 @@ mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK 4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 -# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 -# Label: "Security Communication Root CA" -# Serial: 0 -# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a -# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 -# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- - # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Label: "XRamp Global CA Root" @@ -502,47 +474,6 @@ ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- -# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG -# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG -# Label: "SwissSign Silver CA - G2" -# Serial: 5700383053117599563 -# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 -# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb -# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu -IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow -RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY -U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv -Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br -YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF -nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH -6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt -eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ -c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ -MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH -HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf -jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 -5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB -rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c -wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB -AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp -WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 -xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ -2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ -IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 -aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X -em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR -dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ -OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ -hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy -tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- - # Issuer: CN=SecureTrust CA O=SecureTrust Corporation # Subject: CN=SecureTrust CA O=SecureTrust Corporation # Label: "SecureTrust CA" @@ -791,63 +722,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Label: "Hongkong Post Root CA 1" -# Serial: 1000 -# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca -# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 -# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- - -# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. -# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. -# Label: "SecureSign RootCA11" -# Serial: 1 -# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 -# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 -# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr -MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG -A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 -MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp -Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD -QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz -i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 -h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV -MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 -UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni -8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC -h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB -AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm -KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ -X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr -QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 -pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN -QSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - # Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. # Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. # Label: "Microsec e-Szigno Root CA 2009" @@ -909,49 +783,6 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- -# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" -# Serial: 6047274297262753887 -# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 -# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa -# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - # Issuer: CN=Izenpe.com O=IZENPE S.A. # Subject: CN=Izenpe.com O=IZENPE S.A. # Label: "Izenpe.com" @@ -1676,50 +1507,6 @@ HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Label: "E-Tugra Certification Authority" -# Serial: 7667447206703254355 -# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 -# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 -# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - # Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Label: "T-TeleSec GlobalRoot Class 2" @@ -3243,50 +3030,6 @@ LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG mpv0 -----END CERTIFICATE----- -# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only -# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only -# Label: "Entrust Root Certification Authority - G4" -# Serial: 289383649854506086828220374796556676440 -# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 -# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 -# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw -gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL -Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg -MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw -BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 -MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 -c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ -bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ -2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E -T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j -5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM -C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T -DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX -wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A -2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm -nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl -N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj -c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS -5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS -Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr -hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ -B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI -AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw -H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ -b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk -2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol -IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk -5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY -n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- - # Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation # Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation # Label: "Microsoft ECC Root Certificate Authority 2017" @@ -4397,113 +4140,6 @@ ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Label: "E-Tugra Global Root CA RSA v3" -# Serial: 75951268308633135324246244059508261641472512052 -# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4 -# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9 -# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2 ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL -BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt -VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw -JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw -OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG -QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD -QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7 -7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx -uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8 -7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/ -rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL -l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG -wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4 -znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO -M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK -5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH -nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo -DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy -tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL -BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ -6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18 -Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ -3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk -vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9 -9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ -mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA -VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF -9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM -moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8 -bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Label: "E-Tugra Global Root CA ECC v3" -# Serial: 218504919822255052842371958738296604628416471745 -# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64 -# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84 -# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13 ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw -gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn -cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD -VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 -NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r -YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh -IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF -Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ -KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK -fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB -Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C -MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp -ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 -7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx -vmjkI6TZraE3 ------END CERTIFICATE----- - -# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. -# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. -# Label: "Security Communication RootCA3" -# Serial: 16247922307909811815 -# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26 -# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a -# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94 ------BEGIN CERTIFICATE----- -MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV -BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw -JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 -MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg -Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r -CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA -lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG -TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 -9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 -8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 -g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we -GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst -+3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M -0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ -T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw -HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS -YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA -FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd -9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI -UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ -OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke -gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf -iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV -nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD -2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// -1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad -TdJ0MN1kURXbg4NR16/9M51NZg== ------END CERTIFICATE----- - # Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. # Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. # Label: "Security Communication ECC RootCA1" @@ -4525,3 +4161,737 @@ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu 9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= -----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G3" +# Serial: 576386314500428537169965010905813481816650257167 +# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 +# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 +# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM +BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe +Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw +IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU +cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS +T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK +AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 +nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep +qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA +yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs +hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX +zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv +kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT +f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA +uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih +MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 +wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 +XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 +JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j +ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV +VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx +xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on +AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d +7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj +gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV ++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo +FGWsJwt0ivKH +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G4" +# Serial: 451799571007117016466790293371524403291602933463 +# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb +# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a +# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw +WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y +MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD +VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz +dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx +s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw +LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD +pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE +AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR +UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj +/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust ECC Root-01 O=CommScope +# Subject: CN=CommScope Public Trust ECC Root-01 O=CommScope +# Label: "CommScope Public Trust ECC Root-01" +# Serial: 385011430473757362783587124273108818652468453534 +# MD5 Fingerprint: 3a:40:a7:fc:03:8c:9c:38:79:2f:3a:a2:6c:b6:0a:16 +# SHA1 Fingerprint: 07:86:c0:d8:dd:8e:c0:80:98:06:98:d0:58:7a:ef:de:a6:cc:a2:5d +# SHA256 Fingerprint: 11:43:7c:da:7b:b4:5e:41:36:5f:45:b3:9a:38:98:6b:0d:e0:0d:ef:34:8e:0c:7b:b0:87:36:33:80:0b:c3:8b +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw +TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t +bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa +Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv +cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C +flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE +hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq +hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg +2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS +Um9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust ECC Root-02 O=CommScope +# Subject: CN=CommScope Public Trust ECC Root-02 O=CommScope +# Label: "CommScope Public Trust ECC Root-02" +# Serial: 234015080301808452132356021271193974922492992893 +# MD5 Fingerprint: 59:b0:44:d5:65:4d:b8:5c:55:19:92:02:b6:d1:94:b2 +# SHA1 Fingerprint: 3c:3f:ef:57:0f:fe:65:93:86:9e:a0:fe:b0:f6:ed:8e:d1:13:c7:e5 +# SHA256 Fingerprint: 2f:fb:7f:81:3b:bb:b3:c8:9a:b4:e8:16:2d:0f:16:d7:15:09:a8:30:cc:9d:73:c2:62:e5:14:08:75:d1:ad:4a +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw +TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t +bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa +Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv +cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL +j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU +v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq +hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n +ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV +mkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust RSA Root-01 O=CommScope +# Subject: CN=CommScope Public Trust RSA Root-01 O=CommScope +# Label: "CommScope Public Trust RSA Root-01" +# Serial: 354030733275608256394402989253558293562031411421 +# MD5 Fingerprint: 0e:b4:15:bc:87:63:5d:5d:02:73:d4:26:38:68:73:d8 +# SHA1 Fingerprint: 6d:0a:5f:f7:b4:23:06:b4:85:b3:b7:97:64:fc:ac:75:f5:33:f2:93 +# SHA256 Fingerprint: 02:bd:f9:6e:2a:45:dd:9b:f1:8f:c7:e1:db:df:21:a0:37:9b:a3:c9:c2:61:03:44:cf:d8:d6:06:fe:c1:ed:81 +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL +BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi +Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1 +NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t +U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt +MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk +YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh +suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al +DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj +WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl +P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547 +KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p +UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/ +kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO +Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB +Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U +CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ +KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ +nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+ +QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v +trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a +aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD +j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4 +Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w +lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn +YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc +icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust RSA Root-02 O=CommScope +# Subject: CN=CommScope Public Trust RSA Root-02 O=CommScope +# Label: "CommScope Public Trust RSA Root-02" +# Serial: 480062499834624527752716769107743131258796508494 +# MD5 Fingerprint: e1:29:f9:62:7b:76:e2:96:6d:f3:d4:d7:0f:ae:1f:aa +# SHA1 Fingerprint: ea:b0:e2:52:1b:89:93:4c:11:68:f2:d8:9a:ac:22:4c:a3:8a:57:ae +# SHA256 Fingerprint: ff:e9:43:d7:93:42:4b:4f:7c:44:0c:1c:3d:64:8d:53:63:f3:4b:82:dc:87:aa:7a:9f:11:8f:c5:de:e1:01:f1 +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL +BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi +Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2 +NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t +U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt +MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE +NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0 +kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C +rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz +hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2 +LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs +n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku +FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5 +kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3 +wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v +wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs +5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ +KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3 ++VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme +APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq +pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT +6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF +sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt +PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d +lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670 +v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O +rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS ECC Root 2020" +# Serial: 72082518505882327255703894282316633856 +# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd +# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec +# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1 +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw +CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH +bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw +MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx +JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE +AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O +tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP +f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA +MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di +z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn +27iQ7t0l +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS RSA Root 2023" +# Serial: 44676229530606711399881795178081572759 +# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2 +# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93 +# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj +MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0 +eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy +MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC +REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG +A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9 +cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV +cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA +U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6 +Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug +BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy +8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J +co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg +8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8 +rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12 +mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg ++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX +gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ +pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm +9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw +M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd +GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+ +CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t +xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+ +w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK +L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj +X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q +ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm +dTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +# Issuer: CN=FIRMAPROFESIONAL CA ROOT-A WEB O=Firmaprofesional SA +# Subject: CN=FIRMAPROFESIONAL CA ROOT-A WEB O=Firmaprofesional SA +# Label: "FIRMAPROFESIONAL CA ROOT-A WEB" +# Serial: 65916896770016886708751106294915943533 +# MD5 Fingerprint: 82:b2:ad:45:00:82:b0:66:63:f8:5f:c3:67:4e:ce:a3 +# SHA1 Fingerprint: a8:31:11:74:a6:14:15:0d:ca:77:dd:0e:e4:0c:5d:58:fc:a0:72:a5 +# SHA256 Fingerprint: be:f2:56:da:f2:6e:9c:69:bd:ec:16:02:35:97:98:f3:ca:f7:18:21:a0:3e:01:82:57:c5:3c:65:61:7f:3d:4a +-----BEGIN CERTIFICATE----- +MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQsw +CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE +YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB +IFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2WhcNNDcwMzMxMDkwMTM2WjBuMQsw +CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE +YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB +IFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zf +e9MEkVz6iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6C +cyvHZpsKjECcfIr28jlgst7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FDY1w8ndYn81LsF7Kpryz3dvgwHQYDVR0O +BBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO +PQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFw +hVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dG +XSaQpYXFuXqUPoeovQA= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA CYBER Root CA" +# Serial: 85076849864375384482682434040119489222 +# MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51 +# SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66 +# SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58 +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ +MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290 +IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5 +WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO +LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P +40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF +avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/ +34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i +JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu +j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf +Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP +2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA +S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA +oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC +kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW +5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd +BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t +tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn +68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn +TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t +RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx +f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI +Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz +8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4 +NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX +xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6 +t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA12" +# Serial: 587887345431707215246142177076162061960426065942 +# MD5 Fingerprint: c6:89:ca:64:42:9b:62:08:49:0b:1e:7f:e9:07:3d:e8 +# SHA1 Fingerprint: 7a:22:1e:3d:de:1b:06:ac:9e:c8:47:70:16:8e:3c:e5:f7:6b:06:f4 +# SHA256 Fingerprint: 3f:03:4b:b5:70:4d:44:b2:d0:85:45:a0:20:57:de:93:eb:f3:90:5f:ce:72:1a:cb:c7:30:c0:6d:da:ee:90:4e +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgw +NTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3emhF +KxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mt +p7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zd +J1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur +FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4J +hscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+K +h9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsF +AAOCAQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6Ld +mmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJ +mBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA +8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7bgoitPQV +55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/ +yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA14" +# Serial: 575790784512929437950770173562378038616896959179 +# MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5 +# SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f +# SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw +NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/ +FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg +vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy +6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo +/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J +kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ +0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib +y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac +18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs +0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB +SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL +ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk +86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib +ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT +zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS +DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4 +2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo +FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy +K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6 +dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl +Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB +365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c +JRNItX+S +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA15" +# Serial: 126083514594751269499665114766174399806381178503 +# MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47 +# SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d +# SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw +UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM +dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy +NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl +cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290 +IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4 +wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR +ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT +9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp +4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6 +bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 2 2023" +# Serial: 153168538924886464690566649552453098598 +# MD5 Fingerprint: e1:09:ed:d3:60:d4:56:1b:47:1f:b7:0c:5f:1b:5f:85 +# SHA1 Fingerprint: 2d:b0:70:ee:71:94:af:69:68:17:db:79:ce:58:9f:a0:6b:96:f7:87 +# SHA256 Fingerprint: 05:52:e6:f8:3f:df:65:e8:fa:96:70:e6:66:df:28:a4:e2:13:40:b5:10:cb:e5:25:66:f9:7c:4f:b9:4b:2b:d1 +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI +MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE +LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw +OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi +MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr +i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE +gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8 +k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT +Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl +2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U +cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP +/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS +uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+ +0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N +DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+ +XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61 +GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI +FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n +riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR +VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc +LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn +4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD +hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG +koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46 +ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS +Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80 +knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ +hJ65bvspmZDogNOfJA== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 2 2023" +# Serial: 139766439402180512324132425437959641711 +# MD5 Fingerprint: 96:b4:78:09:f0:09:cb:77:eb:bb:1b:4d:6f:36:bc:b6 +# SHA1 Fingerprint: a5:5b:d8:47:6c:8f:19:f7:4c:f4:6d:6b:b6:c2:79:82:22:df:54:8b +# SHA256 Fingerprint: 8e:82:21:b2:e7:d4:00:78:36:a1:67:2f:0d:cc:29:9c:33:bc:07:d3:16:f1:32:fa:1a:20:6d:58:71:50:f1:ce +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI +MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE +LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw +OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi +MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK +F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE +7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe +EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6 +lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb +RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV +jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc +jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx +TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ +ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk +hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF +NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH +kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14 +QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4 +pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q +3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU +t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX +cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8 +ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT +2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs +7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP +gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst +Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh +XBxvWHZks/wCuPWdCg== +-----END CERTIFICATE----- diff --git a/dist/ba_data/python-site-packages/certifi/core.py b/dist/ba_data/python-site-packages/certifi/core.py index de028981..91f538bb 100644 --- a/dist/ba_data/python-site-packages/certifi/core.py +++ b/dist/ba_data/python-site-packages/certifi/core.py @@ -5,6 +5,10 @@ This module returns the installation location of cacert.pem or its contents. """ import sys +import atexit + +def exit_cacert_ctx() -> None: + _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] if sys.version_info >= (3, 11): @@ -35,6 +39,7 @@ def where() -> str: # we will also store that at the global level as well. _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) return _CACERT_PATH @@ -70,6 +75,7 @@ def where() -> str: # we will also store that at the global level as well. _CACERT_CTX = get_path("certifi", "cacert.pem") _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) return _CACERT_PATH diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/INSTALLER b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/LICENSE b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/LICENSE new file mode 100644 index 00000000..29225eee --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/LICENSE @@ -0,0 +1,26 @@ + +Except when otherwise stated (look for LICENSE files in directories or +information at the beginning of each file) all software and +documentation is licensed as follows: + + 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. + diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/METADATA b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/METADATA new file mode 100644 index 00000000..f582bfbb --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/METADATA @@ -0,0 +1,39 @@ +Metadata-Version: 2.1 +Name: cffi +Version: 1.16.0 +Summary: Foreign Function Interface for Python calling C code. +Home-page: http://cffi.readthedocs.org +Author: Armin Rigo, Maciej Fijalkowski +Author-email: python-cffi@googlegroups.com +License: MIT +Project-URL: Documentation, http://cffi.readthedocs.org/ +Project-URL: Source Code, https://github.com/python-cffi/cffi +Project-URL: Issue Tracker, https://github.com/python-cffi/cffi/issues +Project-URL: Changelog, https://cffi.readthedocs.io/en/latest/whatsnew.html +Project-URL: Downloads, https://github.com/python-cffi/cffi/releases +Project-URL: Contact, https://groups.google.com/forum/#!forum/python-cffi +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: License :: OSI Approved :: MIT License +Requires-Python: >=3.8 +License-File: LICENSE +Requires-Dist: pycparser + + +CFFI +==== + +Foreign Function Interface for Python calling C code. +Please see the `Documentation `_. + +Contact +------- + +`Mailing list `_ diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/RECORD b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/RECORD new file mode 100644 index 00000000..09056eff --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/RECORD @@ -0,0 +1,48 @@ +_cffi_backend.cpython-312-x86_64-linux-gnu.so,sha256=l3iV6kXpmZSbtiI41QmT1aPg8leJ5Pulx6H-S2qYmyU,1109504 +cffi-1.16.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +cffi-1.16.0.dist-info/LICENSE,sha256=BLgPWwd7vtaICM_rreteNSPyqMmpZJXFh72W3x6sKjM,1294 +cffi-1.16.0.dist-info/METADATA,sha256=qOBI2i0qSlLOKwmzNjbJfLmrTzHV_JFS7uKbcFj_p9Y,1480 +cffi-1.16.0.dist-info/RECORD,, +cffi-1.16.0.dist-info/WHEEL,sha256=4ZiCdXIWMxJyEClivrQv1QAHZpQh8kVYU92_ZAVwaok,152 +cffi-1.16.0.dist-info/entry_points.txt,sha256=y6jTxnyeuLnL-XJcDv8uML3n6wyYiGRg8MTp_QGJ9Ho,75 +cffi-1.16.0.dist-info/top_level.txt,sha256=rE7WR3rZfNKxWI9-jn6hsHCAl7MDkB-FmuQbxWjFehQ,19 +cffi/__init__.py,sha256=uEnzaXlQndR9nc8ar1qk6_coNEfxfn4pA0sWPVg2MP8,513 +cffi/__pycache__/__init__.cpython-312.pyc,, +cffi/__pycache__/_imp_emulation.cpython-312.pyc,, +cffi/__pycache__/_shimmed_dist_utils.cpython-312.pyc,, +cffi/__pycache__/api.cpython-312.pyc,, +cffi/__pycache__/backend_ctypes.cpython-312.pyc,, +cffi/__pycache__/cffi_opcode.cpython-312.pyc,, +cffi/__pycache__/commontypes.cpython-312.pyc,, +cffi/__pycache__/cparser.cpython-312.pyc,, +cffi/__pycache__/error.cpython-312.pyc,, +cffi/__pycache__/ffiplatform.cpython-312.pyc,, +cffi/__pycache__/lock.cpython-312.pyc,, +cffi/__pycache__/model.cpython-312.pyc,, +cffi/__pycache__/pkgconfig.cpython-312.pyc,, +cffi/__pycache__/recompiler.cpython-312.pyc,, +cffi/__pycache__/setuptools_ext.cpython-312.pyc,, +cffi/__pycache__/vengine_cpy.cpython-312.pyc,, +cffi/__pycache__/vengine_gen.cpython-312.pyc,, +cffi/__pycache__/verifier.cpython-312.pyc,, +cffi/_cffi_errors.h,sha256=zQXt7uR_m8gUW-fI2hJg0KoSkJFwXv8RGUkEDZ177dQ,3908 +cffi/_cffi_include.h,sha256=tKnA1rdSoPHp23FnDL1mDGwFo-Uj6fXfA6vA6kcoEUc,14800 +cffi/_embedding.h,sha256=QEmrJKlB_W2VC601CjjyfMuxtgzPQwwEKFlwMCGHbT0,18787 +cffi/_imp_emulation.py,sha256=RxREG8zAbI2RPGBww90u_5fi8sWdahpdipOoPzkp7C0,2960 +cffi/_shimmed_dist_utils.py,sha256=mLuEtxw4gbuA2De_gD7zEhb6Q8Wm2lBPtwC68gd9XTs,2007 +cffi/api.py,sha256=wtJU0aGUC3TyYnjBIgsOIlv7drF19jV-y_srt7c8yhg,42085 +cffi/backend_ctypes.py,sha256=h5ZIzLc6BFVXnGyc9xPqZWUS7qGy7yFSDqXe68Sa8z4,42454 +cffi/cffi_opcode.py,sha256=v9RdD_ovA8rCtqsC95Ivki5V667rAOhGgs3fb2q9xpM,5724 +cffi/commontypes.py,sha256=QS4uxCDI7JhtTyjh1hlnCA-gynmaszWxJaRRLGkJa1A,2689 +cffi/cparser.py,sha256=rO_1pELRw1gI1DE1m4gi2ik5JMfpxouAACLXpRPlVEA,44231 +cffi/error.py,sha256=v6xTiS4U0kvDcy4h_BDRo5v39ZQuj-IMRYLv5ETddZs,877 +cffi/ffiplatform.py,sha256=avxFjdikYGJoEtmJO7ewVmwG_VEVl6EZ_WaNhZYCqv4,3584 +cffi/lock.py,sha256=l9TTdwMIMpi6jDkJGnQgE9cvTIR7CAntIJr8EGHt3pY,747 +cffi/model.py,sha256=RVsAb3h_u7VHWZJ-J_Z4kvB36pFyFG_MVIjPOQ8YhQ8,21790 +cffi/parse_c_type.h,sha256=OdwQfwM9ktq6vlCB43exFQmxDBtj2MBNdK8LYl15tjw,5976 +cffi/pkgconfig.py,sha256=LP1w7vmWvmKwyqLaU1Z243FOWGNQMrgMUZrvgFuOlco,4374 +cffi/recompiler.py,sha256=oTusgKQ02YY6LXhcmWcqpIlPrG178RMXXSBseSACRgg,64601 +cffi/setuptools_ext.py,sha256=-ebj79lO2_AUH-kRcaja2pKY1Z_5tloGwsJgzK8P3Cc,8871 +cffi/vengine_cpy.py,sha256=nK_im1DbdIGMMgxFgeo1MndFjaB-Qlkc2ZYlSquLjs0,43351 +cffi/vengine_gen.py,sha256=5dX7s1DU6pTBOMI6oTVn_8Bnmru_lj932B6b4v29Hlg,26684 +cffi/verifier.py,sha256=oX8jpaohg2Qm3aHcznidAdvrVm5N4sQYG0a3Eo5mIl4,11182 diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/WHEEL b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/WHEEL new file mode 100644 index 00000000..d1b3f1da --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: false +Tag: cp312-cp312-manylinux_2_17_x86_64 +Tag: cp312-cp312-manylinux2014_x86_64 + diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/entry_points.txt b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/entry_points.txt new file mode 100644 index 00000000..4b0274f2 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[distutils.setup_keywords] +cffi_modules = cffi.setuptools_ext:cffi_modules diff --git a/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/top_level.txt b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/top_level.txt new file mode 100644 index 00000000..f6457795 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi-1.16.0.dist-info/top_level.txt @@ -0,0 +1,2 @@ +_cffi_backend +cffi diff --git a/dist/ba_data/python-site-packages/cffi.libs/libffi-2a6f5b63.so.8.1.0 b/dist/ba_data/python-site-packages/cffi.libs/libffi-2a6f5b63.so.8.1.0 deleted file mode 100644 index 81b2c133..00000000 Binary files a/dist/ba_data/python-site-packages/cffi.libs/libffi-2a6f5b63.so.8.1.0 and /dev/null differ diff --git a/dist/ba_data/python-site-packages/cffi/__init__.py b/dist/ba_data/python-site-packages/cffi/__init__.py index 90e2e655..90dedf43 100644 --- a/dist/ba_data/python-site-packages/cffi/__init__.py +++ b/dist/ba_data/python-site-packages/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.15.1" -__version_info__ = (1, 15, 1) +__version__ = "1.16.0" +__version_info__ = (1, 16, 0) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/dist/ba_data/python-site-packages/cffi/_embedding.h b/dist/ba_data/python-site-packages/cffi/_embedding.h index 8e8df882..1cb66f23 100644 --- a/dist/ba_data/python-site-packages/cffi/_embedding.h +++ b/dist/ba_data/python-site-packages/cffi/_embedding.h @@ -225,7 +225,7 @@ static int _cffi_initialize_python(void) if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.15.1" + "\ncompiled with cffi version: 1.16.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); @@ -283,6 +283,15 @@ static int _cffi_carefully_make_gil(void) Python < 3.8 because someone might use a mixture of cffi embedded modules, some of which were compiled before this file changed. + + In Python >= 3.12, this stopped working because that particular + tp_version_tag gets modified during interpreter startup. It's + arguably a bad idea before 3.12 too, but again we can't change + that because someone might use a mixture of cffi embedded + modules, and no-one reported a bug so far. In Python >= 3.12 + we go instead for PyCapsuleType.tp_as_buffer, which is supposed + to always be NULL. We write to it temporarily a pointer to + a struct full of NULLs, which is semantically the same. */ #ifdef WITH_THREAD @@ -307,19 +316,32 @@ static int _cffi_carefully_make_gil(void) } } # else +# if PY_VERSION_HEX < 0x030C0000 int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; - int old_value, locked_value; + int old_value, locked_value = -42; assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); +# else + static struct ebp_s { PyBufferProcs buf; int mark; } empty_buffer_procs; + empty_buffer_procs.mark = -42; + PyBufferProcs *volatile *lock = (PyBufferProcs *volatile *) + &PyCapsule_Type.tp_as_buffer; + PyBufferProcs *old_value, *locked_value = &empty_buffer_procs.buf; +# endif while (1) { /* spin loop */ old_value = *lock; - locked_value = -42; if (old_value == 0) { if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { +# if PY_VERSION_HEX < 0x030C0000 assert(old_value == locked_value); +# else + /* The pointer should point to a possibly different + empty_buffer_procs from another C extension module */ + assert(((struct ebp_s *)old_value)->mark == -42); +# endif /* should ideally do a spin loop instruction here, but hard to do it portably and doesn't really matter I think: PyEval_InitThreads() should be very fast, and diff --git a/dist/ba_data/python-site-packages/cffi/_imp_emulation.py b/dist/ba_data/python-site-packages/cffi/_imp_emulation.py new file mode 100644 index 00000000..136abddd --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/_imp_emulation.py @@ -0,0 +1,83 @@ + +try: + # this works on Python < 3.12 + from imp import * + +except ImportError: + # this is a limited emulation for Python >= 3.12. + # Note that this is used only for tests or for the old ffi.verify(). + # This is copied from the source code of Python 3.11. + + from _imp import (acquire_lock, release_lock, + is_builtin, is_frozen) + + from importlib._bootstrap import _load + + from importlib import machinery + import os + import sys + import tokenize + + SEARCH_ERROR = 0 + PY_SOURCE = 1 + PY_COMPILED = 2 + C_EXTENSION = 3 + PY_RESOURCE = 4 + PKG_DIRECTORY = 5 + C_BUILTIN = 6 + PY_FROZEN = 7 + PY_CODERESOURCE = 8 + IMP_HOOK = 9 + + def get_suffixes(): + extensions = [(s, 'rb', C_EXTENSION) + for s in machinery.EXTENSION_SUFFIXES] + source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] + bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES] + return extensions + source + bytecode + + def find_module(name, path=None): + if not isinstance(name, str): + raise TypeError("'name' must be a str, not {}".format(type(name))) + elif not isinstance(path, (type(None), list)): + # Backwards-compatibility + raise RuntimeError("'path' must be None or a list, " + "not {}".format(type(path))) + + if path is None: + if is_builtin(name): + return None, None, ('', '', C_BUILTIN) + elif is_frozen(name): + return None, None, ('', '', PY_FROZEN) + else: + path = sys.path + + for entry in path: + package_directory = os.path.join(entry, name) + for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]: + package_file_name = '__init__' + suffix + file_path = os.path.join(package_directory, package_file_name) + if os.path.isfile(file_path): + return None, package_directory, ('', '', PKG_DIRECTORY) + for suffix, mode, type_ in get_suffixes(): + file_name = name + suffix + file_path = os.path.join(entry, file_name) + if os.path.isfile(file_path): + break + else: + continue + break # Break out of outer loop when breaking out of inner loop. + else: + raise ImportError(name, name=name) + + encoding = None + if 'b' not in mode: + with open(file_path, 'rb') as file: + encoding = tokenize.detect_encoding(file.readline)[0] + file = open(file_path, mode, encoding=encoding) + return file, file_path, (suffix, mode, type_) + + def load_dynamic(name, path, file=None): + loader = machinery.ExtensionFileLoader(name, path) + spec = machinery.ModuleSpec(name=name, loader=loader, origin=path) + return _load(spec) diff --git a/dist/ba_data/python-site-packages/cffi/_shimmed_dist_utils.py b/dist/ba_data/python-site-packages/cffi/_shimmed_dist_utils.py new file mode 100644 index 00000000..611bf40f --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/_shimmed_dist_utils.py @@ -0,0 +1,41 @@ +""" +Temporary shim module to indirect the bits of distutils we need from setuptools/distutils while providing useful +error messages beyond `No module named 'distutils' on Python >= 3.12, or when setuptools' vendored distutils is broken. + +This is a compromise to avoid a hard-dep on setuptools for Python >= 3.12, since many users don't need runtime compilation support from CFFI. +""" +import sys + +try: + # import setuptools first; this is the most robust way to ensure its embedded distutils is available + # (the .pth shim should usually work, but this is even more robust) + import setuptools +except Exception as ex: + if sys.version_info >= (3, 12): + # Python 3.12 has no built-in distutils to fall back on, so any import problem is fatal + raise Exception("This CFFI feature requires setuptools on Python >= 3.12. The setuptools module is missing or non-functional.") from ex + + # silently ignore on older Pythons (support fallback to stdlib distutils where available) +else: + del setuptools + +try: + # bring in just the bits of distutils we need, whether they really came from setuptools or stdlib-embedded distutils + from distutils import log, sysconfig + from distutils.ccompiler import CCompiler + from distutils.command.build_ext import build_ext + from distutils.core import Distribution, Extension + from distutils.dir_util import mkpath + from distutils.errors import DistutilsSetupError, CompileError, LinkError + from distutils.log import set_threshold, set_verbosity + + if sys.platform == 'win32': + from distutils.msvc9compiler import MSVCCompiler +except Exception as ex: + if sys.version_info >= (3, 12): + raise Exception("This CFFI feature requires setuptools on Python >= 3.12. Please install the setuptools package.") from ex + + # anything older, just let the underlying distutils import error fly + raise Exception("This CFFI feature requires distutils. Please install the distutils or setuptools package.") from ex + +del sys diff --git a/dist/ba_data/python-site-packages/cffi/api.py b/dist/ba_data/python-site-packages/cffi/api.py index 999a8aef..edeb7928 100644 --- a/dist/ba_data/python-site-packages/cffi/api.py +++ b/dist/ba_data/python-site-packages/cffi/api.py @@ -622,7 +622,7 @@ def ensure(key, value): try: import sysconfig except ImportError: # 2.6 - from distutils import sysconfig + from cffi._shimmed_dist_utils import sysconfig template = "python%d.%d" if sysconfig.get_config_var('DEBUG_EXT'): template += sysconfig.get_config_var('DEBUG_EXT') @@ -658,7 +658,7 @@ def set_source_pkgconfig(self, module_name, pkgconfig_libs, source, self.set_source(module_name, source, source_extension, **kwds) def distutils_extension(self, tmpdir='build', verbose=True): - from distutils.dir_util import mkpath + from cffi._shimmed_dist_utils import mkpath from .recompiler import recompile # if not hasattr(self, '_assigned_source'): diff --git a/dist/ba_data/python-site-packages/cffi/ffiplatform.py b/dist/ba_data/python-site-packages/cffi/ffiplatform.py index 85313460..adca28f1 100644 --- a/dist/ba_data/python-site-packages/cffi/ffiplatform.py +++ b/dist/ba_data/python-site-packages/cffi/ffiplatform.py @@ -6,8 +6,7 @@ 'extra_objects', 'depends'] def get_extension(srcfilename, modname, sources=(), **kwds): - _hack_at_distutils() - from distutils.core import Extension + from cffi._shimmed_dist_utils import Extension allsources = [srcfilename] for src in sources: allsources.append(os.path.normpath(src)) @@ -16,7 +15,6 @@ def get_extension(srcfilename, modname, sources=(), **kwds): def compile(tmpdir, ext, compiler_verbose=0, debug=None): """Compile a C extension module using distutils.""" - _hack_at_distutils() saved_environ = os.environ.copy() try: outputfilename = _build(tmpdir, ext, compiler_verbose, debug) @@ -31,9 +29,8 @@ def compile(tmpdir, ext, compiler_verbose=0, debug=None): def _build(tmpdir, ext, compiler_verbose=0, debug=None): # XXX compact but horrible :-( - from distutils.core import Distribution - import distutils.errors, distutils.log - # + from cffi._shimmed_dist_utils import Distribution, CompileError, LinkError, set_threshold, set_verbosity + dist = Distribution({'ext_modules': [ext]}) dist.parse_config_files() options = dist.get_option_dict('build_ext') @@ -45,16 +42,15 @@ def _build(tmpdir, ext, compiler_verbose=0, debug=None): options['build_temp'] = ('ffiplatform', tmpdir) # try: - old_level = distutils.log.set_threshold(0) or 0 + old_level = set_threshold(0) or 0 try: - distutils.log.set_verbosity(compiler_verbose) + set_verbosity(compiler_verbose) dist.run_command('build_ext') cmd_obj = dist.get_command_obj('build_ext') [soname] = cmd_obj.get_outputs() finally: - distutils.log.set_threshold(old_level) - except (distutils.errors.CompileError, - distutils.errors.LinkError) as e: + set_threshold(old_level) + except (CompileError, LinkError) as e: raise VerificationError('%s: %s' % (e.__class__.__name__, e)) # return soname @@ -115,13 +111,3 @@ def flatten(x): f = cStringIO.StringIO() _flatten(x, f) return f.getvalue() - -def _hack_at_distutils(): - # Windows-only workaround for some configurations: see - # https://bugs.python.org/issue23246 (Python 2.7 with - # a specific MS compiler suite download) - if sys.platform == "win32": - try: - import setuptools # for side-effects, patches distutils - except ImportError: - pass diff --git a/dist/ba_data/python-site-packages/cffi/model.py b/dist/ba_data/python-site-packages/cffi/model.py index ad1c1764..1708f43d 100644 --- a/dist/ba_data/python-site-packages/cffi/model.py +++ b/dist/ba_data/python-site-packages/cffi/model.py @@ -264,9 +264,10 @@ class PointerType(BaseType): def __init__(self, totype, quals=0): self.totype = totype self.quals = quals - extra = qualify(quals, " *&") + extra = " *&" if totype.is_array_type: extra = "(%s)" % (extra.lstrip(),) + extra = qualify(quals, extra) self.c_name_with_marker = totype.c_name_with_marker.replace('&', extra) def build_backend_type(self, ffi, finishlist): diff --git a/dist/ba_data/python-site-packages/cffi/recompiler.py b/dist/ba_data/python-site-packages/cffi/recompiler.py index 5d9d32d7..4167bc05 100644 --- a/dist/ba_data/python-site-packages/cffi/recompiler.py +++ b/dist/ba_data/python-site-packages/cffi/recompiler.py @@ -1483,13 +1483,13 @@ def _unpatch_meths(patchlist): def _patch_for_embedding(patchlist): if sys.platform == 'win32': # we must not remove the manifest when building for embedding! - from distutils.msvc9compiler import MSVCCompiler + from cffi._shimmed_dist_utils import MSVCCompiler _patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref', lambda self, manifest_file: manifest_file) if sys.platform == 'darwin': # we must not make a '-bundle', but a '-dynamiclib' instead - from distutils.ccompiler import CCompiler + from cffi._shimmed_dist_utils import CCompiler def my_link_shared_object(self, *args, **kwds): if '-bundle' in self.linker_so: self.linker_so = list(self.linker_so) @@ -1501,7 +1501,7 @@ def my_link_shared_object(self, *args, **kwds): my_link_shared_object) def _patch_for_target(patchlist, target): - from distutils.command.build_ext import build_ext + from cffi._shimmed_dist_utils import build_ext # if 'target' is different from '*', we need to patch some internal # method to just return this 'target' value, instead of having it # built from module_name diff --git a/dist/ba_data/python-site-packages/cffi/setuptools_ext.py b/dist/ba_data/python-site-packages/cffi/setuptools_ext.py index 8fe36148..681b49d7 100644 --- a/dist/ba_data/python-site-packages/cffi/setuptools_ext.py +++ b/dist/ba_data/python-site-packages/cffi/setuptools_ext.py @@ -8,7 +8,7 @@ basestring = str def error(msg): - from distutils.errors import DistutilsSetupError + from cffi._shimmed_dist_utils import DistutilsSetupError raise DistutilsSetupError(msg) @@ -104,11 +104,9 @@ def _set_py_limited_api(Extension, kwds): return kwds def _add_c_module(dist, ffi, module_name, source, source_extension, kwds): - from distutils.core import Extension # We are a setuptools extension. Need this build_ext for py_limited_api. from setuptools.command.build_ext import build_ext - from distutils.dir_util import mkpath - from distutils import log + from cffi._shimmed_dist_utils import Extension, log, mkpath from cffi import recompiler allsources = ['$PLACEHOLDER'] @@ -150,10 +148,9 @@ def run(self): def _add_py_module(dist, ffi, module_name): - from distutils.dir_util import mkpath from setuptools.command.build_py import build_py from setuptools.command.build_ext import build_ext - from distutils import log + from cffi._shimmed_dist_utils import log, mkpath from cffi import recompiler def generate_mod(py_file): diff --git a/dist/ba_data/python-site-packages/cffi/vengine_cpy.py b/dist/ba_data/python-site-packages/cffi/vengine_cpy.py index 6de0df0e..49727d36 100644 --- a/dist/ba_data/python-site-packages/cffi/vengine_cpy.py +++ b/dist/ba_data/python-site-packages/cffi/vengine_cpy.py @@ -1,9 +1,10 @@ # # DEPRECATED: implementation for ffi.verify() # -import sys, imp +import sys from . import model from .error import VerificationError +from . import _imp_emulation as imp class VCPythonEngine(object): diff --git a/dist/ba_data/python-site-packages/cffi/verifier.py b/dist/ba_data/python-site-packages/cffi/verifier.py index a500c781..e392a2b7 100644 --- a/dist/ba_data/python-site-packages/cffi/verifier.py +++ b/dist/ba_data/python-site-packages/cffi/verifier.py @@ -117,7 +117,6 @@ def get_module_name(self): return basename def get_extension(self): - ffiplatform._hack_at_distutils() # backward compatibility hack if not self._has_source: with self.ffi._lock: if not self._has_source: diff --git a/dist/ba_data/python-site-packages/chardet/__init__.py b/dist/ba_data/python-site-packages/chardet/__init__.py deleted file mode 100644 index 80ad2546..00000000 --- a/dist/ba_data/python-site-packages/chardet/__init__.py +++ /dev/null @@ -1,83 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - - -from .universaldetector import UniversalDetector -from .enums import InputState -from .version import __version__, VERSION - - -__all__ = ['UniversalDetector', 'detect', 'detect_all', '__version__', 'VERSION'] - - -def detect(byte_str): - """ - Detect the encoding of the given byte string. - - :param byte_str: The byte sequence to examine. - :type byte_str: ``bytes`` or ``bytearray`` - """ - if not isinstance(byte_str, bytearray): - if not isinstance(byte_str, bytes): - raise TypeError('Expected object of type bytes or bytearray, got: ' - '{}'.format(type(byte_str))) - else: - byte_str = bytearray(byte_str) - detector = UniversalDetector() - detector.feed(byte_str) - return detector.close() - - -def detect_all(byte_str): - """ - Detect all the possible encodings of the given byte string. - - :param byte_str: The byte sequence to examine. - :type byte_str: ``bytes`` or ``bytearray`` - """ - if not isinstance(byte_str, bytearray): - if not isinstance(byte_str, bytes): - raise TypeError('Expected object of type bytes or bytearray, got: ' - '{}'.format(type(byte_str))) - else: - byte_str = bytearray(byte_str) - - detector = UniversalDetector() - detector.feed(byte_str) - detector.close() - - if detector._input_state == InputState.HIGH_BYTE: - results = [] - for prober in detector._charset_probers: - if prober.get_confidence() > detector.MINIMUM_THRESHOLD: - charset_name = prober.charset_name - lower_charset_name = prober.charset_name.lower() - # Use Windows encoding name instead of ISO-8859 if we saw any - # extra Windows-specific bytes - if lower_charset_name.startswith('iso-8859'): - if detector._has_win_bytes: - charset_name = detector.ISO_WIN_MAP.get(lower_charset_name, - charset_name) - results.append({ - 'encoding': charset_name, - 'confidence': prober.get_confidence(), - 'language': prober.language, - }) - if len(results) > 0: - return sorted(results, key=lambda result: -result['confidence']) - - return [detector.result] diff --git a/dist/ba_data/python-site-packages/chardet/big5freq.py b/dist/ba_data/python-site-packages/chardet/big5freq.py deleted file mode 100644 index 38f32517..00000000 --- a/dist/ba_data/python-site-packages/chardet/big5freq.py +++ /dev/null @@ -1,386 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# Big5 frequency table -# by Taiwan's Mandarin Promotion Council -# -# -# 128 --> 0.42261 -# 256 --> 0.57851 -# 512 --> 0.74851 -# 1024 --> 0.89384 -# 2048 --> 0.97583 -# -# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 -# Random Distribution Ration = 512/(5401-512)=0.105 -# -# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR - -BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 - -#Char to FreqOrder table -BIG5_TABLE_SIZE = 5376 - -BIG5_CHAR_TO_FREQ_ORDER = ( - 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 -3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 -1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 - 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 -3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 -4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 -5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 - 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 - 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 - 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 -2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 -1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 -3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 - 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 -1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 -3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 -2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 - 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 -3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 -1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 -5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 - 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 -5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 -1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 - 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 - 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 -3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 -3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 - 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 -2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 -2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 - 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 - 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 -3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 -1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 -1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 -1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 -2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 - 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 -4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 -1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 -5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 -2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 - 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 - 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 - 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 - 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 -5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 - 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 -1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 - 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 - 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 -5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 -1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 - 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 -3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 -4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 -3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 - 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 - 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 -1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 -4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 -3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 -3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 -2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 -5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 -3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 -5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 -1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 -2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 -1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 - 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 -1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 -4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 -3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 - 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 - 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 - 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 -2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 -5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 -1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 -2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 -1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 -1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 -5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 -5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 -5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 -3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 -4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 -4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 -2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 -5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 -3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 - 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 -5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 -5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 -1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 -2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 -3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 -4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 -5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 -3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 -4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 -1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 -1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 -4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 -1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 - 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 -1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 -1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 -3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 - 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 -5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 -2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 -1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 -1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 -5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 - 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 -4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 - 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 -2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 - 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 -1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 -1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 - 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 -4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 -4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 -1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 -3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 -5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 -5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 -1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 -2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 -1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 -3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 -2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 -3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 -2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 -4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 -4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 -3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 - 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 -3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 - 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 -3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 -4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 -3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 -1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 -5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 - 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 -5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 -1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 - 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 -4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 -4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 - 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 -2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 -2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 -3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 -1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 -4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 -2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 -1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 -1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 -2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 -3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 -1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 -5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 -1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 -4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 -1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 - 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 -1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 -4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 -4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 -2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 -1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 -4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 - 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 -5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 -2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 -3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 -4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 - 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 -5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 -5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 -1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 -4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 -4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 -2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 -3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 -3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 -2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 -1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 -4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 -3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 -3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 -2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 -4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 -5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 -3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 -2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 -3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 -1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 -2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 -3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 -4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 -2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 -2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 -5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 -1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 -2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 -1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 -3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 -4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 -2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 -3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 -3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 -2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 -4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 -2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 -3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 -4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 -5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 -3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 - 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 -1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 -4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 -1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 -4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 -5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 - 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 -5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 -5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 -2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 -3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 -2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 -2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 - 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 -1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 -4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 -3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 -3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 - 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 -2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 - 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 -2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 -4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 -1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 -4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 -1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 -3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 - 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 -3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 -5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 -5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 -3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 -3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 -1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 -2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 -5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 -1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 -1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 -3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 - 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 -1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 -4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 -5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 -2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 -3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 - 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 -1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 -2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 -2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 -5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 -5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 -5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 -2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 -2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 -1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 -4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 -3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 -3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 -4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 -4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 -2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 -2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 -5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 -4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 -5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 -4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 - 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 - 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 -1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 -3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 -4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 -1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 -5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 -2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 -2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 -3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 -5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 -1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 -3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 -5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 -1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 -5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 -2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 -3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 -2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 -3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 -3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 -3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 -4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 - 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 -2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 -4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 -3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 -5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 -1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 -5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 - 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 -1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 - 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 -4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 -1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 -4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 -1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 - 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 -3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 -4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 -5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 - 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 -3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 - 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 -2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 -) - diff --git a/dist/ba_data/python-site-packages/chardet/big5prober.py b/dist/ba_data/python-site-packages/chardet/big5prober.py deleted file mode 100644 index 98f99701..00000000 --- a/dist/ba_data/python-site-packages/chardet/big5prober.py +++ /dev/null @@ -1,47 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import Big5DistributionAnalysis -from .mbcssm import BIG5_SM_MODEL - - -class Big5Prober(MultiByteCharSetProber): - def __init__(self): - super(Big5Prober, self).__init__() - self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) - self.distribution_analyzer = Big5DistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "Big5" - - @property - def language(self): - return "Chinese" diff --git a/dist/ba_data/python-site-packages/chardet/chardistribution.py b/dist/ba_data/python-site-packages/chardet/chardistribution.py deleted file mode 100644 index c0395f4a..00000000 --- a/dist/ba_data/python-site-packages/chardet/chardistribution.py +++ /dev/null @@ -1,233 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, - EUCTW_TYPICAL_DISTRIBUTION_RATIO) -from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, - EUCKR_TYPICAL_DISTRIBUTION_RATIO) -from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, - GB2312_TYPICAL_DISTRIBUTION_RATIO) -from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, - BIG5_TYPICAL_DISTRIBUTION_RATIO) -from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, - JIS_TYPICAL_DISTRIBUTION_RATIO) - - -class CharDistributionAnalysis(object): - ENOUGH_DATA_THRESHOLD = 1024 - SURE_YES = 0.99 - SURE_NO = 0.01 - MINIMUM_DATA_THRESHOLD = 3 - - def __init__(self): - # Mapping table to get frequency order from char order (get from - # GetOrder()) - self._char_to_freq_order = None - self._table_size = None # Size of above table - # This is a constant value which varies from language to language, - # used in calculating confidence. See - # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html - # for further detail. - self.typical_distribution_ratio = None - self._done = None - self._total_chars = None - self._freq_chars = None - self.reset() - - def reset(self): - """reset analyser, clear any state""" - # If this flag is set to True, detection is done and conclusion has - # been made - self._done = False - self._total_chars = 0 # Total characters encountered - # The number of characters whose frequency order is less than 512 - self._freq_chars = 0 - - def feed(self, char, char_len): - """feed a character with known length""" - if char_len == 2: - # we only care about 2-bytes character in our distribution analysis - order = self.get_order(char) - else: - order = -1 - if order >= 0: - self._total_chars += 1 - # order is valid - if order < self._table_size: - if 512 > self._char_to_freq_order[order]: - self._freq_chars += 1 - - def get_confidence(self): - """return confidence based on existing data""" - # if we didn't receive any character in our consideration range, - # return negative answer - if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: - return self.SURE_NO - - if self._total_chars != self._freq_chars: - r = (self._freq_chars / ((self._total_chars - self._freq_chars) - * self.typical_distribution_ratio)) - if r < self.SURE_YES: - return r - - # normalize confidence (we don't want to be 100% sure) - return self.SURE_YES - - def got_enough_data(self): - # It is not necessary to receive all data to draw conclusion. - # For charset detection, certain amount of data is enough - return self._total_chars > self.ENOUGH_DATA_THRESHOLD - - def get_order(self, byte_str): - # We do not handle characters based on the original encoding string, - # but convert this encoding string to a number, here called order. - # This allows multiple encodings of a language to share one frequency - # table. - return -1 - - -class EUCTWDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(EUCTWDistributionAnalysis, self).__init__() - self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER - self._table_size = EUCTW_TABLE_SIZE - self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for euc-TW encoding, we are interested - # first byte range: 0xc4 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char = byte_str[0] - if first_char >= 0xC4: - return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 - else: - return -1 - - -class EUCKRDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(EUCKRDistributionAnalysis, self).__init__() - self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER - self._table_size = EUCKR_TABLE_SIZE - self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for euc-KR encoding, we are interested - # first byte range: 0xb0 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char = byte_str[0] - if first_char >= 0xB0: - return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 - else: - return -1 - - -class GB2312DistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(GB2312DistributionAnalysis, self).__init__() - self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER - self._table_size = GB2312_TABLE_SIZE - self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for GB2312 encoding, we are interested - # first byte range: 0xb0 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char, second_char = byte_str[0], byte_str[1] - if (first_char >= 0xB0) and (second_char >= 0xA1): - return 94 * (first_char - 0xB0) + second_char - 0xA1 - else: - return -1 - - -class Big5DistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(Big5DistributionAnalysis, self).__init__() - self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER - self._table_size = BIG5_TABLE_SIZE - self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for big5 encoding, we are interested - # first byte range: 0xa4 -- 0xfe - # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char, second_char = byte_str[0], byte_str[1] - if first_char >= 0xA4: - if second_char >= 0xA1: - return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 - else: - return 157 * (first_char - 0xA4) + second_char - 0x40 - else: - return -1 - - -class SJISDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(SJISDistributionAnalysis, self).__init__() - self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER - self._table_size = JIS_TABLE_SIZE - self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for sjis encoding, we are interested - # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe - # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe - # no validation needed here. State machine has done that - first_char, second_char = byte_str[0], byte_str[1] - if (first_char >= 0x81) and (first_char <= 0x9F): - order = 188 * (first_char - 0x81) - elif (first_char >= 0xE0) and (first_char <= 0xEF): - order = 188 * (first_char - 0xE0 + 31) - else: - return -1 - order = order + second_char - 0x40 - if second_char > 0x7F: - order = -1 - return order - - -class EUCJPDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(EUCJPDistributionAnalysis, self).__init__() - self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER - self._table_size = JIS_TABLE_SIZE - self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for euc-JP encoding, we are interested - # first byte range: 0xa0 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - char = byte_str[0] - if char >= 0xA0: - return 94 * (char - 0xA1) + byte_str[1] - 0xa1 - else: - return -1 diff --git a/dist/ba_data/python-site-packages/chardet/charsetgroupprober.py b/dist/ba_data/python-site-packages/chardet/charsetgroupprober.py deleted file mode 100644 index 5812cef0..00000000 --- a/dist/ba_data/python-site-packages/chardet/charsetgroupprober.py +++ /dev/null @@ -1,107 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import ProbingState -from .charsetprober import CharSetProber - - -class CharSetGroupProber(CharSetProber): - def __init__(self, lang_filter=None): - super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) - self._active_num = 0 - self.probers = [] - self._best_guess_prober = None - - def reset(self): - super(CharSetGroupProber, self).reset() - self._active_num = 0 - for prober in self.probers: - if prober: - prober.reset() - prober.active = True - self._active_num += 1 - self._best_guess_prober = None - - @property - def charset_name(self): - if not self._best_guess_prober: - self.get_confidence() - if not self._best_guess_prober: - return None - return self._best_guess_prober.charset_name - - @property - def language(self): - if not self._best_guess_prober: - self.get_confidence() - if not self._best_guess_prober: - return None - return self._best_guess_prober.language - - def feed(self, byte_str): - for prober in self.probers: - if not prober: - continue - if not prober.active: - continue - state = prober.feed(byte_str) - if not state: - continue - if state == ProbingState.FOUND_IT: - self._best_guess_prober = prober - self._state = ProbingState.FOUND_IT - return self.state - elif state == ProbingState.NOT_ME: - prober.active = False - self._active_num -= 1 - if self._active_num <= 0: - self._state = ProbingState.NOT_ME - return self.state - return self.state - - def get_confidence(self): - state = self.state - if state == ProbingState.FOUND_IT: - return 0.99 - elif state == ProbingState.NOT_ME: - return 0.01 - best_conf = 0.0 - self._best_guess_prober = None - for prober in self.probers: - if not prober: - continue - if not prober.active: - self.logger.debug('%s not active', prober.charset_name) - continue - conf = prober.get_confidence() - self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) - if best_conf < conf: - best_conf = conf - self._best_guess_prober = prober - if not self._best_guess_prober: - return 0.0 - return best_conf diff --git a/dist/ba_data/python-site-packages/chardet/charsetprober.py b/dist/ba_data/python-site-packages/chardet/charsetprober.py deleted file mode 100644 index eac4e598..00000000 --- a/dist/ba_data/python-site-packages/chardet/charsetprober.py +++ /dev/null @@ -1,145 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -import logging -import re - -from .enums import ProbingState - - -class CharSetProber(object): - - SHORTCUT_THRESHOLD = 0.95 - - def __init__(self, lang_filter=None): - self._state = None - self.lang_filter = lang_filter - self.logger = logging.getLogger(__name__) - - def reset(self): - self._state = ProbingState.DETECTING - - @property - def charset_name(self): - return None - - def feed(self, buf): - pass - - @property - def state(self): - return self._state - - def get_confidence(self): - return 0.0 - - @staticmethod - def filter_high_byte_only(buf): - buf = re.sub(b'([\x00-\x7F])+', b' ', buf) - return buf - - @staticmethod - def filter_international_words(buf): - """ - We define three types of bytes: - alphabet: english alphabets [a-zA-Z] - international: international characters [\x80-\xFF] - marker: everything else [^a-zA-Z\x80-\xFF] - - The input buffer can be thought to contain a series of words delimited - by markers. This function works to filter all words that contain at - least one international character. All contiguous sequences of markers - are replaced by a single space ascii character. - - This filter applies to all scripts which do not use English characters. - """ - filtered = bytearray() - - # This regex expression filters out only words that have at-least one - # international character. The word may include one marker character at - # the end. - words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', - buf) - - for word in words: - filtered.extend(word[:-1]) - - # If the last character in the word is a marker, replace it with a - # space as markers shouldn't affect our analysis (they are used - # similarly across all languages and may thus have similar - # frequencies). - last_char = word[-1:] - if not last_char.isalpha() and last_char < b'\x80': - last_char = b' ' - filtered.extend(last_char) - - return filtered - - @staticmethod - def filter_with_english_letters(buf): - """ - Returns a copy of ``buf`` that retains only the sequences of English - alphabet and high byte characters that are not between <> characters. - Also retains English alphabet and high byte characters immediately - before occurrences of >. - - This filter can be applied to all scripts which contain both English - characters and extended ASCII characters, but is currently only used by - ``Latin1Prober``. - """ - filtered = bytearray() - in_tag = False - prev = 0 - - for curr in range(len(buf)): - # Slice here to get bytes instead of an int with Python 3 - buf_char = buf[curr:curr + 1] - # Check if we're coming out of or entering an HTML tag - if buf_char == b'>': - in_tag = False - elif buf_char == b'<': - in_tag = True - - # If current character is not extended-ASCII and not alphabetic... - if buf_char < b'\x80' and not buf_char.isalpha(): - # ...and we're not in a tag - if curr > prev and not in_tag: - # Keep everything after last non-extended-ASCII, - # non-alphabetic character - filtered.extend(buf[prev:curr]) - # Output a space to delimit stretch we kept - filtered.extend(b' ') - prev = curr + 1 - - # If we're not in a tag... - if not in_tag: - # Keep everything after last non-extended-ASCII, non-alphabetic - # character - filtered.extend(buf[prev:]) - - return filtered diff --git a/dist/ba_data/python-site-packages/chardet/cli/chardetect.py b/dist/ba_data/python-site-packages/chardet/cli/chardetect.py deleted file mode 100644 index e1d8cd69..00000000 --- a/dist/ba_data/python-site-packages/chardet/cli/chardetect.py +++ /dev/null @@ -1,84 +0,0 @@ -""" -Script which takes one or more file paths and reports on their detected -encodings - -Example:: - - % chardetect somefile someotherfile - somefile: windows-1252 with confidence 0.5 - someotherfile: ascii with confidence 1.0 - -If no paths are provided, it takes its input from stdin. - -""" - -from __future__ import absolute_import, print_function, unicode_literals - -import argparse -import sys - -from chardet import __version__ -from chardet.compat import PY2 -from chardet.universaldetector import UniversalDetector - - -def description_of(lines, name='stdin'): - """ - Return a string describing the probable encoding of a file or - list of strings. - - :param lines: The lines to get the encoding of. - :type lines: Iterable of bytes - :param name: Name of file or collection of lines - :type name: str - """ - u = UniversalDetector() - for line in lines: - line = bytearray(line) - u.feed(line) - # shortcut out of the loop to save reading further - particularly useful if we read a BOM. - if u.done: - break - u.close() - result = u.result - if PY2: - name = name.decode(sys.getfilesystemencoding(), 'ignore') - if result['encoding']: - return '{}: {} with confidence {}'.format(name, result['encoding'], - result['confidence']) - else: - return '{}: no result'.format(name) - - -def main(argv=None): - """ - Handles command line arguments and gets things started. - - :param argv: List of arguments, as if specified on the command-line. - If None, ``sys.argv[1:]`` is used instead. - :type argv: list of str - """ - # Get command line arguments - parser = argparse.ArgumentParser( - description="Takes one or more file paths and reports their detected \ - encodings") - parser.add_argument('input', - help='File whose encoding we would like to determine. \ - (default: stdin)', - type=argparse.FileType('rb'), nargs='*', - default=[sys.stdin if PY2 else sys.stdin.buffer]) - parser.add_argument('--version', action='version', - version='%(prog)s {}'.format(__version__)) - args = parser.parse_args(argv) - - for f in args.input: - if f.isatty(): - print("You are running chardetect interactively. Press " + - "CTRL-D twice at the start of a blank line to signal the " + - "end of your input. If you want help, run chardetect " + - "--help\n", file=sys.stderr) - print(description_of(f, f.name)) - - -if __name__ == '__main__': - main() diff --git a/dist/ba_data/python-site-packages/chardet/codingstatemachine.py b/dist/ba_data/python-site-packages/chardet/codingstatemachine.py deleted file mode 100644 index 68fba44f..00000000 --- a/dist/ba_data/python-site-packages/chardet/codingstatemachine.py +++ /dev/null @@ -1,88 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -import logging - -from .enums import MachineState - - -class CodingStateMachine(object): - """ - A state machine to verify a byte sequence for a particular encoding. For - each byte the detector receives, it will feed that byte to every active - state machine available, one byte at a time. The state machine changes its - state based on its previous state and the byte it receives. There are 3 - states in a state machine that are of interest to an auto-detector: - - START state: This is the state to start with, or a legal byte sequence - (i.e. a valid code point) for character has been identified. - - ME state: This indicates that the state machine identified a byte sequence - that is specific to the charset it is designed for and that - there is no other possible encoding which can contain this byte - sequence. This will to lead to an immediate positive answer for - the detector. - - ERROR state: This indicates the state machine identified an illegal byte - sequence for that encoding. This will lead to an immediate - negative answer for this encoding. Detector will exclude this - encoding from consideration from here on. - """ - def __init__(self, sm): - self._model = sm - self._curr_byte_pos = 0 - self._curr_char_len = 0 - self._curr_state = None - self.logger = logging.getLogger(__name__) - self.reset() - - def reset(self): - self._curr_state = MachineState.START - - def next_state(self, c): - # for each byte we get its class - # if it is first byte, we also get byte length - byte_class = self._model['class_table'][c] - if self._curr_state == MachineState.START: - self._curr_byte_pos = 0 - self._curr_char_len = self._model['char_len_table'][byte_class] - # from byte's class and state_table, we get its next state - curr_state = (self._curr_state * self._model['class_factor'] - + byte_class) - self._curr_state = self._model['state_table'][curr_state] - self._curr_byte_pos += 1 - return self._curr_state - - def get_current_charlen(self): - return self._curr_char_len - - def get_coding_state_machine(self): - return self._model['name'] - - @property - def language(self): - return self._model['language'] diff --git a/dist/ba_data/python-site-packages/chardet/compat.py b/dist/ba_data/python-site-packages/chardet/compat.py deleted file mode 100644 index 8941572b..00000000 --- a/dist/ba_data/python-site-packages/chardet/compat.py +++ /dev/null @@ -1,36 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# Contributor(s): -# Dan Blanchard -# Ian Cordasco -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -import sys - - -if sys.version_info < (3, 0): - PY2 = True - PY3 = False - string_types = (str, unicode) - text_type = unicode - iteritems = dict.iteritems -else: - PY2 = False - PY3 = True - string_types = (bytes, str) - text_type = str - iteritems = dict.items diff --git a/dist/ba_data/python-site-packages/chardet/cp949prober.py b/dist/ba_data/python-site-packages/chardet/cp949prober.py deleted file mode 100644 index efd793ab..00000000 --- a/dist/ba_data/python-site-packages/chardet/cp949prober.py +++ /dev/null @@ -1,49 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .chardistribution import EUCKRDistributionAnalysis -from .codingstatemachine import CodingStateMachine -from .mbcharsetprober import MultiByteCharSetProber -from .mbcssm import CP949_SM_MODEL - - -class CP949Prober(MultiByteCharSetProber): - def __init__(self): - super(CP949Prober, self).__init__() - self.coding_sm = CodingStateMachine(CP949_SM_MODEL) - # NOTE: CP949 is a superset of EUC-KR, so the distribution should be - # not different. - self.distribution_analyzer = EUCKRDistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "CP949" - - @property - def language(self): - return "Korean" diff --git a/dist/ba_data/python-site-packages/chardet/enums.py b/dist/ba_data/python-site-packages/chardet/enums.py deleted file mode 100644 index 04512072..00000000 --- a/dist/ba_data/python-site-packages/chardet/enums.py +++ /dev/null @@ -1,76 +0,0 @@ -""" -All of the Enums that are used throughout the chardet package. - -:author: Dan Blanchard (dan.blanchard@gmail.com) -""" - - -class InputState(object): - """ - This enum represents the different states a universal detector can be in. - """ - PURE_ASCII = 0 - ESC_ASCII = 1 - HIGH_BYTE = 2 - - -class LanguageFilter(object): - """ - This enum represents the different language filters we can apply to a - ``UniversalDetector``. - """ - CHINESE_SIMPLIFIED = 0x01 - CHINESE_TRADITIONAL = 0x02 - JAPANESE = 0x04 - KOREAN = 0x08 - NON_CJK = 0x10 - ALL = 0x1F - CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL - CJK = CHINESE | JAPANESE | KOREAN - - -class ProbingState(object): - """ - This enum represents the different states a prober can be in. - """ - DETECTING = 0 - FOUND_IT = 1 - NOT_ME = 2 - - -class MachineState(object): - """ - This enum represents the different states a state machine can be in. - """ - START = 0 - ERROR = 1 - ITS_ME = 2 - - -class SequenceLikelihood(object): - """ - This enum represents the likelihood of a character following the previous one. - """ - NEGATIVE = 0 - UNLIKELY = 1 - LIKELY = 2 - POSITIVE = 3 - - @classmethod - def get_num_categories(cls): - """:returns: The number of likelihood categories in the enum.""" - return 4 - - -class CharacterCategory(object): - """ - This enum represents the different categories language models for - ``SingleByteCharsetProber`` put characters into. - - Anything less than CONTROL is considered a letter. - """ - UNDEFINED = 255 - LINE_BREAK = 254 - SYMBOL = 253 - DIGIT = 252 - CONTROL = 251 diff --git a/dist/ba_data/python-site-packages/chardet/escprober.py b/dist/ba_data/python-site-packages/chardet/escprober.py deleted file mode 100644 index c70493f2..00000000 --- a/dist/ba_data/python-site-packages/chardet/escprober.py +++ /dev/null @@ -1,101 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .codingstatemachine import CodingStateMachine -from .enums import LanguageFilter, ProbingState, MachineState -from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, - ISO2022KR_SM_MODEL) - - -class EscCharSetProber(CharSetProber): - """ - This CharSetProber uses a "code scheme" approach for detecting encodings, - whereby easily recognizable escape or shift sequences are relied on to - identify these encodings. - """ - - def __init__(self, lang_filter=None): - super(EscCharSetProber, self).__init__(lang_filter=lang_filter) - self.coding_sm = [] - if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: - self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) - self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) - if self.lang_filter & LanguageFilter.JAPANESE: - self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) - if self.lang_filter & LanguageFilter.KOREAN: - self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) - self.active_sm_count = None - self._detected_charset = None - self._detected_language = None - self._state = None - self.reset() - - def reset(self): - super(EscCharSetProber, self).reset() - for coding_sm in self.coding_sm: - if not coding_sm: - continue - coding_sm.active = True - coding_sm.reset() - self.active_sm_count = len(self.coding_sm) - self._detected_charset = None - self._detected_language = None - - @property - def charset_name(self): - return self._detected_charset - - @property - def language(self): - return self._detected_language - - def get_confidence(self): - if self._detected_charset: - return 0.99 - else: - return 0.00 - - def feed(self, byte_str): - for c in byte_str: - for coding_sm in self.coding_sm: - if not coding_sm or not coding_sm.active: - continue - coding_state = coding_sm.next_state(c) - if coding_state == MachineState.ERROR: - coding_sm.active = False - self.active_sm_count -= 1 - if self.active_sm_count <= 0: - self._state = ProbingState.NOT_ME - return self.state - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - self._detected_charset = coding_sm.get_coding_state_machine() - self._detected_language = coding_sm.language - return self.state - - return self.state diff --git a/dist/ba_data/python-site-packages/chardet/escsm.py b/dist/ba_data/python-site-packages/chardet/escsm.py deleted file mode 100644 index 0069523a..00000000 --- a/dist/ba_data/python-site-packages/chardet/escsm.py +++ /dev/null @@ -1,246 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import MachineState - -HZ_CLS = ( -1,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,0,0, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,0,0,0,0, # 20 - 27 -0,0,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -0,0,0,0,0,0,0,0, # 40 - 47 -0,0,0,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,4,0,5,2,0, # 78 - 7f -1,1,1,1,1,1,1,1, # 80 - 87 -1,1,1,1,1,1,1,1, # 88 - 8f -1,1,1,1,1,1,1,1, # 90 - 97 -1,1,1,1,1,1,1,1, # 98 - 9f -1,1,1,1,1,1,1,1, # a0 - a7 -1,1,1,1,1,1,1,1, # a8 - af -1,1,1,1,1,1,1,1, # b0 - b7 -1,1,1,1,1,1,1,1, # b8 - bf -1,1,1,1,1,1,1,1, # c0 - c7 -1,1,1,1,1,1,1,1, # c8 - cf -1,1,1,1,1,1,1,1, # d0 - d7 -1,1,1,1,1,1,1,1, # d8 - df -1,1,1,1,1,1,1,1, # e0 - e7 -1,1,1,1,1,1,1,1, # e8 - ef -1,1,1,1,1,1,1,1, # f0 - f7 -1,1,1,1,1,1,1,1, # f8 - ff -) - -HZ_ST = ( -MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 - 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f - 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 - 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f -) - -HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) - -HZ_SM_MODEL = {'class_table': HZ_CLS, - 'class_factor': 6, - 'state_table': HZ_ST, - 'char_len_table': HZ_CHAR_LEN_TABLE, - 'name': "HZ-GB-2312", - 'language': 'Chinese'} - -ISO2022CN_CLS = ( -2,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,0,0, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,0,0,0,0, # 20 - 27 -0,3,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -0,0,0,4,0,0,0,0, # 40 - 47 -0,0,0,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,0,0,0,0,0, # 78 - 7f -2,2,2,2,2,2,2,2, # 80 - 87 -2,2,2,2,2,2,2,2, # 88 - 8f -2,2,2,2,2,2,2,2, # 90 - 97 -2,2,2,2,2,2,2,2, # 98 - 9f -2,2,2,2,2,2,2,2, # a0 - a7 -2,2,2,2,2,2,2,2, # a8 - af -2,2,2,2,2,2,2,2, # b0 - b7 -2,2,2,2,2,2,2,2, # b8 - bf -2,2,2,2,2,2,2,2, # c0 - c7 -2,2,2,2,2,2,2,2, # c8 - cf -2,2,2,2,2,2,2,2, # d0 - d7 -2,2,2,2,2,2,2,2, # d8 - df -2,2,2,2,2,2,2,2, # e0 - e7 -2,2,2,2,2,2,2,2, # e8 - ef -2,2,2,2,2,2,2,2, # f0 - f7 -2,2,2,2,2,2,2,2, # f8 - ff -) - -ISO2022CN_ST = ( -MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 -MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f -MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 - 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f -) - -ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) - -ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, - 'class_factor': 9, - 'state_table': ISO2022CN_ST, - 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, - 'name': "ISO-2022-CN", - 'language': 'Chinese'} - -ISO2022JP_CLS = ( -2,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,2,2, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,7,0,0,0, # 20 - 27 -3,0,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -6,0,4,0,8,0,0,0, # 40 - 47 -0,9,5,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,0,0,0,0,0, # 78 - 7f -2,2,2,2,2,2,2,2, # 80 - 87 -2,2,2,2,2,2,2,2, # 88 - 8f -2,2,2,2,2,2,2,2, # 90 - 97 -2,2,2,2,2,2,2,2, # 98 - 9f -2,2,2,2,2,2,2,2, # a0 - a7 -2,2,2,2,2,2,2,2, # a8 - af -2,2,2,2,2,2,2,2, # b0 - b7 -2,2,2,2,2,2,2,2, # b8 - bf -2,2,2,2,2,2,2,2, # c0 - c7 -2,2,2,2,2,2,2,2, # c8 - cf -2,2,2,2,2,2,2,2, # d0 - d7 -2,2,2,2,2,2,2,2, # d8 - df -2,2,2,2,2,2,2,2, # e0 - e7 -2,2,2,2,2,2,2,2, # e8 - ef -2,2,2,2,2,2,2,2, # f0 - f7 -2,2,2,2,2,2,2,2, # f8 - ff -) - -ISO2022JP_ST = ( -MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 -MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f -MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 -) - -ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - -ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, - 'class_factor': 10, - 'state_table': ISO2022JP_ST, - 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, - 'name': "ISO-2022-JP", - 'language': 'Japanese'} - -ISO2022KR_CLS = ( -2,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,0,0, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,3,0,0,0, # 20 - 27 -0,4,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -0,0,0,5,0,0,0,0, # 40 - 47 -0,0,0,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,0,0,0,0,0, # 78 - 7f -2,2,2,2,2,2,2,2, # 80 - 87 -2,2,2,2,2,2,2,2, # 88 - 8f -2,2,2,2,2,2,2,2, # 90 - 97 -2,2,2,2,2,2,2,2, # 98 - 9f -2,2,2,2,2,2,2,2, # a0 - a7 -2,2,2,2,2,2,2,2, # a8 - af -2,2,2,2,2,2,2,2, # b0 - b7 -2,2,2,2,2,2,2,2, # b8 - bf -2,2,2,2,2,2,2,2, # c0 - c7 -2,2,2,2,2,2,2,2, # c8 - cf -2,2,2,2,2,2,2,2, # d0 - d7 -2,2,2,2,2,2,2,2, # d8 - df -2,2,2,2,2,2,2,2, # e0 - e7 -2,2,2,2,2,2,2,2, # e8 - ef -2,2,2,2,2,2,2,2, # f0 - f7 -2,2,2,2,2,2,2,2, # f8 - ff -) - -ISO2022KR_ST = ( -MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 -) - -ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) - -ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, - 'class_factor': 6, - 'state_table': ISO2022KR_ST, - 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, - 'name': "ISO-2022-KR", - 'language': 'Korean'} - - diff --git a/dist/ba_data/python-site-packages/chardet/eucjpprober.py b/dist/ba_data/python-site-packages/chardet/eucjpprober.py deleted file mode 100644 index 20ce8f7d..00000000 --- a/dist/ba_data/python-site-packages/chardet/eucjpprober.py +++ /dev/null @@ -1,92 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import ProbingState, MachineState -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import EUCJPDistributionAnalysis -from .jpcntx import EUCJPContextAnalysis -from .mbcssm import EUCJP_SM_MODEL - - -class EUCJPProber(MultiByteCharSetProber): - def __init__(self): - super(EUCJPProber, self).__init__() - self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) - self.distribution_analyzer = EUCJPDistributionAnalysis() - self.context_analyzer = EUCJPContextAnalysis() - self.reset() - - def reset(self): - super(EUCJPProber, self).reset() - self.context_analyzer.reset() - - @property - def charset_name(self): - return "EUC-JP" - - @property - def language(self): - return "Japanese" - - def feed(self, byte_str): - for i in range(len(byte_str)): - # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte - coding_state = self.coding_sm.next_state(byte_str[i]) - if coding_state == MachineState.ERROR: - self.logger.debug('%s %s prober hit error at byte %s', - self.charset_name, self.language, i) - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - char_len = self.coding_sm.get_current_charlen() - if i == 0: - self._last_char[1] = byte_str[0] - self.context_analyzer.feed(self._last_char, char_len) - self.distribution_analyzer.feed(self._last_char, char_len) - else: - self.context_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - self.distribution_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - - self._last_char[0] = byte_str[-1] - - if self.state == ProbingState.DETECTING: - if (self.context_analyzer.got_enough_data() and - (self.get_confidence() > self.SHORTCUT_THRESHOLD)): - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - context_conf = self.context_analyzer.get_confidence() - distrib_conf = self.distribution_analyzer.get_confidence() - return max(context_conf, distrib_conf) diff --git a/dist/ba_data/python-site-packages/chardet/euckrfreq.py b/dist/ba_data/python-site-packages/chardet/euckrfreq.py deleted file mode 100644 index b68078cb..00000000 --- a/dist/ba_data/python-site-packages/chardet/euckrfreq.py +++ /dev/null @@ -1,195 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# Sampling from about 20M text materials include literature and computer technology - -# 128 --> 0.79 -# 256 --> 0.92 -# 512 --> 0.986 -# 1024 --> 0.99944 -# 2048 --> 0.99999 -# -# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 -# Random Distribution Ration = 512 / (2350-512) = 0.279. -# -# Typical Distribution Ratio - -EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 - -EUCKR_TABLE_SIZE = 2352 - -# Char to FreqOrder table , -EUCKR_CHAR_TO_FREQ_ORDER = ( - 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, -1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, -1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, - 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, - 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, - 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, -1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, - 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, - 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, -1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, -1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, -1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, -1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, -1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, - 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, -1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, -1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, -1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, -1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, - 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, -1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, - 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, - 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, -1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, - 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, -1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, - 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, - 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, -1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, -1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, -1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, -1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, - 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, -1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, - 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, - 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, -1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, -1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, -1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, -1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, -1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, -1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, - 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, - 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, - 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, -1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, - 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, -1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, - 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, - 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, -2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, - 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, - 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, -2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, -2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, -2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, - 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, - 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, -2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, - 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, -1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, -2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, -1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, -2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, -2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, -1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, - 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, -2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, -2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, - 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, - 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, -2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, -1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, -2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, -2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, -2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, -2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, -2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, -2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, -1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, -2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, -2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, -2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, -2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, -2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, -1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, -1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, -2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, -1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, -2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, -1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, - 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, -2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, - 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, -2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, - 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, -2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, -2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, - 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, -2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, -1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, - 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, -1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, -2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, -1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, -2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, - 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, -2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, -1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, -2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, -1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, -2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, -1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, - 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, -2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, -2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, - 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, - 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, -1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, -1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, - 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, -2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, -2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, - 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, - 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, - 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, -2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, - 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, - 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, -2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, -2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, - 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, -2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, -1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, - 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, -2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, -2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, -2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, - 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, - 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, - 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, -2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, -2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, -2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, -1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, -2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, - 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 -) - diff --git a/dist/ba_data/python-site-packages/chardet/euckrprober.py b/dist/ba_data/python-site-packages/chardet/euckrprober.py deleted file mode 100644 index 345a060d..00000000 --- a/dist/ba_data/python-site-packages/chardet/euckrprober.py +++ /dev/null @@ -1,47 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import EUCKRDistributionAnalysis -from .mbcssm import EUCKR_SM_MODEL - - -class EUCKRProber(MultiByteCharSetProber): - def __init__(self): - super(EUCKRProber, self).__init__() - self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) - self.distribution_analyzer = EUCKRDistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "EUC-KR" - - @property - def language(self): - return "Korean" diff --git a/dist/ba_data/python-site-packages/chardet/euctwfreq.py b/dist/ba_data/python-site-packages/chardet/euctwfreq.py deleted file mode 100644 index ed7a995a..00000000 --- a/dist/ba_data/python-site-packages/chardet/euctwfreq.py +++ /dev/null @@ -1,387 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# EUCTW frequency table -# Converted from big5 work -# by Taiwan's Mandarin Promotion Council -# - -# 128 --> 0.42261 -# 256 --> 0.57851 -# 512 --> 0.74851 -# 1024 --> 0.89384 -# 2048 --> 0.97583 -# -# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 -# Random Distribution Ration = 512/(5401-512)=0.105 -# -# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR - -EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 - -# Char to FreqOrder table , -EUCTW_TABLE_SIZE = 5376 - -EUCTW_CHAR_TO_FREQ_ORDER = ( - 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 -3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 -1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 - 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 -3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 -4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 -7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 - 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 - 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 - 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 -2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 -1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 -3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 - 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 -1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 -3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 -2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 - 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 -3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 -1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 -7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 - 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 -7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 -1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 - 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 - 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 -3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 -3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 - 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 -2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 -2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 - 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 - 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 -3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 -1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 -1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 -1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 -2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 - 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 -4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 -1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 -7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 -2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 - 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 - 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 - 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 - 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 -7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 - 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 -1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 - 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 - 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 -7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 -1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 - 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 -3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 -4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 -3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 - 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 - 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 -1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 -4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 -3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 -3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 -2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 -7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 -3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 -7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 -1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 -2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 -1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 - 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 -1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 -4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 -3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 - 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 - 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 - 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 -2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 -7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 -1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 -2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 -1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 -1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 -7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 -7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 -7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 -3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 -4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 -1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 -7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 -2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 -7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 -3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 -3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 -7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 -2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 -7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 - 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 -4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 -2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 -7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 -3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 -2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 -2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 - 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 -2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 -1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 -1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 -2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 -1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 -7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 -7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 -2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 -4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 -1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 -7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 - 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 -4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 - 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 -2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 - 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 -1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 -1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 - 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 -3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 -3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 -1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 -3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 -7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 -7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 -1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 -2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 -1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 -3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 -2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 -3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 -2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 -4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 -4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 -3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 - 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 -3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 - 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 -3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 -3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 -3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 -1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 -7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 - 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 -7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 -1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 - 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 -4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 -3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 - 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 -2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 -2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 -3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 -1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 -4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 -2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 -1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 -1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 -2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 -3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 -1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 -7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 -1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 -4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 -1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 - 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 -1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 -3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 -3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 -2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 -1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 -4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 - 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 -7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 -2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 -3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 -4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 - 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 -7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 -7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 -1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 -4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 -3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 -2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 -3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 -3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 -2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 -1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 -4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 -3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 -3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 -2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 -4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 -7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 -3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 -2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 -3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 -1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 -2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 -3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 -4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 -2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 -2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 -7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 -1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 -2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 -1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 -3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 -4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 -2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 -3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 -3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 -2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 -4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 -2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 -3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 -4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 -7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 -3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 - 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 -1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 -4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 -1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 -4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 -7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 - 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 -7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 -2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 -1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 -1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 -3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 - 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 - 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 - 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 -3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 -2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 - 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 -7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 -1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 -3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 -7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 -1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 -7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 -4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 -1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 -2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 -2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 -4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 - 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 - 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 -3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 -3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 -1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 -2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 -7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 -1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 -1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 -3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 - 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 -1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 -4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 -7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 -2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 -3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 - 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 -1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 -2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 -2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 -7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 -7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 -7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 -2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 -2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 -1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 -4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 -3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 -3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 -4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 -4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 -2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 -2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 -7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 -4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 -7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 -2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 -1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 -3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 -4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 -2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 - 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 -2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 -1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 -2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 -2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 -4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 -7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 -1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 -3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 -7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 -1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 -8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 -2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 -8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 -2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 -2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 -8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 -8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 -8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 - 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 -8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 -4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 -3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 -8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 -1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 -8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 - 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 -1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 - 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 -4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 -1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 -4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 -1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 - 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 -3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 -4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 -8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 - 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 -3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 - 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 -2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 -) - diff --git a/dist/ba_data/python-site-packages/chardet/euctwprober.py b/dist/ba_data/python-site-packages/chardet/euctwprober.py deleted file mode 100644 index 35669cc4..00000000 --- a/dist/ba_data/python-site-packages/chardet/euctwprober.py +++ /dev/null @@ -1,46 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import EUCTWDistributionAnalysis -from .mbcssm import EUCTW_SM_MODEL - -class EUCTWProber(MultiByteCharSetProber): - def __init__(self): - super(EUCTWProber, self).__init__() - self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) - self.distribution_analyzer = EUCTWDistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "EUC-TW" - - @property - def language(self): - return "Taiwan" diff --git a/dist/ba_data/python-site-packages/chardet/gb2312freq.py b/dist/ba_data/python-site-packages/chardet/gb2312freq.py deleted file mode 100644 index 697837bd..00000000 --- a/dist/ba_data/python-site-packages/chardet/gb2312freq.py +++ /dev/null @@ -1,283 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# GB2312 most frequently used character table -# -# Char to FreqOrder table , from hz6763 - -# 512 --> 0.79 -- 0.79 -# 1024 --> 0.92 -- 0.13 -# 2048 --> 0.98 -- 0.06 -# 6768 --> 1.00 -- 0.02 -# -# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 -# Random Distribution Ration = 512 / (3755 - 512) = 0.157 -# -# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR - -GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 - -GB2312_TABLE_SIZE = 3760 - -GB2312_CHAR_TO_FREQ_ORDER = ( -1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, -2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, -2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, - 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, -1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, -1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, - 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, -1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, -2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, -3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, - 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, -1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, - 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, -2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, - 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, -2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, -1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, -3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, - 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, -1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, - 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, -2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, -1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, -3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, -1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, -2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, -1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, - 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, -3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, -3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, - 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, -3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, - 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, -1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, -3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, -2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, -1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, - 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, -1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, -4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, - 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, -3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, -3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, - 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, -1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, -2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, -1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, -1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, - 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, -3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, -3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, -4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, - 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, -3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, -1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, -1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, -4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, - 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, - 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, -3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, -1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, - 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, -1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, -2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, - 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, - 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, - 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, -3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, -4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, -3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, - 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, -2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, -2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, -2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, - 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, -2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, - 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, - 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, - 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, -3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, -2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, -2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, -1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, - 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, -2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, - 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, - 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, -1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, -1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, - 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, - 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, -1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, -2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, -3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, -2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, -2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, -2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, -3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, -1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, -1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, -2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, -1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, -3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, -1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, -1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, -3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, - 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, -2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, -1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, -4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, -1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, -1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, -3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, -1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, - 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, - 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, -1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, - 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, -1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, -1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, - 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, -3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, -4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, -3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, -2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, -2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, -1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, -3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, -2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, -1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, -1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, - 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, -2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, -2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, -3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, -4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, -3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, - 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, -3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, -2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, -1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, - 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, - 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, -3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, -4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, -2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, -1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, -1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, - 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, -1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, -3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, - 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, - 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, -1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, - 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, -1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, - 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, -2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, - 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, -2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, -2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, -1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, -1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, -2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, - 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, -1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, -1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, -2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, -2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, -3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, -1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, -4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, - 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, - 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, -3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, -1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, - 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, -3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, -1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, -4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, -1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, -2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, -1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, - 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, -1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, -3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, - 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, -2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, - 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, -1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, -1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, -1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, -3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, -2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, -3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, -3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, -3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, - 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, -2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, - 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, -2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, - 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, -1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, - 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, - 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, -1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, -3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, -3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, -1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, -1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, -3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, -2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, -2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, -1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, -3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, - 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, -4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, -1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, -2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, -3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, -3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, -1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, - 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, - 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, -2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, - 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, -1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, - 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, -1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, -1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, -1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, -1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, -1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, - 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, - 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 -) - diff --git a/dist/ba_data/python-site-packages/chardet/gb2312prober.py b/dist/ba_data/python-site-packages/chardet/gb2312prober.py deleted file mode 100644 index 8446d2dd..00000000 --- a/dist/ba_data/python-site-packages/chardet/gb2312prober.py +++ /dev/null @@ -1,46 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import GB2312DistributionAnalysis -from .mbcssm import GB2312_SM_MODEL - -class GB2312Prober(MultiByteCharSetProber): - def __init__(self): - super(GB2312Prober, self).__init__() - self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) - self.distribution_analyzer = GB2312DistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "GB2312" - - @property - def language(self): - return "Chinese" diff --git a/dist/ba_data/python-site-packages/chardet/hebrewprober.py b/dist/ba_data/python-site-packages/chardet/hebrewprober.py deleted file mode 100644 index b0e1bf49..00000000 --- a/dist/ba_data/python-site-packages/chardet/hebrewprober.py +++ /dev/null @@ -1,292 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Shy Shalom -# Portions created by the Initial Developer are Copyright (C) 2005 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState - -# This prober doesn't actually recognize a language or a charset. -# It is a helper prober for the use of the Hebrew model probers - -### General ideas of the Hebrew charset recognition ### -# -# Four main charsets exist in Hebrew: -# "ISO-8859-8" - Visual Hebrew -# "windows-1255" - Logical Hebrew -# "ISO-8859-8-I" - Logical Hebrew -# "x-mac-hebrew" - ?? Logical Hebrew ?? -# -# Both "ISO" charsets use a completely identical set of code points, whereas -# "windows-1255" and "x-mac-hebrew" are two different proper supersets of -# these code points. windows-1255 defines additional characters in the range -# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific -# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. -# x-mac-hebrew defines similar additional code points but with a different -# mapping. -# -# As far as an average Hebrew text with no diacritics is concerned, all four -# charsets are identical with respect to code points. Meaning that for the -# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters -# (including final letters). -# -# The dominant difference between these charsets is their directionality. -# "Visual" directionality means that the text is ordered as if the renderer is -# not aware of a BIDI rendering algorithm. The renderer sees the text and -# draws it from left to right. The text itself when ordered naturally is read -# backwards. A buffer of Visual Hebrew generally looks like so: -# "[last word of first line spelled backwards] [whole line ordered backwards -# and spelled backwards] [first word of first line spelled backwards] -# [end of line] [last word of second line] ... etc' " -# adding punctuation marks, numbers and English text to visual text is -# naturally also "visual" and from left to right. -# -# "Logical" directionality means the text is ordered "naturally" according to -# the order it is read. It is the responsibility of the renderer to display -# the text from right to left. A BIDI algorithm is used to place general -# punctuation marks, numbers and English text in the text. -# -# Texts in x-mac-hebrew are almost impossible to find on the Internet. From -# what little evidence I could find, it seems that its general directionality -# is Logical. -# -# To sum up all of the above, the Hebrew probing mechanism knows about two -# charsets: -# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are -# backwards while line order is natural. For charset recognition purposes -# the line order is unimportant (In fact, for this implementation, even -# word order is unimportant). -# Logical Hebrew - "windows-1255" - normal, naturally ordered text. -# -# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be -# specifically identified. -# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew -# that contain special punctuation marks or diacritics is displayed with -# some unconverted characters showing as question marks. This problem might -# be corrected using another model prober for x-mac-hebrew. Due to the fact -# that x-mac-hebrew texts are so rare, writing another model prober isn't -# worth the effort and performance hit. -# -#### The Prober #### -# -# The prober is divided between two SBCharSetProbers and a HebrewProber, -# all of which are managed, created, fed data, inquired and deleted by the -# SBCSGroupProber. The two SBCharSetProbers identify that the text is in -# fact some kind of Hebrew, Logical or Visual. The final decision about which -# one is it is made by the HebrewProber by combining final-letter scores -# with the scores of the two SBCharSetProbers to produce a final answer. -# -# The SBCSGroupProber is responsible for stripping the original text of HTML -# tags, English characters, numbers, low-ASCII punctuation characters, spaces -# and new lines. It reduces any sequence of such characters to a single space. -# The buffer fed to each prober in the SBCS group prober is pure text in -# high-ASCII. -# The two SBCharSetProbers (model probers) share the same language model: -# Win1255Model. -# The first SBCharSetProber uses the model normally as any other -# SBCharSetProber does, to recognize windows-1255, upon which this model was -# built. The second SBCharSetProber is told to make the pair-of-letter -# lookup in the language model backwards. This in practice exactly simulates -# a visual Hebrew model using the windows-1255 logical Hebrew model. -# -# The HebrewProber is not using any language model. All it does is look for -# final-letter evidence suggesting the text is either logical Hebrew or visual -# Hebrew. Disjointed from the model probers, the results of the HebrewProber -# alone are meaningless. HebrewProber always returns 0.00 as confidence -# since it never identifies a charset by itself. Instead, the pointer to the -# HebrewProber is passed to the model probers as a helper "Name Prober". -# When the Group prober receives a positive identification from any prober, -# it asks for the name of the charset identified. If the prober queried is a -# Hebrew model prober, the model prober forwards the call to the -# HebrewProber to make the final decision. In the HebrewProber, the -# decision is made according to the final-letters scores maintained and Both -# model probers scores. The answer is returned in the form of the name of the -# charset identified, either "windows-1255" or "ISO-8859-8". - -class HebrewProber(CharSetProber): - # windows-1255 / ISO-8859-8 code points of interest - FINAL_KAF = 0xea - NORMAL_KAF = 0xeb - FINAL_MEM = 0xed - NORMAL_MEM = 0xee - FINAL_NUN = 0xef - NORMAL_NUN = 0xf0 - FINAL_PE = 0xf3 - NORMAL_PE = 0xf4 - FINAL_TSADI = 0xf5 - NORMAL_TSADI = 0xf6 - - # Minimum Visual vs Logical final letter score difference. - # If the difference is below this, don't rely solely on the final letter score - # distance. - MIN_FINAL_CHAR_DISTANCE = 5 - - # Minimum Visual vs Logical model score difference. - # If the difference is below this, don't rely at all on the model score - # distance. - MIN_MODEL_DISTANCE = 0.01 - - VISUAL_HEBREW_NAME = "ISO-8859-8" - LOGICAL_HEBREW_NAME = "windows-1255" - - def __init__(self): - super(HebrewProber, self).__init__() - self._final_char_logical_score = None - self._final_char_visual_score = None - self._prev = None - self._before_prev = None - self._logical_prober = None - self._visual_prober = None - self.reset() - - def reset(self): - self._final_char_logical_score = 0 - self._final_char_visual_score = 0 - # The two last characters seen in the previous buffer, - # mPrev and mBeforePrev are initialized to space in order to simulate - # a word delimiter at the beginning of the data - self._prev = ' ' - self._before_prev = ' ' - # These probers are owned by the group prober. - - def set_model_probers(self, logicalProber, visualProber): - self._logical_prober = logicalProber - self._visual_prober = visualProber - - def is_final(self, c): - return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, - self.FINAL_PE, self.FINAL_TSADI] - - def is_non_final(self, c): - # The normal Tsadi is not a good Non-Final letter due to words like - # 'lechotet' (to chat) containing an apostrophe after the tsadi. This - # apostrophe is converted to a space in FilterWithoutEnglishLetters - # causing the Non-Final tsadi to appear at an end of a word even - # though this is not the case in the original text. - # The letters Pe and Kaf rarely display a related behavior of not being - # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' - # for example legally end with a Non-Final Pe or Kaf. However, the - # benefit of these letters as Non-Final letters outweighs the damage - # since these words are quite rare. - return c in [self.NORMAL_KAF, self.NORMAL_MEM, - self.NORMAL_NUN, self.NORMAL_PE] - - def feed(self, byte_str): - # Final letter analysis for logical-visual decision. - # Look for evidence that the received buffer is either logical Hebrew - # or visual Hebrew. - # The following cases are checked: - # 1) A word longer than 1 letter, ending with a final letter. This is - # an indication that the text is laid out "naturally" since the - # final letter really appears at the end. +1 for logical score. - # 2) A word longer than 1 letter, ending with a Non-Final letter. In - # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, - # should not end with the Non-Final form of that letter. Exceptions - # to this rule are mentioned above in isNonFinal(). This is an - # indication that the text is laid out backwards. +1 for visual - # score - # 3) A word longer than 1 letter, starting with a final letter. Final - # letters should not appear at the beginning of a word. This is an - # indication that the text is laid out backwards. +1 for visual - # score. - # - # The visual score and logical score are accumulated throughout the - # text and are finally checked against each other in GetCharSetName(). - # No checking for final letters in the middle of words is done since - # that case is not an indication for either Logical or Visual text. - # - # We automatically filter out all 7-bit characters (replace them with - # spaces) so the word boundary detection works properly. [MAP] - - if self.state == ProbingState.NOT_ME: - # Both model probers say it's not them. No reason to continue. - return ProbingState.NOT_ME - - byte_str = self.filter_high_byte_only(byte_str) - - for cur in byte_str: - if cur == ' ': - # We stand on a space - a word just ended - if self._before_prev != ' ': - # next-to-last char was not a space so self._prev is not a - # 1 letter word - if self.is_final(self._prev): - # case (1) [-2:not space][-1:final letter][cur:space] - self._final_char_logical_score += 1 - elif self.is_non_final(self._prev): - # case (2) [-2:not space][-1:Non-Final letter][ - # cur:space] - self._final_char_visual_score += 1 - else: - # Not standing on a space - if ((self._before_prev == ' ') and - (self.is_final(self._prev)) and (cur != ' ')): - # case (3) [-2:space][-1:final letter][cur:not space] - self._final_char_visual_score += 1 - self._before_prev = self._prev - self._prev = cur - - # Forever detecting, till the end or until both model probers return - # ProbingState.NOT_ME (handled above) - return ProbingState.DETECTING - - @property - def charset_name(self): - # Make the decision: is it Logical or Visual? - # If the final letter score distance is dominant enough, rely on it. - finalsub = self._final_char_logical_score - self._final_char_visual_score - if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: - return self.LOGICAL_HEBREW_NAME - if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: - return self.VISUAL_HEBREW_NAME - - # It's not dominant enough, try to rely on the model scores instead. - modelsub = (self._logical_prober.get_confidence() - - self._visual_prober.get_confidence()) - if modelsub > self.MIN_MODEL_DISTANCE: - return self.LOGICAL_HEBREW_NAME - if modelsub < -self.MIN_MODEL_DISTANCE: - return self.VISUAL_HEBREW_NAME - - # Still no good, back to final letter distance, maybe it'll save the - # day. - if finalsub < 0.0: - return self.VISUAL_HEBREW_NAME - - # (finalsub > 0 - Logical) or (don't know what to do) default to - # Logical. - return self.LOGICAL_HEBREW_NAME - - @property - def language(self): - return 'Hebrew' - - @property - def state(self): - # Remain active as long as any of the model probers are active. - if (self._logical_prober.state == ProbingState.NOT_ME) and \ - (self._visual_prober.state == ProbingState.NOT_ME): - return ProbingState.NOT_ME - return ProbingState.DETECTING diff --git a/dist/ba_data/python-site-packages/chardet/jisfreq.py b/dist/ba_data/python-site-packages/chardet/jisfreq.py deleted file mode 100644 index 83fc082b..00000000 --- a/dist/ba_data/python-site-packages/chardet/jisfreq.py +++ /dev/null @@ -1,325 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# Sampling from about 20M text materials include literature and computer technology -# -# Japanese frequency table, applied to both S-JIS and EUC-JP -# They are sorted in order. - -# 128 --> 0.77094 -# 256 --> 0.85710 -# 512 --> 0.92635 -# 1024 --> 0.97130 -# 2048 --> 0.99431 -# -# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 -# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 -# -# Typical Distribution Ratio, 25% of IDR - -JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 - -# Char to FreqOrder table , -JIS_TABLE_SIZE = 4368 - -JIS_CHAR_TO_FREQ_ORDER = ( - 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 -3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 -1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 -2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 -2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 -5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 -1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 -5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 -5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 -5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 -5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 -5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 -5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 -1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 -1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 -1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 -2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 -3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 -3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 - 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 - 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 -1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 - 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 -5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 - 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 - 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 - 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 - 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 - 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 -5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 -5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 -5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 -4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 -5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 -5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 -5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 -5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 -5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 -5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 -5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 -5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 -5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 -3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 -5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 -5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 -5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 -5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 -5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 -5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 -5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 -5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 -5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 -5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 -5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 -5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 -5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 -5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 -5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 -5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 -5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 -5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 -5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 -5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 -5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 -5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 -5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 -5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 -5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 -5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 -5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 -5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 -5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 -5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 -5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 -5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 -5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 -5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 -5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 -5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 -5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 -5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 -6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 -6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 -6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 -6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 -6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 -6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 -6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 -6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 -4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 - 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 - 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 -1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 -1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 - 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 -3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 -3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 - 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 -3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 -3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 - 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 -2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 - 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 -3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 -1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 - 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 -1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 - 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 -2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 -2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 -2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 -2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 -1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 -1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 -1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 -1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 -2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 -1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 -2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 -1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 -1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 -1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 -1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 -1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 -1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 - 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 - 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 -1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 -2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 -2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 -2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 -3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 -3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 - 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 -3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 -1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 - 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 -2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 -1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 - 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 -3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 -4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 -2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 -1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 -2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 -1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 - 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 - 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 -1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 -2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 -2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 -2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 -3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 -1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 -2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 - 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 - 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 - 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 -1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 -2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 - 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 -1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 -1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 - 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 -1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 -1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 -1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 - 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 -2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 - 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 -2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 -3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 -2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 -1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 -6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 -1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 -2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 -1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 - 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 - 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 -3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 -3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 -1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 -1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 -1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 -1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 - 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 - 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 -2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 - 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 -3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 -2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 - 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 -1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 -2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 - 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 -1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 - 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 -4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 -2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 -1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 - 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 -1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 -2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 - 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 -6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 -1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 -1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 -2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 -3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 - 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 -3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 -1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 - 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 -1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 - 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 -3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 - 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 -2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 - 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 -4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 -2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 -1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 -1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 -1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 - 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 -1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 -3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 -1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 -3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 - 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 - 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 - 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 -2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 -1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 - 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 -1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 - 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 -1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 - 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 - 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 - 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 -1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 -1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 -2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 -4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 - 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 -1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 - 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 -1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 -3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 -1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 -2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 -2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 -1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 -1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 -2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 - 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 -2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 -1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 -1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 -1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 -1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 -3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 -2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 -2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 - 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 -3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 -3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 -1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 -2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 -1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 -2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 -) - - diff --git a/dist/ba_data/python-site-packages/chardet/jpcntx.py b/dist/ba_data/python-site-packages/chardet/jpcntx.py deleted file mode 100644 index 20044e4b..00000000 --- a/dist/ba_data/python-site-packages/chardet/jpcntx.py +++ /dev/null @@ -1,233 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - - -# This is hiragana 2-char sequence table, the number in each cell represents its frequency category -jp2CharContext = ( -(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), -(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), -(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), -(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), -(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), -(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), -(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), -(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), -(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), -(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), -(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), -(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), -(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), -(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), -(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), -(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), -(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), -(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), -(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), -(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), -(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), -(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), -(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), -(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), -(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), -(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), -(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), -(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), -(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), -(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), -(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), -(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), -(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), -(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), -(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), -(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), -(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), -(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), -(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), -(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), -(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), -(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), -(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), -(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), -(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), -(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), -(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), -(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), -(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), -(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), -(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), -(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), -(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), -(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), -(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), -(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), -(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), -(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), -(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), -(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), -(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), -(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), -(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), -(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), -(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), -(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), -(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), -(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), -(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), -(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), -(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), -(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), -(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), -(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), -) - -class JapaneseContextAnalysis(object): - NUM_OF_CATEGORY = 6 - DONT_KNOW = -1 - ENOUGH_REL_THRESHOLD = 100 - MAX_REL_THRESHOLD = 1000 - MINIMUM_DATA_THRESHOLD = 4 - - def __init__(self): - self._total_rel = None - self._rel_sample = None - self._need_to_skip_char_num = None - self._last_char_order = None - self._done = None - self.reset() - - def reset(self): - self._total_rel = 0 # total sequence received - # category counters, each integer counts sequence in its category - self._rel_sample = [0] * self.NUM_OF_CATEGORY - # if last byte in current buffer is not the last byte of a character, - # we need to know how many bytes to skip in next buffer - self._need_to_skip_char_num = 0 - self._last_char_order = -1 # The order of previous char - # If this flag is set to True, detection is done and conclusion has - # been made - self._done = False - - def feed(self, byte_str, num_bytes): - if self._done: - return - - # The buffer we got is byte oriented, and a character may span in more than one - # buffers. In case the last one or two byte in last buffer is not - # complete, we record how many byte needed to complete that character - # and skip these bytes here. We can choose to record those bytes as - # well and analyse the character once it is complete, but since a - # character will not make much difference, by simply skipping - # this character will simply our logic and improve performance. - i = self._need_to_skip_char_num - while i < num_bytes: - order, char_len = self.get_order(byte_str[i:i + 2]) - i += char_len - if i > num_bytes: - self._need_to_skip_char_num = i - num_bytes - self._last_char_order = -1 - else: - if (order != -1) and (self._last_char_order != -1): - self._total_rel += 1 - if self._total_rel > self.MAX_REL_THRESHOLD: - self._done = True - break - self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 - self._last_char_order = order - - def got_enough_data(self): - return self._total_rel > self.ENOUGH_REL_THRESHOLD - - def get_confidence(self): - # This is just one way to calculate confidence. It works well for me. - if self._total_rel > self.MINIMUM_DATA_THRESHOLD: - return (self._total_rel - self._rel_sample[0]) / self._total_rel - else: - return self.DONT_KNOW - - def get_order(self, byte_str): - return -1, 1 - -class SJISContextAnalysis(JapaneseContextAnalysis): - def __init__(self): - super(SJISContextAnalysis, self).__init__() - self._charset_name = "SHIFT_JIS" - - @property - def charset_name(self): - return self._charset_name - - def get_order(self, byte_str): - if not byte_str: - return -1, 1 - # find out current char's byte length - first_char = byte_str[0] - if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): - char_len = 2 - if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): - self._charset_name = "CP932" - else: - char_len = 1 - - # return its order if it is hiragana - if len(byte_str) > 1: - second_char = byte_str[1] - if (first_char == 202) and (0x9F <= second_char <= 0xF1): - return second_char - 0x9F, char_len - - return -1, char_len - -class EUCJPContextAnalysis(JapaneseContextAnalysis): - def get_order(self, byte_str): - if not byte_str: - return -1, 1 - # find out current char's byte length - first_char = byte_str[0] - if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): - char_len = 2 - elif first_char == 0x8F: - char_len = 3 - else: - char_len = 1 - - # return its order if it is hiragana - if len(byte_str) > 1: - second_char = byte_str[1] - if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): - return second_char - 0xA1, char_len - - return -1, char_len - - diff --git a/dist/ba_data/python-site-packages/chardet/langbulgarianmodel.py b/dist/ba_data/python-site-packages/chardet/langbulgarianmodel.py deleted file mode 100644 index 561bfd90..00000000 --- a/dist/ba_data/python-site-packages/chardet/langbulgarianmodel.py +++ /dev/null @@ -1,4650 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -BULGARIAN_LANG_MODEL = { - 63: { # 'e' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 1, # 'б' - 9: 1, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 1, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 0, # 'и' - 26: 1, # 'й' - 12: 1, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 1, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 1, # 'с' - 5: 1, # 'т' - 19: 0, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 45: { # '\xad' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 0, # 'Л' - 38: 1, # 'М' - 36: 0, # 'Н' - 41: 1, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 1, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 1, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 0, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 0, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 0, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 31: { # 'А' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 1, # 'А' - 32: 1, # 'Б' - 35: 2, # 'В' - 43: 1, # 'Г' - 37: 2, # 'Д' - 44: 2, # 'Е' - 55: 1, # 'Ж' - 47: 2, # 'З' - 40: 1, # 'И' - 59: 1, # 'Й' - 33: 1, # 'К' - 46: 2, # 'Л' - 38: 1, # 'М' - 36: 2, # 'Н' - 41: 1, # 'О' - 30: 2, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 1, # 'У' - 48: 2, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 2, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 1, # 'а' - 18: 2, # 'б' - 9: 2, # 'в' - 20: 2, # 'г' - 11: 2, # 'д' - 3: 1, # 'е' - 23: 1, # 'ж' - 15: 2, # 'з' - 2: 0, # 'и' - 26: 2, # 'й' - 12: 2, # 'к' - 10: 3, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 0, # 'о' - 13: 2, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 1, # 'у' - 29: 2, # 'ф' - 25: 1, # 'х' - 22: 1, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 32: { # 'Б' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 2, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 2, # 'Д' - 44: 1, # 'Е' - 55: 1, # 'Ж' - 47: 2, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 2, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 1, # 'У' - 48: 2, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 0, # 'Ш' - 57: 1, # 'Щ' - 61: 2, # 'Ъ' - 60: 1, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 2, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 1, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 35: { # 'В' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 2, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 1, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 2, # 'Ф' - 49: 0, # 'Х' - 53: 1, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 2, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 2, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 2, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 2, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 43: { # 'Г' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 2, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 0, # 'П' - 39: 1, # 'Р' - 28: 1, # 'С' - 34: 0, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 1, # 'Щ' - 61: 1, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 1, # 'б' - 9: 1, # 'в' - 20: 0, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 2, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 1, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 37: { # 'Д' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 2, # 'В' - 43: 1, # 'Г' - 37: 2, # 'Д' - 44: 2, # 'Е' - 55: 2, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 2, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 2, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 2, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 44: { # 'Е' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 1, # 'Б' - 35: 2, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 1, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 1, # 'Й' - 33: 2, # 'К' - 46: 2, # 'Л' - 38: 1, # 'М' - 36: 2, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 1, # 'У' - 48: 2, # 'Ф' - 49: 1, # 'Х' - 53: 2, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 1, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 0, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 2, # 'д' - 3: 0, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 0, # 'и' - 26: 1, # 'й' - 12: 2, # 'к' - 10: 2, # 'л' - 14: 2, # 'м' - 6: 2, # 'н' - 4: 0, # 'о' - 13: 1, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 1, # 'т' - 19: 1, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 55: { # 'Ж' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 1, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 47: { # 'З' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 2, # 'Н' - 41: 1, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 1, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 2, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 1, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 1, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 40: { # 'И' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 1, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 2, # 'Е' - 55: 1, # 'Ж' - 47: 2, # 'З' - 40: 1, # 'И' - 59: 1, # 'Й' - 33: 2, # 'К' - 46: 2, # 'Л' - 38: 2, # 'М' - 36: 2, # 'Н' - 41: 1, # 'О' - 30: 1, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 0, # 'У' - 48: 1, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 1, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 2, # 'Я' - 1: 1, # 'а' - 18: 1, # 'б' - 9: 3, # 'в' - 20: 2, # 'г' - 11: 1, # 'д' - 3: 1, # 'е' - 23: 0, # 'ж' - 15: 3, # 'з' - 2: 0, # 'и' - 26: 1, # 'й' - 12: 1, # 'к' - 10: 2, # 'л' - 14: 2, # 'м' - 6: 2, # 'н' - 4: 0, # 'о' - 13: 1, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 0, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 1, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 59: { # 'Й' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 1, # 'С' - 34: 1, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 1, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 0, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 1, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 0, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 2, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 33: { # 'К' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 0, # 'М' - 36: 2, # 'Н' - 41: 2, # 'О' - 30: 2, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 1, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 1, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 2, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 3, # 'р' - 8: 1, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 46: { # 'Л' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 2, # 'Г' - 37: 1, # 'Д' - 44: 2, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 0, # 'Р' - 28: 1, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 1, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 1, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 2, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 38: { # 'М' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 2, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 1, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 2, # 'л' - 14: 0, # 'м' - 6: 2, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 36: { # 'Н' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 2, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 2, # 'Д' - 44: 2, # 'Е' - 55: 1, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 1, # 'Й' - 33: 2, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 1, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 1, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 2, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 41: { # 'О' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 1, # 'Б' - 35: 2, # 'В' - 43: 1, # 'Г' - 37: 2, # 'Д' - 44: 1, # 'Е' - 55: 1, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 1, # 'Й' - 33: 2, # 'К' - 46: 2, # 'Л' - 38: 2, # 'М' - 36: 2, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 1, # 'Х' - 53: 0, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 1, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 1, # 'а' - 18: 2, # 'б' - 9: 2, # 'в' - 20: 2, # 'г' - 11: 1, # 'д' - 3: 1, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 0, # 'и' - 26: 1, # 'й' - 12: 2, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 0, # 'о' - 13: 2, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 3, # 'т' - 19: 1, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 1, # 'ц' - 21: 2, # 'ч' - 27: 0, # 'ш' - 24: 2, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 30: { # 'П' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 2, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 2, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 3, # 'л' - 14: 0, # 'м' - 6: 1, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 3, # 'р' - 8: 1, # 'с' - 5: 1, # 'т' - 19: 2, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 39: { # 'Р' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 2, # 'Г' - 37: 2, # 'Д' - 44: 2, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 0, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 2, # 'П' - 39: 1, # 'Р' - 28: 1, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 1, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 1, # 'с' - 5: 0, # 'т' - 19: 3, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 28: { # 'С' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 3, # 'А' - 32: 2, # 'Б' - 35: 2, # 'В' - 43: 1, # 'Г' - 37: 2, # 'Д' - 44: 2, # 'Е' - 55: 1, # 'Ж' - 47: 1, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 2, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 2, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 2, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 1, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 2, # 'к' - 10: 3, # 'л' - 14: 2, # 'м' - 6: 1, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 2, # 'р' - 8: 0, # 'с' - 5: 3, # 'т' - 19: 2, # 'у' - 29: 2, # 'ф' - 25: 1, # 'х' - 22: 1, # 'ц' - 21: 1, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 34: { # 'Т' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 2, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 2, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 2, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 2, # 'О' - 30: 1, # 'П' - 39: 2, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 1, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 1, # 'Ъ' - 60: 0, # 'Ю' - 56: 1, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 1, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 1, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 3, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 51: { # 'У' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 1, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 2, # 'Е' - 55: 1, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 0, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 1, # 'С' - 34: 2, # 'Т' - 51: 0, # 'У' - 48: 1, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 1, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 2, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 2, # 'и' - 26: 1, # 'й' - 12: 2, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 2, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 2, # 'с' - 5: 1, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 2, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 48: { # 'Ф' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 2, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 1, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 2, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 2, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 49: { # 'Х' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 1, # 'П' - 39: 1, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 1, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 1, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 0, # 'н' - 4: 2, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 53: { # 'Ц' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 2, # 'И' - 59: 0, # 'Й' - 33: 2, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 1, # 'Р' - 28: 2, # 'С' - 34: 0, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 2, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 1, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 50: { # 'Ч' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 2, # 'А' - 32: 1, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 1, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 2, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 1, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 54: { # 'Ш' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 1, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 1, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 1, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 2, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 2, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 1, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 57: { # 'Щ' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 1, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 1, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 1, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 1, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 61: { # 'Ъ' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 1, # 'Д' - 44: 0, # 'Е' - 55: 1, # 'Ж' - 47: 1, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 2, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 0, # 'О' - 30: 1, # 'П' - 39: 2, # 'Р' - 28: 1, # 'С' - 34: 1, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 1, # 'Х' - 53: 1, # 'Ц' - 50: 1, # 'Ч' - 54: 1, # 'Ш' - 57: 1, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 0, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 0, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 1, # 'л' - 14: 0, # 'м' - 6: 1, # 'н' - 4: 0, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 60: { # 'Ю' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 1, # 'Б' - 35: 0, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 0, # 'Е' - 55: 1, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 0, # 'М' - 36: 1, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 1, # 'Р' - 28: 1, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 1, # 'б' - 9: 1, # 'в' - 20: 2, # 'г' - 11: 1, # 'д' - 3: 0, # 'е' - 23: 2, # 'ж' - 15: 1, # 'з' - 2: 1, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 0, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 1, # 'с' - 5: 1, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 56: { # 'Я' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 1, # 'Б' - 35: 1, # 'В' - 43: 1, # 'Г' - 37: 1, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 1, # 'Л' - 38: 1, # 'М' - 36: 1, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 1, # 'С' - 34: 2, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 1, # 'б' - 9: 1, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 0, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 1, # 'и' - 26: 1, # 'й' - 12: 1, # 'к' - 10: 1, # 'л' - 14: 2, # 'м' - 6: 2, # 'н' - 4: 0, # 'о' - 13: 2, # 'п' - 7: 1, # 'р' - 8: 1, # 'с' - 5: 1, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 1: { # 'а' - 63: 1, # 'e' - 45: 1, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 1, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 1, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 3, # 'з' - 2: 3, # 'и' - 26: 3, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 2, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 3, # 'ф' - 25: 3, # 'х' - 22: 3, # 'ц' - 21: 3, # 'ч' - 27: 3, # 'ш' - 24: 3, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 18: { # 'б' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 3, # 'в' - 20: 1, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 3, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 1, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 0, # 'т' - 19: 3, # 'у' - 29: 0, # 'ф' - 25: 2, # 'х' - 22: 1, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 3, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 9: { # 'в' - 63: 1, # 'e' - 45: 1, # '\xad' - 31: 0, # 'А' - 32: 1, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 0, # 'в' - 20: 2, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 3, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 2, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 3, # 'ч' - 27: 2, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 20: { # 'г' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 3, # 'л' - 14: 1, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 1, # 'п' - 7: 3, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 3, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 11: { # 'д' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 2, # 'б' - 9: 3, # 'в' - 20: 2, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 2, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 1, # 'т' - 19: 3, # 'у' - 29: 1, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 3: { # 'е' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 2, # 'е' - 23: 3, # 'ж' - 15: 3, # 'з' - 2: 2, # 'и' - 26: 3, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 2, # 'у' - 29: 3, # 'ф' - 25: 3, # 'х' - 22: 3, # 'ц' - 21: 3, # 'ч' - 27: 3, # 'ш' - 24: 3, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 23: { # 'ж' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 2, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 3, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 1, # 'с' - 5: 1, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 1, # 'ц' - 21: 1, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 15: { # 'з' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 1, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 2, # 'ш' - 24: 1, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 2: { # 'и' - 63: 1, # 'e' - 45: 1, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 1, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 1, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 1, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 1, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 3, # 'з' - 2: 3, # 'и' - 26: 3, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 2, # 'у' - 29: 3, # 'ф' - 25: 3, # 'х' - 22: 3, # 'ц' - 21: 3, # 'ч' - 27: 3, # 'ш' - 24: 3, # 'щ' - 17: 2, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 26: { # 'й' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 1, # 'а' - 18: 2, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 2, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 2, # 'з' - 2: 1, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 2, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 2, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 1, # 'у' - 29: 2, # 'ф' - 25: 1, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 12: { # 'к' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 1, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 1, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 3, # 'в' - 20: 2, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 2, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 3, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 1, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 3, # 'ц' - 21: 2, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 10: { # 'л' - 63: 1, # 'e' - 45: 1, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 1, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 2, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 1, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 2, # 'п' - 7: 2, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 2, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 2, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 2, # 'ь' - 42: 3, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 14: { # 'м' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 1, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 2, # 'к' - 10: 3, # 'л' - 14: 1, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 1, # 'т' - 19: 3, # 'у' - 29: 2, # 'ф' - 25: 1, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 2, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 6: { # 'н' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 1, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 2, # 'б' - 9: 2, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 2, # 'ж' - 15: 2, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 1, # 'п' - 7: 2, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 3, # 'ф' - 25: 2, # 'х' - 22: 3, # 'ц' - 21: 3, # 'ч' - 27: 2, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 2, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 4: { # 'о' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 2, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 3, # 'з' - 2: 3, # 'и' - 26: 3, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 2, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 2, # 'у' - 29: 3, # 'ф' - 25: 3, # 'х' - 22: 3, # 'ц' - 21: 3, # 'ч' - 27: 3, # 'ш' - 24: 3, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 13: { # 'п' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 1, # 'й' - 12: 2, # 'к' - 10: 3, # 'л' - 14: 1, # 'м' - 6: 2, # 'н' - 4: 3, # 'о' - 13: 1, # 'п' - 7: 3, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 3, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 7: { # 'р' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 3, # 'е' - 23: 3, # 'ж' - 15: 2, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 2, # 'п' - 7: 1, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 2, # 'ф' - 25: 3, # 'х' - 22: 3, # 'ц' - 21: 2, # 'ч' - 27: 3, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 1, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 8: { # 'с' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 2, # 'б' - 9: 3, # 'в' - 20: 2, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 1, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 2, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 2, # 'ш' - 24: 0, # 'щ' - 17: 3, # 'ъ' - 52: 2, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 5: { # 'т' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 2, # 'г' - 11: 2, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 2, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 3, # 'у' - 29: 1, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 2, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 3, # 'ъ' - 52: 2, # 'ь' - 42: 2, # 'ю' - 16: 3, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 19: { # 'у' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 2, # 'е' - 23: 3, # 'ж' - 15: 3, # 'з' - 2: 2, # 'и' - 26: 2, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 2, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 1, # 'у' - 29: 2, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 3, # 'ч' - 27: 3, # 'ш' - 24: 2, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 29: { # 'ф' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 1, # 'в' - 20: 1, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 2, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 2, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 2, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 25: { # 'х' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 3, # 'в' - 20: 0, # 'г' - 11: 1, # 'д' - 3: 2, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 2, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 1, # 'п' - 7: 3, # 'р' - 8: 1, # 'с' - 5: 2, # 'т' - 19: 3, # 'у' - 29: 0, # 'ф' - 25: 1, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 22: { # 'ц' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 2, # 'в' - 20: 1, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 1, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 2, # 'к' - 10: 1, # 'л' - 14: 1, # 'м' - 6: 1, # 'н' - 4: 2, # 'о' - 13: 1, # 'п' - 7: 1, # 'р' - 8: 1, # 'с' - 5: 1, # 'т' - 19: 2, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 1, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 0, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 21: { # 'ч' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 1, # 'б' - 9: 3, # 'в' - 20: 1, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 1, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 2, # 'л' - 14: 2, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 2, # 'р' - 8: 0, # 'с' - 5: 2, # 'т' - 19: 3, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 1, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 27: { # 'ш' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 2, # 'в' - 20: 0, # 'г' - 11: 1, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 3, # 'к' - 10: 2, # 'л' - 14: 1, # 'м' - 6: 3, # 'н' - 4: 2, # 'о' - 13: 2, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 1, # 'т' - 19: 2, # 'у' - 29: 1, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 1, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 2, # 'ъ' - 52: 1, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 24: { # 'щ' - 63: 1, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 3, # 'а' - 18: 0, # 'б' - 9: 1, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 3, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 3, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 2, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 1, # 'р' - 8: 0, # 'с' - 5: 2, # 'т' - 19: 3, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 1, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 2, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 17: { # 'ъ' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 1, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 3, # 'г' - 11: 3, # 'д' - 3: 2, # 'е' - 23: 3, # 'ж' - 15: 3, # 'з' - 2: 1, # 'и' - 26: 2, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 3, # 'о' - 13: 3, # 'п' - 7: 3, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 1, # 'у' - 29: 1, # 'ф' - 25: 2, # 'х' - 22: 2, # 'ц' - 21: 3, # 'ч' - 27: 2, # 'ш' - 24: 3, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 2, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 52: { # 'ь' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 1, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 0, # 'и' - 26: 0, # 'й' - 12: 1, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 1, # 'н' - 4: 3, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 1, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 1, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 1, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 42: { # 'ю' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 1, # 'а' - 18: 2, # 'б' - 9: 1, # 'в' - 20: 2, # 'г' - 11: 2, # 'д' - 3: 1, # 'е' - 23: 2, # 'ж' - 15: 2, # 'з' - 2: 1, # 'и' - 26: 1, # 'й' - 12: 2, # 'к' - 10: 2, # 'л' - 14: 2, # 'м' - 6: 2, # 'н' - 4: 1, # 'о' - 13: 1, # 'п' - 7: 2, # 'р' - 8: 2, # 'с' - 5: 2, # 'т' - 19: 1, # 'у' - 29: 1, # 'ф' - 25: 1, # 'х' - 22: 2, # 'ц' - 21: 3, # 'ч' - 27: 1, # 'ш' - 24: 1, # 'щ' - 17: 1, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 16: { # 'я' - 63: 0, # 'e' - 45: 1, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 3, # 'б' - 9: 3, # 'в' - 20: 2, # 'г' - 11: 3, # 'д' - 3: 2, # 'е' - 23: 1, # 'ж' - 15: 2, # 'з' - 2: 1, # 'и' - 26: 2, # 'й' - 12: 3, # 'к' - 10: 3, # 'л' - 14: 3, # 'м' - 6: 3, # 'н' - 4: 1, # 'о' - 13: 2, # 'п' - 7: 2, # 'р' - 8: 3, # 'с' - 5: 3, # 'т' - 19: 1, # 'у' - 29: 1, # 'ф' - 25: 3, # 'х' - 22: 2, # 'ц' - 21: 1, # 'ч' - 27: 1, # 'ш' - 24: 2, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 1, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 58: { # 'є' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 0, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 0, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 0, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, - 62: { # '№' - 63: 0, # 'e' - 45: 0, # '\xad' - 31: 0, # 'А' - 32: 0, # 'Б' - 35: 0, # 'В' - 43: 0, # 'Г' - 37: 0, # 'Д' - 44: 0, # 'Е' - 55: 0, # 'Ж' - 47: 0, # 'З' - 40: 0, # 'И' - 59: 0, # 'Й' - 33: 0, # 'К' - 46: 0, # 'Л' - 38: 0, # 'М' - 36: 0, # 'Н' - 41: 0, # 'О' - 30: 0, # 'П' - 39: 0, # 'Р' - 28: 0, # 'С' - 34: 0, # 'Т' - 51: 0, # 'У' - 48: 0, # 'Ф' - 49: 0, # 'Х' - 53: 0, # 'Ц' - 50: 0, # 'Ч' - 54: 0, # 'Ш' - 57: 0, # 'Щ' - 61: 0, # 'Ъ' - 60: 0, # 'Ю' - 56: 0, # 'Я' - 1: 0, # 'а' - 18: 0, # 'б' - 9: 0, # 'в' - 20: 0, # 'г' - 11: 0, # 'д' - 3: 0, # 'е' - 23: 0, # 'ж' - 15: 0, # 'з' - 2: 0, # 'и' - 26: 0, # 'й' - 12: 0, # 'к' - 10: 0, # 'л' - 14: 0, # 'м' - 6: 0, # 'н' - 4: 0, # 'о' - 13: 0, # 'п' - 7: 0, # 'р' - 8: 0, # 'с' - 5: 0, # 'т' - 19: 0, # 'у' - 29: 0, # 'ф' - 25: 0, # 'х' - 22: 0, # 'ц' - 21: 0, # 'ч' - 27: 0, # 'ш' - 24: 0, # 'щ' - 17: 0, # 'ъ' - 52: 0, # 'ь' - 42: 0, # 'ю' - 16: 0, # 'я' - 58: 0, # 'є' - 62: 0, # '№' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -ISO_8859_5_BULGARIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 77, # 'A' - 66: 90, # 'B' - 67: 99, # 'C' - 68: 100, # 'D' - 69: 72, # 'E' - 70: 109, # 'F' - 71: 107, # 'G' - 72: 101, # 'H' - 73: 79, # 'I' - 74: 185, # 'J' - 75: 81, # 'K' - 76: 102, # 'L' - 77: 76, # 'M' - 78: 94, # 'N' - 79: 82, # 'O' - 80: 110, # 'P' - 81: 186, # 'Q' - 82: 108, # 'R' - 83: 91, # 'S' - 84: 74, # 'T' - 85: 119, # 'U' - 86: 84, # 'V' - 87: 96, # 'W' - 88: 111, # 'X' - 89: 187, # 'Y' - 90: 115, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 65, # 'a' - 98: 69, # 'b' - 99: 70, # 'c' - 100: 66, # 'd' - 101: 63, # 'e' - 102: 68, # 'f' - 103: 112, # 'g' - 104: 103, # 'h' - 105: 92, # 'i' - 106: 194, # 'j' - 107: 104, # 'k' - 108: 95, # 'l' - 109: 86, # 'm' - 110: 87, # 'n' - 111: 71, # 'o' - 112: 116, # 'p' - 113: 195, # 'q' - 114: 85, # 'r' - 115: 93, # 's' - 116: 97, # 't' - 117: 113, # 'u' - 118: 196, # 'v' - 119: 197, # 'w' - 120: 198, # 'x' - 121: 199, # 'y' - 122: 200, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 194, # '\x80' - 129: 195, # '\x81' - 130: 196, # '\x82' - 131: 197, # '\x83' - 132: 198, # '\x84' - 133: 199, # '\x85' - 134: 200, # '\x86' - 135: 201, # '\x87' - 136: 202, # '\x88' - 137: 203, # '\x89' - 138: 204, # '\x8a' - 139: 205, # '\x8b' - 140: 206, # '\x8c' - 141: 207, # '\x8d' - 142: 208, # '\x8e' - 143: 209, # '\x8f' - 144: 210, # '\x90' - 145: 211, # '\x91' - 146: 212, # '\x92' - 147: 213, # '\x93' - 148: 214, # '\x94' - 149: 215, # '\x95' - 150: 216, # '\x96' - 151: 217, # '\x97' - 152: 218, # '\x98' - 153: 219, # '\x99' - 154: 220, # '\x9a' - 155: 221, # '\x9b' - 156: 222, # '\x9c' - 157: 223, # '\x9d' - 158: 224, # '\x9e' - 159: 225, # '\x9f' - 160: 81, # '\xa0' - 161: 226, # 'Ё' - 162: 227, # 'Ђ' - 163: 228, # 'Ѓ' - 164: 229, # 'Є' - 165: 230, # 'Ѕ' - 166: 105, # 'І' - 167: 231, # 'Ї' - 168: 232, # 'Ј' - 169: 233, # 'Љ' - 170: 234, # 'Њ' - 171: 235, # 'Ћ' - 172: 236, # 'Ќ' - 173: 45, # '\xad' - 174: 237, # 'Ў' - 175: 238, # 'Џ' - 176: 31, # 'А' - 177: 32, # 'Б' - 178: 35, # 'В' - 179: 43, # 'Г' - 180: 37, # 'Д' - 181: 44, # 'Е' - 182: 55, # 'Ж' - 183: 47, # 'З' - 184: 40, # 'И' - 185: 59, # 'Й' - 186: 33, # 'К' - 187: 46, # 'Л' - 188: 38, # 'М' - 189: 36, # 'Н' - 190: 41, # 'О' - 191: 30, # 'П' - 192: 39, # 'Р' - 193: 28, # 'С' - 194: 34, # 'Т' - 195: 51, # 'У' - 196: 48, # 'Ф' - 197: 49, # 'Х' - 198: 53, # 'Ц' - 199: 50, # 'Ч' - 200: 54, # 'Ш' - 201: 57, # 'Щ' - 202: 61, # 'Ъ' - 203: 239, # 'Ы' - 204: 67, # 'Ь' - 205: 240, # 'Э' - 206: 60, # 'Ю' - 207: 56, # 'Я' - 208: 1, # 'а' - 209: 18, # 'б' - 210: 9, # 'в' - 211: 20, # 'г' - 212: 11, # 'д' - 213: 3, # 'е' - 214: 23, # 'ж' - 215: 15, # 'з' - 216: 2, # 'и' - 217: 26, # 'й' - 218: 12, # 'к' - 219: 10, # 'л' - 220: 14, # 'м' - 221: 6, # 'н' - 222: 4, # 'о' - 223: 13, # 'п' - 224: 7, # 'р' - 225: 8, # 'с' - 226: 5, # 'т' - 227: 19, # 'у' - 228: 29, # 'ф' - 229: 25, # 'х' - 230: 22, # 'ц' - 231: 21, # 'ч' - 232: 27, # 'ш' - 233: 24, # 'щ' - 234: 17, # 'ъ' - 235: 75, # 'ы' - 236: 52, # 'ь' - 237: 241, # 'э' - 238: 42, # 'ю' - 239: 16, # 'я' - 240: 62, # '№' - 241: 242, # 'ё' - 242: 243, # 'ђ' - 243: 244, # 'ѓ' - 244: 58, # 'є' - 245: 245, # 'ѕ' - 246: 98, # 'і' - 247: 246, # 'ї' - 248: 247, # 'ј' - 249: 248, # 'љ' - 250: 249, # 'њ' - 251: 250, # 'ћ' - 252: 251, # 'ќ' - 253: 91, # '§' - 254: 252, # 'ў' - 255: 253, # 'џ' -} - -ISO_8859_5_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', - language='Bulgarian', - char_to_order_map=ISO_8859_5_BULGARIAN_CHAR_TO_ORDER, - language_model=BULGARIAN_LANG_MODEL, - typical_positive_ratio=0.969392, - keep_ascii_letters=False, - alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') - -WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 77, # 'A' - 66: 90, # 'B' - 67: 99, # 'C' - 68: 100, # 'D' - 69: 72, # 'E' - 70: 109, # 'F' - 71: 107, # 'G' - 72: 101, # 'H' - 73: 79, # 'I' - 74: 185, # 'J' - 75: 81, # 'K' - 76: 102, # 'L' - 77: 76, # 'M' - 78: 94, # 'N' - 79: 82, # 'O' - 80: 110, # 'P' - 81: 186, # 'Q' - 82: 108, # 'R' - 83: 91, # 'S' - 84: 74, # 'T' - 85: 119, # 'U' - 86: 84, # 'V' - 87: 96, # 'W' - 88: 111, # 'X' - 89: 187, # 'Y' - 90: 115, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 65, # 'a' - 98: 69, # 'b' - 99: 70, # 'c' - 100: 66, # 'd' - 101: 63, # 'e' - 102: 68, # 'f' - 103: 112, # 'g' - 104: 103, # 'h' - 105: 92, # 'i' - 106: 194, # 'j' - 107: 104, # 'k' - 108: 95, # 'l' - 109: 86, # 'm' - 110: 87, # 'n' - 111: 71, # 'o' - 112: 116, # 'p' - 113: 195, # 'q' - 114: 85, # 'r' - 115: 93, # 's' - 116: 97, # 't' - 117: 113, # 'u' - 118: 196, # 'v' - 119: 197, # 'w' - 120: 198, # 'x' - 121: 199, # 'y' - 122: 200, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 206, # 'Ђ' - 129: 207, # 'Ѓ' - 130: 208, # '‚' - 131: 209, # 'ѓ' - 132: 210, # '„' - 133: 211, # '…' - 134: 212, # '†' - 135: 213, # '‡' - 136: 120, # '€' - 137: 214, # '‰' - 138: 215, # 'Љ' - 139: 216, # '‹' - 140: 217, # 'Њ' - 141: 218, # 'Ќ' - 142: 219, # 'Ћ' - 143: 220, # 'Џ' - 144: 221, # 'ђ' - 145: 78, # '‘' - 146: 64, # '’' - 147: 83, # '“' - 148: 121, # '”' - 149: 98, # '•' - 150: 117, # '–' - 151: 105, # '—' - 152: 222, # None - 153: 223, # '™' - 154: 224, # 'љ' - 155: 225, # '›' - 156: 226, # 'њ' - 157: 227, # 'ќ' - 158: 228, # 'ћ' - 159: 229, # 'џ' - 160: 88, # '\xa0' - 161: 230, # 'Ў' - 162: 231, # 'ў' - 163: 232, # 'Ј' - 164: 233, # '¤' - 165: 122, # 'Ґ' - 166: 89, # '¦' - 167: 106, # '§' - 168: 234, # 'Ё' - 169: 235, # '©' - 170: 236, # 'Є' - 171: 237, # '«' - 172: 238, # '¬' - 173: 45, # '\xad' - 174: 239, # '®' - 175: 240, # 'Ї' - 176: 73, # '°' - 177: 80, # '±' - 178: 118, # 'І' - 179: 114, # 'і' - 180: 241, # 'ґ' - 181: 242, # 'µ' - 182: 243, # '¶' - 183: 244, # '·' - 184: 245, # 'ё' - 185: 62, # '№' - 186: 58, # 'є' - 187: 246, # '»' - 188: 247, # 'ј' - 189: 248, # 'Ѕ' - 190: 249, # 'ѕ' - 191: 250, # 'ї' - 192: 31, # 'А' - 193: 32, # 'Б' - 194: 35, # 'В' - 195: 43, # 'Г' - 196: 37, # 'Д' - 197: 44, # 'Е' - 198: 55, # 'Ж' - 199: 47, # 'З' - 200: 40, # 'И' - 201: 59, # 'Й' - 202: 33, # 'К' - 203: 46, # 'Л' - 204: 38, # 'М' - 205: 36, # 'Н' - 206: 41, # 'О' - 207: 30, # 'П' - 208: 39, # 'Р' - 209: 28, # 'С' - 210: 34, # 'Т' - 211: 51, # 'У' - 212: 48, # 'Ф' - 213: 49, # 'Х' - 214: 53, # 'Ц' - 215: 50, # 'Ч' - 216: 54, # 'Ш' - 217: 57, # 'Щ' - 218: 61, # 'Ъ' - 219: 251, # 'Ы' - 220: 67, # 'Ь' - 221: 252, # 'Э' - 222: 60, # 'Ю' - 223: 56, # 'Я' - 224: 1, # 'а' - 225: 18, # 'б' - 226: 9, # 'в' - 227: 20, # 'г' - 228: 11, # 'д' - 229: 3, # 'е' - 230: 23, # 'ж' - 231: 15, # 'з' - 232: 2, # 'и' - 233: 26, # 'й' - 234: 12, # 'к' - 235: 10, # 'л' - 236: 14, # 'м' - 237: 6, # 'н' - 238: 4, # 'о' - 239: 13, # 'п' - 240: 7, # 'р' - 241: 8, # 'с' - 242: 5, # 'т' - 243: 19, # 'у' - 244: 29, # 'ф' - 245: 25, # 'х' - 246: 22, # 'ц' - 247: 21, # 'ч' - 248: 27, # 'ш' - 249: 24, # 'щ' - 250: 17, # 'ъ' - 251: 75, # 'ы' - 252: 52, # 'ь' - 253: 253, # 'э' - 254: 42, # 'ю' - 255: 16, # 'я' -} - -WINDOWS_1251_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', - language='Bulgarian', - char_to_order_map=WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER, - language_model=BULGARIAN_LANG_MODEL, - typical_positive_ratio=0.969392, - keep_ascii_letters=False, - alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') - diff --git a/dist/ba_data/python-site-packages/chardet/langgreekmodel.py b/dist/ba_data/python-site-packages/chardet/langgreekmodel.py deleted file mode 100644 index 02b94de6..00000000 --- a/dist/ba_data/python-site-packages/chardet/langgreekmodel.py +++ /dev/null @@ -1,4398 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -GREEK_LANG_MODEL = { - 60: { # 'e' - 60: 2, # 'e' - 55: 1, # 'o' - 58: 2, # 't' - 36: 1, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 1, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 55: { # 'o' - 60: 0, # 'e' - 55: 2, # 'o' - 58: 2, # 't' - 36: 1, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 1, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 1, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 58: { # 't' - 60: 2, # 'e' - 55: 1, # 'o' - 58: 1, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 1, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 36: { # '·' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 61: { # 'Ά' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 1, # 'γ' - 21: 2, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 1, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 46: { # 'Έ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 2, # 'β' - 20: 2, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 2, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 0, # 'ο' - 9: 2, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 1, # 'σ' - 2: 2, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 3, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 54: { # 'Ό' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 2, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 2, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 2, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 31: { # 'Α' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 2, # 'Β' - 43: 2, # 'Γ' - 41: 1, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 2, # 'Θ' - 47: 2, # 'Ι' - 44: 2, # 'Κ' - 53: 2, # 'Λ' - 38: 2, # 'Μ' - 49: 2, # 'Ν' - 59: 1, # 'Ξ' - 39: 0, # 'Ο' - 35: 2, # 'Π' - 48: 2, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 2, # 'Υ' - 56: 2, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 2, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 1, # 'θ' - 5: 0, # 'ι' - 11: 2, # 'κ' - 16: 3, # 'λ' - 10: 2, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 0, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 2, # 'ς' - 7: 2, # 'σ' - 2: 0, # 'τ' - 12: 3, # 'υ' - 28: 2, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 2, # 'ύ' - 27: 0, # 'ώ' - }, - 51: { # 'Β' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 1, # 'Ε' - 40: 1, # 'Η' - 52: 0, # 'Θ' - 47: 1, # 'Ι' - 44: 0, # 'Κ' - 53: 1, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 2, # 'ή' - 15: 0, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 43: { # 'Γ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 1, # 'Α' - 51: 0, # 'Β' - 43: 2, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 1, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 1, # 'Κ' - 53: 1, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 1, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 2, # 'Υ' - 56: 0, # 'Φ' - 50: 1, # 'Χ' - 57: 2, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 41: { # 'Δ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 2, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 2, # 'ή' - 15: 2, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 1, # 'ό' - 26: 2, # 'ύ' - 27: 2, # 'ώ' - }, - 34: { # 'Ε' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 2, # 'Γ' - 41: 2, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 2, # 'Κ' - 53: 2, # 'Λ' - 38: 2, # 'Μ' - 49: 2, # 'Ν' - 59: 1, # 'Ξ' - 39: 0, # 'Ο' - 35: 2, # 'Π' - 48: 2, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 2, # 'Υ' - 56: 0, # 'Φ' - 50: 2, # 'Χ' - 57: 2, # 'Ω' - 17: 3, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 3, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 3, # 'γ' - 21: 2, # 'δ' - 3: 1, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 1, # 'θ' - 5: 2, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 2, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 0, # 'ο' - 9: 3, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 2, # 'σ' - 2: 2, # 'τ' - 12: 2, # 'υ' - 28: 2, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 1, # 'ύ' - 27: 0, # 'ώ' - }, - 40: { # 'Η' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 1, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 2, # 'Θ' - 47: 0, # 'Ι' - 44: 2, # 'Κ' - 53: 0, # 'Λ' - 38: 2, # 'Μ' - 49: 2, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 2, # 'Π' - 48: 2, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 1, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 1, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 1, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 52: { # 'Θ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 1, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 1, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 2, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 2, # 'ύ' - 27: 0, # 'ώ' - }, - 47: { # 'Ι' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 1, # 'Β' - 43: 1, # 'Γ' - 41: 2, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 2, # 'Κ' - 53: 2, # 'Λ' - 38: 2, # 'Μ' - 49: 2, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 0, # 'Υ' - 56: 2, # 'Φ' - 50: 0, # 'Χ' - 57: 2, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 2, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 1, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 2, # 'σ' - 2: 1, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 1, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 44: { # 'Κ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 1, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 1, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 0, # 'Σ' - 33: 1, # 'Τ' - 45: 2, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 1, # 'Ω' - 17: 3, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 2, # 'ό' - 26: 2, # 'ύ' - 27: 2, # 'ώ' - }, - 53: { # 'Λ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 2, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 2, # 'Σ' - 33: 0, # 'Τ' - 45: 2, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 2, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 0, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 1, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 2, # 'ό' - 26: 2, # 'ύ' - 27: 0, # 'ώ' - }, - 38: { # 'Μ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 2, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 2, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 2, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 2, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 3, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 2, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 49: { # 'Ν' - 60: 2, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 2, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 2, # 'Ω' - 17: 0, # 'ά' - 18: 2, # 'έ' - 22: 0, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 1, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 1, # 'ω' - 19: 2, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 59: { # 'Ξ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 1, # 'Ε' - 40: 1, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 1, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 2, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 39: { # 'Ο' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 1, # 'Β' - 43: 2, # 'Γ' - 41: 2, # 'Δ' - 34: 2, # 'Ε' - 40: 1, # 'Η' - 52: 2, # 'Θ' - 47: 2, # 'Ι' - 44: 2, # 'Κ' - 53: 2, # 'Λ' - 38: 2, # 'Μ' - 49: 2, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 2, # 'Π' - 48: 2, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 2, # 'Υ' - 56: 2, # 'Φ' - 50: 2, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 2, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 2, # 'κ' - 16: 2, # 'λ' - 10: 2, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 2, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 2, # 'τ' - 12: 2, # 'υ' - 28: 1, # 'φ' - 23: 1, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 2, # 'ύ' - 27: 0, # 'ώ' - }, - 35: { # 'Π' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 2, # 'Λ' - 38: 1, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 0, # 'Σ' - 33: 1, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 1, # 'Χ' - 57: 2, # 'Ω' - 17: 2, # 'ά' - 18: 1, # 'έ' - 22: 1, # 'ή' - 15: 2, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 2, # 'ό' - 26: 0, # 'ύ' - 27: 3, # 'ώ' - }, - 48: { # 'Ρ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 1, # 'Γ' - 41: 1, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 2, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 0, # 'Σ' - 33: 1, # 'Τ' - 45: 1, # 'Υ' - 56: 0, # 'Φ' - 50: 1, # 'Χ' - 57: 1, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 2, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 1, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 2, # 'ύ' - 27: 0, # 'ώ' - }, - 37: { # 'Σ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 1, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 2, # 'Κ' - 53: 0, # 'Λ' - 38: 2, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 2, # 'Υ' - 56: 0, # 'Φ' - 50: 2, # 'Χ' - 57: 2, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 2, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 2, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 2, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 2, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 2, # 'ύ' - 27: 2, # 'ώ' - }, - 33: { # 'Τ' - 60: 0, # 'e' - 55: 1, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 2, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 2, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 0, # 'Σ' - 33: 1, # 'Τ' - 45: 1, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 2, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 0, # 'ή' - 15: 2, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 2, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 2, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 2, # 'ό' - 26: 2, # 'ύ' - 27: 3, # 'ώ' - }, - 45: { # 'Υ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 2, # 'Γ' - 41: 0, # 'Δ' - 34: 1, # 'Ε' - 40: 2, # 'Η' - 52: 2, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 1, # 'Λ' - 38: 2, # 'Μ' - 49: 2, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 2, # 'Π' - 48: 1, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 1, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 3, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 56: { # 'Φ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 1, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 1, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 2, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 2, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 1, # 'ύ' - 27: 1, # 'ώ' - }, - 50: { # 'Χ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 1, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 2, # 'Ε' - 40: 2, # 'Η' - 52: 0, # 'Θ' - 47: 2, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 1, # 'Ν' - 59: 0, # 'Ξ' - 39: 1, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 1, # 'Χ' - 57: 1, # 'Ω' - 17: 2, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 2, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 2, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 57: { # 'Ω' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 1, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 1, # 'Λ' - 38: 0, # 'Μ' - 49: 2, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 2, # 'Ρ' - 37: 2, # 'Σ' - 33: 2, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 2, # 'ρ' - 14: 2, # 'ς' - 7: 2, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 1, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 17: { # 'ά' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 3, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 3, # 'ε' - 32: 3, # 'ζ' - 13: 0, # 'η' - 25: 3, # 'θ' - 5: 2, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 0, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 3, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 18: { # 'έ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 3, # 'α' - 29: 2, # 'β' - 20: 3, # 'γ' - 21: 2, # 'δ' - 3: 3, # 'ε' - 32: 2, # 'ζ' - 13: 0, # 'η' - 25: 3, # 'θ' - 5: 0, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 3, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 22: { # 'ή' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 1, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 3, # 'θ' - 5: 0, # 'ι' - 11: 3, # 'κ' - 16: 2, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 0, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 15: { # 'ί' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 3, # 'α' - 29: 2, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 3, # 'ε' - 32: 3, # 'ζ' - 13: 3, # 'η' - 25: 3, # 'θ' - 5: 0, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 1, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 3, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 1: { # 'α' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 2, # 'έ' - 22: 0, # 'ή' - 15: 3, # 'ί' - 1: 0, # 'α' - 29: 3, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 2, # 'ε' - 32: 3, # 'ζ' - 13: 1, # 'η' - 25: 3, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 2, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 0, # 'ω' - 19: 2, # 'ό' - 26: 2, # 'ύ' - 27: 0, # 'ώ' - }, - 29: { # 'β' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 2, # 'έ' - 22: 3, # 'ή' - 15: 2, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 2, # 'γ' - 21: 2, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 3, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 2, # 'ό' - 26: 2, # 'ύ' - 27: 2, # 'ώ' - }, - 20: { # 'γ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 3, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 3, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 2, # 'ύ' - 27: 3, # 'ώ' - }, - 21: { # 'δ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 3: { # 'ε' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 3, # 'ί' - 1: 2, # 'α' - 29: 3, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 2, # 'ε' - 32: 2, # 'ζ' - 13: 0, # 'η' - 25: 3, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 2, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 3, # 'ω' - 19: 2, # 'ό' - 26: 3, # 'ύ' - 27: 2, # 'ώ' - }, - 32: { # 'ζ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 2, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 1, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 2, # 'ό' - 26: 0, # 'ύ' - 27: 2, # 'ώ' - }, - 13: { # 'η' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 3, # 'γ' - 21: 2, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 3, # 'θ' - 5: 0, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 0, # 'ο' - 9: 2, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 25: { # 'θ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 2, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 1, # 'λ' - 10: 3, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 5: { # 'ι' - 60: 0, # 'e' - 55: 1, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 1, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 0, # 'ί' - 1: 3, # 'α' - 29: 3, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 3, # 'ε' - 32: 2, # 'ζ' - 13: 3, # 'η' - 25: 3, # 'θ' - 5: 0, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 0, # 'ύ' - 27: 3, # 'ώ' - }, - 11: { # 'κ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 3, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 2, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 2, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 2, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 16: { # 'λ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 1, # 'β' - 20: 2, # 'γ' - 21: 1, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 2, # 'θ' - 5: 3, # 'ι' - 11: 2, # 'κ' - 16: 3, # 'λ' - 10: 2, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 2, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 10: { # 'μ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 1, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 3, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 2, # 'υ' - 28: 3, # 'φ' - 23: 0, # 'χ' - 42: 2, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 2, # 'ύ' - 27: 2, # 'ώ' - }, - 6: { # 'ν' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 3, # 'δ' - 3: 3, # 'ε' - 32: 2, # 'ζ' - 13: 3, # 'η' - 25: 3, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 1, # 'λ' - 10: 0, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 30: { # 'ξ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 2, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 2, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 2, # 'ό' - 26: 3, # 'ύ' - 27: 1, # 'ώ' - }, - 4: { # 'ο' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 2, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 2, # 'α' - 29: 3, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 3, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 2, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 2, # 'ω' - 19: 1, # 'ό' - 26: 3, # 'ύ' - 27: 2, # 'ώ' - }, - 9: { # 'π' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 3, # 'λ' - 10: 0, # 'μ' - 6: 2, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 2, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 2, # 'ύ' - 27: 3, # 'ώ' - }, - 8: { # 'ρ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 2, # 'β' - 20: 3, # 'γ' - 21: 2, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 3, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 1, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 3, # 'ο' - 9: 2, # 'π' - 8: 2, # 'ρ' - 14: 0, # 'ς' - 7: 2, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 14: { # 'ς' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 2, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 0, # 'θ' - 5: 0, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 0, # 'τ' - 12: 0, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 7: { # 'σ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 3, # 'β' - 20: 0, # 'γ' - 21: 2, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 3, # 'θ' - 5: 3, # 'ι' - 11: 3, # 'κ' - 16: 2, # 'λ' - 10: 3, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 3, # 'φ' - 23: 3, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 2, # 'ώ' - }, - 2: { # 'τ' - 60: 0, # 'e' - 55: 2, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 2, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 3, # 'ι' - 11: 2, # 'κ' - 16: 2, # 'λ' - 10: 3, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 2, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 12: { # 'υ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 3, # 'ή' - 15: 2, # 'ί' - 1: 3, # 'α' - 29: 2, # 'β' - 20: 3, # 'γ' - 21: 2, # 'δ' - 3: 2, # 'ε' - 32: 2, # 'ζ' - 13: 2, # 'η' - 25: 3, # 'θ' - 5: 2, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 3, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 2, # 'ω' - 19: 2, # 'ό' - 26: 0, # 'ύ' - 27: 2, # 'ώ' - }, - 28: { # 'φ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 3, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 2, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 0, # 'μ' - 6: 1, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 1, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 2, # 'ύ' - 27: 2, # 'ώ' - }, - 23: { # 'χ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 3, # 'ά' - 18: 2, # 'έ' - 22: 3, # 'ή' - 15: 3, # 'ί' - 1: 3, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 2, # 'θ' - 5: 3, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 2, # 'μ' - 6: 3, # 'ν' - 30: 0, # 'ξ' - 4: 3, # 'ο' - 9: 0, # 'π' - 8: 3, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 3, # 'τ' - 12: 3, # 'υ' - 28: 0, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 3, # 'ω' - 19: 3, # 'ό' - 26: 3, # 'ύ' - 27: 3, # 'ώ' - }, - 42: { # 'ψ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 2, # 'ά' - 18: 2, # 'έ' - 22: 1, # 'ή' - 15: 2, # 'ί' - 1: 2, # 'α' - 29: 0, # 'β' - 20: 0, # 'γ' - 21: 0, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 3, # 'η' - 25: 0, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 0, # 'λ' - 10: 0, # 'μ' - 6: 0, # 'ν' - 30: 0, # 'ξ' - 4: 2, # 'ο' - 9: 0, # 'π' - 8: 0, # 'ρ' - 14: 0, # 'ς' - 7: 0, # 'σ' - 2: 2, # 'τ' - 12: 1, # 'υ' - 28: 0, # 'φ' - 23: 0, # 'χ' - 42: 0, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 24: { # 'ω' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 1, # 'ά' - 18: 0, # 'έ' - 22: 2, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 2, # 'β' - 20: 3, # 'γ' - 21: 2, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 0, # 'η' - 25: 3, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 0, # 'ξ' - 4: 0, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 2, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 19: { # 'ό' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 3, # 'β' - 20: 3, # 'γ' - 21: 3, # 'δ' - 3: 1, # 'ε' - 32: 2, # 'ζ' - 13: 2, # 'η' - 25: 2, # 'θ' - 5: 2, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 1, # 'ξ' - 4: 2, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 3, # 'χ' - 42: 2, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 26: { # 'ύ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 2, # 'α' - 29: 2, # 'β' - 20: 2, # 'γ' - 21: 1, # 'δ' - 3: 3, # 'ε' - 32: 0, # 'ζ' - 13: 2, # 'η' - 25: 3, # 'θ' - 5: 0, # 'ι' - 11: 3, # 'κ' - 16: 3, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 2, # 'ξ' - 4: 3, # 'ο' - 9: 3, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 2, # 'φ' - 23: 2, # 'χ' - 42: 2, # 'ψ' - 24: 2, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, - 27: { # 'ώ' - 60: 0, # 'e' - 55: 0, # 'o' - 58: 0, # 't' - 36: 0, # '·' - 61: 0, # 'Ά' - 46: 0, # 'Έ' - 54: 0, # 'Ό' - 31: 0, # 'Α' - 51: 0, # 'Β' - 43: 0, # 'Γ' - 41: 0, # 'Δ' - 34: 0, # 'Ε' - 40: 0, # 'Η' - 52: 0, # 'Θ' - 47: 0, # 'Ι' - 44: 0, # 'Κ' - 53: 0, # 'Λ' - 38: 0, # 'Μ' - 49: 0, # 'Ν' - 59: 0, # 'Ξ' - 39: 0, # 'Ο' - 35: 0, # 'Π' - 48: 0, # 'Ρ' - 37: 0, # 'Σ' - 33: 0, # 'Τ' - 45: 0, # 'Υ' - 56: 0, # 'Φ' - 50: 0, # 'Χ' - 57: 0, # 'Ω' - 17: 0, # 'ά' - 18: 0, # 'έ' - 22: 0, # 'ή' - 15: 0, # 'ί' - 1: 0, # 'α' - 29: 1, # 'β' - 20: 0, # 'γ' - 21: 3, # 'δ' - 3: 0, # 'ε' - 32: 0, # 'ζ' - 13: 1, # 'η' - 25: 2, # 'θ' - 5: 2, # 'ι' - 11: 0, # 'κ' - 16: 2, # 'λ' - 10: 3, # 'μ' - 6: 3, # 'ν' - 30: 1, # 'ξ' - 4: 0, # 'ο' - 9: 2, # 'π' - 8: 3, # 'ρ' - 14: 3, # 'ς' - 7: 3, # 'σ' - 2: 3, # 'τ' - 12: 0, # 'υ' - 28: 1, # 'φ' - 23: 1, # 'χ' - 42: 0, # 'ψ' - 24: 0, # 'ω' - 19: 0, # 'ό' - 26: 0, # 'ύ' - 27: 0, # 'ώ' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -WINDOWS_1253_GREEK_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 82, # 'A' - 66: 100, # 'B' - 67: 104, # 'C' - 68: 94, # 'D' - 69: 98, # 'E' - 70: 101, # 'F' - 71: 116, # 'G' - 72: 102, # 'H' - 73: 111, # 'I' - 74: 187, # 'J' - 75: 117, # 'K' - 76: 92, # 'L' - 77: 88, # 'M' - 78: 113, # 'N' - 79: 85, # 'O' - 80: 79, # 'P' - 81: 118, # 'Q' - 82: 105, # 'R' - 83: 83, # 'S' - 84: 67, # 'T' - 85: 114, # 'U' - 86: 119, # 'V' - 87: 95, # 'W' - 88: 99, # 'X' - 89: 109, # 'Y' - 90: 188, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 72, # 'a' - 98: 70, # 'b' - 99: 80, # 'c' - 100: 81, # 'd' - 101: 60, # 'e' - 102: 96, # 'f' - 103: 93, # 'g' - 104: 89, # 'h' - 105: 68, # 'i' - 106: 120, # 'j' - 107: 97, # 'k' - 108: 77, # 'l' - 109: 86, # 'm' - 110: 69, # 'n' - 111: 55, # 'o' - 112: 78, # 'p' - 113: 115, # 'q' - 114: 65, # 'r' - 115: 66, # 's' - 116: 58, # 't' - 117: 76, # 'u' - 118: 106, # 'v' - 119: 103, # 'w' - 120: 87, # 'x' - 121: 107, # 'y' - 122: 112, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 255, # '€' - 129: 255, # None - 130: 255, # '‚' - 131: 255, # 'ƒ' - 132: 255, # '„' - 133: 255, # '…' - 134: 255, # '†' - 135: 255, # '‡' - 136: 255, # None - 137: 255, # '‰' - 138: 255, # None - 139: 255, # '‹' - 140: 255, # None - 141: 255, # None - 142: 255, # None - 143: 255, # None - 144: 255, # None - 145: 255, # '‘' - 146: 255, # '’' - 147: 255, # '“' - 148: 255, # '”' - 149: 255, # '•' - 150: 255, # '–' - 151: 255, # '—' - 152: 255, # None - 153: 255, # '™' - 154: 255, # None - 155: 255, # '›' - 156: 255, # None - 157: 255, # None - 158: 255, # None - 159: 255, # None - 160: 253, # '\xa0' - 161: 233, # '΅' - 162: 61, # 'Ά' - 163: 253, # '£' - 164: 253, # '¤' - 165: 253, # '¥' - 166: 253, # '¦' - 167: 253, # '§' - 168: 253, # '¨' - 169: 253, # '©' - 170: 253, # None - 171: 253, # '«' - 172: 253, # '¬' - 173: 74, # '\xad' - 174: 253, # '®' - 175: 253, # '―' - 176: 253, # '°' - 177: 253, # '±' - 178: 253, # '²' - 179: 253, # '³' - 180: 247, # '΄' - 181: 253, # 'µ' - 182: 253, # '¶' - 183: 36, # '·' - 184: 46, # 'Έ' - 185: 71, # 'Ή' - 186: 73, # 'Ί' - 187: 253, # '»' - 188: 54, # 'Ό' - 189: 253, # '½' - 190: 108, # 'Ύ' - 191: 123, # 'Ώ' - 192: 110, # 'ΐ' - 193: 31, # 'Α' - 194: 51, # 'Β' - 195: 43, # 'Γ' - 196: 41, # 'Δ' - 197: 34, # 'Ε' - 198: 91, # 'Ζ' - 199: 40, # 'Η' - 200: 52, # 'Θ' - 201: 47, # 'Ι' - 202: 44, # 'Κ' - 203: 53, # 'Λ' - 204: 38, # 'Μ' - 205: 49, # 'Ν' - 206: 59, # 'Ξ' - 207: 39, # 'Ο' - 208: 35, # 'Π' - 209: 48, # 'Ρ' - 210: 250, # None - 211: 37, # 'Σ' - 212: 33, # 'Τ' - 213: 45, # 'Υ' - 214: 56, # 'Φ' - 215: 50, # 'Χ' - 216: 84, # 'Ψ' - 217: 57, # 'Ω' - 218: 120, # 'Ϊ' - 219: 121, # 'Ϋ' - 220: 17, # 'ά' - 221: 18, # 'έ' - 222: 22, # 'ή' - 223: 15, # 'ί' - 224: 124, # 'ΰ' - 225: 1, # 'α' - 226: 29, # 'β' - 227: 20, # 'γ' - 228: 21, # 'δ' - 229: 3, # 'ε' - 230: 32, # 'ζ' - 231: 13, # 'η' - 232: 25, # 'θ' - 233: 5, # 'ι' - 234: 11, # 'κ' - 235: 16, # 'λ' - 236: 10, # 'μ' - 237: 6, # 'ν' - 238: 30, # 'ξ' - 239: 4, # 'ο' - 240: 9, # 'π' - 241: 8, # 'ρ' - 242: 14, # 'ς' - 243: 7, # 'σ' - 244: 2, # 'τ' - 245: 12, # 'υ' - 246: 28, # 'φ' - 247: 23, # 'χ' - 248: 42, # 'ψ' - 249: 24, # 'ω' - 250: 64, # 'ϊ' - 251: 75, # 'ϋ' - 252: 19, # 'ό' - 253: 26, # 'ύ' - 254: 27, # 'ώ' - 255: 253, # None -} - -WINDOWS_1253_GREEK_MODEL = SingleByteCharSetModel(charset_name='windows-1253', - language='Greek', - char_to_order_map=WINDOWS_1253_GREEK_CHAR_TO_ORDER, - language_model=GREEK_LANG_MODEL, - typical_positive_ratio=0.982851, - keep_ascii_letters=False, - alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') - -ISO_8859_7_GREEK_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 82, # 'A' - 66: 100, # 'B' - 67: 104, # 'C' - 68: 94, # 'D' - 69: 98, # 'E' - 70: 101, # 'F' - 71: 116, # 'G' - 72: 102, # 'H' - 73: 111, # 'I' - 74: 187, # 'J' - 75: 117, # 'K' - 76: 92, # 'L' - 77: 88, # 'M' - 78: 113, # 'N' - 79: 85, # 'O' - 80: 79, # 'P' - 81: 118, # 'Q' - 82: 105, # 'R' - 83: 83, # 'S' - 84: 67, # 'T' - 85: 114, # 'U' - 86: 119, # 'V' - 87: 95, # 'W' - 88: 99, # 'X' - 89: 109, # 'Y' - 90: 188, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 72, # 'a' - 98: 70, # 'b' - 99: 80, # 'c' - 100: 81, # 'd' - 101: 60, # 'e' - 102: 96, # 'f' - 103: 93, # 'g' - 104: 89, # 'h' - 105: 68, # 'i' - 106: 120, # 'j' - 107: 97, # 'k' - 108: 77, # 'l' - 109: 86, # 'm' - 110: 69, # 'n' - 111: 55, # 'o' - 112: 78, # 'p' - 113: 115, # 'q' - 114: 65, # 'r' - 115: 66, # 's' - 116: 58, # 't' - 117: 76, # 'u' - 118: 106, # 'v' - 119: 103, # 'w' - 120: 87, # 'x' - 121: 107, # 'y' - 122: 112, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 255, # '\x80' - 129: 255, # '\x81' - 130: 255, # '\x82' - 131: 255, # '\x83' - 132: 255, # '\x84' - 133: 255, # '\x85' - 134: 255, # '\x86' - 135: 255, # '\x87' - 136: 255, # '\x88' - 137: 255, # '\x89' - 138: 255, # '\x8a' - 139: 255, # '\x8b' - 140: 255, # '\x8c' - 141: 255, # '\x8d' - 142: 255, # '\x8e' - 143: 255, # '\x8f' - 144: 255, # '\x90' - 145: 255, # '\x91' - 146: 255, # '\x92' - 147: 255, # '\x93' - 148: 255, # '\x94' - 149: 255, # '\x95' - 150: 255, # '\x96' - 151: 255, # '\x97' - 152: 255, # '\x98' - 153: 255, # '\x99' - 154: 255, # '\x9a' - 155: 255, # '\x9b' - 156: 255, # '\x9c' - 157: 255, # '\x9d' - 158: 255, # '\x9e' - 159: 255, # '\x9f' - 160: 253, # '\xa0' - 161: 233, # '‘' - 162: 90, # '’' - 163: 253, # '£' - 164: 253, # '€' - 165: 253, # '₯' - 166: 253, # '¦' - 167: 253, # '§' - 168: 253, # '¨' - 169: 253, # '©' - 170: 253, # 'ͺ' - 171: 253, # '«' - 172: 253, # '¬' - 173: 74, # '\xad' - 174: 253, # None - 175: 253, # '―' - 176: 253, # '°' - 177: 253, # '±' - 178: 253, # '²' - 179: 253, # '³' - 180: 247, # '΄' - 181: 248, # '΅' - 182: 61, # 'Ά' - 183: 36, # '·' - 184: 46, # 'Έ' - 185: 71, # 'Ή' - 186: 73, # 'Ί' - 187: 253, # '»' - 188: 54, # 'Ό' - 189: 253, # '½' - 190: 108, # 'Ύ' - 191: 123, # 'Ώ' - 192: 110, # 'ΐ' - 193: 31, # 'Α' - 194: 51, # 'Β' - 195: 43, # 'Γ' - 196: 41, # 'Δ' - 197: 34, # 'Ε' - 198: 91, # 'Ζ' - 199: 40, # 'Η' - 200: 52, # 'Θ' - 201: 47, # 'Ι' - 202: 44, # 'Κ' - 203: 53, # 'Λ' - 204: 38, # 'Μ' - 205: 49, # 'Ν' - 206: 59, # 'Ξ' - 207: 39, # 'Ο' - 208: 35, # 'Π' - 209: 48, # 'Ρ' - 210: 250, # None - 211: 37, # 'Σ' - 212: 33, # 'Τ' - 213: 45, # 'Υ' - 214: 56, # 'Φ' - 215: 50, # 'Χ' - 216: 84, # 'Ψ' - 217: 57, # 'Ω' - 218: 120, # 'Ϊ' - 219: 121, # 'Ϋ' - 220: 17, # 'ά' - 221: 18, # 'έ' - 222: 22, # 'ή' - 223: 15, # 'ί' - 224: 124, # 'ΰ' - 225: 1, # 'α' - 226: 29, # 'β' - 227: 20, # 'γ' - 228: 21, # 'δ' - 229: 3, # 'ε' - 230: 32, # 'ζ' - 231: 13, # 'η' - 232: 25, # 'θ' - 233: 5, # 'ι' - 234: 11, # 'κ' - 235: 16, # 'λ' - 236: 10, # 'μ' - 237: 6, # 'ν' - 238: 30, # 'ξ' - 239: 4, # 'ο' - 240: 9, # 'π' - 241: 8, # 'ρ' - 242: 14, # 'ς' - 243: 7, # 'σ' - 244: 2, # 'τ' - 245: 12, # 'υ' - 246: 28, # 'φ' - 247: 23, # 'χ' - 248: 42, # 'ψ' - 249: 24, # 'ω' - 250: 64, # 'ϊ' - 251: 75, # 'ϋ' - 252: 19, # 'ό' - 253: 26, # 'ύ' - 254: 27, # 'ώ' - 255: 253, # None -} - -ISO_8859_7_GREEK_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-7', - language='Greek', - char_to_order_map=ISO_8859_7_GREEK_CHAR_TO_ORDER, - language_model=GREEK_LANG_MODEL, - typical_positive_ratio=0.982851, - keep_ascii_letters=False, - alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') - diff --git a/dist/ba_data/python-site-packages/chardet/langhebrewmodel.py b/dist/ba_data/python-site-packages/chardet/langhebrewmodel.py deleted file mode 100644 index 40fd674c..00000000 --- a/dist/ba_data/python-site-packages/chardet/langhebrewmodel.py +++ /dev/null @@ -1,4383 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -HEBREW_LANG_MODEL = { - 50: { # 'a' - 50: 0, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 2, # 'l' - 54: 2, # 'n' - 49: 0, # 'o' - 51: 2, # 'r' - 43: 1, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 1, # 'ק' - 7: 0, # 'ר' - 10: 1, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 60: { # 'c' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 0, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 0, # 'n' - 49: 1, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 61: { # 'd' - 50: 1, # 'a' - 60: 0, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 1, # 'n' - 49: 2, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 0, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 1, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 42: { # 'e' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 2, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 2, # 'l' - 54: 2, # 'n' - 49: 1, # 'o' - 51: 2, # 'r' - 43: 2, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 1, # '–' - 52: 2, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 53: { # 'i' - 50: 1, # 'a' - 60: 2, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 0, # 'i' - 56: 1, # 'l' - 54: 2, # 'n' - 49: 2, # 'o' - 51: 1, # 'r' - 43: 2, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 56: { # 'l' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 2, # 'e' - 53: 2, # 'i' - 56: 2, # 'l' - 54: 1, # 'n' - 49: 1, # 'o' - 51: 0, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 54: { # 'n' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 1, # 'n' - 49: 1, # 'o' - 51: 0, # 'r' - 43: 1, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 2, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 49: { # 'o' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 2, # 'n' - 49: 1, # 'o' - 51: 2, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 51: { # 'r' - 50: 2, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 2, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 1, # 'n' - 49: 2, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 2, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 43: { # 's' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 0, # 'd' - 42: 2, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 1, # 'n' - 49: 1, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 2, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 44: { # 't' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 0, # 'd' - 42: 2, # 'e' - 53: 2, # 'i' - 56: 1, # 'l' - 54: 0, # 'n' - 49: 1, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 1, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 2, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 63: { # 'u' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 1, # 'n' - 49: 0, # 'o' - 51: 1, # 'r' - 43: 2, # 's' - 44: 1, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 34: { # '\xa0' - 50: 1, # 'a' - 60: 0, # 'c' - 61: 1, # 'd' - 42: 0, # 'e' - 53: 1, # 'i' - 56: 0, # 'l' - 54: 1, # 'n' - 49: 1, # 'o' - 51: 0, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 0, # 'u' - 34: 2, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 1, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 2, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 2, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 1, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 55: { # '´' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 1, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 2, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 1, # 'ן' - 12: 1, # 'נ' - 19: 1, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 48: { # '¼' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 1, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 39: { # '½' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 57: { # '¾' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 30: { # 'ְ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 1, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 1, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 2, # 'ג' - 16: 2, # 'ד' - 3: 2, # 'ה' - 2: 2, # 'ו' - 24: 2, # 'ז' - 14: 2, # 'ח' - 22: 2, # 'ט' - 1: 2, # 'י' - 25: 2, # 'ך' - 15: 2, # 'כ' - 4: 2, # 'ל' - 11: 1, # 'ם' - 6: 2, # 'מ' - 23: 0, # 'ן' - 12: 2, # 'נ' - 19: 2, # 'ס' - 13: 2, # 'ע' - 26: 0, # 'ף' - 18: 2, # 'פ' - 27: 0, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 59: { # 'ֱ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 1, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 1, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 2, # 'ל' - 11: 0, # 'ם' - 6: 2, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 41: { # 'ֲ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 2, # 'ב' - 20: 1, # 'ג' - 16: 2, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 1, # 'י' - 25: 1, # 'ך' - 15: 1, # 'כ' - 4: 2, # 'ל' - 11: 0, # 'ם' - 6: 2, # 'מ' - 23: 0, # 'ן' - 12: 2, # 'נ' - 19: 1, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 2, # 'צ' - 17: 1, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 33: { # 'ִ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 1, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 1, # 'ִ' - 37: 0, # 'ֵ' - 36: 1, # 'ֶ' - 31: 0, # 'ַ' - 29: 1, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 1, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 2, # 'ב' - 20: 2, # 'ג' - 16: 2, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 2, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 2, # 'כ' - 4: 2, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 2, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 2, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 37: { # 'ֵ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 1, # 'ֶ' - 31: 1, # 'ַ' - 29: 1, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 1, # 'ג' - 16: 2, # 'ד' - 3: 2, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 2, # 'ח' - 22: 1, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 1, # 'כ' - 4: 2, # 'ל' - 11: 2, # 'ם' - 6: 1, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 1, # 'ס' - 13: 2, # 'ע' - 26: 1, # 'ף' - 18: 1, # 'פ' - 27: 1, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 36: { # 'ֶ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 1, # 'ֶ' - 31: 1, # 'ַ' - 29: 1, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 1, # 'ג' - 16: 2, # 'ד' - 3: 2, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 2, # 'ח' - 22: 1, # 'ט' - 1: 2, # 'י' - 25: 2, # 'ך' - 15: 1, # 'כ' - 4: 2, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 2, # 'ס' - 13: 1, # 'ע' - 26: 1, # 'ף' - 18: 1, # 'פ' - 27: 2, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 31: { # 'ַ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 1, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 1, # 'ֶ' - 31: 0, # 'ַ' - 29: 2, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 2, # 'ג' - 16: 2, # 'ד' - 3: 2, # 'ה' - 2: 1, # 'ו' - 24: 2, # 'ז' - 14: 2, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 2, # 'כ' - 4: 2, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 2, # 'ס' - 13: 2, # 'ע' - 26: 2, # 'ף' - 18: 2, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 29: { # 'ָ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 1, # 'ַ' - 29: 2, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 1, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 2, # 'ג' - 16: 2, # 'ד' - 3: 3, # 'ה' - 2: 2, # 'ו' - 24: 2, # 'ז' - 14: 2, # 'ח' - 22: 1, # 'ט' - 1: 2, # 'י' - 25: 2, # 'ך' - 15: 2, # 'כ' - 4: 2, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 1, # 'ס' - 13: 2, # 'ע' - 26: 1, # 'ף' - 18: 2, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 35: { # 'ֹ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 1, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 1, # 'ג' - 16: 2, # 'ד' - 3: 2, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 1, # 'י' - 25: 1, # 'ך' - 15: 2, # 'כ' - 4: 2, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 2, # 'ס' - 13: 2, # 'ע' - 26: 1, # 'ף' - 18: 2, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 62: { # 'ֻ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 1, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 2, # 'ל' - 11: 1, # 'ם' - 6: 1, # 'מ' - 23: 1, # 'ן' - 12: 1, # 'נ' - 19: 1, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 28: { # 'ּ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 3, # 'ְ' - 59: 0, # 'ֱ' - 41: 1, # 'ֲ' - 33: 3, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 3, # 'ַ' - 29: 3, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 0, # 'ּ' - 38: 2, # 'ׁ' - 45: 1, # 'ׂ' - 9: 2, # 'א' - 8: 2, # 'ב' - 20: 1, # 'ג' - 16: 2, # 'ד' - 3: 1, # 'ה' - 2: 2, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 2, # 'י' - 25: 2, # 'ך' - 15: 2, # 'כ' - 4: 2, # 'ל' - 11: 1, # 'ם' - 6: 2, # 'מ' - 23: 1, # 'ן' - 12: 2, # 'נ' - 19: 1, # 'ס' - 13: 2, # 'ע' - 26: 1, # 'ף' - 18: 1, # 'פ' - 27: 1, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 2, # 'ר' - 10: 2, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 38: { # 'ׁ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 2, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 45: { # 'ׂ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 1, # 'ֵ' - 36: 2, # 'ֶ' - 31: 1, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 1, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 2, # 'ו' - 24: 0, # 'ז' - 14: 1, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 1, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 0, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 0, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 9: { # 'א' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 2, # 'ֱ' - 41: 2, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 2, # 'ע' - 26: 3, # 'ף' - 18: 3, # 'פ' - 27: 1, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 8: { # 'ב' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 1, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 3, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 1, # 'ף' - 18: 3, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 1, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 20: { # 'ג' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 2, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 1, # 'ִ' - 37: 1, # 'ֵ' - 36: 1, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 0, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 3, # 'ב' - 20: 2, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 2, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 1, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 2, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 2, # 'פ' - 27: 1, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 16: { # 'ד' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 1, # 'ז' - 14: 2, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 2, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 2, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 0, # 'ץ' - 21: 2, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 3: { # 'ה' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 1, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 1, # 'ְ' - 59: 1, # 'ֱ' - 41: 2, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 3, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 0, # 'ף' - 18: 3, # 'פ' - 27: 1, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 1, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 2: { # 'ו' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 1, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 1, # 'ֵ' - 36: 1, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 3, # 'ֹ' - 62: 0, # 'ֻ' - 28: 3, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 3, # 'ף' - 18: 3, # 'פ' - 27: 3, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 1, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 24: { # 'ז' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 1, # 'ֲ' - 33: 1, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 2, # 'ב' - 20: 2, # 'ג' - 16: 2, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 2, # 'ז' - 14: 2, # 'ח' - 22: 1, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 2, # 'נ' - 19: 1, # 'ס' - 13: 2, # 'ע' - 26: 1, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 2, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 1, # 'ש' - 5: 2, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 14: { # 'ח' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 1, # 'ֱ' - 41: 2, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 3, # 'ב' - 20: 2, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 2, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 2, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 1, # 'ע' - 26: 2, # 'ף' - 18: 2, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 22: { # 'ט' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 1, # 'ֵ' - 36: 1, # 'ֶ' - 31: 2, # 'ַ' - 29: 1, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 1, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 1, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 2, # 'ז' - 14: 3, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 2, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 2, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 3, # 'ר' - 10: 2, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 1: { # 'י' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 1, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 3, # 'ף' - 18: 3, # 'פ' - 27: 3, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 1, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 25: { # 'ך' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 2, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 1, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 1, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 1, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 15: { # 'כ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 3, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 2, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 2, # 'ע' - 26: 3, # 'ף' - 18: 3, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 2, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 4: { # 'ל' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 3, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 1, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 11: { # 'ם' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 1, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 0, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 1, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 6: { # 'מ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 0, # 'ף' - 18: 3, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 23: { # 'ן' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 1, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 0, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 1, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 1, # 'ס' - 13: 1, # 'ע' - 26: 1, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 1, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 1, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 12: { # 'נ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 19: { # 'ס' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 1, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 1, # 'ָ' - 35: 1, # 'ֹ' - 62: 2, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 1, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 2, # 'ס' - 13: 3, # 'ע' - 26: 3, # 'ף' - 18: 3, # 'פ' - 27: 0, # 'ץ' - 21: 2, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 1, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 13: { # 'ע' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 1, # 'ְ' - 59: 1, # 'ֱ' - 41: 2, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 1, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 2, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 2, # 'ע' - 26: 1, # 'ף' - 18: 2, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 26: { # 'ף' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 1, # 'ו' - 24: 0, # 'ז' - 14: 1, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 1, # 'ס' - 13: 0, # 'ע' - 26: 1, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 1, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 18: { # 'פ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 1, # 'ֵ' - 36: 2, # 'ֶ' - 31: 1, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 2, # 'ב' - 20: 3, # 'ג' - 16: 2, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 2, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 2, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 2, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 27: { # 'ץ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 1, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 0, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 21: { # 'צ' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 1, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 2, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 1, # 'ז' - 14: 3, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 1, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 1, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 2, # 'ץ' - 21: 2, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 0, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 17: { # 'ק' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 1, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 1, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 2, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 2, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 1, # 'ך' - 15: 1, # 'כ' - 4: 3, # 'ל' - 11: 2, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 2, # 'ץ' - 21: 3, # 'צ' - 17: 2, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 7: { # 'ר' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 2, # '´' - 48: 1, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 1, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 2, # 'ֹ' - 62: 1, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 3, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 3, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 3, # 'ץ' - 21: 3, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 10: { # 'ש' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 1, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 1, # 'ִ' - 37: 1, # 'ֵ' - 36: 1, # 'ֶ' - 31: 1, # 'ַ' - 29: 1, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 3, # 'ׁ' - 45: 2, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 3, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 2, # 'ז' - 14: 3, # 'ח' - 22: 3, # 'ט' - 1: 3, # 'י' - 25: 3, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 2, # 'ן' - 12: 3, # 'נ' - 19: 2, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 1, # '…' - }, - 5: { # 'ת' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 1, # '\xa0' - 55: 0, # '´' - 48: 1, # '¼' - 39: 1, # '½' - 57: 0, # '¾' - 30: 2, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 2, # 'ִ' - 37: 2, # 'ֵ' - 36: 2, # 'ֶ' - 31: 2, # 'ַ' - 29: 2, # 'ָ' - 35: 1, # 'ֹ' - 62: 1, # 'ֻ' - 28: 2, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 3, # 'א' - 8: 3, # 'ב' - 20: 3, # 'ג' - 16: 2, # 'ד' - 3: 3, # 'ה' - 2: 3, # 'ו' - 24: 2, # 'ז' - 14: 3, # 'ח' - 22: 2, # 'ט' - 1: 3, # 'י' - 25: 2, # 'ך' - 15: 3, # 'כ' - 4: 3, # 'ל' - 11: 3, # 'ם' - 6: 3, # 'מ' - 23: 3, # 'ן' - 12: 3, # 'נ' - 19: 2, # 'ס' - 13: 3, # 'ע' - 26: 2, # 'ף' - 18: 3, # 'פ' - 27: 1, # 'ץ' - 21: 2, # 'צ' - 17: 3, # 'ק' - 7: 3, # 'ר' - 10: 3, # 'ש' - 5: 3, # 'ת' - 32: 1, # '–' - 52: 1, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, - 32: { # '–' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 1, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 1, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 0, # 'ז' - 14: 1, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 1, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 1, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 52: { # '’' - 50: 1, # 'a' - 60: 0, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 1, # 'r' - 43: 2, # 's' - 44: 2, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 1, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 47: { # '“' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 1, # 'l' - 54: 1, # 'n' - 49: 1, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 1, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 2, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 1, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 1, # 'ח' - 22: 1, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 1, # 'ס' - 13: 1, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 1, # 'צ' - 17: 1, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 46: { # '”' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 1, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 1, # 'ב' - 20: 1, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 1, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 0, # '†' - 40: 0, # '…' - }, - 58: { # '†' - 50: 0, # 'a' - 60: 0, # 'c' - 61: 0, # 'd' - 42: 0, # 'e' - 53: 0, # 'i' - 56: 0, # 'l' - 54: 0, # 'n' - 49: 0, # 'o' - 51: 0, # 'r' - 43: 0, # 's' - 44: 0, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 0, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 0, # 'ה' - 2: 0, # 'ו' - 24: 0, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 0, # 'י' - 25: 0, # 'ך' - 15: 0, # 'כ' - 4: 0, # 'ל' - 11: 0, # 'ם' - 6: 0, # 'מ' - 23: 0, # 'ן' - 12: 0, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 0, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 0, # 'ר' - 10: 0, # 'ש' - 5: 0, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 0, # '”' - 58: 2, # '†' - 40: 0, # '…' - }, - 40: { # '…' - 50: 1, # 'a' - 60: 1, # 'c' - 61: 1, # 'd' - 42: 1, # 'e' - 53: 1, # 'i' - 56: 0, # 'l' - 54: 1, # 'n' - 49: 0, # 'o' - 51: 1, # 'r' - 43: 1, # 's' - 44: 1, # 't' - 63: 0, # 'u' - 34: 0, # '\xa0' - 55: 0, # '´' - 48: 0, # '¼' - 39: 0, # '½' - 57: 0, # '¾' - 30: 0, # 'ְ' - 59: 0, # 'ֱ' - 41: 0, # 'ֲ' - 33: 0, # 'ִ' - 37: 0, # 'ֵ' - 36: 0, # 'ֶ' - 31: 0, # 'ַ' - 29: 0, # 'ָ' - 35: 0, # 'ֹ' - 62: 0, # 'ֻ' - 28: 0, # 'ּ' - 38: 0, # 'ׁ' - 45: 0, # 'ׂ' - 9: 1, # 'א' - 8: 0, # 'ב' - 20: 0, # 'ג' - 16: 0, # 'ד' - 3: 1, # 'ה' - 2: 1, # 'ו' - 24: 1, # 'ז' - 14: 0, # 'ח' - 22: 0, # 'ט' - 1: 1, # 'י' - 25: 0, # 'ך' - 15: 1, # 'כ' - 4: 1, # 'ל' - 11: 0, # 'ם' - 6: 1, # 'מ' - 23: 0, # 'ן' - 12: 1, # 'נ' - 19: 0, # 'ס' - 13: 0, # 'ע' - 26: 0, # 'ף' - 18: 1, # 'פ' - 27: 0, # 'ץ' - 21: 0, # 'צ' - 17: 0, # 'ק' - 7: 1, # 'ר' - 10: 1, # 'ש' - 5: 1, # 'ת' - 32: 0, # '–' - 52: 0, # '’' - 47: 0, # '“' - 46: 1, # '”' - 58: 0, # '†' - 40: 2, # '…' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -WINDOWS_1255_HEBREW_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 69, # 'A' - 66: 91, # 'B' - 67: 79, # 'C' - 68: 80, # 'D' - 69: 92, # 'E' - 70: 89, # 'F' - 71: 97, # 'G' - 72: 90, # 'H' - 73: 68, # 'I' - 74: 111, # 'J' - 75: 112, # 'K' - 76: 82, # 'L' - 77: 73, # 'M' - 78: 95, # 'N' - 79: 85, # 'O' - 80: 78, # 'P' - 81: 121, # 'Q' - 82: 86, # 'R' - 83: 71, # 'S' - 84: 67, # 'T' - 85: 102, # 'U' - 86: 107, # 'V' - 87: 84, # 'W' - 88: 114, # 'X' - 89: 103, # 'Y' - 90: 115, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 50, # 'a' - 98: 74, # 'b' - 99: 60, # 'c' - 100: 61, # 'd' - 101: 42, # 'e' - 102: 76, # 'f' - 103: 70, # 'g' - 104: 64, # 'h' - 105: 53, # 'i' - 106: 105, # 'j' - 107: 93, # 'k' - 108: 56, # 'l' - 109: 65, # 'm' - 110: 54, # 'n' - 111: 49, # 'o' - 112: 66, # 'p' - 113: 110, # 'q' - 114: 51, # 'r' - 115: 43, # 's' - 116: 44, # 't' - 117: 63, # 'u' - 118: 81, # 'v' - 119: 77, # 'w' - 120: 98, # 'x' - 121: 75, # 'y' - 122: 108, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 124, # '€' - 129: 202, # None - 130: 203, # '‚' - 131: 204, # 'ƒ' - 132: 205, # '„' - 133: 40, # '…' - 134: 58, # '†' - 135: 206, # '‡' - 136: 207, # 'ˆ' - 137: 208, # '‰' - 138: 209, # None - 139: 210, # '‹' - 140: 211, # None - 141: 212, # None - 142: 213, # None - 143: 214, # None - 144: 215, # None - 145: 83, # '‘' - 146: 52, # '’' - 147: 47, # '“' - 148: 46, # '”' - 149: 72, # '•' - 150: 32, # '–' - 151: 94, # '—' - 152: 216, # '˜' - 153: 113, # '™' - 154: 217, # None - 155: 109, # '›' - 156: 218, # None - 157: 219, # None - 158: 220, # None - 159: 221, # None - 160: 34, # '\xa0' - 161: 116, # '¡' - 162: 222, # '¢' - 163: 118, # '£' - 164: 100, # '₪' - 165: 223, # '¥' - 166: 224, # '¦' - 167: 117, # '§' - 168: 119, # '¨' - 169: 104, # '©' - 170: 125, # '×' - 171: 225, # '«' - 172: 226, # '¬' - 173: 87, # '\xad' - 174: 99, # '®' - 175: 227, # '¯' - 176: 106, # '°' - 177: 122, # '±' - 178: 123, # '²' - 179: 228, # '³' - 180: 55, # '´' - 181: 229, # 'µ' - 182: 230, # '¶' - 183: 101, # '·' - 184: 231, # '¸' - 185: 232, # '¹' - 186: 120, # '÷' - 187: 233, # '»' - 188: 48, # '¼' - 189: 39, # '½' - 190: 57, # '¾' - 191: 234, # '¿' - 192: 30, # 'ְ' - 193: 59, # 'ֱ' - 194: 41, # 'ֲ' - 195: 88, # 'ֳ' - 196: 33, # 'ִ' - 197: 37, # 'ֵ' - 198: 36, # 'ֶ' - 199: 31, # 'ַ' - 200: 29, # 'ָ' - 201: 35, # 'ֹ' - 202: 235, # None - 203: 62, # 'ֻ' - 204: 28, # 'ּ' - 205: 236, # 'ֽ' - 206: 126, # '־' - 207: 237, # 'ֿ' - 208: 238, # '׀' - 209: 38, # 'ׁ' - 210: 45, # 'ׂ' - 211: 239, # '׃' - 212: 240, # 'װ' - 213: 241, # 'ױ' - 214: 242, # 'ײ' - 215: 243, # '׳' - 216: 127, # '״' - 217: 244, # None - 218: 245, # None - 219: 246, # None - 220: 247, # None - 221: 248, # None - 222: 249, # None - 223: 250, # None - 224: 9, # 'א' - 225: 8, # 'ב' - 226: 20, # 'ג' - 227: 16, # 'ד' - 228: 3, # 'ה' - 229: 2, # 'ו' - 230: 24, # 'ז' - 231: 14, # 'ח' - 232: 22, # 'ט' - 233: 1, # 'י' - 234: 25, # 'ך' - 235: 15, # 'כ' - 236: 4, # 'ל' - 237: 11, # 'ם' - 238: 6, # 'מ' - 239: 23, # 'ן' - 240: 12, # 'נ' - 241: 19, # 'ס' - 242: 13, # 'ע' - 243: 26, # 'ף' - 244: 18, # 'פ' - 245: 27, # 'ץ' - 246: 21, # 'צ' - 247: 17, # 'ק' - 248: 7, # 'ר' - 249: 10, # 'ש' - 250: 5, # 'ת' - 251: 251, # None - 252: 252, # None - 253: 128, # '\u200e' - 254: 96, # '\u200f' - 255: 253, # None -} - -WINDOWS_1255_HEBREW_MODEL = SingleByteCharSetModel(charset_name='windows-1255', - language='Hebrew', - char_to_order_map=WINDOWS_1255_HEBREW_CHAR_TO_ORDER, - language_model=HEBREW_LANG_MODEL, - typical_positive_ratio=0.984004, - keep_ascii_letters=False, - alphabet='אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ') - diff --git a/dist/ba_data/python-site-packages/chardet/langhungarianmodel.py b/dist/ba_data/python-site-packages/chardet/langhungarianmodel.py deleted file mode 100644 index 24a097f5..00000000 --- a/dist/ba_data/python-site-packages/chardet/langhungarianmodel.py +++ /dev/null @@ -1,4650 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -HUNGARIAN_LANG_MODEL = { - 28: { # 'A' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 2, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 2, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 2, # 'K' - 41: 2, # 'L' - 34: 1, # 'M' - 35: 2, # 'N' - 47: 1, # 'O' - 46: 2, # 'P' - 43: 2, # 'R' - 33: 2, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 2, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 1, # 'j' - 7: 2, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 2, # 'n' - 8: 0, # 'o' - 23: 2, # 'p' - 10: 2, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 1, # 'u' - 19: 1, # 'v' - 62: 1, # 'x' - 16: 0, # 'y' - 11: 3, # 'z' - 51: 1, # 'Á' - 44: 0, # 'É' - 61: 1, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 40: { # 'B' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 0, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 3, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 2, # 'i' - 22: 1, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 3, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 54: { # 'C' - 28: 1, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 0, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 2, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 0, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 1, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 3, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 1, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 45: { # 'D' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 0, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 0, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 3, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 1, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 1, # 'o' - 23: 0, # 'p' - 10: 2, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 2, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 1, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 0, # 'ű' - }, - 32: { # 'E' - 28: 1, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 2, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 2, # 'K' - 41: 2, # 'L' - 34: 2, # 'M' - 35: 2, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 2, # 'R' - 33: 2, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 1, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 3, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 2, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 2, # 's' - 3: 1, # 't' - 21: 2, # 'u' - 19: 1, # 'v' - 62: 1, # 'x' - 16: 0, # 'y' - 11: 3, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 0, # 'Ú' - 63: 1, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 1, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 50: { # 'F' - 28: 1, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 0, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 0, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 0, # 'V' - 55: 1, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 1, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 2, # 'i' - 22: 1, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 2, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 0, # 'Ú' - 63: 1, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 2, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 49: { # 'G' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 2, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 1, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 2, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 2, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 0, # 'ű' - }, - 38: { # 'H' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 0, # 'D' - 32: 1, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 1, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 1, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 1, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 0, # 'V' - 55: 1, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 2, # 'i' - 22: 1, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 0, # 'n' - 8: 3, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 2, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 2, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 1, # 'é' - 30: 2, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 39: { # 'I' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 2, # 'K' - 41: 2, # 'L' - 34: 1, # 'M' - 35: 2, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 2, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 2, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 0, # 'e' - 27: 1, # 'f' - 12: 2, # 'g' - 20: 1, # 'h' - 9: 0, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 1, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 2, # 's' - 3: 2, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 53: { # 'J' - 28: 2, # 'A' - 40: 0, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 1, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 1, # 'o' - 23: 0, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 2, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 2, # 'ó' - 24: 2, # 'ö' - 31: 1, # 'ú' - 29: 0, # 'ü' - 42: 1, # 'ő' - 56: 0, # 'ű' - }, - 36: { # 'K' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 0, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 1, # 'f' - 12: 0, # 'g' - 20: 1, # 'h' - 9: 3, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 2, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 2, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 2, # 'ö' - 31: 1, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 0, # 'ű' - }, - 41: { # 'L' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 2, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 3, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 2, # 'i' - 22: 1, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 2, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 0, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 34: { # 'M' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 0, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 3, # 'a' - 18: 0, # 'b' - 26: 1, # 'c' - 17: 0, # 'd' - 1: 3, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 3, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 3, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 2, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 1, # 'ű' - }, - 35: { # 'N' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 2, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 2, # 'Y' - 52: 1, # 'Z' - 2: 3, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 3, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 2, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 2, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 1, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 1, # 'ő' - 56: 0, # 'ű' - }, - 47: { # 'O' - 28: 1, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 2, # 'K' - 41: 2, # 'L' - 34: 2, # 'M' - 35: 2, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 2, # 'R' - 33: 2, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 1, # 'j' - 7: 2, # 'k' - 6: 2, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 1, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 1, # 's' - 3: 2, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 1, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 1, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 46: { # 'P' - 28: 1, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 0, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 2, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 1, # 'f' - 12: 0, # 'g' - 20: 1, # 'h' - 9: 2, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 2, # 'r' - 5: 1, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 0, # 'Ú' - 63: 1, # 'Ü' - 14: 3, # 'á' - 15: 2, # 'é' - 30: 0, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 0, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 0, # 'ű' - }, - 43: { # 'R' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 2, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 1, # 'h' - 9: 2, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 2, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 2, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 33: { # 'S' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 2, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 3, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 1, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 1, # 'h' - 9: 2, # 'i' - 22: 0, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 1, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 1, # 't' - 21: 1, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 3, # 'z' - 51: 2, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 37: { # 'T' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 1, # 'P' - 43: 2, # 'R' - 33: 1, # 'S' - 37: 2, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 2, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 1, # 'h' - 9: 2, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 0, # 't' - 21: 2, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 1, # 'z' - 51: 2, # 'Á' - 44: 2, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 2, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 57: { # 'U' - 28: 1, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 2, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 1, # 'e' - 27: 0, # 'f' - 12: 2, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 1, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 48: { # 'V' - 28: 2, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 0, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 2, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 2, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 2, # 'o' - 23: 0, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 2, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 0, # 'Ú' - 63: 1, # 'Ü' - 14: 2, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 0, # 'ó' - 24: 1, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 55: { # 'Y' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 1, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 2, # 'Z' - 2: 1, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 1, # 'd' - 1: 1, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 8: 1, # 'o' - 23: 1, # 'p' - 10: 0, # 'r' - 5: 0, # 's' - 3: 0, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 1, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 52: { # 'Z' - 28: 2, # 'A' - 40: 1, # 'B' - 54: 0, # 'C' - 45: 1, # 'D' - 32: 2, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 2, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 2, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 2, # 'S' - 37: 1, # 'T' - 57: 1, # 'U' - 48: 1, # 'V' - 55: 1, # 'Y' - 52: 1, # 'Z' - 2: 1, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 1, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 1, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 8: 1, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 2, # 's' - 3: 0, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 2, # 'Á' - 44: 1, # 'É' - 61: 1, # 'Í' - 58: 1, # 'Ó' - 59: 1, # 'Ö' - 60: 1, # 'Ú' - 63: 1, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 2: { # 'a' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 2, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 2, # 'o' - 23: 3, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 1, # 'x' - 16: 2, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 18: { # 'b' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 2, # 'k' - 6: 2, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 2, # 's' - 3: 1, # 't' - 21: 3, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 3, # 'ó' - 24: 2, # 'ö' - 31: 2, # 'ú' - 29: 2, # 'ü' - 42: 2, # 'ő' - 56: 1, # 'ű' - }, - 26: { # 'c' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 1, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 1, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 1, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 1, # 'j' - 7: 2, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 3, # 's' - 3: 2, # 't' - 21: 2, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 2, # 'á' - 15: 2, # 'é' - 30: 2, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 17: { # 'd' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 2, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 2, # 'k' - 6: 1, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 2, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 3, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 2, # 'ú' - 29: 2, # 'ü' - 42: 2, # 'ő' - 56: 1, # 'ű' - }, - 1: { # 'e' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 2, # 'e' - 27: 3, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 2, # 'o' - 23: 3, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 2, # 'u' - 19: 3, # 'v' - 62: 2, # 'x' - 16: 2, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 27: { # 'f' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 3, # 'o' - 23: 0, # 'p' - 10: 3, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 2, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 0, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 3, # 'ö' - 31: 1, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 12: { # 'g' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 2, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 2, # 'k' - 6: 3, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 3, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 3, # 'ó' - 24: 2, # 'ö' - 31: 2, # 'ú' - 29: 2, # 'ü' - 42: 2, # 'ő' - 56: 1, # 'ű' - }, - 20: { # 'h' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 0, # 'd' - 1: 3, # 'e' - 27: 0, # 'f' - 12: 1, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 3, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 2, # 's' - 3: 1, # 't' - 21: 3, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 2, # 'y' - 11: 0, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 3, # 'í' - 25: 2, # 'ó' - 24: 2, # 'ö' - 31: 2, # 'ú' - 29: 1, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 9: { # 'i' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 3, # 'e' - 27: 3, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 2, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 2, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 1, # 'x' - 16: 1, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 3, # 'ó' - 24: 1, # 'ö' - 31: 2, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 1, # 'ű' - }, - 22: { # 'j' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 2, # 'b' - 26: 1, # 'c' - 17: 3, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 2, # 'h' - 9: 1, # 'i' - 22: 2, # 'j' - 7: 2, # 'k' - 6: 2, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 2, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 1, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 3, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 7: { # 'k' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 1, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 2, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 3, # 'í' - 25: 2, # 'ó' - 24: 3, # 'ö' - 31: 1, # 'ú' - 29: 3, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 6: { # 'l' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 1, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 1, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 2, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 3, # 'e' - 27: 3, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 2, # 'p' - 10: 2, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 3, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 3, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 2, # 'ú' - 29: 2, # 'ü' - 42: 3, # 'ő' - 56: 1, # 'ű' - }, - 13: { # 'm' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 1, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 8: 3, # 'o' - 23: 3, # 'p' - 10: 2, # 'r' - 5: 2, # 's' - 3: 2, # 't' - 21: 3, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 2, # 'ó' - 24: 2, # 'ö' - 31: 2, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 2, # 'ű' - }, - 4: { # 'n' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 2, # 'p' - 10: 2, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 2, # 'v' - 62: 1, # 'x' - 16: 3, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 2, # 'ó' - 24: 3, # 'ö' - 31: 2, # 'ú' - 29: 3, # 'ü' - 42: 2, # 'ő' - 56: 1, # 'ű' - }, - 8: { # 'o' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 1, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 2, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 2, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 1, # 'o' - 23: 3, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 2, # 'u' - 19: 3, # 'v' - 62: 1, # 'x' - 16: 1, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 23: { # 'p' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 1, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 2, # 'k' - 6: 3, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 8: 3, # 'o' - 23: 3, # 'p' - 10: 3, # 'r' - 5: 2, # 's' - 3: 2, # 't' - 21: 3, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 2, # 'ó' - 24: 2, # 'ö' - 31: 1, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 10: { # 'r' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 1, # 'x' - 16: 2, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 3, # 'ú' - 29: 3, # 'ü' - 42: 2, # 'ő' - 56: 2, # 'ű' - }, - 5: { # 's' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 2, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 2, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 1, # 'j' - 7: 3, # 'k' - 6: 2, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 3, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 3, # 'ú' - 29: 3, # 'ü' - 42: 2, # 'ő' - 56: 1, # 'ű' - }, - 3: { # 't' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 1, # 'g' - 20: 3, # 'h' - 9: 3, # 'i' - 22: 3, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 3, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 3, # 'ú' - 29: 3, # 'ü' - 42: 3, # 'ő' - 56: 2, # 'ű' - }, - 21: { # 'u' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 2, # 'b' - 26: 2, # 'c' - 17: 3, # 'd' - 1: 2, # 'e' - 27: 1, # 'f' - 12: 3, # 'g' - 20: 2, # 'h' - 9: 2, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 1, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 1, # 'u' - 19: 3, # 'v' - 62: 1, # 'x' - 16: 1, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 2, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 0, # 'ö' - 31: 1, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 19: { # 'v' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 2, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 3, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 1, # 'r' - 5: 2, # 's' - 3: 2, # 't' - 21: 2, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 2, # 'ó' - 24: 2, # 'ö' - 31: 1, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 1, # 'ű' - }, - 62: { # 'x' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 0, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 1, # 'i' - 22: 0, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 1, # 'o' - 23: 1, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 1, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 1, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 16: { # 'y' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 2, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 3, # 'e' - 27: 2, # 'f' - 12: 2, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 2, # 'j' - 7: 2, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 2, # 'p' - 10: 2, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 2, # 'í' - 25: 2, # 'ó' - 24: 3, # 'ö' - 31: 2, # 'ú' - 29: 2, # 'ü' - 42: 1, # 'ő' - 56: 2, # 'ű' - }, - 11: { # 'z' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 3, # 'a' - 18: 2, # 'b' - 26: 1, # 'c' - 17: 3, # 'd' - 1: 3, # 'e' - 27: 1, # 'f' - 12: 2, # 'g' - 20: 2, # 'h' - 9: 3, # 'i' - 22: 1, # 'j' - 7: 3, # 'k' - 6: 2, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 3, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 3, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 3, # 'á' - 15: 3, # 'é' - 30: 3, # 'í' - 25: 3, # 'ó' - 24: 3, # 'ö' - 31: 2, # 'ú' - 29: 3, # 'ü' - 42: 2, # 'ő' - 56: 1, # 'ű' - }, - 51: { # 'Á' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 0, # 'E' - 50: 1, # 'F' - 49: 2, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 2, # 'L' - 34: 1, # 'M' - 35: 2, # 'N' - 47: 0, # 'O' - 46: 1, # 'P' - 43: 2, # 'R' - 33: 2, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 0, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 1, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 44: { # 'É' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 1, # 'E' - 50: 0, # 'F' - 49: 2, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 2, # 'L' - 34: 1, # 'M' - 35: 2, # 'N' - 47: 0, # 'O' - 46: 1, # 'P' - 43: 2, # 'R' - 33: 2, # 'S' - 37: 2, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 0, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 2, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 3, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 0, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 61: { # 'Í' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 0, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 1, # 'J' - 36: 0, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 0, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 2, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 1, # 'm' - 4: 0, # 'n' - 8: 0, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 0, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 58: { # 'Ó' - 28: 1, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 0, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 1, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 2, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 0, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 2, # 'h' - 9: 0, # 'i' - 22: 0, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 0, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 1, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 59: { # 'Ö' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 0, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 0, # 'O' - 46: 1, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 0, # 'b' - 26: 1, # 'c' - 17: 1, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 0, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 0, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 8: 0, # 'o' - 23: 0, # 'p' - 10: 2, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 60: { # 'Ú' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 1, # 'C' - 45: 1, # 'D' - 32: 0, # 'E' - 50: 1, # 'F' - 49: 1, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 0, # 'b' - 26: 0, # 'c' - 17: 0, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 2, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 2, # 'j' - 7: 0, # 'k' - 6: 0, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 8: 0, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 0, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 0, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 63: { # 'Ü' - 28: 0, # 'A' - 40: 1, # 'B' - 54: 0, # 'C' - 45: 1, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 1, # 'G' - 38: 1, # 'H' - 39: 0, # 'I' - 53: 1, # 'J' - 36: 1, # 'K' - 41: 1, # 'L' - 34: 1, # 'M' - 35: 1, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 1, # 'R' - 33: 1, # 'S' - 37: 1, # 'T' - 57: 0, # 'U' - 48: 1, # 'V' - 55: 0, # 'Y' - 52: 1, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 0, # 'c' - 17: 1, # 'd' - 1: 0, # 'e' - 27: 0, # 'f' - 12: 1, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 0, # 'j' - 7: 0, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 8: 0, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 1, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 14: { # 'á' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 3, # 'b' - 26: 3, # 'c' - 17: 3, # 'd' - 1: 1, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 2, # 'h' - 9: 2, # 'i' - 22: 3, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 1, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 2, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 1, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 2, # 'é' - 30: 1, # 'í' - 25: 0, # 'ó' - 24: 1, # 'ö' - 31: 0, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 15: { # 'é' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 3, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 3, # 'g' - 20: 3, # 'h' - 9: 2, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 1, # 'o' - 23: 3, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 0, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 30: { # 'í' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 0, # 'a' - 18: 1, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 0, # 'e' - 27: 1, # 'f' - 12: 3, # 'g' - 20: 0, # 'h' - 9: 0, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 2, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 2, # 's' - 3: 3, # 't' - 21: 0, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 25: { # 'ó' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 2, # 'a' - 18: 3, # 'b' - 26: 2, # 'c' - 17: 3, # 'd' - 1: 1, # 'e' - 27: 2, # 'f' - 12: 2, # 'g' - 20: 2, # 'h' - 9: 2, # 'i' - 22: 2, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 8: 1, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 1, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 0, # 'ó' - 24: 1, # 'ö' - 31: 1, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 24: { # 'ö' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 0, # 'a' - 18: 3, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 0, # 'e' - 27: 1, # 'f' - 12: 2, # 'g' - 20: 1, # 'h' - 9: 0, # 'i' - 22: 1, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 8: 0, # 'o' - 23: 2, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 3, # 't' - 21: 0, # 'u' - 19: 3, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 3, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 31: { # 'ú' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 1, # 'b' - 26: 2, # 'c' - 17: 1, # 'd' - 1: 1, # 'e' - 27: 2, # 'f' - 12: 3, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 3, # 'j' - 7: 1, # 'k' - 6: 3, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 3, # 'r' - 5: 3, # 's' - 3: 2, # 't' - 21: 1, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 1, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 29: { # 'ü' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 1, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 3, # 'g' - 20: 2, # 'h' - 9: 1, # 'i' - 22: 1, # 'j' - 7: 3, # 'k' - 6: 3, # 'l' - 13: 1, # 'm' - 4: 3, # 'n' - 8: 0, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 2, # 's' - 3: 2, # 't' - 21: 0, # 'u' - 19: 2, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 1, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 42: { # 'ő' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 2, # 'b' - 26: 1, # 'c' - 17: 2, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 1, # 'j' - 7: 2, # 'k' - 6: 3, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 8: 1, # 'o' - 23: 1, # 'p' - 10: 2, # 'r' - 5: 2, # 's' - 3: 2, # 't' - 21: 1, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 1, # 'é' - 30: 1, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 1, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, - 56: { # 'ű' - 28: 0, # 'A' - 40: 0, # 'B' - 54: 0, # 'C' - 45: 0, # 'D' - 32: 0, # 'E' - 50: 0, # 'F' - 49: 0, # 'G' - 38: 0, # 'H' - 39: 0, # 'I' - 53: 0, # 'J' - 36: 0, # 'K' - 41: 0, # 'L' - 34: 0, # 'M' - 35: 0, # 'N' - 47: 0, # 'O' - 46: 0, # 'P' - 43: 0, # 'R' - 33: 0, # 'S' - 37: 0, # 'T' - 57: 0, # 'U' - 48: 0, # 'V' - 55: 0, # 'Y' - 52: 0, # 'Z' - 2: 1, # 'a' - 18: 1, # 'b' - 26: 0, # 'c' - 17: 1, # 'd' - 1: 1, # 'e' - 27: 1, # 'f' - 12: 1, # 'g' - 20: 1, # 'h' - 9: 1, # 'i' - 22: 1, # 'j' - 7: 1, # 'k' - 6: 1, # 'l' - 13: 0, # 'm' - 4: 2, # 'n' - 8: 0, # 'o' - 23: 0, # 'p' - 10: 1, # 'r' - 5: 1, # 's' - 3: 1, # 't' - 21: 0, # 'u' - 19: 1, # 'v' - 62: 0, # 'x' - 16: 0, # 'y' - 11: 2, # 'z' - 51: 0, # 'Á' - 44: 0, # 'É' - 61: 0, # 'Í' - 58: 0, # 'Ó' - 59: 0, # 'Ö' - 60: 0, # 'Ú' - 63: 0, # 'Ü' - 14: 0, # 'á' - 15: 0, # 'é' - 30: 0, # 'í' - 25: 0, # 'ó' - 24: 0, # 'ö' - 31: 0, # 'ú' - 29: 0, # 'ü' - 42: 0, # 'ő' - 56: 0, # 'ű' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 28, # 'A' - 66: 40, # 'B' - 67: 54, # 'C' - 68: 45, # 'D' - 69: 32, # 'E' - 70: 50, # 'F' - 71: 49, # 'G' - 72: 38, # 'H' - 73: 39, # 'I' - 74: 53, # 'J' - 75: 36, # 'K' - 76: 41, # 'L' - 77: 34, # 'M' - 78: 35, # 'N' - 79: 47, # 'O' - 80: 46, # 'P' - 81: 72, # 'Q' - 82: 43, # 'R' - 83: 33, # 'S' - 84: 37, # 'T' - 85: 57, # 'U' - 86: 48, # 'V' - 87: 64, # 'W' - 88: 68, # 'X' - 89: 55, # 'Y' - 90: 52, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 2, # 'a' - 98: 18, # 'b' - 99: 26, # 'c' - 100: 17, # 'd' - 101: 1, # 'e' - 102: 27, # 'f' - 103: 12, # 'g' - 104: 20, # 'h' - 105: 9, # 'i' - 106: 22, # 'j' - 107: 7, # 'k' - 108: 6, # 'l' - 109: 13, # 'm' - 110: 4, # 'n' - 111: 8, # 'o' - 112: 23, # 'p' - 113: 67, # 'q' - 114: 10, # 'r' - 115: 5, # 's' - 116: 3, # 't' - 117: 21, # 'u' - 118: 19, # 'v' - 119: 65, # 'w' - 120: 62, # 'x' - 121: 16, # 'y' - 122: 11, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 161, # '€' - 129: 162, # None - 130: 163, # '‚' - 131: 164, # None - 132: 165, # '„' - 133: 166, # '…' - 134: 167, # '†' - 135: 168, # '‡' - 136: 169, # None - 137: 170, # '‰' - 138: 171, # 'Š' - 139: 172, # '‹' - 140: 173, # 'Ś' - 141: 174, # 'Ť' - 142: 175, # 'Ž' - 143: 176, # 'Ź' - 144: 177, # None - 145: 178, # '‘' - 146: 179, # '’' - 147: 180, # '“' - 148: 78, # '”' - 149: 181, # '•' - 150: 69, # '–' - 151: 182, # '—' - 152: 183, # None - 153: 184, # '™' - 154: 185, # 'š' - 155: 186, # '›' - 156: 187, # 'ś' - 157: 188, # 'ť' - 158: 189, # 'ž' - 159: 190, # 'ź' - 160: 191, # '\xa0' - 161: 192, # 'ˇ' - 162: 193, # '˘' - 163: 194, # 'Ł' - 164: 195, # '¤' - 165: 196, # 'Ą' - 166: 197, # '¦' - 167: 76, # '§' - 168: 198, # '¨' - 169: 199, # '©' - 170: 200, # 'Ş' - 171: 201, # '«' - 172: 202, # '¬' - 173: 203, # '\xad' - 174: 204, # '®' - 175: 205, # 'Ż' - 176: 81, # '°' - 177: 206, # '±' - 178: 207, # '˛' - 179: 208, # 'ł' - 180: 209, # '´' - 181: 210, # 'µ' - 182: 211, # '¶' - 183: 212, # '·' - 184: 213, # '¸' - 185: 214, # 'ą' - 186: 215, # 'ş' - 187: 216, # '»' - 188: 217, # 'Ľ' - 189: 218, # '˝' - 190: 219, # 'ľ' - 191: 220, # 'ż' - 192: 221, # 'Ŕ' - 193: 51, # 'Á' - 194: 83, # 'Â' - 195: 222, # 'Ă' - 196: 80, # 'Ä' - 197: 223, # 'Ĺ' - 198: 224, # 'Ć' - 199: 225, # 'Ç' - 200: 226, # 'Č' - 201: 44, # 'É' - 202: 227, # 'Ę' - 203: 228, # 'Ë' - 204: 229, # 'Ě' - 205: 61, # 'Í' - 206: 230, # 'Î' - 207: 231, # 'Ď' - 208: 232, # 'Đ' - 209: 233, # 'Ń' - 210: 234, # 'Ň' - 211: 58, # 'Ó' - 212: 235, # 'Ô' - 213: 66, # 'Ő' - 214: 59, # 'Ö' - 215: 236, # '×' - 216: 237, # 'Ř' - 217: 238, # 'Ů' - 218: 60, # 'Ú' - 219: 70, # 'Ű' - 220: 63, # 'Ü' - 221: 239, # 'Ý' - 222: 240, # 'Ţ' - 223: 241, # 'ß' - 224: 84, # 'ŕ' - 225: 14, # 'á' - 226: 75, # 'â' - 227: 242, # 'ă' - 228: 71, # 'ä' - 229: 82, # 'ĺ' - 230: 243, # 'ć' - 231: 73, # 'ç' - 232: 244, # 'č' - 233: 15, # 'é' - 234: 85, # 'ę' - 235: 79, # 'ë' - 236: 86, # 'ě' - 237: 30, # 'í' - 238: 77, # 'î' - 239: 87, # 'ď' - 240: 245, # 'đ' - 241: 246, # 'ń' - 242: 247, # 'ň' - 243: 25, # 'ó' - 244: 74, # 'ô' - 245: 42, # 'ő' - 246: 24, # 'ö' - 247: 248, # '÷' - 248: 249, # 'ř' - 249: 250, # 'ů' - 250: 31, # 'ú' - 251: 56, # 'ű' - 252: 29, # 'ü' - 253: 251, # 'ý' - 254: 252, # 'ţ' - 255: 253, # '˙' -} - -WINDOWS_1250_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1250', - language='Hungarian', - char_to_order_map=WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER, - language_model=HUNGARIAN_LANG_MODEL, - typical_positive_ratio=0.947368, - keep_ascii_letters=True, - alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') - -ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 28, # 'A' - 66: 40, # 'B' - 67: 54, # 'C' - 68: 45, # 'D' - 69: 32, # 'E' - 70: 50, # 'F' - 71: 49, # 'G' - 72: 38, # 'H' - 73: 39, # 'I' - 74: 53, # 'J' - 75: 36, # 'K' - 76: 41, # 'L' - 77: 34, # 'M' - 78: 35, # 'N' - 79: 47, # 'O' - 80: 46, # 'P' - 81: 71, # 'Q' - 82: 43, # 'R' - 83: 33, # 'S' - 84: 37, # 'T' - 85: 57, # 'U' - 86: 48, # 'V' - 87: 64, # 'W' - 88: 68, # 'X' - 89: 55, # 'Y' - 90: 52, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 2, # 'a' - 98: 18, # 'b' - 99: 26, # 'c' - 100: 17, # 'd' - 101: 1, # 'e' - 102: 27, # 'f' - 103: 12, # 'g' - 104: 20, # 'h' - 105: 9, # 'i' - 106: 22, # 'j' - 107: 7, # 'k' - 108: 6, # 'l' - 109: 13, # 'm' - 110: 4, # 'n' - 111: 8, # 'o' - 112: 23, # 'p' - 113: 67, # 'q' - 114: 10, # 'r' - 115: 5, # 's' - 116: 3, # 't' - 117: 21, # 'u' - 118: 19, # 'v' - 119: 65, # 'w' - 120: 62, # 'x' - 121: 16, # 'y' - 122: 11, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 159, # '\x80' - 129: 160, # '\x81' - 130: 161, # '\x82' - 131: 162, # '\x83' - 132: 163, # '\x84' - 133: 164, # '\x85' - 134: 165, # '\x86' - 135: 166, # '\x87' - 136: 167, # '\x88' - 137: 168, # '\x89' - 138: 169, # '\x8a' - 139: 170, # '\x8b' - 140: 171, # '\x8c' - 141: 172, # '\x8d' - 142: 173, # '\x8e' - 143: 174, # '\x8f' - 144: 175, # '\x90' - 145: 176, # '\x91' - 146: 177, # '\x92' - 147: 178, # '\x93' - 148: 179, # '\x94' - 149: 180, # '\x95' - 150: 181, # '\x96' - 151: 182, # '\x97' - 152: 183, # '\x98' - 153: 184, # '\x99' - 154: 185, # '\x9a' - 155: 186, # '\x9b' - 156: 187, # '\x9c' - 157: 188, # '\x9d' - 158: 189, # '\x9e' - 159: 190, # '\x9f' - 160: 191, # '\xa0' - 161: 192, # 'Ą' - 162: 193, # '˘' - 163: 194, # 'Ł' - 164: 195, # '¤' - 165: 196, # 'Ľ' - 166: 197, # 'Ś' - 167: 75, # '§' - 168: 198, # '¨' - 169: 199, # 'Š' - 170: 200, # 'Ş' - 171: 201, # 'Ť' - 172: 202, # 'Ź' - 173: 203, # '\xad' - 174: 204, # 'Ž' - 175: 205, # 'Ż' - 176: 79, # '°' - 177: 206, # 'ą' - 178: 207, # '˛' - 179: 208, # 'ł' - 180: 209, # '´' - 181: 210, # 'ľ' - 182: 211, # 'ś' - 183: 212, # 'ˇ' - 184: 213, # '¸' - 185: 214, # 'š' - 186: 215, # 'ş' - 187: 216, # 'ť' - 188: 217, # 'ź' - 189: 218, # '˝' - 190: 219, # 'ž' - 191: 220, # 'ż' - 192: 221, # 'Ŕ' - 193: 51, # 'Á' - 194: 81, # 'Â' - 195: 222, # 'Ă' - 196: 78, # 'Ä' - 197: 223, # 'Ĺ' - 198: 224, # 'Ć' - 199: 225, # 'Ç' - 200: 226, # 'Č' - 201: 44, # 'É' - 202: 227, # 'Ę' - 203: 228, # 'Ë' - 204: 229, # 'Ě' - 205: 61, # 'Í' - 206: 230, # 'Î' - 207: 231, # 'Ď' - 208: 232, # 'Đ' - 209: 233, # 'Ń' - 210: 234, # 'Ň' - 211: 58, # 'Ó' - 212: 235, # 'Ô' - 213: 66, # 'Ő' - 214: 59, # 'Ö' - 215: 236, # '×' - 216: 237, # 'Ř' - 217: 238, # 'Ů' - 218: 60, # 'Ú' - 219: 69, # 'Ű' - 220: 63, # 'Ü' - 221: 239, # 'Ý' - 222: 240, # 'Ţ' - 223: 241, # 'ß' - 224: 82, # 'ŕ' - 225: 14, # 'á' - 226: 74, # 'â' - 227: 242, # 'ă' - 228: 70, # 'ä' - 229: 80, # 'ĺ' - 230: 243, # 'ć' - 231: 72, # 'ç' - 232: 244, # 'č' - 233: 15, # 'é' - 234: 83, # 'ę' - 235: 77, # 'ë' - 236: 84, # 'ě' - 237: 30, # 'í' - 238: 76, # 'î' - 239: 85, # 'ď' - 240: 245, # 'đ' - 241: 246, # 'ń' - 242: 247, # 'ň' - 243: 25, # 'ó' - 244: 73, # 'ô' - 245: 42, # 'ő' - 246: 24, # 'ö' - 247: 248, # '÷' - 248: 249, # 'ř' - 249: 250, # 'ů' - 250: 31, # 'ú' - 251: 56, # 'ű' - 252: 29, # 'ü' - 253: 251, # 'ý' - 254: 252, # 'ţ' - 255: 253, # '˙' -} - -ISO_8859_2_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-2', - language='Hungarian', - char_to_order_map=ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER, - language_model=HUNGARIAN_LANG_MODEL, - typical_positive_ratio=0.947368, - keep_ascii_letters=True, - alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') - diff --git a/dist/ba_data/python-site-packages/chardet/langrussianmodel.py b/dist/ba_data/python-site-packages/chardet/langrussianmodel.py deleted file mode 100644 index 569689d0..00000000 --- a/dist/ba_data/python-site-packages/chardet/langrussianmodel.py +++ /dev/null @@ -1,5718 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -RUSSIAN_LANG_MODEL = { - 37: { # 'А' - 37: 0, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 1, # 'Ж' - 51: 1, # 'З' - 42: 1, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 2, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 1, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 1, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 1, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 0, # 'е' - 24: 1, # 'ж' - 20: 1, # 'з' - 4: 0, # 'и' - 23: 1, # 'й' - 11: 2, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 0, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 2, # 'у' - 39: 2, # 'ф' - 26: 2, # 'х' - 28: 0, # 'ц' - 22: 1, # 'ч' - 25: 2, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 44: { # 'Б' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 1, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 2, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 33: { # 'В' - 37: 2, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 1, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 2, # 'а' - 21: 1, # 'б' - 10: 1, # 'в' - 19: 1, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 2, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 2, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 1, # 'ц' - 22: 2, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 1, # 'ъ' - 18: 3, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 0, # 'ю' - 16: 1, # 'я' - }, - 46: { # 'Г' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 2, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 1, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 1, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 41: { # 'Д' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 2, # 'Е' - 56: 1, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 2, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 3, # 'ж' - 20: 1, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 1, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 48: { # 'Е' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 1, # 'Ж' - 51: 1, # 'З' - 42: 1, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 2, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 2, # 'Р' - 32: 2, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 1, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 0, # 'а' - 21: 0, # 'б' - 10: 2, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 2, # 'е' - 24: 1, # 'ж' - 20: 1, # 'з' - 4: 0, # 'и' - 23: 2, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 1, # 'н' - 1: 0, # 'о' - 15: 1, # 'п' - 9: 1, # 'р' - 7: 3, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 2, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 56: { # 'Ж' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 1, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 1, # 'б' - 10: 0, # 'в' - 19: 1, # 'г' - 13: 1, # 'д' - 2: 2, # 'е' - 24: 1, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 1, # 'м' - 5: 0, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 2, # 'ю' - 16: 0, # 'я' - }, - 51: { # 'З' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 0, # 'г' - 13: 2, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 1, # 'л' - 12: 1, # 'м' - 5: 2, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 1, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 1, # 'я' - }, - 42: { # 'И' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 2, # 'Е' - 56: 1, # 'Ж' - 51: 1, # 'З' - 42: 1, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 2, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 1, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 1, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 2, # 'з' - 4: 1, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 1, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 1, # 'у' - 39: 1, # 'ф' - 26: 2, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 60: { # 'Й' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 1, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 0, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 36: { # 'К' - 37: 2, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 1, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 2, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 1, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 0, # 'м' - 5: 1, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 49: { # 'Л' - 37: 2, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 1, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 1, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 0, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 0, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 1, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 1, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 1, # 'л' - 12: 0, # 'м' - 5: 1, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 2, # 'ю' - 16: 1, # 'я' - }, - 38: { # 'М' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 1, # 'Ф' - 55: 1, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 0, # 'Ь' - 47: 1, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 1, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 1, # 'л' - 12: 1, # 'м' - 5: 2, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 1, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 31: { # 'Н' - 37: 2, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 1, # 'З' - 42: 2, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 1, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 1, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 3, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 2, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 34: { # 'О' - 37: 0, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 2, # 'Д' - 48: 1, # 'Е' - 56: 1, # 'Ж' - 51: 1, # 'З' - 42: 1, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 2, # 'Л' - 38: 1, # 'М' - 31: 2, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 2, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 1, # 'Ф' - 55: 1, # 'Х' - 58: 0, # 'Ц' - 50: 1, # 'Ч' - 57: 1, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 1, # 'а' - 21: 2, # 'б' - 10: 1, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 0, # 'е' - 24: 1, # 'ж' - 20: 1, # 'з' - 4: 0, # 'и' - 23: 1, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 3, # 'н' - 1: 0, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 1, # 'у' - 39: 1, # 'ф' - 26: 2, # 'х' - 28: 1, # 'ц' - 22: 2, # 'ч' - 25: 2, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 35: { # 'П' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 2, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 1, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 0, # 'м' - 5: 1, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 3, # 'р' - 7: 1, # 'с' - 6: 1, # 'т' - 14: 2, # 'у' - 39: 1, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 2, # 'ь' - 30: 1, # 'э' - 27: 0, # 'ю' - 16: 2, # 'я' - }, - 45: { # 'Р' - 37: 2, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 2, # 'Е' - 56: 1, # 'Ж' - 51: 0, # 'З' - 42: 2, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 2, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 1, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 1, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 1, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 2, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 2, # 'я' - }, - 32: { # 'С' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 2, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 1, # 'Ч' - 57: 1, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 1, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 2, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 1, # 'ж' - 20: 1, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 2, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 1, # 'с' - 6: 3, # 'т' - 14: 2, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 1, # 'ц' - 22: 1, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 1, # 'ъ' - 18: 1, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 40: { # 'Т' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 2, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 1, # 'Ь' - 47: 1, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 1, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 1, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 52: { # 'У' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 1, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 0, # 'Ц' - 50: 1, # 'Ч' - 57: 1, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 1, # 'Ю' - 43: 0, # 'Я' - 3: 1, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 2, # 'д' - 2: 1, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 2, # 'и' - 23: 1, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 1, # 'н' - 1: 2, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 0, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 1, # 'ц' - 22: 2, # 'ч' - 25: 1, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 53: { # 'Ф' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 0, # 'с' - 6: 1, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 55: { # 'Х' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 2, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 0, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 1, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 1, # 'ь' - 30: 1, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 58: { # 'Ц' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 1, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 1, # 'а' - 21: 0, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 0, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 1, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 50: { # 'Ч' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 1, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 1, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 1, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 1, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 3, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 1, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 57: { # 'Ш' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 1, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 0, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 1, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 1, # 'н' - 1: 2, # 'о' - 15: 2, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 2, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 63: { # 'Щ' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 1, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 1, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 1, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 1, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 1, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 1, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 62: { # 'Ы' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 1, # 'Ц' - 50: 0, # 'Ч' - 57: 1, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 0, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 0, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 0, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 61: { # 'Ь' - 37: 0, # 'А' - 44: 1, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 0, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 1, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 1, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 1, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 1, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 0, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 0, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 0, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 0, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 47: { # 'Э' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 1, # 'Й' - 36: 1, # 'К' - 49: 1, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 1, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 1, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 2, # 'д' - 2: 0, # 'е' - 24: 1, # 'ж' - 20: 0, # 'з' - 4: 0, # 'и' - 23: 2, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 0, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 1, # 'с' - 6: 3, # 'т' - 14: 1, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 59: { # 'Ю' - 37: 1, # 'А' - 44: 1, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 1, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 0, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 1, # 'б' - 10: 0, # 'в' - 19: 1, # 'г' - 13: 1, # 'д' - 2: 0, # 'е' - 24: 1, # 'ж' - 20: 0, # 'з' - 4: 0, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 2, # 'н' - 1: 0, # 'о' - 15: 1, # 'п' - 9: 1, # 'р' - 7: 1, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 43: { # 'Я' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 1, # 'В' - 46: 1, # 'Г' - 41: 0, # 'Д' - 48: 1, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 1, # 'С' - 40: 1, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 1, # 'Х' - 58: 0, # 'Ц' - 50: 1, # 'Ч' - 57: 0, # 'Ш' - 63: 1, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 1, # 'Ю' - 43: 1, # 'Я' - 3: 0, # 'а' - 21: 1, # 'б' - 10: 1, # 'в' - 19: 1, # 'г' - 13: 1, # 'д' - 2: 0, # 'е' - 24: 0, # 'ж' - 20: 1, # 'з' - 4: 0, # 'и' - 23: 1, # 'й' - 11: 1, # 'к' - 8: 1, # 'л' - 12: 1, # 'м' - 5: 2, # 'н' - 1: 0, # 'о' - 15: 1, # 'п' - 9: 1, # 'р' - 7: 1, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 0, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 3: { # 'а' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 1, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 3, # 'з' - 4: 3, # 'и' - 23: 3, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 2, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 3, # 'ц' - 22: 3, # 'ч' - 25: 3, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 2, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 21: { # 'б' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 1, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 1, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 0, # 'ф' - 26: 2, # 'х' - 28: 1, # 'ц' - 22: 1, # 'ч' - 25: 2, # 'ш' - 29: 3, # 'щ' - 54: 2, # 'ъ' - 18: 3, # 'ы' - 17: 2, # 'ь' - 30: 1, # 'э' - 27: 2, # 'ю' - 16: 3, # 'я' - }, - 10: { # 'в' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 2, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 1, # 'ж' - 20: 3, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 2, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 3, # 'ш' - 29: 2, # 'щ' - 54: 2, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 3, # 'я' - }, - 19: { # 'г' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 3, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 1, # 'ц' - 22: 2, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 1, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 13: { # 'д' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 3, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 2, # 'х' - 28: 3, # 'ц' - 22: 2, # 'ч' - 25: 2, # 'ш' - 29: 1, # 'щ' - 54: 2, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 1, # 'э' - 27: 2, # 'ю' - 16: 3, # 'я' - }, - 2: { # 'е' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 3, # 'з' - 4: 2, # 'и' - 23: 3, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 2, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 3, # 'ц' - 22: 3, # 'ч' - 25: 3, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 2, # 'ю' - 16: 3, # 'я' - }, - 24: { # 'ж' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 1, # 'в' - 19: 2, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 3, # 'н' - 1: 2, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 1, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 0, # 'х' - 28: 1, # 'ц' - 22: 2, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 2, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 20: { # 'з' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 3, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 1, # 'ц' - 22: 2, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 2, # 'ъ' - 18: 3, # 'ы' - 17: 2, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 3, # 'я' - }, - 4: { # 'и' - 37: 1, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 3, # 'з' - 4: 3, # 'и' - 23: 3, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 2, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 3, # 'ц' - 22: 3, # 'ч' - 25: 3, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 2, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 23: { # 'й' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 1, # 'а' - 21: 1, # 'б' - 10: 1, # 'в' - 19: 2, # 'г' - 13: 3, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 2, # 'з' - 4: 1, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 2, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 1, # 'у' - 39: 2, # 'ф' - 26: 1, # 'х' - 28: 2, # 'ц' - 22: 3, # 'ч' - 25: 2, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 2, # 'я' - }, - 11: { # 'к' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 3, # 'в' - 19: 1, # 'г' - 13: 1, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 3, # 'л' - 12: 1, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 2, # 'х' - 28: 2, # 'ц' - 22: 1, # 'ч' - 25: 2, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 1, # 'ы' - 17: 1, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 8: { # 'л' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 3, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 1, # 'р' - 7: 3, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 2, # 'х' - 28: 1, # 'ц' - 22: 3, # 'ч' - 25: 2, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 1, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 12: { # 'м' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 2, # 'г' - 13: 1, # 'д' - 2: 3, # 'е' - 24: 1, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 2, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 1, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 2, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 3, # 'я' - }, - 5: { # 'н' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 2, # 'х' - 28: 3, # 'ц' - 22: 3, # 'ч' - 25: 2, # 'ш' - 29: 2, # 'щ' - 54: 1, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 1, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 1: { # 'о' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 3, # 'з' - 4: 3, # 'и' - 23: 3, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 2, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 2, # 'ц' - 22: 3, # 'ч' - 25: 3, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 2, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 15: { # 'п' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 3, # 'л' - 12: 1, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 3, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 0, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 1, # 'ш' - 29: 1, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 2, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 3, # 'я' - }, - 9: { # 'р' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 2, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 3, # 'ш' - 29: 2, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 2, # 'э' - 27: 2, # 'ю' - 16: 3, # 'я' - }, - 7: { # 'с' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 1, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 3, # 'в' - 19: 2, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 2, # 'ц' - 22: 3, # 'ч' - 25: 2, # 'ш' - 29: 1, # 'щ' - 54: 2, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 2, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 6: { # 'т' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 2, # 'б' - 10: 3, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 1, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 2, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 2, # 'ш' - 29: 2, # 'щ' - 54: 2, # 'ъ' - 18: 3, # 'ы' - 17: 3, # 'ь' - 30: 2, # 'э' - 27: 2, # 'ю' - 16: 3, # 'я' - }, - 14: { # 'у' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 3, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 3, # 'з' - 4: 2, # 'и' - 23: 2, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 2, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 1, # 'у' - 39: 2, # 'ф' - 26: 3, # 'х' - 28: 2, # 'ц' - 22: 3, # 'ч' - 25: 3, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 2, # 'э' - 27: 3, # 'ю' - 16: 2, # 'я' - }, - 39: { # 'ф' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 0, # 'в' - 19: 1, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 1, # 'н' - 1: 3, # 'о' - 15: 1, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 2, # 'у' - 39: 2, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 1, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 2, # 'ы' - 17: 1, # 'ь' - 30: 2, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 26: { # 'х' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 3, # 'в' - 19: 1, # 'г' - 13: 1, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 1, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 1, # 'п' - 9: 3, # 'р' - 7: 2, # 'с' - 6: 2, # 'т' - 14: 2, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 1, # 'ц' - 22: 1, # 'ч' - 25: 2, # 'ш' - 29: 0, # 'щ' - 54: 1, # 'ъ' - 18: 0, # 'ы' - 17: 1, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 28: { # 'ц' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 1, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 1, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 2, # 'к' - 8: 1, # 'л' - 12: 1, # 'м' - 5: 1, # 'н' - 1: 3, # 'о' - 15: 0, # 'п' - 9: 1, # 'р' - 7: 0, # 'с' - 6: 1, # 'т' - 14: 3, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 1, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 3, # 'ы' - 17: 1, # 'ь' - 30: 0, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 22: { # 'ч' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 1, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 2, # 'л' - 12: 1, # 'м' - 5: 3, # 'н' - 1: 2, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 1, # 'с' - 6: 3, # 'т' - 14: 3, # 'у' - 39: 1, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 1, # 'ч' - 25: 2, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 3, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 25: { # 'ш' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 1, # 'б' - 10: 2, # 'в' - 19: 1, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 2, # 'м' - 5: 3, # 'н' - 1: 3, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 1, # 'с' - 6: 2, # 'т' - 14: 3, # 'у' - 39: 2, # 'ф' - 26: 1, # 'х' - 28: 1, # 'ц' - 22: 1, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 3, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 0, # 'я' - }, - 29: { # 'щ' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 3, # 'а' - 21: 0, # 'б' - 10: 1, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 3, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 3, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 1, # 'м' - 5: 2, # 'н' - 1: 1, # 'о' - 15: 0, # 'п' - 9: 2, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 2, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 2, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 0, # 'я' - }, - 54: { # 'ъ' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 0, # 'б' - 10: 0, # 'в' - 19: 0, # 'г' - 13: 0, # 'д' - 2: 2, # 'е' - 24: 0, # 'ж' - 20: 0, # 'з' - 4: 0, # 'и' - 23: 0, # 'й' - 11: 0, # 'к' - 8: 0, # 'л' - 12: 0, # 'м' - 5: 0, # 'н' - 1: 0, # 'о' - 15: 0, # 'п' - 9: 0, # 'р' - 7: 0, # 'с' - 6: 0, # 'т' - 14: 0, # 'у' - 39: 0, # 'ф' - 26: 0, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 0, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 1, # 'ю' - 16: 2, # 'я' - }, - 18: { # 'ы' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 3, # 'б' - 10: 3, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 2, # 'и' - 23: 3, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 1, # 'о' - 15: 3, # 'п' - 9: 3, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 1, # 'у' - 39: 0, # 'ф' - 26: 3, # 'х' - 28: 2, # 'ц' - 22: 3, # 'ч' - 25: 3, # 'ш' - 29: 2, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 0, # 'ю' - 16: 2, # 'я' - }, - 17: { # 'ь' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 2, # 'б' - 10: 2, # 'в' - 19: 2, # 'г' - 13: 2, # 'д' - 2: 3, # 'е' - 24: 1, # 'ж' - 20: 3, # 'з' - 4: 2, # 'и' - 23: 0, # 'й' - 11: 3, # 'к' - 8: 0, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 2, # 'о' - 15: 2, # 'п' - 9: 1, # 'р' - 7: 3, # 'с' - 6: 2, # 'т' - 14: 0, # 'у' - 39: 2, # 'ф' - 26: 1, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 3, # 'ш' - 29: 2, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 3, # 'ю' - 16: 3, # 'я' - }, - 30: { # 'э' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 1, # 'М' - 31: 1, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 1, # 'Р' - 32: 1, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 1, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 1, # 'б' - 10: 1, # 'в' - 19: 1, # 'г' - 13: 2, # 'д' - 2: 1, # 'е' - 24: 0, # 'ж' - 20: 1, # 'з' - 4: 0, # 'и' - 23: 2, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 0, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 2, # 'с' - 6: 3, # 'т' - 14: 1, # 'у' - 39: 2, # 'ф' - 26: 1, # 'х' - 28: 0, # 'ц' - 22: 0, # 'ч' - 25: 1, # 'ш' - 29: 0, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 1, # 'ю' - 16: 1, # 'я' - }, - 27: { # 'ю' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 2, # 'а' - 21: 3, # 'б' - 10: 1, # 'в' - 19: 2, # 'г' - 13: 3, # 'д' - 2: 1, # 'е' - 24: 2, # 'ж' - 20: 2, # 'з' - 4: 1, # 'и' - 23: 1, # 'й' - 11: 2, # 'к' - 8: 2, # 'л' - 12: 2, # 'м' - 5: 2, # 'н' - 1: 1, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 0, # 'у' - 39: 1, # 'ф' - 26: 2, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 2, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 1, # 'э' - 27: 2, # 'ю' - 16: 1, # 'я' - }, - 16: { # 'я' - 37: 0, # 'А' - 44: 0, # 'Б' - 33: 0, # 'В' - 46: 0, # 'Г' - 41: 0, # 'Д' - 48: 0, # 'Е' - 56: 0, # 'Ж' - 51: 0, # 'З' - 42: 0, # 'И' - 60: 0, # 'Й' - 36: 0, # 'К' - 49: 0, # 'Л' - 38: 0, # 'М' - 31: 0, # 'Н' - 34: 0, # 'О' - 35: 0, # 'П' - 45: 0, # 'Р' - 32: 0, # 'С' - 40: 0, # 'Т' - 52: 0, # 'У' - 53: 0, # 'Ф' - 55: 0, # 'Х' - 58: 0, # 'Ц' - 50: 0, # 'Ч' - 57: 0, # 'Ш' - 63: 0, # 'Щ' - 62: 0, # 'Ы' - 61: 0, # 'Ь' - 47: 0, # 'Э' - 59: 0, # 'Ю' - 43: 0, # 'Я' - 3: 0, # 'а' - 21: 2, # 'б' - 10: 3, # 'в' - 19: 2, # 'г' - 13: 3, # 'д' - 2: 3, # 'е' - 24: 3, # 'ж' - 20: 3, # 'з' - 4: 2, # 'и' - 23: 2, # 'й' - 11: 3, # 'к' - 8: 3, # 'л' - 12: 3, # 'м' - 5: 3, # 'н' - 1: 0, # 'о' - 15: 2, # 'п' - 9: 2, # 'р' - 7: 3, # 'с' - 6: 3, # 'т' - 14: 1, # 'у' - 39: 1, # 'ф' - 26: 3, # 'х' - 28: 2, # 'ц' - 22: 2, # 'ч' - 25: 2, # 'ш' - 29: 3, # 'щ' - 54: 0, # 'ъ' - 18: 0, # 'ы' - 17: 0, # 'ь' - 30: 0, # 'э' - 27: 2, # 'ю' - 16: 2, # 'я' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -IBM866_RUSSIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 142, # 'A' - 66: 143, # 'B' - 67: 144, # 'C' - 68: 145, # 'D' - 69: 146, # 'E' - 70: 147, # 'F' - 71: 148, # 'G' - 72: 149, # 'H' - 73: 150, # 'I' - 74: 151, # 'J' - 75: 152, # 'K' - 76: 74, # 'L' - 77: 153, # 'M' - 78: 75, # 'N' - 79: 154, # 'O' - 80: 155, # 'P' - 81: 156, # 'Q' - 82: 157, # 'R' - 83: 158, # 'S' - 84: 159, # 'T' - 85: 160, # 'U' - 86: 161, # 'V' - 87: 162, # 'W' - 88: 163, # 'X' - 89: 164, # 'Y' - 90: 165, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 71, # 'a' - 98: 172, # 'b' - 99: 66, # 'c' - 100: 173, # 'd' - 101: 65, # 'e' - 102: 174, # 'f' - 103: 76, # 'g' - 104: 175, # 'h' - 105: 64, # 'i' - 106: 176, # 'j' - 107: 177, # 'k' - 108: 77, # 'l' - 109: 72, # 'm' - 110: 178, # 'n' - 111: 69, # 'o' - 112: 67, # 'p' - 113: 179, # 'q' - 114: 78, # 'r' - 115: 73, # 's' - 116: 180, # 't' - 117: 181, # 'u' - 118: 79, # 'v' - 119: 182, # 'w' - 120: 183, # 'x' - 121: 184, # 'y' - 122: 185, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 37, # 'А' - 129: 44, # 'Б' - 130: 33, # 'В' - 131: 46, # 'Г' - 132: 41, # 'Д' - 133: 48, # 'Е' - 134: 56, # 'Ж' - 135: 51, # 'З' - 136: 42, # 'И' - 137: 60, # 'Й' - 138: 36, # 'К' - 139: 49, # 'Л' - 140: 38, # 'М' - 141: 31, # 'Н' - 142: 34, # 'О' - 143: 35, # 'П' - 144: 45, # 'Р' - 145: 32, # 'С' - 146: 40, # 'Т' - 147: 52, # 'У' - 148: 53, # 'Ф' - 149: 55, # 'Х' - 150: 58, # 'Ц' - 151: 50, # 'Ч' - 152: 57, # 'Ш' - 153: 63, # 'Щ' - 154: 70, # 'Ъ' - 155: 62, # 'Ы' - 156: 61, # 'Ь' - 157: 47, # 'Э' - 158: 59, # 'Ю' - 159: 43, # 'Я' - 160: 3, # 'а' - 161: 21, # 'б' - 162: 10, # 'в' - 163: 19, # 'г' - 164: 13, # 'д' - 165: 2, # 'е' - 166: 24, # 'ж' - 167: 20, # 'з' - 168: 4, # 'и' - 169: 23, # 'й' - 170: 11, # 'к' - 171: 8, # 'л' - 172: 12, # 'м' - 173: 5, # 'н' - 174: 1, # 'о' - 175: 15, # 'п' - 176: 191, # '░' - 177: 192, # '▒' - 178: 193, # '▓' - 179: 194, # '│' - 180: 195, # '┤' - 181: 196, # '╡' - 182: 197, # '╢' - 183: 198, # '╖' - 184: 199, # '╕' - 185: 200, # '╣' - 186: 201, # '║' - 187: 202, # '╗' - 188: 203, # '╝' - 189: 204, # '╜' - 190: 205, # '╛' - 191: 206, # '┐' - 192: 207, # '└' - 193: 208, # '┴' - 194: 209, # '┬' - 195: 210, # '├' - 196: 211, # '─' - 197: 212, # '┼' - 198: 213, # '╞' - 199: 214, # '╟' - 200: 215, # '╚' - 201: 216, # '╔' - 202: 217, # '╩' - 203: 218, # '╦' - 204: 219, # '╠' - 205: 220, # '═' - 206: 221, # '╬' - 207: 222, # '╧' - 208: 223, # '╨' - 209: 224, # '╤' - 210: 225, # '╥' - 211: 226, # '╙' - 212: 227, # '╘' - 213: 228, # '╒' - 214: 229, # '╓' - 215: 230, # '╫' - 216: 231, # '╪' - 217: 232, # '┘' - 218: 233, # '┌' - 219: 234, # '█' - 220: 235, # '▄' - 221: 236, # '▌' - 222: 237, # '▐' - 223: 238, # '▀' - 224: 9, # 'р' - 225: 7, # 'с' - 226: 6, # 'т' - 227: 14, # 'у' - 228: 39, # 'ф' - 229: 26, # 'х' - 230: 28, # 'ц' - 231: 22, # 'ч' - 232: 25, # 'ш' - 233: 29, # 'щ' - 234: 54, # 'ъ' - 235: 18, # 'ы' - 236: 17, # 'ь' - 237: 30, # 'э' - 238: 27, # 'ю' - 239: 16, # 'я' - 240: 239, # 'Ё' - 241: 68, # 'ё' - 242: 240, # 'Є' - 243: 241, # 'є' - 244: 242, # 'Ї' - 245: 243, # 'ї' - 246: 244, # 'Ў' - 247: 245, # 'ў' - 248: 246, # '°' - 249: 247, # '∙' - 250: 248, # '·' - 251: 249, # '√' - 252: 250, # '№' - 253: 251, # '¤' - 254: 252, # '■' - 255: 255, # '\xa0' -} - -IBM866_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM866', - language='Russian', - char_to_order_map=IBM866_RUSSIAN_CHAR_TO_ORDER, - language_model=RUSSIAN_LANG_MODEL, - typical_positive_ratio=0.976601, - keep_ascii_letters=False, - alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') - -WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 142, # 'A' - 66: 143, # 'B' - 67: 144, # 'C' - 68: 145, # 'D' - 69: 146, # 'E' - 70: 147, # 'F' - 71: 148, # 'G' - 72: 149, # 'H' - 73: 150, # 'I' - 74: 151, # 'J' - 75: 152, # 'K' - 76: 74, # 'L' - 77: 153, # 'M' - 78: 75, # 'N' - 79: 154, # 'O' - 80: 155, # 'P' - 81: 156, # 'Q' - 82: 157, # 'R' - 83: 158, # 'S' - 84: 159, # 'T' - 85: 160, # 'U' - 86: 161, # 'V' - 87: 162, # 'W' - 88: 163, # 'X' - 89: 164, # 'Y' - 90: 165, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 71, # 'a' - 98: 172, # 'b' - 99: 66, # 'c' - 100: 173, # 'd' - 101: 65, # 'e' - 102: 174, # 'f' - 103: 76, # 'g' - 104: 175, # 'h' - 105: 64, # 'i' - 106: 176, # 'j' - 107: 177, # 'k' - 108: 77, # 'l' - 109: 72, # 'm' - 110: 178, # 'n' - 111: 69, # 'o' - 112: 67, # 'p' - 113: 179, # 'q' - 114: 78, # 'r' - 115: 73, # 's' - 116: 180, # 't' - 117: 181, # 'u' - 118: 79, # 'v' - 119: 182, # 'w' - 120: 183, # 'x' - 121: 184, # 'y' - 122: 185, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 191, # 'Ђ' - 129: 192, # 'Ѓ' - 130: 193, # '‚' - 131: 194, # 'ѓ' - 132: 195, # '„' - 133: 196, # '…' - 134: 197, # '†' - 135: 198, # '‡' - 136: 199, # '€' - 137: 200, # '‰' - 138: 201, # 'Љ' - 139: 202, # '‹' - 140: 203, # 'Њ' - 141: 204, # 'Ќ' - 142: 205, # 'Ћ' - 143: 206, # 'Џ' - 144: 207, # 'ђ' - 145: 208, # '‘' - 146: 209, # '’' - 147: 210, # '“' - 148: 211, # '”' - 149: 212, # '•' - 150: 213, # '–' - 151: 214, # '—' - 152: 215, # None - 153: 216, # '™' - 154: 217, # 'љ' - 155: 218, # '›' - 156: 219, # 'њ' - 157: 220, # 'ќ' - 158: 221, # 'ћ' - 159: 222, # 'џ' - 160: 223, # '\xa0' - 161: 224, # 'Ў' - 162: 225, # 'ў' - 163: 226, # 'Ј' - 164: 227, # '¤' - 165: 228, # 'Ґ' - 166: 229, # '¦' - 167: 230, # '§' - 168: 231, # 'Ё' - 169: 232, # '©' - 170: 233, # 'Є' - 171: 234, # '«' - 172: 235, # '¬' - 173: 236, # '\xad' - 174: 237, # '®' - 175: 238, # 'Ї' - 176: 239, # '°' - 177: 240, # '±' - 178: 241, # 'І' - 179: 242, # 'і' - 180: 243, # 'ґ' - 181: 244, # 'µ' - 182: 245, # '¶' - 183: 246, # '·' - 184: 68, # 'ё' - 185: 247, # '№' - 186: 248, # 'є' - 187: 249, # '»' - 188: 250, # 'ј' - 189: 251, # 'Ѕ' - 190: 252, # 'ѕ' - 191: 253, # 'ї' - 192: 37, # 'А' - 193: 44, # 'Б' - 194: 33, # 'В' - 195: 46, # 'Г' - 196: 41, # 'Д' - 197: 48, # 'Е' - 198: 56, # 'Ж' - 199: 51, # 'З' - 200: 42, # 'И' - 201: 60, # 'Й' - 202: 36, # 'К' - 203: 49, # 'Л' - 204: 38, # 'М' - 205: 31, # 'Н' - 206: 34, # 'О' - 207: 35, # 'П' - 208: 45, # 'Р' - 209: 32, # 'С' - 210: 40, # 'Т' - 211: 52, # 'У' - 212: 53, # 'Ф' - 213: 55, # 'Х' - 214: 58, # 'Ц' - 215: 50, # 'Ч' - 216: 57, # 'Ш' - 217: 63, # 'Щ' - 218: 70, # 'Ъ' - 219: 62, # 'Ы' - 220: 61, # 'Ь' - 221: 47, # 'Э' - 222: 59, # 'Ю' - 223: 43, # 'Я' - 224: 3, # 'а' - 225: 21, # 'б' - 226: 10, # 'в' - 227: 19, # 'г' - 228: 13, # 'д' - 229: 2, # 'е' - 230: 24, # 'ж' - 231: 20, # 'з' - 232: 4, # 'и' - 233: 23, # 'й' - 234: 11, # 'к' - 235: 8, # 'л' - 236: 12, # 'м' - 237: 5, # 'н' - 238: 1, # 'о' - 239: 15, # 'п' - 240: 9, # 'р' - 241: 7, # 'с' - 242: 6, # 'т' - 243: 14, # 'у' - 244: 39, # 'ф' - 245: 26, # 'х' - 246: 28, # 'ц' - 247: 22, # 'ч' - 248: 25, # 'ш' - 249: 29, # 'щ' - 250: 54, # 'ъ' - 251: 18, # 'ы' - 252: 17, # 'ь' - 253: 30, # 'э' - 254: 27, # 'ю' - 255: 16, # 'я' -} - -WINDOWS_1251_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', - language='Russian', - char_to_order_map=WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER, - language_model=RUSSIAN_LANG_MODEL, - typical_positive_ratio=0.976601, - keep_ascii_letters=False, - alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') - -IBM855_RUSSIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 142, # 'A' - 66: 143, # 'B' - 67: 144, # 'C' - 68: 145, # 'D' - 69: 146, # 'E' - 70: 147, # 'F' - 71: 148, # 'G' - 72: 149, # 'H' - 73: 150, # 'I' - 74: 151, # 'J' - 75: 152, # 'K' - 76: 74, # 'L' - 77: 153, # 'M' - 78: 75, # 'N' - 79: 154, # 'O' - 80: 155, # 'P' - 81: 156, # 'Q' - 82: 157, # 'R' - 83: 158, # 'S' - 84: 159, # 'T' - 85: 160, # 'U' - 86: 161, # 'V' - 87: 162, # 'W' - 88: 163, # 'X' - 89: 164, # 'Y' - 90: 165, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 71, # 'a' - 98: 172, # 'b' - 99: 66, # 'c' - 100: 173, # 'd' - 101: 65, # 'e' - 102: 174, # 'f' - 103: 76, # 'g' - 104: 175, # 'h' - 105: 64, # 'i' - 106: 176, # 'j' - 107: 177, # 'k' - 108: 77, # 'l' - 109: 72, # 'm' - 110: 178, # 'n' - 111: 69, # 'o' - 112: 67, # 'p' - 113: 179, # 'q' - 114: 78, # 'r' - 115: 73, # 's' - 116: 180, # 't' - 117: 181, # 'u' - 118: 79, # 'v' - 119: 182, # 'w' - 120: 183, # 'x' - 121: 184, # 'y' - 122: 185, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 191, # 'ђ' - 129: 192, # 'Ђ' - 130: 193, # 'ѓ' - 131: 194, # 'Ѓ' - 132: 68, # 'ё' - 133: 195, # 'Ё' - 134: 196, # 'є' - 135: 197, # 'Є' - 136: 198, # 'ѕ' - 137: 199, # 'Ѕ' - 138: 200, # 'і' - 139: 201, # 'І' - 140: 202, # 'ї' - 141: 203, # 'Ї' - 142: 204, # 'ј' - 143: 205, # 'Ј' - 144: 206, # 'љ' - 145: 207, # 'Љ' - 146: 208, # 'њ' - 147: 209, # 'Њ' - 148: 210, # 'ћ' - 149: 211, # 'Ћ' - 150: 212, # 'ќ' - 151: 213, # 'Ќ' - 152: 214, # 'ў' - 153: 215, # 'Ў' - 154: 216, # 'џ' - 155: 217, # 'Џ' - 156: 27, # 'ю' - 157: 59, # 'Ю' - 158: 54, # 'ъ' - 159: 70, # 'Ъ' - 160: 3, # 'а' - 161: 37, # 'А' - 162: 21, # 'б' - 163: 44, # 'Б' - 164: 28, # 'ц' - 165: 58, # 'Ц' - 166: 13, # 'д' - 167: 41, # 'Д' - 168: 2, # 'е' - 169: 48, # 'Е' - 170: 39, # 'ф' - 171: 53, # 'Ф' - 172: 19, # 'г' - 173: 46, # 'Г' - 174: 218, # '«' - 175: 219, # '»' - 176: 220, # '░' - 177: 221, # '▒' - 178: 222, # '▓' - 179: 223, # '│' - 180: 224, # '┤' - 181: 26, # 'х' - 182: 55, # 'Х' - 183: 4, # 'и' - 184: 42, # 'И' - 185: 225, # '╣' - 186: 226, # '║' - 187: 227, # '╗' - 188: 228, # '╝' - 189: 23, # 'й' - 190: 60, # 'Й' - 191: 229, # '┐' - 192: 230, # '└' - 193: 231, # '┴' - 194: 232, # '┬' - 195: 233, # '├' - 196: 234, # '─' - 197: 235, # '┼' - 198: 11, # 'к' - 199: 36, # 'К' - 200: 236, # '╚' - 201: 237, # '╔' - 202: 238, # '╩' - 203: 239, # '╦' - 204: 240, # '╠' - 205: 241, # '═' - 206: 242, # '╬' - 207: 243, # '¤' - 208: 8, # 'л' - 209: 49, # 'Л' - 210: 12, # 'м' - 211: 38, # 'М' - 212: 5, # 'н' - 213: 31, # 'Н' - 214: 1, # 'о' - 215: 34, # 'О' - 216: 15, # 'п' - 217: 244, # '┘' - 218: 245, # '┌' - 219: 246, # '█' - 220: 247, # '▄' - 221: 35, # 'П' - 222: 16, # 'я' - 223: 248, # '▀' - 224: 43, # 'Я' - 225: 9, # 'р' - 226: 45, # 'Р' - 227: 7, # 'с' - 228: 32, # 'С' - 229: 6, # 'т' - 230: 40, # 'Т' - 231: 14, # 'у' - 232: 52, # 'У' - 233: 24, # 'ж' - 234: 56, # 'Ж' - 235: 10, # 'в' - 236: 33, # 'В' - 237: 17, # 'ь' - 238: 61, # 'Ь' - 239: 249, # '№' - 240: 250, # '\xad' - 241: 18, # 'ы' - 242: 62, # 'Ы' - 243: 20, # 'з' - 244: 51, # 'З' - 245: 25, # 'ш' - 246: 57, # 'Ш' - 247: 30, # 'э' - 248: 47, # 'Э' - 249: 29, # 'щ' - 250: 63, # 'Щ' - 251: 22, # 'ч' - 252: 50, # 'Ч' - 253: 251, # '§' - 254: 252, # '■' - 255: 255, # '\xa0' -} - -IBM855_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM855', - language='Russian', - char_to_order_map=IBM855_RUSSIAN_CHAR_TO_ORDER, - language_model=RUSSIAN_LANG_MODEL, - typical_positive_ratio=0.976601, - keep_ascii_letters=False, - alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') - -KOI8_R_RUSSIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 142, # 'A' - 66: 143, # 'B' - 67: 144, # 'C' - 68: 145, # 'D' - 69: 146, # 'E' - 70: 147, # 'F' - 71: 148, # 'G' - 72: 149, # 'H' - 73: 150, # 'I' - 74: 151, # 'J' - 75: 152, # 'K' - 76: 74, # 'L' - 77: 153, # 'M' - 78: 75, # 'N' - 79: 154, # 'O' - 80: 155, # 'P' - 81: 156, # 'Q' - 82: 157, # 'R' - 83: 158, # 'S' - 84: 159, # 'T' - 85: 160, # 'U' - 86: 161, # 'V' - 87: 162, # 'W' - 88: 163, # 'X' - 89: 164, # 'Y' - 90: 165, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 71, # 'a' - 98: 172, # 'b' - 99: 66, # 'c' - 100: 173, # 'd' - 101: 65, # 'e' - 102: 174, # 'f' - 103: 76, # 'g' - 104: 175, # 'h' - 105: 64, # 'i' - 106: 176, # 'j' - 107: 177, # 'k' - 108: 77, # 'l' - 109: 72, # 'm' - 110: 178, # 'n' - 111: 69, # 'o' - 112: 67, # 'p' - 113: 179, # 'q' - 114: 78, # 'r' - 115: 73, # 's' - 116: 180, # 't' - 117: 181, # 'u' - 118: 79, # 'v' - 119: 182, # 'w' - 120: 183, # 'x' - 121: 184, # 'y' - 122: 185, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 191, # '─' - 129: 192, # '│' - 130: 193, # '┌' - 131: 194, # '┐' - 132: 195, # '└' - 133: 196, # '┘' - 134: 197, # '├' - 135: 198, # '┤' - 136: 199, # '┬' - 137: 200, # '┴' - 138: 201, # '┼' - 139: 202, # '▀' - 140: 203, # '▄' - 141: 204, # '█' - 142: 205, # '▌' - 143: 206, # '▐' - 144: 207, # '░' - 145: 208, # '▒' - 146: 209, # '▓' - 147: 210, # '⌠' - 148: 211, # '■' - 149: 212, # '∙' - 150: 213, # '√' - 151: 214, # '≈' - 152: 215, # '≤' - 153: 216, # '≥' - 154: 217, # '\xa0' - 155: 218, # '⌡' - 156: 219, # '°' - 157: 220, # '²' - 158: 221, # '·' - 159: 222, # '÷' - 160: 223, # '═' - 161: 224, # '║' - 162: 225, # '╒' - 163: 68, # 'ё' - 164: 226, # '╓' - 165: 227, # '╔' - 166: 228, # '╕' - 167: 229, # '╖' - 168: 230, # '╗' - 169: 231, # '╘' - 170: 232, # '╙' - 171: 233, # '╚' - 172: 234, # '╛' - 173: 235, # '╜' - 174: 236, # '╝' - 175: 237, # '╞' - 176: 238, # '╟' - 177: 239, # '╠' - 178: 240, # '╡' - 179: 241, # 'Ё' - 180: 242, # '╢' - 181: 243, # '╣' - 182: 244, # '╤' - 183: 245, # '╥' - 184: 246, # '╦' - 185: 247, # '╧' - 186: 248, # '╨' - 187: 249, # '╩' - 188: 250, # '╪' - 189: 251, # '╫' - 190: 252, # '╬' - 191: 253, # '©' - 192: 27, # 'ю' - 193: 3, # 'а' - 194: 21, # 'б' - 195: 28, # 'ц' - 196: 13, # 'д' - 197: 2, # 'е' - 198: 39, # 'ф' - 199: 19, # 'г' - 200: 26, # 'х' - 201: 4, # 'и' - 202: 23, # 'й' - 203: 11, # 'к' - 204: 8, # 'л' - 205: 12, # 'м' - 206: 5, # 'н' - 207: 1, # 'о' - 208: 15, # 'п' - 209: 16, # 'я' - 210: 9, # 'р' - 211: 7, # 'с' - 212: 6, # 'т' - 213: 14, # 'у' - 214: 24, # 'ж' - 215: 10, # 'в' - 216: 17, # 'ь' - 217: 18, # 'ы' - 218: 20, # 'з' - 219: 25, # 'ш' - 220: 30, # 'э' - 221: 29, # 'щ' - 222: 22, # 'ч' - 223: 54, # 'ъ' - 224: 59, # 'Ю' - 225: 37, # 'А' - 226: 44, # 'Б' - 227: 58, # 'Ц' - 228: 41, # 'Д' - 229: 48, # 'Е' - 230: 53, # 'Ф' - 231: 46, # 'Г' - 232: 55, # 'Х' - 233: 42, # 'И' - 234: 60, # 'Й' - 235: 36, # 'К' - 236: 49, # 'Л' - 237: 38, # 'М' - 238: 31, # 'Н' - 239: 34, # 'О' - 240: 35, # 'П' - 241: 43, # 'Я' - 242: 45, # 'Р' - 243: 32, # 'С' - 244: 40, # 'Т' - 245: 52, # 'У' - 246: 56, # 'Ж' - 247: 33, # 'В' - 248: 61, # 'Ь' - 249: 62, # 'Ы' - 250: 51, # 'З' - 251: 57, # 'Ш' - 252: 47, # 'Э' - 253: 63, # 'Щ' - 254: 50, # 'Ч' - 255: 70, # 'Ъ' -} - -KOI8_R_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='KOI8-R', - language='Russian', - char_to_order_map=KOI8_R_RUSSIAN_CHAR_TO_ORDER, - language_model=RUSSIAN_LANG_MODEL, - typical_positive_ratio=0.976601, - keep_ascii_letters=False, - alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') - -MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 142, # 'A' - 66: 143, # 'B' - 67: 144, # 'C' - 68: 145, # 'D' - 69: 146, # 'E' - 70: 147, # 'F' - 71: 148, # 'G' - 72: 149, # 'H' - 73: 150, # 'I' - 74: 151, # 'J' - 75: 152, # 'K' - 76: 74, # 'L' - 77: 153, # 'M' - 78: 75, # 'N' - 79: 154, # 'O' - 80: 155, # 'P' - 81: 156, # 'Q' - 82: 157, # 'R' - 83: 158, # 'S' - 84: 159, # 'T' - 85: 160, # 'U' - 86: 161, # 'V' - 87: 162, # 'W' - 88: 163, # 'X' - 89: 164, # 'Y' - 90: 165, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 71, # 'a' - 98: 172, # 'b' - 99: 66, # 'c' - 100: 173, # 'd' - 101: 65, # 'e' - 102: 174, # 'f' - 103: 76, # 'g' - 104: 175, # 'h' - 105: 64, # 'i' - 106: 176, # 'j' - 107: 177, # 'k' - 108: 77, # 'l' - 109: 72, # 'm' - 110: 178, # 'n' - 111: 69, # 'o' - 112: 67, # 'p' - 113: 179, # 'q' - 114: 78, # 'r' - 115: 73, # 's' - 116: 180, # 't' - 117: 181, # 'u' - 118: 79, # 'v' - 119: 182, # 'w' - 120: 183, # 'x' - 121: 184, # 'y' - 122: 185, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 37, # 'А' - 129: 44, # 'Б' - 130: 33, # 'В' - 131: 46, # 'Г' - 132: 41, # 'Д' - 133: 48, # 'Е' - 134: 56, # 'Ж' - 135: 51, # 'З' - 136: 42, # 'И' - 137: 60, # 'Й' - 138: 36, # 'К' - 139: 49, # 'Л' - 140: 38, # 'М' - 141: 31, # 'Н' - 142: 34, # 'О' - 143: 35, # 'П' - 144: 45, # 'Р' - 145: 32, # 'С' - 146: 40, # 'Т' - 147: 52, # 'У' - 148: 53, # 'Ф' - 149: 55, # 'Х' - 150: 58, # 'Ц' - 151: 50, # 'Ч' - 152: 57, # 'Ш' - 153: 63, # 'Щ' - 154: 70, # 'Ъ' - 155: 62, # 'Ы' - 156: 61, # 'Ь' - 157: 47, # 'Э' - 158: 59, # 'Ю' - 159: 43, # 'Я' - 160: 191, # '†' - 161: 192, # '°' - 162: 193, # 'Ґ' - 163: 194, # '£' - 164: 195, # '§' - 165: 196, # '•' - 166: 197, # '¶' - 167: 198, # 'І' - 168: 199, # '®' - 169: 200, # '©' - 170: 201, # '™' - 171: 202, # 'Ђ' - 172: 203, # 'ђ' - 173: 204, # '≠' - 174: 205, # 'Ѓ' - 175: 206, # 'ѓ' - 176: 207, # '∞' - 177: 208, # '±' - 178: 209, # '≤' - 179: 210, # '≥' - 180: 211, # 'і' - 181: 212, # 'µ' - 182: 213, # 'ґ' - 183: 214, # 'Ј' - 184: 215, # 'Є' - 185: 216, # 'є' - 186: 217, # 'Ї' - 187: 218, # 'ї' - 188: 219, # 'Љ' - 189: 220, # 'љ' - 190: 221, # 'Њ' - 191: 222, # 'њ' - 192: 223, # 'ј' - 193: 224, # 'Ѕ' - 194: 225, # '¬' - 195: 226, # '√' - 196: 227, # 'ƒ' - 197: 228, # '≈' - 198: 229, # '∆' - 199: 230, # '«' - 200: 231, # '»' - 201: 232, # '…' - 202: 233, # '\xa0' - 203: 234, # 'Ћ' - 204: 235, # 'ћ' - 205: 236, # 'Ќ' - 206: 237, # 'ќ' - 207: 238, # 'ѕ' - 208: 239, # '–' - 209: 240, # '—' - 210: 241, # '“' - 211: 242, # '”' - 212: 243, # '‘' - 213: 244, # '’' - 214: 245, # '÷' - 215: 246, # '„' - 216: 247, # 'Ў' - 217: 248, # 'ў' - 218: 249, # 'Џ' - 219: 250, # 'џ' - 220: 251, # '№' - 221: 252, # 'Ё' - 222: 68, # 'ё' - 223: 16, # 'я' - 224: 3, # 'а' - 225: 21, # 'б' - 226: 10, # 'в' - 227: 19, # 'г' - 228: 13, # 'д' - 229: 2, # 'е' - 230: 24, # 'ж' - 231: 20, # 'з' - 232: 4, # 'и' - 233: 23, # 'й' - 234: 11, # 'к' - 235: 8, # 'л' - 236: 12, # 'м' - 237: 5, # 'н' - 238: 1, # 'о' - 239: 15, # 'п' - 240: 9, # 'р' - 241: 7, # 'с' - 242: 6, # 'т' - 243: 14, # 'у' - 244: 39, # 'ф' - 245: 26, # 'х' - 246: 28, # 'ц' - 247: 22, # 'ч' - 248: 25, # 'ш' - 249: 29, # 'щ' - 250: 54, # 'ъ' - 251: 18, # 'ы' - 252: 17, # 'ь' - 253: 30, # 'э' - 254: 27, # 'ю' - 255: 255, # '€' -} - -MACCYRILLIC_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='MacCyrillic', - language='Russian', - char_to_order_map=MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER, - language_model=RUSSIAN_LANG_MODEL, - typical_positive_ratio=0.976601, - keep_ascii_letters=False, - alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') - -ISO_8859_5_RUSSIAN_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 142, # 'A' - 66: 143, # 'B' - 67: 144, # 'C' - 68: 145, # 'D' - 69: 146, # 'E' - 70: 147, # 'F' - 71: 148, # 'G' - 72: 149, # 'H' - 73: 150, # 'I' - 74: 151, # 'J' - 75: 152, # 'K' - 76: 74, # 'L' - 77: 153, # 'M' - 78: 75, # 'N' - 79: 154, # 'O' - 80: 155, # 'P' - 81: 156, # 'Q' - 82: 157, # 'R' - 83: 158, # 'S' - 84: 159, # 'T' - 85: 160, # 'U' - 86: 161, # 'V' - 87: 162, # 'W' - 88: 163, # 'X' - 89: 164, # 'Y' - 90: 165, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 71, # 'a' - 98: 172, # 'b' - 99: 66, # 'c' - 100: 173, # 'd' - 101: 65, # 'e' - 102: 174, # 'f' - 103: 76, # 'g' - 104: 175, # 'h' - 105: 64, # 'i' - 106: 176, # 'j' - 107: 177, # 'k' - 108: 77, # 'l' - 109: 72, # 'm' - 110: 178, # 'n' - 111: 69, # 'o' - 112: 67, # 'p' - 113: 179, # 'q' - 114: 78, # 'r' - 115: 73, # 's' - 116: 180, # 't' - 117: 181, # 'u' - 118: 79, # 'v' - 119: 182, # 'w' - 120: 183, # 'x' - 121: 184, # 'y' - 122: 185, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 191, # '\x80' - 129: 192, # '\x81' - 130: 193, # '\x82' - 131: 194, # '\x83' - 132: 195, # '\x84' - 133: 196, # '\x85' - 134: 197, # '\x86' - 135: 198, # '\x87' - 136: 199, # '\x88' - 137: 200, # '\x89' - 138: 201, # '\x8a' - 139: 202, # '\x8b' - 140: 203, # '\x8c' - 141: 204, # '\x8d' - 142: 205, # '\x8e' - 143: 206, # '\x8f' - 144: 207, # '\x90' - 145: 208, # '\x91' - 146: 209, # '\x92' - 147: 210, # '\x93' - 148: 211, # '\x94' - 149: 212, # '\x95' - 150: 213, # '\x96' - 151: 214, # '\x97' - 152: 215, # '\x98' - 153: 216, # '\x99' - 154: 217, # '\x9a' - 155: 218, # '\x9b' - 156: 219, # '\x9c' - 157: 220, # '\x9d' - 158: 221, # '\x9e' - 159: 222, # '\x9f' - 160: 223, # '\xa0' - 161: 224, # 'Ё' - 162: 225, # 'Ђ' - 163: 226, # 'Ѓ' - 164: 227, # 'Є' - 165: 228, # 'Ѕ' - 166: 229, # 'І' - 167: 230, # 'Ї' - 168: 231, # 'Ј' - 169: 232, # 'Љ' - 170: 233, # 'Њ' - 171: 234, # 'Ћ' - 172: 235, # 'Ќ' - 173: 236, # '\xad' - 174: 237, # 'Ў' - 175: 238, # 'Џ' - 176: 37, # 'А' - 177: 44, # 'Б' - 178: 33, # 'В' - 179: 46, # 'Г' - 180: 41, # 'Д' - 181: 48, # 'Е' - 182: 56, # 'Ж' - 183: 51, # 'З' - 184: 42, # 'И' - 185: 60, # 'Й' - 186: 36, # 'К' - 187: 49, # 'Л' - 188: 38, # 'М' - 189: 31, # 'Н' - 190: 34, # 'О' - 191: 35, # 'П' - 192: 45, # 'Р' - 193: 32, # 'С' - 194: 40, # 'Т' - 195: 52, # 'У' - 196: 53, # 'Ф' - 197: 55, # 'Х' - 198: 58, # 'Ц' - 199: 50, # 'Ч' - 200: 57, # 'Ш' - 201: 63, # 'Щ' - 202: 70, # 'Ъ' - 203: 62, # 'Ы' - 204: 61, # 'Ь' - 205: 47, # 'Э' - 206: 59, # 'Ю' - 207: 43, # 'Я' - 208: 3, # 'а' - 209: 21, # 'б' - 210: 10, # 'в' - 211: 19, # 'г' - 212: 13, # 'д' - 213: 2, # 'е' - 214: 24, # 'ж' - 215: 20, # 'з' - 216: 4, # 'и' - 217: 23, # 'й' - 218: 11, # 'к' - 219: 8, # 'л' - 220: 12, # 'м' - 221: 5, # 'н' - 222: 1, # 'о' - 223: 15, # 'п' - 224: 9, # 'р' - 225: 7, # 'с' - 226: 6, # 'т' - 227: 14, # 'у' - 228: 39, # 'ф' - 229: 26, # 'х' - 230: 28, # 'ц' - 231: 22, # 'ч' - 232: 25, # 'ш' - 233: 29, # 'щ' - 234: 54, # 'ъ' - 235: 18, # 'ы' - 236: 17, # 'ь' - 237: 30, # 'э' - 238: 27, # 'ю' - 239: 16, # 'я' - 240: 239, # '№' - 241: 68, # 'ё' - 242: 240, # 'ђ' - 243: 241, # 'ѓ' - 244: 242, # 'є' - 245: 243, # 'ѕ' - 246: 244, # 'і' - 247: 245, # 'ї' - 248: 246, # 'ј' - 249: 247, # 'љ' - 250: 248, # 'њ' - 251: 249, # 'ћ' - 252: 250, # 'ќ' - 253: 251, # '§' - 254: 252, # 'ў' - 255: 255, # 'џ' -} - -ISO_8859_5_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', - language='Russian', - char_to_order_map=ISO_8859_5_RUSSIAN_CHAR_TO_ORDER, - language_model=RUSSIAN_LANG_MODEL, - typical_positive_ratio=0.976601, - keep_ascii_letters=False, - alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') - diff --git a/dist/ba_data/python-site-packages/chardet/langthaimodel.py b/dist/ba_data/python-site-packages/chardet/langthaimodel.py deleted file mode 100644 index d0191f24..00000000 --- a/dist/ba_data/python-site-packages/chardet/langthaimodel.py +++ /dev/null @@ -1,4383 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -THAI_LANG_MODEL = { - 5: { # 'ก' - 5: 2, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 2, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 3, # 'ฎ' - 57: 2, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 2, # 'ณ' - 20: 2, # 'ด' - 19: 3, # 'ต' - 44: 0, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 1, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 1, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 2, # 'ม' - 16: 1, # 'ย' - 2: 3, # 'ร' - 61: 2, # 'ฤ' - 15: 3, # 'ล' - 12: 3, # 'ว' - 42: 2, # 'ศ' - 46: 3, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 3, # 'อ' - 63: 1, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 3, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 0, # 'ึ' - 27: 2, # 'ื' - 32: 2, # 'ุ' - 35: 1, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 1, # 'ใ' - 33: 2, # 'ไ' - 50: 1, # 'ๆ' - 37: 3, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 30: { # 'ข' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 1, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 2, # 'ณ' - 20: 0, # 'ด' - 19: 2, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 1, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 2, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 1, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 2, # 'ี' - 40: 3, # 'ึ' - 27: 1, # 'ื' - 32: 1, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 2, # '่' - 7: 3, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 24: { # 'ค' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 2, # 'ค' - 8: 2, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 2, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 0, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 2, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 3, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 2, # 'า' - 36: 3, # 'ำ' - 23: 3, # 'ิ' - 13: 2, # 'ี' - 40: 0, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 2, # 'ู' - 11: 1, # 'เ' - 28: 0, # 'แ' - 41: 3, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 8: { # 'ง' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 3, # 'ค' - 8: 2, # 'ง' - 26: 2, # 'จ' - 52: 1, # 'ฉ' - 34: 2, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 3, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 1, # 'ฝ' - 31: 2, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 2, # 'ม' - 16: 1, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 2, # 'ว' - 42: 2, # 'ศ' - 46: 1, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 1, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 1, # 'ื' - 32: 1, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 3, # 'ๆ' - 37: 0, # '็' - 6: 2, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 26: { # 'จ' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 0, # 'ค' - 8: 2, # 'ง' - 26: 3, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 1, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 1, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 1, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 1, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 3, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 3, # 'ำ' - 23: 2, # 'ิ' - 13: 1, # 'ี' - 40: 3, # 'ึ' - 27: 1, # 'ื' - 32: 3, # 'ุ' - 35: 2, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 2, # '่' - 7: 2, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 52: { # 'ฉ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 3, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 3, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 1, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 1, # 'ั' - 1: 1, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 1, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 34: { # 'ช' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 1, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 1, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 1, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 2, # 'ั' - 1: 3, # 'า' - 36: 1, # 'ำ' - 23: 3, # 'ิ' - 13: 2, # 'ี' - 40: 0, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 1, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 51: { # 'ซ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 1, # 'ั' - 1: 1, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 2, # 'ี' - 40: 3, # 'ึ' - 27: 2, # 'ื' - 32: 1, # 'ุ' - 35: 1, # 'ู' - 11: 1, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 1, # '่' - 7: 2, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 47: { # 'ญ' - 5: 1, # 'ก' - 30: 1, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 3, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 1, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 2, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 2, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 0, # 'ไ' - 50: 1, # 'ๆ' - 37: 0, # '็' - 6: 2, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 58: { # 'ฎ' - 5: 2, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 1, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 2, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 57: { # 'ฏ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 3, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 49: { # 'ฐ' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 2, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 53: { # 'ฑ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 55: { # 'ฒ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 43: { # 'ณ' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 3, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 3, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 1, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 3, # 'ะ' - 10: 0, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 2, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 20: { # 'ด' - 5: 2, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 1, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 2, # 'ม' - 16: 3, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 3, # 'ั' - 1: 2, # 'า' - 36: 2, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 1, # 'ึ' - 27: 2, # 'ื' - 32: 3, # 'ุ' - 35: 2, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 2, # 'ๆ' - 37: 2, # '็' - 6: 1, # '่' - 7: 3, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 19: { # 'ต' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 1, # 'ต' - 44: 2, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 1, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 2, # 'ภ' - 9: 1, # 'ม' - 16: 1, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 3, # 'ส' - 21: 0, # 'ห' - 4: 3, # 'อ' - 63: 1, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 2, # 'ำ' - 23: 3, # 'ิ' - 13: 2, # 'ี' - 40: 1, # 'ึ' - 27: 1, # 'ื' - 32: 3, # 'ุ' - 35: 2, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 1, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 2, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 44: { # 'ถ' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 2, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 2, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 1, # 'ี' - 40: 3, # 'ึ' - 27: 2, # 'ื' - 32: 2, # 'ุ' - 35: 3, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 2, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 14: { # 'ท' - 5: 1, # 'ก' - 30: 1, # 'ข' - 24: 3, # 'ค' - 8: 1, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 3, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 2, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 3, # 'ย' - 2: 3, # 'ร' - 61: 1, # 'ฤ' - 15: 1, # 'ล' - 12: 2, # 'ว' - 42: 3, # 'ศ' - 46: 1, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 3, # 'ำ' - 23: 2, # 'ิ' - 13: 3, # 'ี' - 40: 2, # 'ึ' - 27: 1, # 'ื' - 32: 3, # 'ุ' - 35: 1, # 'ู' - 11: 0, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 48: { # 'ธ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 1, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 2, # 'า' - 36: 0, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 2, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 3: { # 'น' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 3, # 'ค' - 8: 1, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 1, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 2, # 'ถ' - 14: 3, # 'ท' - 48: 3, # 'ธ' - 3: 2, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 0, # 'ฝ' - 31: 2, # 'พ' - 54: 1, # 'ฟ' - 45: 1, # 'ภ' - 9: 2, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 1, # 'ฤ' - 15: 2, # 'ล' - 12: 3, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 3, # 'อ' - 63: 1, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 3, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 3, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 2, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 3, # 'โ' - 29: 3, # 'ใ' - 33: 3, # 'ไ' - 50: 2, # 'ๆ' - 37: 1, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 17: { # 'บ' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 1, # 'ง' - 26: 1, # 'จ' - 52: 1, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 3, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 1, # 'ฟ' - 45: 1, # 'ภ' - 9: 1, # 'ม' - 16: 0, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 3, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 2, # 'อ' - 63: 1, # 'ฯ' - 22: 0, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 2, # 'ำ' - 23: 2, # 'ิ' - 13: 2, # 'ี' - 40: 0, # 'ึ' - 27: 2, # 'ื' - 32: 3, # 'ุ' - 35: 2, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 2, # '่' - 7: 2, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 25: { # 'ป' - 5: 2, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 1, # 'ฎ' - 57: 3, # 'ฏ' - 49: 1, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 1, # 'ต' - 44: 1, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 0, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 1, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 0, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 1, # 'ษ' - 18: 2, # 'ส' - 21: 1, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 3, # 'ั' - 1: 1, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 3, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 1, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 2, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 2, # 'ไ' - 50: 0, # 'ๆ' - 37: 3, # '็' - 6: 1, # '่' - 7: 2, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 39: { # 'ผ' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 1, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 2, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 1, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 1, # 'ื' - 32: 0, # 'ุ' - 35: 3, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 1, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 62: { # 'ฝ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 1, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 1, # 'ี' - 40: 2, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 2, # '่' - 7: 1, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 31: { # 'พ' - 5: 1, # 'ก' - 30: 1, # 'ข' - 24: 1, # 'ค' - 8: 1, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 1, # 'ณ' - 20: 1, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 2, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 0, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 2, # 'ย' - 2: 3, # 'ร' - 61: 2, # 'ฤ' - 15: 2, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 1, # 'ห' - 4: 2, # 'อ' - 63: 1, # 'ฯ' - 22: 0, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 3, # 'ิ' - 13: 2, # 'ี' - 40: 1, # 'ึ' - 27: 3, # 'ื' - 32: 1, # 'ุ' - 35: 2, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 1, # '็' - 6: 0, # '่' - 7: 1, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 54: { # 'ฟ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 2, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 2, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 1, # 'ื' - 32: 1, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 2, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 45: { # 'ภ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 3, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 2, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 9: { # 'ม' - 5: 2, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 2, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 1, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 3, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 2, # 'ม' - 16: 1, # 'ย' - 2: 2, # 'ร' - 61: 2, # 'ฤ' - 15: 2, # 'ล' - 12: 2, # 'ว' - 42: 1, # 'ศ' - 46: 1, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 0, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 3, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 2, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 1, # 'ๆ' - 37: 1, # '็' - 6: 3, # '่' - 7: 2, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 16: { # 'ย' - 5: 3, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 2, # 'ช' - 51: 0, # 'ซ' - 47: 2, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 2, # 'ม' - 16: 0, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 3, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 1, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 3, # 'ี' - 40: 1, # 'ึ' - 27: 2, # 'ื' - 32: 2, # 'ุ' - 35: 3, # 'ู' - 11: 2, # 'เ' - 28: 1, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 2, # 'ๆ' - 37: 1, # '็' - 6: 3, # '่' - 7: 2, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 2: { # 'ร' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 2, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 3, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 3, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 3, # 'ถ' - 14: 3, # 'ท' - 48: 1, # 'ธ' - 3: 2, # 'น' - 17: 2, # 'บ' - 25: 3, # 'ป' - 39: 2, # 'ผ' - 62: 1, # 'ฝ' - 31: 2, # 'พ' - 54: 1, # 'ฟ' - 45: 1, # 'ภ' - 9: 3, # 'ม' - 16: 2, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 3, # 'ว' - 42: 2, # 'ศ' - 46: 2, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 3, # 'อ' - 63: 1, # 'ฯ' - 22: 3, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 2, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 3, # 'ู' - 11: 3, # 'เ' - 28: 3, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 3, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 3, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 61: { # 'ฤ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 2, # 'ต' - 44: 0, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 2, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 15: { # 'ล' - 5: 2, # 'ก' - 30: 3, # 'ข' - 24: 1, # 'ค' - 8: 3, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 1, # 'ม' - 16: 3, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 1, # 'ห' - 4: 3, # 'อ' - 63: 2, # 'ฯ' - 22: 3, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 2, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 2, # 'ึ' - 27: 3, # 'ื' - 32: 2, # 'ุ' - 35: 3, # 'ู' - 11: 2, # 'เ' - 28: 1, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 2, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 12: { # 'ว' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 1, # 'ค' - 8: 3, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 1, # 'ณ' - 20: 2, # 'ด' - 19: 1, # 'ต' - 44: 1, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 1, # 'ฟ' - 45: 0, # 'ภ' - 9: 3, # 'ม' - 16: 3, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 3, # 'ิ' - 13: 2, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 2, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 1, # 'ใ' - 33: 2, # 'ไ' - 50: 1, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 42: { # 'ศ' - 5: 1, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 1, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 2, # 'ว' - 42: 1, # 'ศ' - 46: 2, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 2, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 2, # 'ิ' - 13: 0, # 'ี' - 40: 3, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 2, # 'ู' - 11: 0, # 'เ' - 28: 1, # 'แ' - 41: 0, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 46: { # 'ษ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 2, # 'ฎ' - 57: 1, # 'ฏ' - 49: 2, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 3, # 'ณ' - 20: 0, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 1, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 2, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 18: { # 'ส' - 5: 2, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 2, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 3, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 2, # 'ภ' - 9: 3, # 'ม' - 16: 1, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 2, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 3, # 'ำ' - 23: 3, # 'ิ' - 13: 3, # 'ี' - 40: 2, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 3, # 'ู' - 11: 2, # 'เ' - 28: 0, # 'แ' - 41: 1, # 'โ' - 29: 0, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 1, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 21: { # 'ห' - 5: 3, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 1, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 2, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 3, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 0, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 3, # 'ม' - 16: 2, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 0, # 'ำ' - 23: 1, # 'ิ' - 13: 1, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 1, # 'ุ' - 35: 1, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 3, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 4: { # 'อ' - 5: 3, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 1, # 'ฟ' - 45: 1, # 'ภ' - 9: 3, # 'ม' - 16: 3, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 2, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 2, # 'ะ' - 10: 3, # 'ั' - 1: 3, # 'า' - 36: 2, # 'ำ' - 23: 2, # 'ิ' - 13: 3, # 'ี' - 40: 0, # 'ึ' - 27: 3, # 'ื' - 32: 3, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 1, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 1, # 'ๆ' - 37: 1, # '็' - 6: 2, # '่' - 7: 2, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 63: { # 'ฯ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 22: { # 'ะ' - 5: 3, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 1, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 3, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 1, # 'ถ' - 14: 3, # 'ท' - 48: 1, # 'ธ' - 3: 2, # 'น' - 17: 3, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 2, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 3, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 2, # 'อ' - 63: 1, # 'ฯ' - 22: 1, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 10: { # 'ั' - 5: 3, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 3, # 'ง' - 26: 3, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 3, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 2, # 'ฐ' - 53: 0, # 'ฑ' - 55: 3, # 'ฒ' - 43: 3, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 0, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 2, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 3, # 'ม' - 16: 3, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 3, # 'ว' - 42: 2, # 'ศ' - 46: 0, # 'ษ' - 18: 3, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 1: { # 'า' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 3, # 'ค' - 8: 3, # 'ง' - 26: 3, # 'จ' - 52: 0, # 'ฉ' - 34: 3, # 'ช' - 51: 1, # 'ซ' - 47: 2, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 3, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 1, # 'ถ' - 14: 3, # 'ท' - 48: 2, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 1, # 'ฝ' - 31: 3, # 'พ' - 54: 1, # 'ฟ' - 45: 1, # 'ภ' - 9: 3, # 'ม' - 16: 3, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 3, # 'ว' - 42: 2, # 'ศ' - 46: 3, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 2, # 'อ' - 63: 1, # 'ฯ' - 22: 3, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 1, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 36: { # 'ำ' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 3, # 'ค' - 8: 2, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 1, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 1, # 'ต' - 44: 1, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 1, # 'บ' - 25: 1, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 1, # 'ม' - 16: 0, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 3, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 23: { # 'ิ' - 5: 3, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 3, # 'จ' - 52: 0, # 'ฉ' - 34: 3, # 'ช' - 51: 0, # 'ซ' - 47: 2, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 1, # 'ถ' - 14: 3, # 'ท' - 48: 3, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 0, # 'ฝ' - 31: 3, # 'พ' - 54: 1, # 'ฟ' - 45: 2, # 'ภ' - 9: 3, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 3, # 'ว' - 42: 3, # 'ศ' - 46: 2, # 'ษ' - 18: 2, # 'ส' - 21: 3, # 'ห' - 4: 1, # 'อ' - 63: 1, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 1, # 'แ' - 41: 1, # 'โ' - 29: 1, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 2, # '้' - 38: 2, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 13: { # 'ี' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 1, # 'ผ' - 62: 0, # 'ฝ' - 31: 2, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 3, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 2, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 1, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 1, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 40: { # 'ึ' - 5: 3, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 3, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 1, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 27: { # 'ื' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 3, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 32: { # 'ุ' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 3, # 'ค' - 8: 3, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 2, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 1, # 'ฒ' - 43: 3, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 1, # 'ธ' - 3: 2, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 1, # 'ภ' - 9: 3, # 'ม' - 16: 1, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 1, # 'ว' - 42: 1, # 'ศ' - 46: 2, # 'ษ' - 18: 1, # 'ส' - 21: 1, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 0, # 'แ' - 41: 1, # 'โ' - 29: 0, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 2, # '้' - 38: 1, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 35: { # 'ู' - 5: 3, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 2, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 2, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 1, # 'ณ' - 20: 2, # 'ด' - 19: 2, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 2, # 'น' - 17: 0, # 'บ' - 25: 3, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 1, # 'แ' - 41: 1, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 3, # '่' - 7: 3, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 11: { # 'เ' - 5: 3, # 'ก' - 30: 3, # 'ข' - 24: 3, # 'ค' - 8: 2, # 'ง' - 26: 3, # 'จ' - 52: 3, # 'ฉ' - 34: 3, # 'ช' - 51: 2, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 1, # 'ณ' - 20: 3, # 'ด' - 19: 3, # 'ต' - 44: 1, # 'ถ' - 14: 3, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 3, # 'ป' - 39: 2, # 'ผ' - 62: 1, # 'ฝ' - 31: 3, # 'พ' - 54: 1, # 'ฟ' - 45: 3, # 'ภ' - 9: 3, # 'ม' - 16: 2, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 3, # 'ว' - 42: 2, # 'ศ' - 46: 0, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 28: { # 'แ' - 5: 3, # 'ก' - 30: 2, # 'ข' - 24: 2, # 'ค' - 8: 1, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 3, # 'ต' - 44: 2, # 'ถ' - 14: 3, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 2, # 'ป' - 39: 3, # 'ผ' - 62: 0, # 'ฝ' - 31: 2, # 'พ' - 54: 2, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 41: { # 'โ' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 1, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 2, # 'ต' - 44: 0, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 1, # 'บ' - 25: 3, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 1, # 'ฟ' - 45: 1, # 'ภ' - 9: 1, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 3, # 'ล' - 12: 0, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 0, # 'ห' - 4: 2, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 29: { # 'ใ' - 5: 2, # 'ก' - 30: 0, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 3, # 'จ' - 52: 0, # 'ฉ' - 34: 3, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 1, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 3, # 'ส' - 21: 3, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 33: { # 'ไ' - 5: 1, # 'ก' - 30: 2, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 3, # 'ด' - 19: 1, # 'ต' - 44: 0, # 'ถ' - 14: 3, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 1, # 'บ' - 25: 3, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 2, # 'ฟ' - 45: 0, # 'ภ' - 9: 3, # 'ม' - 16: 0, # 'ย' - 2: 3, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 3, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 2, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 50: { # 'ๆ' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 37: { # '็' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 2, # 'ง' - 26: 3, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 1, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 2, # 'ต' - 44: 0, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 3, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 1, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 2, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 0, # 'ห' - 4: 1, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 1, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 6: { # '่' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 1, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 1, # 'ธ' - 3: 3, # 'น' - 17: 1, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 1, # 'ฝ' - 31: 1, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 3, # 'ม' - 16: 3, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 2, # 'ล' - 12: 3, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 1, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 1, # 'ะ' - 10: 0, # 'ั' - 1: 3, # 'า' - 36: 2, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 3, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 1, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 7: { # '้' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 2, # 'ค' - 8: 3, # 'ง' - 26: 2, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 1, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 1, # 'ด' - 19: 2, # 'ต' - 44: 1, # 'ถ' - 14: 2, # 'ท' - 48: 0, # 'ธ' - 3: 3, # 'น' - 17: 2, # 'บ' - 25: 2, # 'ป' - 39: 2, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 1, # 'ฟ' - 45: 0, # 'ภ' - 9: 3, # 'ม' - 16: 2, # 'ย' - 2: 2, # 'ร' - 61: 0, # 'ฤ' - 15: 1, # 'ล' - 12: 3, # 'ว' - 42: 1, # 'ศ' - 46: 0, # 'ษ' - 18: 2, # 'ส' - 21: 2, # 'ห' - 4: 3, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 3, # 'า' - 36: 2, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 2, # 'ใ' - 33: 2, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 38: { # '์' - 5: 2, # 'ก' - 30: 1, # 'ข' - 24: 1, # 'ค' - 8: 0, # 'ง' - 26: 1, # 'จ' - 52: 0, # 'ฉ' - 34: 1, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 2, # 'ด' - 19: 1, # 'ต' - 44: 1, # 'ถ' - 14: 1, # 'ท' - 48: 0, # 'ธ' - 3: 1, # 'น' - 17: 1, # 'บ' - 25: 1, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 1, # 'พ' - 54: 1, # 'ฟ' - 45: 0, # 'ภ' - 9: 2, # 'ม' - 16: 0, # 'ย' - 2: 1, # 'ร' - 61: 1, # 'ฤ' - 15: 1, # 'ล' - 12: 1, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 1, # 'ส' - 21: 1, # 'ห' - 4: 2, # 'อ' - 63: 1, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 2, # 'เ' - 28: 2, # 'แ' - 41: 1, # 'โ' - 29: 1, # 'ใ' - 33: 1, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 0, # '๑' - 59: 0, # '๒' - 60: 0, # '๕' - }, - 56: { # '๑' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 2, # '๑' - 59: 1, # '๒' - 60: 1, # '๕' - }, - 59: { # '๒' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 1, # '๑' - 59: 1, # '๒' - 60: 3, # '๕' - }, - 60: { # '๕' - 5: 0, # 'ก' - 30: 0, # 'ข' - 24: 0, # 'ค' - 8: 0, # 'ง' - 26: 0, # 'จ' - 52: 0, # 'ฉ' - 34: 0, # 'ช' - 51: 0, # 'ซ' - 47: 0, # 'ญ' - 58: 0, # 'ฎ' - 57: 0, # 'ฏ' - 49: 0, # 'ฐ' - 53: 0, # 'ฑ' - 55: 0, # 'ฒ' - 43: 0, # 'ณ' - 20: 0, # 'ด' - 19: 0, # 'ต' - 44: 0, # 'ถ' - 14: 0, # 'ท' - 48: 0, # 'ธ' - 3: 0, # 'น' - 17: 0, # 'บ' - 25: 0, # 'ป' - 39: 0, # 'ผ' - 62: 0, # 'ฝ' - 31: 0, # 'พ' - 54: 0, # 'ฟ' - 45: 0, # 'ภ' - 9: 0, # 'ม' - 16: 0, # 'ย' - 2: 0, # 'ร' - 61: 0, # 'ฤ' - 15: 0, # 'ล' - 12: 0, # 'ว' - 42: 0, # 'ศ' - 46: 0, # 'ษ' - 18: 0, # 'ส' - 21: 0, # 'ห' - 4: 0, # 'อ' - 63: 0, # 'ฯ' - 22: 0, # 'ะ' - 10: 0, # 'ั' - 1: 0, # 'า' - 36: 0, # 'ำ' - 23: 0, # 'ิ' - 13: 0, # 'ี' - 40: 0, # 'ึ' - 27: 0, # 'ื' - 32: 0, # 'ุ' - 35: 0, # 'ู' - 11: 0, # 'เ' - 28: 0, # 'แ' - 41: 0, # 'โ' - 29: 0, # 'ใ' - 33: 0, # 'ไ' - 50: 0, # 'ๆ' - 37: 0, # '็' - 6: 0, # '่' - 7: 0, # '้' - 38: 0, # '์' - 56: 2, # '๑' - 59: 1, # '๒' - 60: 0, # '๕' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -TIS_620_THAI_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 254, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 254, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 253, # ' ' - 33: 253, # '!' - 34: 253, # '"' - 35: 253, # '#' - 36: 253, # '$' - 37: 253, # '%' - 38: 253, # '&' - 39: 253, # "'" - 40: 253, # '(' - 41: 253, # ')' - 42: 253, # '*' - 43: 253, # '+' - 44: 253, # ',' - 45: 253, # '-' - 46: 253, # '.' - 47: 253, # '/' - 48: 252, # '0' - 49: 252, # '1' - 50: 252, # '2' - 51: 252, # '3' - 52: 252, # '4' - 53: 252, # '5' - 54: 252, # '6' - 55: 252, # '7' - 56: 252, # '8' - 57: 252, # '9' - 58: 253, # ':' - 59: 253, # ';' - 60: 253, # '<' - 61: 253, # '=' - 62: 253, # '>' - 63: 253, # '?' - 64: 253, # '@' - 65: 182, # 'A' - 66: 106, # 'B' - 67: 107, # 'C' - 68: 100, # 'D' - 69: 183, # 'E' - 70: 184, # 'F' - 71: 185, # 'G' - 72: 101, # 'H' - 73: 94, # 'I' - 74: 186, # 'J' - 75: 187, # 'K' - 76: 108, # 'L' - 77: 109, # 'M' - 78: 110, # 'N' - 79: 111, # 'O' - 80: 188, # 'P' - 81: 189, # 'Q' - 82: 190, # 'R' - 83: 89, # 'S' - 84: 95, # 'T' - 85: 112, # 'U' - 86: 113, # 'V' - 87: 191, # 'W' - 88: 192, # 'X' - 89: 193, # 'Y' - 90: 194, # 'Z' - 91: 253, # '[' - 92: 253, # '\\' - 93: 253, # ']' - 94: 253, # '^' - 95: 253, # '_' - 96: 253, # '`' - 97: 64, # 'a' - 98: 72, # 'b' - 99: 73, # 'c' - 100: 114, # 'd' - 101: 74, # 'e' - 102: 115, # 'f' - 103: 116, # 'g' - 104: 102, # 'h' - 105: 81, # 'i' - 106: 201, # 'j' - 107: 117, # 'k' - 108: 90, # 'l' - 109: 103, # 'm' - 110: 78, # 'n' - 111: 82, # 'o' - 112: 96, # 'p' - 113: 202, # 'q' - 114: 91, # 'r' - 115: 79, # 's' - 116: 84, # 't' - 117: 104, # 'u' - 118: 105, # 'v' - 119: 97, # 'w' - 120: 98, # 'x' - 121: 92, # 'y' - 122: 203, # 'z' - 123: 253, # '{' - 124: 253, # '|' - 125: 253, # '}' - 126: 253, # '~' - 127: 253, # '\x7f' - 128: 209, # '\x80' - 129: 210, # '\x81' - 130: 211, # '\x82' - 131: 212, # '\x83' - 132: 213, # '\x84' - 133: 88, # '\x85' - 134: 214, # '\x86' - 135: 215, # '\x87' - 136: 216, # '\x88' - 137: 217, # '\x89' - 138: 218, # '\x8a' - 139: 219, # '\x8b' - 140: 220, # '\x8c' - 141: 118, # '\x8d' - 142: 221, # '\x8e' - 143: 222, # '\x8f' - 144: 223, # '\x90' - 145: 224, # '\x91' - 146: 99, # '\x92' - 147: 85, # '\x93' - 148: 83, # '\x94' - 149: 225, # '\x95' - 150: 226, # '\x96' - 151: 227, # '\x97' - 152: 228, # '\x98' - 153: 229, # '\x99' - 154: 230, # '\x9a' - 155: 231, # '\x9b' - 156: 232, # '\x9c' - 157: 233, # '\x9d' - 158: 234, # '\x9e' - 159: 235, # '\x9f' - 160: 236, # None - 161: 5, # 'ก' - 162: 30, # 'ข' - 163: 237, # 'ฃ' - 164: 24, # 'ค' - 165: 238, # 'ฅ' - 166: 75, # 'ฆ' - 167: 8, # 'ง' - 168: 26, # 'จ' - 169: 52, # 'ฉ' - 170: 34, # 'ช' - 171: 51, # 'ซ' - 172: 119, # 'ฌ' - 173: 47, # 'ญ' - 174: 58, # 'ฎ' - 175: 57, # 'ฏ' - 176: 49, # 'ฐ' - 177: 53, # 'ฑ' - 178: 55, # 'ฒ' - 179: 43, # 'ณ' - 180: 20, # 'ด' - 181: 19, # 'ต' - 182: 44, # 'ถ' - 183: 14, # 'ท' - 184: 48, # 'ธ' - 185: 3, # 'น' - 186: 17, # 'บ' - 187: 25, # 'ป' - 188: 39, # 'ผ' - 189: 62, # 'ฝ' - 190: 31, # 'พ' - 191: 54, # 'ฟ' - 192: 45, # 'ภ' - 193: 9, # 'ม' - 194: 16, # 'ย' - 195: 2, # 'ร' - 196: 61, # 'ฤ' - 197: 15, # 'ล' - 198: 239, # 'ฦ' - 199: 12, # 'ว' - 200: 42, # 'ศ' - 201: 46, # 'ษ' - 202: 18, # 'ส' - 203: 21, # 'ห' - 204: 76, # 'ฬ' - 205: 4, # 'อ' - 206: 66, # 'ฮ' - 207: 63, # 'ฯ' - 208: 22, # 'ะ' - 209: 10, # 'ั' - 210: 1, # 'า' - 211: 36, # 'ำ' - 212: 23, # 'ิ' - 213: 13, # 'ี' - 214: 40, # 'ึ' - 215: 27, # 'ื' - 216: 32, # 'ุ' - 217: 35, # 'ู' - 218: 86, # 'ฺ' - 219: 240, # None - 220: 241, # None - 221: 242, # None - 222: 243, # None - 223: 244, # '฿' - 224: 11, # 'เ' - 225: 28, # 'แ' - 226: 41, # 'โ' - 227: 29, # 'ใ' - 228: 33, # 'ไ' - 229: 245, # 'ๅ' - 230: 50, # 'ๆ' - 231: 37, # '็' - 232: 6, # '่' - 233: 7, # '้' - 234: 67, # '๊' - 235: 77, # '๋' - 236: 38, # '์' - 237: 93, # 'ํ' - 238: 246, # '๎' - 239: 247, # '๏' - 240: 68, # '๐' - 241: 56, # '๑' - 242: 59, # '๒' - 243: 65, # '๓' - 244: 69, # '๔' - 245: 60, # '๕' - 246: 70, # '๖' - 247: 80, # '๗' - 248: 71, # '๘' - 249: 87, # '๙' - 250: 248, # '๚' - 251: 249, # '๛' - 252: 250, # None - 253: 251, # None - 254: 252, # None - 255: 253, # None -} - -TIS_620_THAI_MODEL = SingleByteCharSetModel(charset_name='TIS-620', - language='Thai', - char_to_order_map=TIS_620_THAI_CHAR_TO_ORDER, - language_model=THAI_LANG_MODEL, - typical_positive_ratio=0.926386, - keep_ascii_letters=False, - alphabet='กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛') - diff --git a/dist/ba_data/python-site-packages/chardet/langturkishmodel.py b/dist/ba_data/python-site-packages/chardet/langturkishmodel.py deleted file mode 100644 index 8ba93224..00000000 --- a/dist/ba_data/python-site-packages/chardet/langturkishmodel.py +++ /dev/null @@ -1,4383 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from chardet.sbcharsetprober import SingleByteCharSetModel - - -# 3: Positive -# 2: Likely -# 1: Unlikely -# 0: Negative - -TURKISH_LANG_MODEL = { - 23: { # 'A' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 1, # 'h' - 3: 1, # 'i' - 24: 0, # 'j' - 10: 2, # 'k' - 5: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 1, # 'r' - 8: 1, # 's' - 9: 1, # 't' - 14: 1, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 37: { # 'B' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 2, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 1, # 'Ş' - 19: 1, # 'ş' - }, - 47: { # 'C' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 1, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 1, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 2, # 'j' - 10: 1, # 'k' - 5: 2, # 'l' - 13: 2, # 'm' - 4: 2, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 2, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 1, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 39: { # 'D' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 1, # 'l' - 13: 3, # 'm' - 4: 0, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 1, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 1, # 'Ş' - 19: 0, # 'ş' - }, - 29: { # 'E' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 1, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 0, # 'h' - 3: 1, # 'i' - 24: 1, # 'j' - 10: 0, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 1, # 's' - 9: 1, # 't' - 14: 1, # 'u' - 32: 1, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 52: { # 'F' - 23: 0, # 'A' - 37: 1, # 'B' - 47: 1, # 'C' - 39: 1, # 'D' - 29: 1, # 'E' - 52: 2, # 'F' - 36: 0, # 'G' - 45: 2, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 1, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 1, # 'b' - 28: 1, # 'c' - 12: 1, # 'd' - 2: 0, # 'e' - 18: 1, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 2, # 'i' - 24: 1, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 1, # 'm' - 4: 2, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 2, # 'r' - 8: 1, # 's' - 9: 1, # 't' - 14: 1, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 1, # 'Ö' - 55: 2, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 2, # 'ş' - }, - 36: { # 'G' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 2, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 2, # 'N' - 42: 1, # 'O' - 48: 1, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 1, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 1, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 0, # 'r' - 8: 1, # 's' - 9: 1, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 1, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 2, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 45: { # 'H' - 23: 0, # 'A' - 37: 1, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 2, # 'G' - 45: 1, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 1, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 2, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 2, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 1, # 'o' - 26: 1, # 'p' - 7: 1, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 2, # 'ğ' - 41: 1, # 'İ' - 6: 0, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 53: { # 'I' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 2, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 1, # 'Ş' - 19: 1, # 'ş' - }, - 60: { # 'J' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 1, # 'd' - 2: 0, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 1, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 1, # 's' - 9: 0, # 't' - 14: 0, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 16: { # 'K' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 1, # 'e' - 18: 3, # 'f' - 27: 3, # 'g' - 25: 3, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 0, # 'u' - 32: 3, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 1, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 49: { # 'L' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 2, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 2, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 0, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 2, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 2, # 'n' - 15: 1, # 'o' - 26: 1, # 'p' - 7: 1, # 'r' - 8: 1, # 's' - 9: 1, # 't' - 14: 0, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 2, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 1, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 20: { # 'M' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 1, # 'h' - 3: 2, # 'i' - 24: 2, # 'j' - 10: 2, # 'k' - 5: 2, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 3, # 'r' - 8: 0, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 46: { # 'N' - 23: 0, # 'A' - 37: 1, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 2, # 'j' - 10: 1, # 'k' - 5: 1, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 1, # 'o' - 26: 1, # 'p' - 7: 1, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 1, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 1, # 'İ' - 6: 2, # 'ı' - 40: 1, # 'Ş' - 19: 1, # 'ş' - }, - 42: { # 'O' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 1, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 0, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 2, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 2, # 'İ' - 6: 1, # 'ı' - 40: 1, # 'Ş' - 19: 1, # 'ş' - }, - 48: { # 'P' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 2, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 2, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 2, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 0, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 44: { # 'R' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 1, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 2, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 1, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 1, # 'Ş' - 19: 1, # 'ş' - }, - 35: { # 'S' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 1, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 1, # 'l' - 13: 2, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 1, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 2, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 31: { # 'T' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 0, # 'c' - 12: 1, # 'd' - 2: 3, # 'e' - 18: 2, # 'f' - 27: 2, # 'g' - 25: 0, # 'h' - 3: 1, # 'i' - 24: 1, # 'j' - 10: 2, # 'k' - 5: 2, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 2, # 'r' - 8: 0, # 's' - 9: 2, # 't' - 14: 2, # 'u' - 32: 1, # 'v' - 57: 1, # 'w' - 58: 1, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 51: { # 'U' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 1, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 1, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 38: { # 'V' - 23: 1, # 'A' - 37: 1, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 1, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 2, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 2, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 1, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 1, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 3, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 62: { # 'W' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 0, # 'd' - 2: 0, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 0, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 0, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 43: { # 'Y' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 0, # 'G' - 45: 1, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 2, # 'N' - 42: 0, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 1, # 'j' - 10: 1, # 'k' - 5: 1, # 'l' - 13: 3, # 'm' - 4: 0, # 'n' - 15: 2, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 2, # 'Ö' - 55: 1, # 'Ü' - 59: 1, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 0, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 56: { # 'Z' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 2, # 'Z' - 1: 2, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 2, # 'i' - 24: 1, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 1, # 'r' - 8: 1, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 1: { # 'a' - 23: 3, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 1, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 3, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 2, # 'Z' - 1: 2, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 2, # 'e' - 18: 3, # 'f' - 27: 3, # 'g' - 25: 3, # 'h' - 3: 3, # 'i' - 24: 3, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 3, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 3, # 'v' - 57: 2, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 1, # 'î' - 34: 1, # 'ö' - 17: 3, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 21: { # 'b' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 3, # 'g' - 25: 1, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 3, # 'p' - 7: 1, # 'r' - 8: 2, # 's' - 9: 2, # 't' - 14: 2, # 'u' - 32: 1, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 28: { # 'c' - 23: 0, # 'A' - 37: 1, # 'B' - 47: 1, # 'C' - 39: 1, # 'D' - 29: 2, # 'E' - 52: 0, # 'F' - 36: 2, # 'G' - 45: 2, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 2, # 'T' - 51: 2, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 3, # 'Y' - 56: 0, # 'Z' - 1: 1, # 'a' - 21: 1, # 'b' - 28: 2, # 'c' - 12: 2, # 'd' - 2: 1, # 'e' - 18: 1, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 3, # 'i' - 24: 1, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 2, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 1, # 'u' - 32: 0, # 'v' - 57: 1, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 1, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 1, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 1, # 'î' - 34: 2, # 'ö' - 17: 2, # 'ü' - 30: 2, # 'ğ' - 41: 1, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 2, # 'ş' - }, - 12: { # 'd' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 2, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 1, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 1, # 'f' - 27: 3, # 'g' - 25: 3, # 'h' - 3: 2, # 'i' - 24: 3, # 'j' - 10: 2, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 2, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 1, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 3, # 'y' - 22: 1, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 2: { # 'e' - 23: 2, # 'A' - 37: 0, # 'B' - 47: 2, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 1, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 1, # 'R' - 35: 0, # 'S' - 31: 3, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 2, # 'e' - 18: 3, # 'f' - 27: 3, # 'g' - 25: 3, # 'h' - 3: 3, # 'i' - 24: 3, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 3, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 3, # 'v' - 57: 2, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 1, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 3, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 18: { # 'f' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 2, # 'f' - 27: 1, # 'g' - 25: 1, # 'h' - 3: 1, # 'i' - 24: 1, # 'j' - 10: 1, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 1, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 1, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 27: { # 'g' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 1, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 1, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 1, # 'h' - 3: 2, # 'i' - 24: 3, # 'j' - 10: 2, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 2, # 'r' - 8: 2, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 1, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 25: { # 'h' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 2, # 'h' - 3: 2, # 'i' - 24: 3, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 1, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 1, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 3: { # 'i' - 23: 2, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 0, # 'N' - 42: 1, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 1, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 2, # 'f' - 27: 3, # 'g' - 25: 1, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 3, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 1, # 'w' - 58: 1, # 'x' - 11: 3, # 'y' - 22: 1, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 1, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 3, # 'ü' - 30: 0, # 'ğ' - 41: 1, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 24: { # 'j' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 2, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 1, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 2, # 'f' - 27: 1, # 'g' - 25: 1, # 'h' - 3: 2, # 'i' - 24: 1, # 'j' - 10: 2, # 'k' - 5: 2, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 2, # 'r' - 8: 3, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 2, # 'x' - 11: 1, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 10: { # 'k' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 3, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 3, # 'e' - 18: 1, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 2, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 3, # 'p' - 7: 2, # 'r' - 8: 2, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 3, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 5: { # 'l' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 1, # 'e' - 18: 3, # 'f' - 27: 3, # 'g' - 25: 2, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 1, # 'l' - 13: 1, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 2, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 13: { # 'm' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 3, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 2, # 'e' - 18: 3, # 'f' - 27: 3, # 'g' - 25: 3, # 'h' - 3: 3, # 'i' - 24: 3, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 2, # 'u' - 32: 2, # 'v' - 57: 1, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 3, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 4: { # 'n' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 2, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 1, # 'f' - 27: 2, # 'g' - 25: 3, # 'h' - 3: 2, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 3, # 'p' - 7: 2, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 2, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 15: { # 'o' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 2, # 'L' - 20: 0, # 'M' - 46: 2, # 'N' - 42: 1, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 1, # 'i' - 24: 2, # 'j' - 10: 1, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 2, # 'o' - 26: 0, # 'p' - 7: 1, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 2, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 2, # 'ğ' - 41: 2, # 'İ' - 6: 3, # 'ı' - 40: 2, # 'Ş' - 19: 2, # 'ş' - }, - 26: { # 'p' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 1, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 1, # 'h' - 3: 2, # 'i' - 24: 3, # 'j' - 10: 1, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 2, # 'r' - 8: 1, # 's' - 9: 1, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 1, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 7: { # 'r' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 1, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 2, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 1, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 3, # 'h' - 3: 2, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 3, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 8: { # 's' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 2, # 'i' - 24: 3, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 3, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 2, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 9: { # 't' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 2, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 2, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 3, # 'v' - 57: 0, # 'w' - 58: 2, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 14: { # 'u' - 23: 3, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 2, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 3, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 2, # 'Z' - 1: 2, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 2, # 'e' - 18: 2, # 'f' - 27: 3, # 'g' - 25: 3, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 3, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 2, # 'v' - 57: 2, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 3, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 32: { # 'v' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 1, # 'j' - 10: 1, # 'k' - 5: 3, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 1, # 'r' - 8: 2, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 1, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 57: { # 'w' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 1, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 1, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 1, # 's' - 9: 0, # 't' - 14: 1, # 'u' - 32: 0, # 'v' - 57: 2, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 58: { # 'x' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 1, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 1, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 2, # 'i' - 24: 2, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 2, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 1, # 'r' - 8: 2, # 's' - 9: 1, # 't' - 14: 0, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 11: { # 'y' - 23: 1, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 2, # 'i' - 24: 1, # 'j' - 10: 2, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 2, # 'r' - 8: 1, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 1, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 3, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 22: { # 'z' - 23: 2, # 'A' - 37: 2, # 'B' - 47: 1, # 'C' - 39: 2, # 'D' - 29: 3, # 'E' - 52: 1, # 'F' - 36: 2, # 'G' - 45: 2, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 2, # 'N' - 42: 2, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 3, # 'T' - 51: 2, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 1, # 'Z' - 1: 1, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 2, # 'd' - 2: 2, # 'e' - 18: 3, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 2, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 0, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 3, # 'y' - 22: 2, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 2, # 'Ü' - 59: 1, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 2, # 'ü' - 30: 2, # 'ğ' - 41: 1, # 'İ' - 6: 3, # 'ı' - 40: 1, # 'Ş' - 19: 2, # 'ş' - }, - 63: { # '·' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 0, # 'd' - 2: 1, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 0, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 54: { # 'Ç' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 1, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 1, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 1, # 'b' - 28: 0, # 'c' - 12: 1, # 'd' - 2: 0, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 0, # 'h' - 3: 3, # 'i' - 24: 0, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 2, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 2, # 'r' - 8: 0, # 's' - 9: 1, # 't' - 14: 0, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 2, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 50: { # 'Ö' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 1, # 'D' - 29: 2, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 2, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 1, # 'N' - 42: 2, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 2, # 'd' - 2: 0, # 'e' - 18: 1, # 'f' - 27: 1, # 'g' - 25: 1, # 'h' - 3: 2, # 'i' - 24: 0, # 'j' - 10: 2, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 3, # 'n' - 15: 2, # 'o' - 26: 2, # 'p' - 7: 3, # 'r' - 8: 1, # 's' - 9: 2, # 't' - 14: 0, # 'u' - 32: 1, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 2, # 'ü' - 30: 1, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 55: { # 'Ü' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 1, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 1, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 1, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 1, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 1, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 0, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 59: { # 'â' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 0, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 2, # 'm' - 4: 0, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 2, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 1, # 'Ş' - 19: 0, # 'ş' - }, - 33: { # 'ç' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 3, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 0, # 'Z' - 1: 0, # 'a' - 21: 3, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 0, # 'e' - 18: 2, # 'f' - 27: 1, # 'g' - 25: 3, # 'h' - 3: 3, # 'i' - 24: 0, # 'j' - 10: 3, # 'k' - 5: 0, # 'l' - 13: 0, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 3, # 'r' - 8: 2, # 's' - 9: 3, # 't' - 14: 0, # 'u' - 32: 2, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 1, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 61: { # 'î' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 0, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 0, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 2, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 1, # 'j' - 10: 0, # 'k' - 5: 0, # 'l' - 13: 1, # 'm' - 4: 1, # 'n' - 15: 0, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 1, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 1, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 1, # 'î' - 34: 0, # 'ö' - 17: 0, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 1, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 34: { # 'ö' - 23: 0, # 'A' - 37: 1, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 1, # 'G' - 45: 1, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 1, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 2, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 1, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 2, # 'c' - 12: 1, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 2, # 'h' - 3: 1, # 'i' - 24: 2, # 'j' - 10: 1, # 'k' - 5: 2, # 'l' - 13: 3, # 'm' - 4: 2, # 'n' - 15: 2, # 'o' - 26: 0, # 'p' - 7: 0, # 'r' - 8: 3, # 's' - 9: 1, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 1, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 0, # 'ü' - 30: 2, # 'ğ' - 41: 1, # 'İ' - 6: 1, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 17: { # 'ü' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 0, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 1, # 'J' - 16: 1, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 0, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 0, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 0, # 'c' - 12: 1, # 'd' - 2: 3, # 'e' - 18: 1, # 'f' - 27: 2, # 'g' - 25: 0, # 'h' - 3: 1, # 'i' - 24: 1, # 'j' - 10: 2, # 'k' - 5: 3, # 'l' - 13: 2, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 2, # 'p' - 7: 2, # 'r' - 8: 3, # 's' - 9: 2, # 't' - 14: 3, # 'u' - 32: 1, # 'v' - 57: 1, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 2, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 30: { # 'ğ' - 23: 0, # 'A' - 37: 2, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 1, # 'M' - 46: 2, # 'N' - 42: 2, # 'O' - 48: 1, # 'P' - 44: 1, # 'R' - 35: 0, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 2, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 0, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 2, # 'e' - 18: 0, # 'f' - 27: 0, # 'g' - 25: 0, # 'h' - 3: 0, # 'i' - 24: 3, # 'j' - 10: 1, # 'k' - 5: 2, # 'l' - 13: 3, # 'm' - 4: 0, # 'n' - 15: 1, # 'o' - 26: 0, # 'p' - 7: 1, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 2, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 2, # 'İ' - 6: 2, # 'ı' - 40: 2, # 'Ş' - 19: 1, # 'ş' - }, - 41: { # 'İ' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 1, # 'D' - 29: 1, # 'E' - 52: 0, # 'F' - 36: 2, # 'G' - 45: 2, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 2, # 'P' - 44: 0, # 'R' - 35: 1, # 'S' - 31: 1, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 0, # 'Z' - 1: 1, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 2, # 'd' - 2: 1, # 'e' - 18: 0, # 'f' - 27: 3, # 'g' - 25: 2, # 'h' - 3: 2, # 'i' - 24: 2, # 'j' - 10: 2, # 'k' - 5: 0, # 'l' - 13: 1, # 'm' - 4: 3, # 'n' - 15: 1, # 'o' - 26: 1, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 2, # 't' - 14: 0, # 'u' - 32: 0, # 'v' - 57: 1, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 1, # 'Ü' - 59: 1, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 1, # 'ö' - 17: 1, # 'ü' - 30: 2, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 1, # 'ş' - }, - 6: { # 'ı' - 23: 2, # 'A' - 37: 0, # 'B' - 47: 0, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 2, # 'J' - 16: 3, # 'K' - 49: 0, # 'L' - 20: 3, # 'M' - 46: 1, # 'N' - 42: 0, # 'O' - 48: 0, # 'P' - 44: 0, # 'R' - 35: 0, # 'S' - 31: 2, # 'T' - 51: 0, # 'U' - 38: 0, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 1, # 'Z' - 1: 3, # 'a' - 21: 2, # 'b' - 28: 1, # 'c' - 12: 3, # 'd' - 2: 3, # 'e' - 18: 3, # 'f' - 27: 3, # 'g' - 25: 2, # 'h' - 3: 3, # 'i' - 24: 3, # 'j' - 10: 3, # 'k' - 5: 3, # 'l' - 13: 3, # 'm' - 4: 3, # 'n' - 15: 0, # 'o' - 26: 3, # 'p' - 7: 3, # 'r' - 8: 3, # 's' - 9: 3, # 't' - 14: 3, # 'u' - 32: 3, # 'v' - 57: 1, # 'w' - 58: 1, # 'x' - 11: 3, # 'y' - 22: 0, # 'z' - 63: 1, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 2, # 'ç' - 61: 0, # 'î' - 34: 0, # 'ö' - 17: 3, # 'ü' - 30: 0, # 'ğ' - 41: 0, # 'İ' - 6: 3, # 'ı' - 40: 0, # 'Ş' - 19: 0, # 'ş' - }, - 40: { # 'Ş' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 1, # 'D' - 29: 1, # 'E' - 52: 0, # 'F' - 36: 1, # 'G' - 45: 2, # 'H' - 53: 1, # 'I' - 60: 0, # 'J' - 16: 0, # 'K' - 49: 0, # 'L' - 20: 2, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 2, # 'P' - 44: 2, # 'R' - 35: 1, # 'S' - 31: 1, # 'T' - 51: 0, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 2, # 'Y' - 56: 1, # 'Z' - 1: 0, # 'a' - 21: 2, # 'b' - 28: 0, # 'c' - 12: 2, # 'd' - 2: 0, # 'e' - 18: 3, # 'f' - 27: 0, # 'g' - 25: 2, # 'h' - 3: 3, # 'i' - 24: 2, # 'j' - 10: 1, # 'k' - 5: 0, # 'l' - 13: 1, # 'm' - 4: 3, # 'n' - 15: 2, # 'o' - 26: 0, # 'p' - 7: 3, # 'r' - 8: 2, # 's' - 9: 2, # 't' - 14: 1, # 'u' - 32: 3, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 2, # 'y' - 22: 0, # 'z' - 63: 0, # '·' - 54: 0, # 'Ç' - 50: 0, # 'Ö' - 55: 1, # 'Ü' - 59: 0, # 'â' - 33: 0, # 'ç' - 61: 0, # 'î' - 34: 2, # 'ö' - 17: 1, # 'ü' - 30: 2, # 'ğ' - 41: 0, # 'İ' - 6: 2, # 'ı' - 40: 1, # 'Ş' - 19: 2, # 'ş' - }, - 19: { # 'ş' - 23: 0, # 'A' - 37: 0, # 'B' - 47: 1, # 'C' - 39: 0, # 'D' - 29: 0, # 'E' - 52: 2, # 'F' - 36: 1, # 'G' - 45: 0, # 'H' - 53: 0, # 'I' - 60: 0, # 'J' - 16: 3, # 'K' - 49: 2, # 'L' - 20: 0, # 'M' - 46: 1, # 'N' - 42: 1, # 'O' - 48: 1, # 'P' - 44: 1, # 'R' - 35: 1, # 'S' - 31: 0, # 'T' - 51: 1, # 'U' - 38: 1, # 'V' - 62: 0, # 'W' - 43: 1, # 'Y' - 56: 0, # 'Z' - 1: 3, # 'a' - 21: 1, # 'b' - 28: 2, # 'c' - 12: 0, # 'd' - 2: 3, # 'e' - 18: 0, # 'f' - 27: 2, # 'g' - 25: 1, # 'h' - 3: 1, # 'i' - 24: 0, # 'j' - 10: 2, # 'k' - 5: 2, # 'l' - 13: 3, # 'm' - 4: 0, # 'n' - 15: 0, # 'o' - 26: 1, # 'p' - 7: 3, # 'r' - 8: 0, # 's' - 9: 0, # 't' - 14: 3, # 'u' - 32: 0, # 'v' - 57: 0, # 'w' - 58: 0, # 'x' - 11: 0, # 'y' - 22: 2, # 'z' - 63: 0, # '·' - 54: 1, # 'Ç' - 50: 2, # 'Ö' - 55: 0, # 'Ü' - 59: 0, # 'â' - 33: 1, # 'ç' - 61: 1, # 'î' - 34: 2, # 'ö' - 17: 0, # 'ü' - 30: 1, # 'ğ' - 41: 1, # 'İ' - 6: 1, # 'ı' - 40: 1, # 'Ş' - 19: 1, # 'ş' - }, -} - -# 255: Undefined characters that did not exist in training text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 -# 251: Control characters - -# Character Mapping Table(s): -ISO_8859_9_TURKISH_CHAR_TO_ORDER = { - 0: 255, # '\x00' - 1: 255, # '\x01' - 2: 255, # '\x02' - 3: 255, # '\x03' - 4: 255, # '\x04' - 5: 255, # '\x05' - 6: 255, # '\x06' - 7: 255, # '\x07' - 8: 255, # '\x08' - 9: 255, # '\t' - 10: 255, # '\n' - 11: 255, # '\x0b' - 12: 255, # '\x0c' - 13: 255, # '\r' - 14: 255, # '\x0e' - 15: 255, # '\x0f' - 16: 255, # '\x10' - 17: 255, # '\x11' - 18: 255, # '\x12' - 19: 255, # '\x13' - 20: 255, # '\x14' - 21: 255, # '\x15' - 22: 255, # '\x16' - 23: 255, # '\x17' - 24: 255, # '\x18' - 25: 255, # '\x19' - 26: 255, # '\x1a' - 27: 255, # '\x1b' - 28: 255, # '\x1c' - 29: 255, # '\x1d' - 30: 255, # '\x1e' - 31: 255, # '\x1f' - 32: 255, # ' ' - 33: 255, # '!' - 34: 255, # '"' - 35: 255, # '#' - 36: 255, # '$' - 37: 255, # '%' - 38: 255, # '&' - 39: 255, # "'" - 40: 255, # '(' - 41: 255, # ')' - 42: 255, # '*' - 43: 255, # '+' - 44: 255, # ',' - 45: 255, # '-' - 46: 255, # '.' - 47: 255, # '/' - 48: 255, # '0' - 49: 255, # '1' - 50: 255, # '2' - 51: 255, # '3' - 52: 255, # '4' - 53: 255, # '5' - 54: 255, # '6' - 55: 255, # '7' - 56: 255, # '8' - 57: 255, # '9' - 58: 255, # ':' - 59: 255, # ';' - 60: 255, # '<' - 61: 255, # '=' - 62: 255, # '>' - 63: 255, # '?' - 64: 255, # '@' - 65: 23, # 'A' - 66: 37, # 'B' - 67: 47, # 'C' - 68: 39, # 'D' - 69: 29, # 'E' - 70: 52, # 'F' - 71: 36, # 'G' - 72: 45, # 'H' - 73: 53, # 'I' - 74: 60, # 'J' - 75: 16, # 'K' - 76: 49, # 'L' - 77: 20, # 'M' - 78: 46, # 'N' - 79: 42, # 'O' - 80: 48, # 'P' - 81: 69, # 'Q' - 82: 44, # 'R' - 83: 35, # 'S' - 84: 31, # 'T' - 85: 51, # 'U' - 86: 38, # 'V' - 87: 62, # 'W' - 88: 65, # 'X' - 89: 43, # 'Y' - 90: 56, # 'Z' - 91: 255, # '[' - 92: 255, # '\\' - 93: 255, # ']' - 94: 255, # '^' - 95: 255, # '_' - 96: 255, # '`' - 97: 1, # 'a' - 98: 21, # 'b' - 99: 28, # 'c' - 100: 12, # 'd' - 101: 2, # 'e' - 102: 18, # 'f' - 103: 27, # 'g' - 104: 25, # 'h' - 105: 3, # 'i' - 106: 24, # 'j' - 107: 10, # 'k' - 108: 5, # 'l' - 109: 13, # 'm' - 110: 4, # 'n' - 111: 15, # 'o' - 112: 26, # 'p' - 113: 64, # 'q' - 114: 7, # 'r' - 115: 8, # 's' - 116: 9, # 't' - 117: 14, # 'u' - 118: 32, # 'v' - 119: 57, # 'w' - 120: 58, # 'x' - 121: 11, # 'y' - 122: 22, # 'z' - 123: 255, # '{' - 124: 255, # '|' - 125: 255, # '}' - 126: 255, # '~' - 127: 255, # '\x7f' - 128: 180, # '\x80' - 129: 179, # '\x81' - 130: 178, # '\x82' - 131: 177, # '\x83' - 132: 176, # '\x84' - 133: 175, # '\x85' - 134: 174, # '\x86' - 135: 173, # '\x87' - 136: 172, # '\x88' - 137: 171, # '\x89' - 138: 170, # '\x8a' - 139: 169, # '\x8b' - 140: 168, # '\x8c' - 141: 167, # '\x8d' - 142: 166, # '\x8e' - 143: 165, # '\x8f' - 144: 164, # '\x90' - 145: 163, # '\x91' - 146: 162, # '\x92' - 147: 161, # '\x93' - 148: 160, # '\x94' - 149: 159, # '\x95' - 150: 101, # '\x96' - 151: 158, # '\x97' - 152: 157, # '\x98' - 153: 156, # '\x99' - 154: 155, # '\x9a' - 155: 154, # '\x9b' - 156: 153, # '\x9c' - 157: 152, # '\x9d' - 158: 151, # '\x9e' - 159: 106, # '\x9f' - 160: 150, # '\xa0' - 161: 149, # '¡' - 162: 148, # '¢' - 163: 147, # '£' - 164: 146, # '¤' - 165: 145, # '¥' - 166: 144, # '¦' - 167: 100, # '§' - 168: 143, # '¨' - 169: 142, # '©' - 170: 141, # 'ª' - 171: 140, # '«' - 172: 139, # '¬' - 173: 138, # '\xad' - 174: 137, # '®' - 175: 136, # '¯' - 176: 94, # '°' - 177: 80, # '±' - 178: 93, # '²' - 179: 135, # '³' - 180: 105, # '´' - 181: 134, # 'µ' - 182: 133, # '¶' - 183: 63, # '·' - 184: 132, # '¸' - 185: 131, # '¹' - 186: 130, # 'º' - 187: 129, # '»' - 188: 128, # '¼' - 189: 127, # '½' - 190: 126, # '¾' - 191: 125, # '¿' - 192: 124, # 'À' - 193: 104, # 'Á' - 194: 73, # 'Â' - 195: 99, # 'Ã' - 196: 79, # 'Ä' - 197: 85, # 'Å' - 198: 123, # 'Æ' - 199: 54, # 'Ç' - 200: 122, # 'È' - 201: 98, # 'É' - 202: 92, # 'Ê' - 203: 121, # 'Ë' - 204: 120, # 'Ì' - 205: 91, # 'Í' - 206: 103, # 'Î' - 207: 119, # 'Ï' - 208: 68, # 'Ğ' - 209: 118, # 'Ñ' - 210: 117, # 'Ò' - 211: 97, # 'Ó' - 212: 116, # 'Ô' - 213: 115, # 'Õ' - 214: 50, # 'Ö' - 215: 90, # '×' - 216: 114, # 'Ø' - 217: 113, # 'Ù' - 218: 112, # 'Ú' - 219: 111, # 'Û' - 220: 55, # 'Ü' - 221: 41, # 'İ' - 222: 40, # 'Ş' - 223: 86, # 'ß' - 224: 89, # 'à' - 225: 70, # 'á' - 226: 59, # 'â' - 227: 78, # 'ã' - 228: 71, # 'ä' - 229: 82, # 'å' - 230: 88, # 'æ' - 231: 33, # 'ç' - 232: 77, # 'è' - 233: 66, # 'é' - 234: 84, # 'ê' - 235: 83, # 'ë' - 236: 110, # 'ì' - 237: 75, # 'í' - 238: 61, # 'î' - 239: 96, # 'ï' - 240: 30, # 'ğ' - 241: 67, # 'ñ' - 242: 109, # 'ò' - 243: 74, # 'ó' - 244: 87, # 'ô' - 245: 102, # 'õ' - 246: 34, # 'ö' - 247: 95, # '÷' - 248: 81, # 'ø' - 249: 108, # 'ù' - 250: 76, # 'ú' - 251: 72, # 'û' - 252: 17, # 'ü' - 253: 6, # 'ı' - 254: 19, # 'ş' - 255: 107, # 'ÿ' -} - -ISO_8859_9_TURKISH_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-9', - language='Turkish', - char_to_order_map=ISO_8859_9_TURKISH_CHAR_TO_ORDER, - language_model=TURKISH_LANG_MODEL, - typical_positive_ratio=0.97029, - keep_ascii_letters=True, - alphabet='ABCDEFGHIJKLMNOPRSTUVYZabcdefghijklmnoprstuvyzÂÇÎÖÛÜâçîöûüĞğİıŞş') - diff --git a/dist/ba_data/python-site-packages/chardet/latin1prober.py b/dist/ba_data/python-site-packages/chardet/latin1prober.py deleted file mode 100644 index 7d1e8c20..00000000 --- a/dist/ba_data/python-site-packages/chardet/latin1prober.py +++ /dev/null @@ -1,145 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState - -FREQ_CAT_NUM = 4 - -UDF = 0 # undefined -OTH = 1 # other -ASC = 2 # ascii capital letter -ASS = 3 # ascii small letter -ACV = 4 # accent capital vowel -ACO = 5 # accent capital other -ASV = 6 # accent small vowel -ASO = 7 # accent small other -CLASS_NUM = 8 # total classes - -Latin1_CharToClass = ( - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F - OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 - ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F - OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 - ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F - ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 - ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F - OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 - OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F - UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 - OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF - ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 - ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF - ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 - ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF - ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 - ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF - ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 - ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF -) - -# 0 : illegal -# 1 : very unlikely -# 2 : normal -# 3 : very likely -Latin1ClassModel = ( -# UDF OTH ASC ASS ACV ACO ASV ASO - 0, 0, 0, 0, 0, 0, 0, 0, # UDF - 0, 3, 3, 3, 3, 3, 3, 3, # OTH - 0, 3, 3, 3, 3, 3, 3, 3, # ASC - 0, 3, 3, 3, 1, 1, 3, 3, # ASS - 0, 3, 3, 3, 1, 2, 1, 2, # ACV - 0, 3, 3, 3, 3, 3, 3, 3, # ACO - 0, 3, 1, 3, 1, 1, 1, 3, # ASV - 0, 3, 1, 3, 1, 1, 3, 3, # ASO -) - - -class Latin1Prober(CharSetProber): - def __init__(self): - super(Latin1Prober, self).__init__() - self._last_char_class = None - self._freq_counter = None - self.reset() - - def reset(self): - self._last_char_class = OTH - self._freq_counter = [0] * FREQ_CAT_NUM - CharSetProber.reset(self) - - @property - def charset_name(self): - return "ISO-8859-1" - - @property - def language(self): - return "" - - def feed(self, byte_str): - byte_str = self.filter_with_english_letters(byte_str) - for c in byte_str: - char_class = Latin1_CharToClass[c] - freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) - + char_class] - if freq == 0: - self._state = ProbingState.NOT_ME - break - self._freq_counter[freq] += 1 - self._last_char_class = char_class - - return self.state - - def get_confidence(self): - if self.state == ProbingState.NOT_ME: - return 0.01 - - total = sum(self._freq_counter) - if total < 0.01: - confidence = 0.0 - else: - confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) - / total) - if confidence < 0.0: - confidence = 0.0 - # lower the confidence of latin1 so that other more accurate - # detector can take priority. - confidence = confidence * 0.73 - return confidence diff --git a/dist/ba_data/python-site-packages/chardet/mbcharsetprober.py b/dist/ba_data/python-site-packages/chardet/mbcharsetprober.py deleted file mode 100644 index 6256ecfd..00000000 --- a/dist/ba_data/python-site-packages/chardet/mbcharsetprober.py +++ /dev/null @@ -1,91 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# Proofpoint, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState, MachineState - - -class MultiByteCharSetProber(CharSetProber): - """ - MultiByteCharSetProber - """ - - def __init__(self, lang_filter=None): - super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) - self.distribution_analyzer = None - self.coding_sm = None - self._last_char = [0, 0] - - def reset(self): - super(MultiByteCharSetProber, self).reset() - if self.coding_sm: - self.coding_sm.reset() - if self.distribution_analyzer: - self.distribution_analyzer.reset() - self._last_char = [0, 0] - - @property - def charset_name(self): - raise NotImplementedError - - @property - def language(self): - raise NotImplementedError - - def feed(self, byte_str): - for i in range(len(byte_str)): - coding_state = self.coding_sm.next_state(byte_str[i]) - if coding_state == MachineState.ERROR: - self.logger.debug('%s %s prober hit error at byte %s', - self.charset_name, self.language, i) - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - char_len = self.coding_sm.get_current_charlen() - if i == 0: - self._last_char[1] = byte_str[0] - self.distribution_analyzer.feed(self._last_char, char_len) - else: - self.distribution_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - - self._last_char[0] = byte_str[-1] - - if self.state == ProbingState.DETECTING: - if (self.distribution_analyzer.got_enough_data() and - (self.get_confidence() > self.SHORTCUT_THRESHOLD)): - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - return self.distribution_analyzer.get_confidence() diff --git a/dist/ba_data/python-site-packages/chardet/mbcsgroupprober.py b/dist/ba_data/python-site-packages/chardet/mbcsgroupprober.py deleted file mode 100644 index 530abe75..00000000 --- a/dist/ba_data/python-site-packages/chardet/mbcsgroupprober.py +++ /dev/null @@ -1,54 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# Proofpoint, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetgroupprober import CharSetGroupProber -from .utf8prober import UTF8Prober -from .sjisprober import SJISProber -from .eucjpprober import EUCJPProber -from .gb2312prober import GB2312Prober -from .euckrprober import EUCKRProber -from .cp949prober import CP949Prober -from .big5prober import Big5Prober -from .euctwprober import EUCTWProber - - -class MBCSGroupProber(CharSetGroupProber): - def __init__(self, lang_filter=None): - super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) - self.probers = [ - UTF8Prober(), - SJISProber(), - EUCJPProber(), - GB2312Prober(), - EUCKRProber(), - CP949Prober(), - Big5Prober(), - EUCTWProber() - ] - self.reset() diff --git a/dist/ba_data/python-site-packages/chardet/mbcssm.py b/dist/ba_data/python-site-packages/chardet/mbcssm.py deleted file mode 100644 index 8360d0f2..00000000 --- a/dist/ba_data/python-site-packages/chardet/mbcssm.py +++ /dev/null @@ -1,572 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import MachineState - -# BIG5 - -BIG5_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,1, # 78 - 7f - 4,4,4,4,4,4,4,4, # 80 - 87 - 4,4,4,4,4,4,4,4, # 88 - 8f - 4,4,4,4,4,4,4,4, # 90 - 97 - 4,4,4,4,4,4,4,4, # 98 - 9f - 4,3,3,3,3,3,3,3, # a0 - a7 - 3,3,3,3,3,3,3,3, # a8 - af - 3,3,3,3,3,3,3,3, # b0 - b7 - 3,3,3,3,3,3,3,3, # b8 - bf - 3,3,3,3,3,3,3,3, # c0 - c7 - 3,3,3,3,3,3,3,3, # c8 - cf - 3,3,3,3,3,3,3,3, # d0 - d7 - 3,3,3,3,3,3,3,3, # d8 - df - 3,3,3,3,3,3,3,3, # e0 - e7 - 3,3,3,3,3,3,3,3, # e8 - ef - 3,3,3,3,3,3,3,3, # f0 - f7 - 3,3,3,3,3,3,3,0 # f8 - ff -) - -BIG5_ST = ( - MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 -) - -BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) - -BIG5_SM_MODEL = {'class_table': BIG5_CLS, - 'class_factor': 5, - 'state_table': BIG5_ST, - 'char_len_table': BIG5_CHAR_LEN_TABLE, - 'name': 'Big5'} - -# CP949 - -CP949_CLS = ( - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f - 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f - 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f - 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f - 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f - 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f - 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f - 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f - 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af - 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf - 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff -) - -CP949_ST = ( -#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = - MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 -) - -CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) - -CP949_SM_MODEL = {'class_table': CP949_CLS, - 'class_factor': 10, - 'state_table': CP949_ST, - 'char_len_table': CP949_CHAR_LEN_TABLE, - 'name': 'CP949'} - -# EUC-JP - -EUCJP_CLS = ( - 4,4,4,4,4,4,4,4, # 00 - 07 - 4,4,4,4,4,4,5,5, # 08 - 0f - 4,4,4,4,4,4,4,4, # 10 - 17 - 4,4,4,5,4,4,4,4, # 18 - 1f - 4,4,4,4,4,4,4,4, # 20 - 27 - 4,4,4,4,4,4,4,4, # 28 - 2f - 4,4,4,4,4,4,4,4, # 30 - 37 - 4,4,4,4,4,4,4,4, # 38 - 3f - 4,4,4,4,4,4,4,4, # 40 - 47 - 4,4,4,4,4,4,4,4, # 48 - 4f - 4,4,4,4,4,4,4,4, # 50 - 57 - 4,4,4,4,4,4,4,4, # 58 - 5f - 4,4,4,4,4,4,4,4, # 60 - 67 - 4,4,4,4,4,4,4,4, # 68 - 6f - 4,4,4,4,4,4,4,4, # 70 - 77 - 4,4,4,4,4,4,4,4, # 78 - 7f - 5,5,5,5,5,5,5,5, # 80 - 87 - 5,5,5,5,5,5,1,3, # 88 - 8f - 5,5,5,5,5,5,5,5, # 90 - 97 - 5,5,5,5,5,5,5,5, # 98 - 9f - 5,2,2,2,2,2,2,2, # a0 - a7 - 2,2,2,2,2,2,2,2, # a8 - af - 2,2,2,2,2,2,2,2, # b0 - b7 - 2,2,2,2,2,2,2,2, # b8 - bf - 2,2,2,2,2,2,2,2, # c0 - c7 - 2,2,2,2,2,2,2,2, # c8 - cf - 2,2,2,2,2,2,2,2, # d0 - d7 - 2,2,2,2,2,2,2,2, # d8 - df - 0,0,0,0,0,0,0,0, # e0 - e7 - 0,0,0,0,0,0,0,0, # e8 - ef - 0,0,0,0,0,0,0,0, # f0 - f7 - 0,0,0,0,0,0,0,5 # f8 - ff -) - -EUCJP_ST = ( - 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f - 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 -) - -EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) - -EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, - 'class_factor': 6, - 'state_table': EUCJP_ST, - 'char_len_table': EUCJP_CHAR_LEN_TABLE, - 'name': 'EUC-JP'} - -# EUC-KR - -EUCKR_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 1,1,1,1,1,1,1,1, # 40 - 47 - 1,1,1,1,1,1,1,1, # 48 - 4f - 1,1,1,1,1,1,1,1, # 50 - 57 - 1,1,1,1,1,1,1,1, # 58 - 5f - 1,1,1,1,1,1,1,1, # 60 - 67 - 1,1,1,1,1,1,1,1, # 68 - 6f - 1,1,1,1,1,1,1,1, # 70 - 77 - 1,1,1,1,1,1,1,1, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,0,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,2,2,2,2,2,2,2, # a0 - a7 - 2,2,2,2,2,3,3,3, # a8 - af - 2,2,2,2,2,2,2,2, # b0 - b7 - 2,2,2,2,2,2,2,2, # b8 - bf - 2,2,2,2,2,2,2,2, # c0 - c7 - 2,3,2,2,2,2,2,2, # c8 - cf - 2,2,2,2,2,2,2,2, # d0 - d7 - 2,2,2,2,2,2,2,2, # d8 - df - 2,2,2,2,2,2,2,2, # e0 - e7 - 2,2,2,2,2,2,2,2, # e8 - ef - 2,2,2,2,2,2,2,2, # f0 - f7 - 2,2,2,2,2,2,2,0 # f8 - ff -) - -EUCKR_ST = ( - MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f -) - -EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) - -EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, - 'class_factor': 4, - 'state_table': EUCKR_ST, - 'char_len_table': EUCKR_CHAR_LEN_TABLE, - 'name': 'EUC-KR'} - -# EUC-TW - -EUCTW_CLS = ( - 2,2,2,2,2,2,2,2, # 00 - 07 - 2,2,2,2,2,2,0,0, # 08 - 0f - 2,2,2,2,2,2,2,2, # 10 - 17 - 2,2,2,0,2,2,2,2, # 18 - 1f - 2,2,2,2,2,2,2,2, # 20 - 27 - 2,2,2,2,2,2,2,2, # 28 - 2f - 2,2,2,2,2,2,2,2, # 30 - 37 - 2,2,2,2,2,2,2,2, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,2, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,6,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,3,4,4,4,4,4,4, # a0 - a7 - 5,5,1,1,1,1,1,1, # a8 - af - 1,1,1,1,1,1,1,1, # b0 - b7 - 1,1,1,1,1,1,1,1, # b8 - bf - 1,1,3,1,3,3,3,3, # c0 - c7 - 3,3,3,3,3,3,3,3, # c8 - cf - 3,3,3,3,3,3,3,3, # d0 - d7 - 3,3,3,3,3,3,3,3, # d8 - df - 3,3,3,3,3,3,3,3, # e0 - e7 - 3,3,3,3,3,3,3,3, # e8 - ef - 3,3,3,3,3,3,3,3, # f0 - f7 - 3,3,3,3,3,3,3,0 # f8 - ff -) - -EUCTW_ST = ( - MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 - MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f - 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 - MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f -) - -EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) - -EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, - 'class_factor': 7, - 'state_table': EUCTW_ST, - 'char_len_table': EUCTW_CHAR_LEN_TABLE, - 'name': 'x-euc-tw'} - -# GB2312 - -GB2312_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 3,3,3,3,3,3,3,3, # 30 - 37 - 3,3,1,1,1,1,1,1, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,4, # 78 - 7f - 5,6,6,6,6,6,6,6, # 80 - 87 - 6,6,6,6,6,6,6,6, # 88 - 8f - 6,6,6,6,6,6,6,6, # 90 - 97 - 6,6,6,6,6,6,6,6, # 98 - 9f - 6,6,6,6,6,6,6,6, # a0 - a7 - 6,6,6,6,6,6,6,6, # a8 - af - 6,6,6,6,6,6,6,6, # b0 - b7 - 6,6,6,6,6,6,6,6, # b8 - bf - 6,6,6,6,6,6,6,6, # c0 - c7 - 6,6,6,6,6,6,6,6, # c8 - cf - 6,6,6,6,6,6,6,6, # d0 - d7 - 6,6,6,6,6,6,6,6, # d8 - df - 6,6,6,6,6,6,6,6, # e0 - e7 - 6,6,6,6,6,6,6,6, # e8 - ef - 6,6,6,6,6,6,6,6, # f0 - f7 - 6,6,6,6,6,6,6,0 # f8 - ff -) - -GB2312_ST = ( - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 - 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f - MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f -) - -# To be accurate, the length of class 6 can be either 2 or 4. -# But it is not necessary to discriminate between the two since -# it is used for frequency analysis only, and we are validating -# each code range there as well. So it is safe to set it to be -# 2 here. -GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) - -GB2312_SM_MODEL = {'class_table': GB2312_CLS, - 'class_factor': 7, - 'state_table': GB2312_ST, - 'char_len_table': GB2312_CHAR_LEN_TABLE, - 'name': 'GB2312'} - -# Shift_JIS - -SJIS_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,1, # 78 - 7f - 3,3,3,3,3,2,2,3, # 80 - 87 - 3,3,3,3,3,3,3,3, # 88 - 8f - 3,3,3,3,3,3,3,3, # 90 - 97 - 3,3,3,3,3,3,3,3, # 98 - 9f - #0xa0 is illegal in sjis encoding, but some pages does - #contain such byte. We need to be more error forgiven. - 2,2,2,2,2,2,2,2, # a0 - a7 - 2,2,2,2,2,2,2,2, # a8 - af - 2,2,2,2,2,2,2,2, # b0 - b7 - 2,2,2,2,2,2,2,2, # b8 - bf - 2,2,2,2,2,2,2,2, # c0 - c7 - 2,2,2,2,2,2,2,2, # c8 - cf - 2,2,2,2,2,2,2,2, # d0 - d7 - 2,2,2,2,2,2,2,2, # d8 - df - 3,3,3,3,3,3,3,3, # e0 - e7 - 3,3,3,3,3,4,4,4, # e8 - ef - 3,3,3,3,3,3,3,3, # f0 - f7 - 3,3,3,3,3,0,0,0) # f8 - ff - - -SJIS_ST = ( - MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 -) - -SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) - -SJIS_SM_MODEL = {'class_table': SJIS_CLS, - 'class_factor': 6, - 'state_table': SJIS_ST, - 'char_len_table': SJIS_CHAR_LEN_TABLE, - 'name': 'Shift_JIS'} - -# UCS2-BE - -UCS2BE_CLS = ( - 0,0,0,0,0,0,0,0, # 00 - 07 - 0,0,1,0,0,2,0,0, # 08 - 0f - 0,0,0,0,0,0,0,0, # 10 - 17 - 0,0,0,3,0,0,0,0, # 18 - 1f - 0,0,0,0,0,0,0,0, # 20 - 27 - 0,3,3,3,3,3,0,0, # 28 - 2f - 0,0,0,0,0,0,0,0, # 30 - 37 - 0,0,0,0,0,0,0,0, # 38 - 3f - 0,0,0,0,0,0,0,0, # 40 - 47 - 0,0,0,0,0,0,0,0, # 48 - 4f - 0,0,0,0,0,0,0,0, # 50 - 57 - 0,0,0,0,0,0,0,0, # 58 - 5f - 0,0,0,0,0,0,0,0, # 60 - 67 - 0,0,0,0,0,0,0,0, # 68 - 6f - 0,0,0,0,0,0,0,0, # 70 - 77 - 0,0,0,0,0,0,0,0, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,0,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,0,0,0,0,0,0,0, # a0 - a7 - 0,0,0,0,0,0,0,0, # a8 - af - 0,0,0,0,0,0,0,0, # b0 - b7 - 0,0,0,0,0,0,0,0, # b8 - bf - 0,0,0,0,0,0,0,0, # c0 - c7 - 0,0,0,0,0,0,0,0, # c8 - cf - 0,0,0,0,0,0,0,0, # d0 - d7 - 0,0,0,0,0,0,0,0, # d8 - df - 0,0,0,0,0,0,0,0, # e0 - e7 - 0,0,0,0,0,0,0,0, # e8 - ef - 0,0,0,0,0,0,0,0, # f0 - f7 - 0,0,0,0,0,0,4,5 # f8 - ff -) - -UCS2BE_ST = ( - 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 - 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f - 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 - 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f - 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 -) - -UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) - -UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, - 'class_factor': 6, - 'state_table': UCS2BE_ST, - 'char_len_table': UCS2BE_CHAR_LEN_TABLE, - 'name': 'UTF-16BE'} - -# UCS2-LE - -UCS2LE_CLS = ( - 0,0,0,0,0,0,0,0, # 00 - 07 - 0,0,1,0,0,2,0,0, # 08 - 0f - 0,0,0,0,0,0,0,0, # 10 - 17 - 0,0,0,3,0,0,0,0, # 18 - 1f - 0,0,0,0,0,0,0,0, # 20 - 27 - 0,3,3,3,3,3,0,0, # 28 - 2f - 0,0,0,0,0,0,0,0, # 30 - 37 - 0,0,0,0,0,0,0,0, # 38 - 3f - 0,0,0,0,0,0,0,0, # 40 - 47 - 0,0,0,0,0,0,0,0, # 48 - 4f - 0,0,0,0,0,0,0,0, # 50 - 57 - 0,0,0,0,0,0,0,0, # 58 - 5f - 0,0,0,0,0,0,0,0, # 60 - 67 - 0,0,0,0,0,0,0,0, # 68 - 6f - 0,0,0,0,0,0,0,0, # 70 - 77 - 0,0,0,0,0,0,0,0, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,0,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,0,0,0,0,0,0,0, # a0 - a7 - 0,0,0,0,0,0,0,0, # a8 - af - 0,0,0,0,0,0,0,0, # b0 - b7 - 0,0,0,0,0,0,0,0, # b8 - bf - 0,0,0,0,0,0,0,0, # c0 - c7 - 0,0,0,0,0,0,0,0, # c8 - cf - 0,0,0,0,0,0,0,0, # d0 - d7 - 0,0,0,0,0,0,0,0, # d8 - df - 0,0,0,0,0,0,0,0, # e0 - e7 - 0,0,0,0,0,0,0,0, # e8 - ef - 0,0,0,0,0,0,0,0, # f0 - f7 - 0,0,0,0,0,0,4,5 # f8 - ff -) - -UCS2LE_ST = ( - 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 - 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f - 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 - 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f - 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 -) - -UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) - -UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, - 'class_factor': 6, - 'state_table': UCS2LE_ST, - 'char_len_table': UCS2LE_CHAR_LEN_TABLE, - 'name': 'UTF-16LE'} - -# UTF-8 - -UTF8_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 1,1,1,1,1,1,1,1, # 40 - 47 - 1,1,1,1,1,1,1,1, # 48 - 4f - 1,1,1,1,1,1,1,1, # 50 - 57 - 1,1,1,1,1,1,1,1, # 58 - 5f - 1,1,1,1,1,1,1,1, # 60 - 67 - 1,1,1,1,1,1,1,1, # 68 - 6f - 1,1,1,1,1,1,1,1, # 70 - 77 - 1,1,1,1,1,1,1,1, # 78 - 7f - 2,2,2,2,3,3,3,3, # 80 - 87 - 4,4,4,4,4,4,4,4, # 88 - 8f - 4,4,4,4,4,4,4,4, # 90 - 97 - 4,4,4,4,4,4,4,4, # 98 - 9f - 5,5,5,5,5,5,5,5, # a0 - a7 - 5,5,5,5,5,5,5,5, # a8 - af - 5,5,5,5,5,5,5,5, # b0 - b7 - 5,5,5,5,5,5,5,5, # b8 - bf - 0,0,6,6,6,6,6,6, # c0 - c7 - 6,6,6,6,6,6,6,6, # c8 - cf - 6,6,6,6,6,6,6,6, # d0 - d7 - 6,6,6,6,6,6,6,6, # d8 - df - 7,8,8,8,8,8,8,8, # e0 - e7 - 8,8,8,8,8,9,8,8, # e8 - ef - 10,11,11,11,11,11,11,11, # f0 - f7 - 12,13,13,13,14,15,0,0 # f8 - ff -) - -UTF8_ST = ( - MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 - 9, 11, 8, 7, 6, 5, 4, 3,#08-0f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f - MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f - MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f - MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f - MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af - MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf -) - -UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) - -UTF8_SM_MODEL = {'class_table': UTF8_CLS, - 'class_factor': 16, - 'state_table': UTF8_ST, - 'char_len_table': UTF8_CHAR_LEN_TABLE, - 'name': 'UTF-8'} diff --git a/dist/ba_data/python-site-packages/chardet/metadata/languages.py b/dist/ba_data/python-site-packages/chardet/metadata/languages.py deleted file mode 100644 index 3237d5ab..00000000 --- a/dist/ba_data/python-site-packages/chardet/metadata/languages.py +++ /dev/null @@ -1,310 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Metadata about languages used by our model training code for our -SingleByteCharSetProbers. Could be used for other things in the future. - -This code is based on the language metadata from the uchardet project. -""" -from __future__ import absolute_import, print_function - -from string import ascii_letters - - -# TODO: Add Ukranian (KOI8-U) - -class Language(object): - """Metadata about a language useful for training models - - :ivar name: The human name for the language, in English. - :type name: str - :ivar iso_code: 2-letter ISO 639-1 if possible, 3-letter ISO code otherwise, - or use another catalog as a last resort. - :type iso_code: str - :ivar use_ascii: Whether or not ASCII letters should be included in trained - models. - :type use_ascii: bool - :ivar charsets: The charsets we want to support and create data for. - :type charsets: list of str - :ivar alphabet: The characters in the language's alphabet. If `use_ascii` is - `True`, you only need to add those not in the ASCII set. - :type alphabet: str - :ivar wiki_start_pages: The Wikipedia pages to start from if we're crawling - Wikipedia for training data. - :type wiki_start_pages: list of str - """ - def __init__(self, name=None, iso_code=None, use_ascii=True, charsets=None, - alphabet=None, wiki_start_pages=None): - super(Language, self).__init__() - self.name = name - self.iso_code = iso_code - self.use_ascii = use_ascii - self.charsets = charsets - if self.use_ascii: - if alphabet: - alphabet += ascii_letters - else: - alphabet = ascii_letters - elif not alphabet: - raise ValueError('Must supply alphabet if use_ascii is False') - self.alphabet = ''.join(sorted(set(alphabet))) if alphabet else None - self.wiki_start_pages = wiki_start_pages - - def __repr__(self): - return '{}({})'.format(self.__class__.__name__, - ', '.join('{}={!r}'.format(k, v) - for k, v in self.__dict__.items() - if not k.startswith('_'))) - - -LANGUAGES = {'Arabic': Language(name='Arabic', - iso_code='ar', - use_ascii=False, - # We only support encodings that use isolated - # forms, because the current recommendation is - # that the rendering system handles presentation - # forms. This means we purposefully skip IBM864. - charsets=['ISO-8859-6', 'WINDOWS-1256', - 'CP720', 'CP864'], - alphabet=u'ءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿـفقكلمنهوىيًٌٍَُِّ', - wiki_start_pages=[u'الصفحة_الرئيسية']), - 'Belarusian': Language(name='Belarusian', - iso_code='be', - use_ascii=False, - charsets=['ISO-8859-5', 'WINDOWS-1251', - 'IBM866', 'MacCyrillic'], - alphabet=(u'АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШЫЬЭЮЯ' - u'абвгдеёжзійклмнопрстуўфхцчшыьэюяʼ'), - wiki_start_pages=[u'Галоўная_старонка']), - 'Bulgarian': Language(name='Bulgarian', - iso_code='bg', - use_ascii=False, - charsets=['ISO-8859-5', 'WINDOWS-1251', - 'IBM855'], - alphabet=(u'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯ' - u'абвгдежзийклмнопрстуфхцчшщъьюя'), - wiki_start_pages=[u'Начална_страница']), - 'Czech': Language(name='Czech', - iso_code='cz', - use_ascii=True, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=u'áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ', - wiki_start_pages=[u'Hlavní_strana']), - 'Danish': Language(name='Danish', - iso_code='da', - use_ascii=True, - charsets=['ISO-8859-1', 'ISO-8859-15', - 'WINDOWS-1252'], - alphabet=u'æøåÆØÅ', - wiki_start_pages=[u'Forside']), - 'German': Language(name='German', - iso_code='de', - use_ascii=True, - charsets=['ISO-8859-1', 'WINDOWS-1252'], - alphabet=u'äöüßÄÖÜ', - wiki_start_pages=[u'Wikipedia:Hauptseite']), - 'Greek': Language(name='Greek', - iso_code='el', - use_ascii=False, - charsets=['ISO-8859-7', 'WINDOWS-1253'], - alphabet=(u'αβγδεζηθικλμνξοπρσςτυφχψωάέήίόύώ' - u'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΣΤΥΦΧΨΩΆΈΉΊΌΎΏ'), - wiki_start_pages=[u'Πύλη:Κύρια']), - 'English': Language(name='English', - iso_code='en', - use_ascii=True, - charsets=['ISO-8859-1', 'WINDOWS-1252'], - wiki_start_pages=[u'Main_Page']), - 'Esperanto': Language(name='Esperanto', - iso_code='eo', - # Q, W, X, and Y not used at all - use_ascii=False, - charsets=['ISO-8859-3'], - alphabet=(u'abcĉdefgĝhĥijĵklmnoprsŝtuŭvz' - u'ABCĈDEFGĜHĤIJĴKLMNOPRSŜTUŬVZ'), - wiki_start_pages=[u'Vikipedio:Ĉefpaĝo']), - 'Spanish': Language(name='Spanish', - iso_code='es', - use_ascii=True, - charsets=['ISO-8859-1', 'ISO-8859-15', - 'WINDOWS-1252'], - alphabet=u'ñáéíóúüÑÁÉÍÓÚÜ', - wiki_start_pages=[u'Wikipedia:Portada']), - 'Estonian': Language(name='Estonian', - iso_code='et', - use_ascii=False, - charsets=['ISO-8859-4', 'ISO-8859-13', - 'WINDOWS-1257'], - # C, F, Š, Q, W, X, Y, Z, Ž are only for - # loanwords - alphabet=(u'ABDEGHIJKLMNOPRSTUVÕÄÖÜ' - u'abdeghijklmnoprstuvõäöü'), - wiki_start_pages=[u'Esileht']), - 'Finnish': Language(name='Finnish', - iso_code='fi', - use_ascii=True, - charsets=['ISO-8859-1', 'ISO-8859-15', - 'WINDOWS-1252'], - alphabet=u'ÅÄÖŠŽåäöšž', - wiki_start_pages=[u'Wikipedia:Etusivu']), - 'French': Language(name='French', - iso_code='fr', - use_ascii=True, - charsets=['ISO-8859-1', 'ISO-8859-15', - 'WINDOWS-1252'], - alphabet=u'œàâçèéîïùûêŒÀÂÇÈÉÎÏÙÛÊ', - wiki_start_pages=[u'Wikipédia:Accueil_principal', - u'Bœuf (animal)']), - 'Hebrew': Language(name='Hebrew', - iso_code='he', - use_ascii=False, - charsets=['ISO-8859-8', 'WINDOWS-1255'], - alphabet=u'אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ', - wiki_start_pages=[u'עמוד_ראשי']), - 'Croatian': Language(name='Croatian', - iso_code='hr', - # Q, W, X, Y are only used for foreign words. - use_ascii=False, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=(u'abcčćdđefghijklmnoprsštuvzž' - u'ABCČĆDĐEFGHIJKLMNOPRSŠTUVZŽ'), - wiki_start_pages=[u'Glavna_stranica']), - 'Hungarian': Language(name='Hungarian', - iso_code='hu', - # Q, W, X, Y are only used for foreign words. - use_ascii=False, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=(u'abcdefghijklmnoprstuvzáéíóöőúüű' - u'ABCDEFGHIJKLMNOPRSTUVZÁÉÍÓÖŐÚÜŰ'), - wiki_start_pages=[u'Kezdőlap']), - 'Italian': Language(name='Italian', - iso_code='it', - use_ascii=True, - charsets=['ISO-8859-1', 'ISO-8859-15', - 'WINDOWS-1252'], - alphabet=u'ÀÈÉÌÒÓÙàèéìòóù', - wiki_start_pages=[u'Pagina_principale']), - 'Lithuanian': Language(name='Lithuanian', - iso_code='lt', - use_ascii=False, - charsets=['ISO-8859-13', 'WINDOWS-1257', - 'ISO-8859-4'], - # Q, W, and X not used at all - alphabet=(u'AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ' - u'aąbcčdeęėfghiįyjklmnoprsštuųūvzž'), - wiki_start_pages=[u'Pagrindinis_puslapis']), - 'Latvian': Language(name='Latvian', - iso_code='lv', - use_ascii=False, - charsets=['ISO-8859-13', 'WINDOWS-1257', - 'ISO-8859-4'], - # Q, W, X, Y are only for loanwords - alphabet=(u'AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ' - u'aābcčdeēfgģhiījkķlļmnņoprsštuūvzž'), - wiki_start_pages=[u'Sākumlapa']), - 'Macedonian': Language(name='Macedonian', - iso_code='mk', - use_ascii=False, - charsets=['ISO-8859-5', 'WINDOWS-1251', - 'MacCyrillic', 'IBM855'], - alphabet=(u'АБВГДЃЕЖЗЅИЈКЛЉМНЊОПРСТЌУФХЦЧЏШ' - u'абвгдѓежзѕијклљмнњопрстќуфхцчџш'), - wiki_start_pages=[u'Главна_страница']), - 'Dutch': Language(name='Dutch', - iso_code='nl', - use_ascii=True, - charsets=['ISO-8859-1', 'WINDOWS-1252'], - wiki_start_pages=[u'Hoofdpagina']), - 'Polish': Language(name='Polish', - iso_code='pl', - # Q and X are only used for foreign words. - use_ascii=False, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=(u'AĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŹŻ' - u'aąbcćdeęfghijklłmnńoóprsśtuwyzźż'), - wiki_start_pages=[u'Wikipedia:Strona_główna']), - 'Portuguese': Language(name='Portuguese', - iso_code='pt', - use_ascii=True, - charsets=['ISO-8859-1', 'ISO-8859-15', - 'WINDOWS-1252'], - alphabet=u'ÁÂÃÀÇÉÊÍÓÔÕÚáâãàçéêíóôõú', - wiki_start_pages=[u'Wikipédia:Página_principal']), - 'Romanian': Language(name='Romanian', - iso_code='ro', - use_ascii=True, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=u'ăâîșțĂÂÎȘȚ', - wiki_start_pages=[u'Pagina_principală']), - 'Russian': Language(name='Russian', - iso_code='ru', - use_ascii=False, - charsets=['ISO-8859-5', 'WINDOWS-1251', - 'KOI8-R', 'MacCyrillic', 'IBM866', - 'IBM855'], - alphabet=(u'абвгдеёжзийклмнопрстуфхцчшщъыьэюя' - u'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'), - wiki_start_pages=[u'Заглавная_страница']), - 'Slovak': Language(name='Slovak', - iso_code='sk', - use_ascii=True, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=u'áäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽ', - wiki_start_pages=[u'Hlavná_stránka']), - 'Slovene': Language(name='Slovene', - iso_code='sl', - # Q, W, X, Y are only used for foreign words. - use_ascii=False, - charsets=['ISO-8859-2', 'WINDOWS-1250'], - alphabet=(u'abcčdefghijklmnoprsštuvzž' - u'ABCČDEFGHIJKLMNOPRSŠTUVZŽ'), - wiki_start_pages=[u'Glavna_stran']), - # Serbian can be written in both Latin and Cyrillic, but there's no - # simple way to get the Latin alphabet pages from Wikipedia through - # the API, so for now we just support Cyrillic. - 'Serbian': Language(name='Serbian', - iso_code='sr', - alphabet=(u'АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ' - u'абвгдђежзијклљмнњопрстћуфхцчџш'), - charsets=['ISO-8859-5', 'WINDOWS-1251', - 'MacCyrillic', 'IBM855'], - wiki_start_pages=[u'Главна_страна']), - 'Thai': Language(name='Thai', - iso_code='th', - use_ascii=False, - charsets=['ISO-8859-11', 'TIS-620', 'CP874'], - alphabet=u'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛', - wiki_start_pages=[u'หน้าหลัก']), - 'Turkish': Language(name='Turkish', - iso_code='tr', - # Q, W, and X are not used by Turkish - use_ascii=False, - charsets=['ISO-8859-3', 'ISO-8859-9', - 'WINDOWS-1254'], - alphabet=(u'abcçdefgğhıijklmnoöprsştuüvyzâîû' - u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZÂÎÛ'), - wiki_start_pages=[u'Ana_Sayfa']), - 'Vietnamese': Language(name='Vietnamese', - iso_code='vi', - use_ascii=False, - # Windows-1258 is the only common 8-bit - # Vietnamese encoding supported by Python. - # From Wikipedia: - # For systems that lack support for Unicode, - # dozens of 8-bit Vietnamese code pages are - # available.[1] The most common are VISCII - # (TCVN 5712:1993), VPS, and Windows-1258.[3] - # Where ASCII is required, such as when - # ensuring readability in plain text e-mail, - # Vietnamese letters are often encoded - # according to Vietnamese Quoted-Readable - # (VIQR) or VSCII Mnemonic (VSCII-MNEM),[4] - # though usage of either variable-width - # scheme has declined dramatically following - # the adoption of Unicode on the World Wide - # Web. - charsets=['WINDOWS-1258'], - alphabet=(u'aăâbcdđeêghiklmnoôơpqrstuưvxy' - u'AĂÂBCDĐEÊGHIKLMNOÔƠPQRSTUƯVXY'), - wiki_start_pages=[u'Chữ_Quốc_ngữ']), - } diff --git a/dist/ba_data/python-site-packages/chardet/sbcharsetprober.py b/dist/ba_data/python-site-packages/chardet/sbcharsetprober.py deleted file mode 100644 index 46ba835c..00000000 --- a/dist/ba_data/python-site-packages/chardet/sbcharsetprober.py +++ /dev/null @@ -1,145 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from collections import namedtuple - -from .charsetprober import CharSetProber -from .enums import CharacterCategory, ProbingState, SequenceLikelihood - - -SingleByteCharSetModel = namedtuple('SingleByteCharSetModel', - ['charset_name', - 'language', - 'char_to_order_map', - 'language_model', - 'typical_positive_ratio', - 'keep_ascii_letters', - 'alphabet']) - - -class SingleByteCharSetProber(CharSetProber): - SAMPLE_SIZE = 64 - SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 - POSITIVE_SHORTCUT_THRESHOLD = 0.95 - NEGATIVE_SHORTCUT_THRESHOLD = 0.05 - - def __init__(self, model, reversed=False, name_prober=None): - super(SingleByteCharSetProber, self).__init__() - self._model = model - # TRUE if we need to reverse every pair in the model lookup - self._reversed = reversed - # Optional auxiliary prober for name decision - self._name_prober = name_prober - self._last_order = None - self._seq_counters = None - self._total_seqs = None - self._total_char = None - self._freq_char = None - self.reset() - - def reset(self): - super(SingleByteCharSetProber, self).reset() - # char order of last character - self._last_order = 255 - self._seq_counters = [0] * SequenceLikelihood.get_num_categories() - self._total_seqs = 0 - self._total_char = 0 - # characters that fall in our sampling range - self._freq_char = 0 - - @property - def charset_name(self): - if self._name_prober: - return self._name_prober.charset_name - else: - return self._model.charset_name - - @property - def language(self): - if self._name_prober: - return self._name_prober.language - else: - return self._model.language - - def feed(self, byte_str): - # TODO: Make filter_international_words keep things in self.alphabet - if not self._model.keep_ascii_letters: - byte_str = self.filter_international_words(byte_str) - if not byte_str: - return self.state - char_to_order_map = self._model.char_to_order_map - language_model = self._model.language_model - for char in byte_str: - order = char_to_order_map.get(char, CharacterCategory.UNDEFINED) - # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but - # CharacterCategory.SYMBOL is actually 253, so we use CONTROL - # to make it closer to the original intent. The only difference - # is whether or not we count digits and control characters for - # _total_char purposes. - if order < CharacterCategory.CONTROL: - self._total_char += 1 - # TODO: Follow uchardet's lead and discount confidence for frequent - # control characters. - # See https://github.com/BYVoid/uchardet/commit/55b4f23971db61 - if order < self.SAMPLE_SIZE: - self._freq_char += 1 - if self._last_order < self.SAMPLE_SIZE: - self._total_seqs += 1 - if not self._reversed: - lm_cat = language_model[self._last_order][order] - else: - lm_cat = language_model[order][self._last_order] - self._seq_counters[lm_cat] += 1 - self._last_order = order - - charset_name = self._model.charset_name - if self.state == ProbingState.DETECTING: - if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: - confidence = self.get_confidence() - if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: - self.logger.debug('%s confidence = %s, we have a winner', - charset_name, confidence) - self._state = ProbingState.FOUND_IT - elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: - self.logger.debug('%s confidence = %s, below negative ' - 'shortcut threshhold %s', charset_name, - confidence, - self.NEGATIVE_SHORTCUT_THRESHOLD) - self._state = ProbingState.NOT_ME - - return self.state - - def get_confidence(self): - r = 0.01 - if self._total_seqs > 0: - r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / - self._total_seqs / self._model.typical_positive_ratio) - r = r * self._freq_char / self._total_char - if r >= 1.0: - r = 0.99 - return r diff --git a/dist/ba_data/python-site-packages/chardet/sbcsgroupprober.py b/dist/ba_data/python-site-packages/chardet/sbcsgroupprober.py deleted file mode 100644 index bdeef4e1..00000000 --- a/dist/ba_data/python-site-packages/chardet/sbcsgroupprober.py +++ /dev/null @@ -1,83 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetgroupprober import CharSetGroupProber -from .hebrewprober import HebrewProber -from .langbulgarianmodel import (ISO_8859_5_BULGARIAN_MODEL, - WINDOWS_1251_BULGARIAN_MODEL) -from .langgreekmodel import ISO_8859_7_GREEK_MODEL, WINDOWS_1253_GREEK_MODEL -from .langhebrewmodel import WINDOWS_1255_HEBREW_MODEL -# from .langhungarianmodel import (ISO_8859_2_HUNGARIAN_MODEL, -# WINDOWS_1250_HUNGARIAN_MODEL) -from .langrussianmodel import (IBM855_RUSSIAN_MODEL, IBM866_RUSSIAN_MODEL, - ISO_8859_5_RUSSIAN_MODEL, KOI8_R_RUSSIAN_MODEL, - MACCYRILLIC_RUSSIAN_MODEL, - WINDOWS_1251_RUSSIAN_MODEL) -from .langthaimodel import TIS_620_THAI_MODEL -from .langturkishmodel import ISO_8859_9_TURKISH_MODEL -from .sbcharsetprober import SingleByteCharSetProber - - -class SBCSGroupProber(CharSetGroupProber): - def __init__(self): - super(SBCSGroupProber, self).__init__() - hebrew_prober = HebrewProber() - logical_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, - False, hebrew_prober) - # TODO: See if using ISO-8859-8 Hebrew model works better here, since - # it's actually the visual one - visual_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, - True, hebrew_prober) - hebrew_prober.set_model_probers(logical_hebrew_prober, - visual_hebrew_prober) - # TODO: ORDER MATTERS HERE. I changed the order vs what was in master - # and several tests failed that did not before. Some thought - # should be put into the ordering, and we should consider making - # order not matter here, because that is very counter-intuitive. - self.probers = [ - SingleByteCharSetProber(WINDOWS_1251_RUSSIAN_MODEL), - SingleByteCharSetProber(KOI8_R_RUSSIAN_MODEL), - SingleByteCharSetProber(ISO_8859_5_RUSSIAN_MODEL), - SingleByteCharSetProber(MACCYRILLIC_RUSSIAN_MODEL), - SingleByteCharSetProber(IBM866_RUSSIAN_MODEL), - SingleByteCharSetProber(IBM855_RUSSIAN_MODEL), - SingleByteCharSetProber(ISO_8859_7_GREEK_MODEL), - SingleByteCharSetProber(WINDOWS_1253_GREEK_MODEL), - SingleByteCharSetProber(ISO_8859_5_BULGARIAN_MODEL), - SingleByteCharSetProber(WINDOWS_1251_BULGARIAN_MODEL), - # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) - # after we retrain model. - # SingleByteCharSetProber(ISO_8859_2_HUNGARIAN_MODEL), - # SingleByteCharSetProber(WINDOWS_1250_HUNGARIAN_MODEL), - SingleByteCharSetProber(TIS_620_THAI_MODEL), - SingleByteCharSetProber(ISO_8859_9_TURKISH_MODEL), - hebrew_prober, - logical_hebrew_prober, - visual_hebrew_prober, - ] - self.reset() diff --git a/dist/ba_data/python-site-packages/chardet/sjisprober.py b/dist/ba_data/python-site-packages/chardet/sjisprober.py deleted file mode 100644 index 9e29623b..00000000 --- a/dist/ba_data/python-site-packages/chardet/sjisprober.py +++ /dev/null @@ -1,92 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import SJISDistributionAnalysis -from .jpcntx import SJISContextAnalysis -from .mbcssm import SJIS_SM_MODEL -from .enums import ProbingState, MachineState - - -class SJISProber(MultiByteCharSetProber): - def __init__(self): - super(SJISProber, self).__init__() - self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) - self.distribution_analyzer = SJISDistributionAnalysis() - self.context_analyzer = SJISContextAnalysis() - self.reset() - - def reset(self): - super(SJISProber, self).reset() - self.context_analyzer.reset() - - @property - def charset_name(self): - return self.context_analyzer.charset_name - - @property - def language(self): - return "Japanese" - - def feed(self, byte_str): - for i in range(len(byte_str)): - coding_state = self.coding_sm.next_state(byte_str[i]) - if coding_state == MachineState.ERROR: - self.logger.debug('%s %s prober hit error at byte %s', - self.charset_name, self.language, i) - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - char_len = self.coding_sm.get_current_charlen() - if i == 0: - self._last_char[1] = byte_str[0] - self.context_analyzer.feed(self._last_char[2 - char_len:], - char_len) - self.distribution_analyzer.feed(self._last_char, char_len) - else: - self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 - - char_len], char_len) - self.distribution_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - - self._last_char[0] = byte_str[-1] - - if self.state == ProbingState.DETECTING: - if (self.context_analyzer.got_enough_data() and - (self.get_confidence() > self.SHORTCUT_THRESHOLD)): - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - context_conf = self.context_analyzer.get_confidence() - distrib_conf = self.distribution_analyzer.get_confidence() - return max(context_conf, distrib_conf) diff --git a/dist/ba_data/python-site-packages/chardet/universaldetector.py b/dist/ba_data/python-site-packages/chardet/universaldetector.py deleted file mode 100644 index 055a8ac1..00000000 --- a/dist/ba_data/python-site-packages/chardet/universaldetector.py +++ /dev/null @@ -1,286 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### -""" -Module containing the UniversalDetector detector class, which is the primary -class a user of ``chardet`` should use. - -:author: Mark Pilgrim (initial port to Python) -:author: Shy Shalom (original C code) -:author: Dan Blanchard (major refactoring for 3.0) -:author: Ian Cordasco -""" - - -import codecs -import logging -import re - -from .charsetgroupprober import CharSetGroupProber -from .enums import InputState, LanguageFilter, ProbingState -from .escprober import EscCharSetProber -from .latin1prober import Latin1Prober -from .mbcsgroupprober import MBCSGroupProber -from .sbcsgroupprober import SBCSGroupProber - - -class UniversalDetector(object): - """ - The ``UniversalDetector`` class underlies the ``chardet.detect`` function - and coordinates all of the different charset probers. - - To get a ``dict`` containing an encoding and its confidence, you can simply - run: - - .. code:: - - u = UniversalDetector() - u.feed(some_bytes) - u.close() - detected = u.result - - """ - - MINIMUM_THRESHOLD = 0.20 - HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') - ESC_DETECTOR = re.compile(b'(\033|~{)') - WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') - ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', - 'iso-8859-2': 'Windows-1250', - 'iso-8859-5': 'Windows-1251', - 'iso-8859-6': 'Windows-1256', - 'iso-8859-7': 'Windows-1253', - 'iso-8859-8': 'Windows-1255', - 'iso-8859-9': 'Windows-1254', - 'iso-8859-13': 'Windows-1257'} - - def __init__(self, lang_filter=LanguageFilter.ALL): - self._esc_charset_prober = None - self._charset_probers = [] - self.result = None - self.done = None - self._got_data = None - self._input_state = None - self._last_char = None - self.lang_filter = lang_filter - self.logger = logging.getLogger(__name__) - self._has_win_bytes = None - self.reset() - - def reset(self): - """ - Reset the UniversalDetector and all of its probers back to their - initial states. This is called by ``__init__``, so you only need to - call this directly in between analyses of different documents. - """ - self.result = {'encoding': None, 'confidence': 0.0, 'language': None} - self.done = False - self._got_data = False - self._has_win_bytes = False - self._input_state = InputState.PURE_ASCII - self._last_char = b'' - if self._esc_charset_prober: - self._esc_charset_prober.reset() - for prober in self._charset_probers: - prober.reset() - - def feed(self, byte_str): - """ - Takes a chunk of a document and feeds it through all of the relevant - charset probers. - - After calling ``feed``, you can check the value of the ``done`` - attribute to see if you need to continue feeding the - ``UniversalDetector`` more data, or if it has made a prediction - (in the ``result`` attribute). - - .. note:: - You should always call ``close`` when you're done feeding in your - document if ``done`` is not already ``True``. - """ - if self.done: - return - - if not len(byte_str): - return - - if not isinstance(byte_str, bytearray): - byte_str = bytearray(byte_str) - - # First check for known BOMs, since these are guaranteed to be correct - if not self._got_data: - # If the data starts with BOM, we know it is UTF - if byte_str.startswith(codecs.BOM_UTF8): - # EF BB BF UTF-8 with BOM - self.result = {'encoding': "UTF-8-SIG", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith((codecs.BOM_UTF32_LE, - codecs.BOM_UTF32_BE)): - # FF FE 00 00 UTF-32, little-endian BOM - # 00 00 FE FF UTF-32, big-endian BOM - self.result = {'encoding': "UTF-32", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith(b'\xFE\xFF\x00\x00'): - # FE FF 00 00 UCS-4, unusual octet order BOM (3412) - self.result = {'encoding': "X-ISO-10646-UCS-4-3412", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith(b'\x00\x00\xFF\xFE'): - # 00 00 FF FE UCS-4, unusual octet order BOM (2143) - self.result = {'encoding': "X-ISO-10646-UCS-4-2143", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): - # FF FE UTF-16, little endian BOM - # FE FF UTF-16, big endian BOM - self.result = {'encoding': "UTF-16", - 'confidence': 1.0, - 'language': ''} - - self._got_data = True - if self.result['encoding'] is not None: - self.done = True - return - - # If none of those matched and we've only see ASCII so far, check - # for high bytes and escape sequences - if self._input_state == InputState.PURE_ASCII: - if self.HIGH_BYTE_DETECTOR.search(byte_str): - self._input_state = InputState.HIGH_BYTE - elif self._input_state == InputState.PURE_ASCII and \ - self.ESC_DETECTOR.search(self._last_char + byte_str): - self._input_state = InputState.ESC_ASCII - - self._last_char = byte_str[-1:] - - # If we've seen escape sequences, use the EscCharSetProber, which - # uses a simple state machine to check for known escape sequences in - # HZ and ISO-2022 encodings, since those are the only encodings that - # use such sequences. - if self._input_state == InputState.ESC_ASCII: - if not self._esc_charset_prober: - self._esc_charset_prober = EscCharSetProber(self.lang_filter) - if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: - self.result = {'encoding': - self._esc_charset_prober.charset_name, - 'confidence': - self._esc_charset_prober.get_confidence(), - 'language': - self._esc_charset_prober.language} - self.done = True - # If we've seen high bytes (i.e., those with values greater than 127), - # we need to do more complicated checks using all our multi-byte and - # single-byte probers that are left. The single-byte probers - # use character bigram distributions to determine the encoding, whereas - # the multi-byte probers use a combination of character unigram and - # bigram distributions. - elif self._input_state == InputState.HIGH_BYTE: - if not self._charset_probers: - self._charset_probers = [MBCSGroupProber(self.lang_filter)] - # If we're checking non-CJK encodings, use single-byte prober - if self.lang_filter & LanguageFilter.NON_CJK: - self._charset_probers.append(SBCSGroupProber()) - self._charset_probers.append(Latin1Prober()) - for prober in self._charset_probers: - if prober.feed(byte_str) == ProbingState.FOUND_IT: - self.result = {'encoding': prober.charset_name, - 'confidence': prober.get_confidence(), - 'language': prober.language} - self.done = True - break - if self.WIN_BYTE_DETECTOR.search(byte_str): - self._has_win_bytes = True - - def close(self): - """ - Stop analyzing the current document and come up with a final - prediction. - - :returns: The ``result`` attribute, a ``dict`` with the keys - `encoding`, `confidence`, and `language`. - """ - # Don't bother with checks if we're already done - if self.done: - return self.result - self.done = True - - if not self._got_data: - self.logger.debug('no data received!') - - # Default to ASCII if it is all we've seen so far - elif self._input_state == InputState.PURE_ASCII: - self.result = {'encoding': 'ascii', - 'confidence': 1.0, - 'language': ''} - - # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD - elif self._input_state == InputState.HIGH_BYTE: - prober_confidence = None - max_prober_confidence = 0.0 - max_prober = None - for prober in self._charset_probers: - if not prober: - continue - prober_confidence = prober.get_confidence() - if prober_confidence > max_prober_confidence: - max_prober_confidence = prober_confidence - max_prober = prober - if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): - charset_name = max_prober.charset_name - lower_charset_name = max_prober.charset_name.lower() - confidence = max_prober.get_confidence() - # Use Windows encoding name instead of ISO-8859 if we saw any - # extra Windows-specific bytes - if lower_charset_name.startswith('iso-8859'): - if self._has_win_bytes: - charset_name = self.ISO_WIN_MAP.get(lower_charset_name, - charset_name) - self.result = {'encoding': charset_name, - 'confidence': confidence, - 'language': max_prober.language} - - # Log all prober confidences if none met MINIMUM_THRESHOLD - if self.logger.getEffectiveLevel() <= logging.DEBUG: - if self.result['encoding'] is None: - self.logger.debug('no probers hit minimum threshold') - for group_prober in self._charset_probers: - if not group_prober: - continue - if isinstance(group_prober, CharSetGroupProber): - for prober in group_prober.probers: - self.logger.debug('%s %s confidence = %s', - prober.charset_name, - prober.language, - prober.get_confidence()) - else: - self.logger.debug('%s %s confidence = %s', - group_prober.charset_name, - group_prober.language, - group_prober.get_confidence()) - return self.result diff --git a/dist/ba_data/python-site-packages/chardet/utf8prober.py b/dist/ba_data/python-site-packages/chardet/utf8prober.py deleted file mode 100644 index 6c3196cc..00000000 --- a/dist/ba_data/python-site-packages/chardet/utf8prober.py +++ /dev/null @@ -1,82 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState, MachineState -from .codingstatemachine import CodingStateMachine -from .mbcssm import UTF8_SM_MODEL - - - -class UTF8Prober(CharSetProber): - ONE_CHAR_PROB = 0.5 - - def __init__(self): - super(UTF8Prober, self).__init__() - self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) - self._num_mb_chars = None - self.reset() - - def reset(self): - super(UTF8Prober, self).reset() - self.coding_sm.reset() - self._num_mb_chars = 0 - - @property - def charset_name(self): - return "utf-8" - - @property - def language(self): - return "" - - def feed(self, byte_str): - for c in byte_str: - coding_state = self.coding_sm.next_state(c) - if coding_state == MachineState.ERROR: - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - if self.coding_sm.get_current_charlen() >= 2: - self._num_mb_chars += 1 - - if self.state == ProbingState.DETECTING: - if self.get_confidence() > self.SHORTCUT_THRESHOLD: - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - unlike = 0.99 - if self._num_mb_chars < 6: - unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars - return 1.0 - unlike - else: - return unlike diff --git a/dist/ba_data/python-site-packages/chardet/version.py b/dist/ba_data/python-site-packages/chardet/version.py deleted file mode 100644 index 70369b9d..00000000 --- a/dist/ba_data/python-site-packages/chardet/version.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -This module exists only to simplify retrieving the version number of chardet -from within setup.py and from chardet subpackages. - -:author: Dan Blanchard (dan.blanchard@gmail.com) -""" - -__version__ = "4.0.0" -VERSION = __version__.split('.') diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/INSTALLER b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/LICENSE b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/LICENSE new file mode 100644 index 00000000..ad82355b --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 TAHRI Ahmed R. + +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. \ No newline at end of file diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/METADATA b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/METADATA new file mode 100644 index 00000000..822550e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/METADATA @@ -0,0 +1,683 @@ +Metadata-Version: 2.1 +Name: charset-normalizer +Version: 3.3.2 +Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet. +Home-page: https://github.com/Ousret/charset_normalizer +Author: Ahmed TAHRI +Author-email: ahmed.tahri@cloudnursery.dev +License: MIT +Project-URL: Bug Reports, https://github.com/Ousret/charset_normalizer/issues +Project-URL: Documentation, https://charset-normalizer.readthedocs.io/en/latest +Keywords: encoding,charset,charset-detector,detector,normalization,unicode,chardet,detect +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Text Processing :: Linguistic +Classifier: Topic :: Utilities +Classifier: Typing :: Typed +Requires-Python: >=3.7.0 +Description-Content-Type: text/markdown +License-File: LICENSE +Provides-Extra: unicode_backport + +

    Charset Detection, for Everyone 👋

    + +

    + The Real First Universal Charset Detector
    + + + + + Download Count Total + + + + +

    +

    + Featured Packages
    + + Static Badge + + + Static Badge + +

    +

    + In other language (unofficial port - by the community)
    + + Static Badge + +

    + +> A library that helps you read text from an unknown charset encoding.
    Motivated by `chardet`, +> I'm trying to resolve the issue by taking a new approach. +> All IANA character set names for which the Python core library provides codecs are supported. + +

    + >>>>> 👉 Try Me Online Now, Then Adopt Me 👈 <<<<< +

    + +This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**. + +| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) | +|--------------------------------------------------|:---------------------------------------------:|:--------------------------------------------------------------------------------------------------:|:-----------------------------------------------:| +| `Fast` | ❌ | ✅ | ✅ | +| `Universal**` | ❌ | ✅ | ❌ | +| `Reliable` **without** distinguishable standards | ❌ | ✅ | ✅ | +| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ | +| `License` | LGPL-2.1
    _restrictive_ | MIT | MPL-1.1
    _restrictive_ | +| `Native Python` | ✅ | ✅ | ❌ | +| `Detect spoken language` | ❌ | ✅ | N/A | +| `UnicodeDecodeError Safety` | ❌ | ✅ | ❌ | +| `Whl Size (min)` | 193.6 kB | 42 kB | ~200 kB | +| `Supported Encoding` | 33 | 🎉 [99](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40 | + +

    +Reading Normalized TextCat Reading Text +

    + +*\*\* : They are clearly using specific code for a specific encoding even if covering most of used one*
    +Did you got there because of the logs? See [https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html](https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html) + +## ⚡ Performance + +This package offer better performance than its counterpart Chardet. Here are some numbers. + +| Package | Accuracy | Mean per file (ms) | File per sec (est) | +|-----------------------------------------------|:--------:|:------------------:|:------------------:| +| [chardet](https://github.com/chardet/chardet) | 86 % | 200 ms | 5 file/sec | +| charset-normalizer | **98 %** | **10 ms** | 100 file/sec | + +| Package | 99th percentile | 95th percentile | 50th percentile | +|-----------------------------------------------|:---------------:|:---------------:|:---------------:| +| [chardet](https://github.com/chardet/chardet) | 1200 ms | 287 ms | 23 ms | +| charset-normalizer | 100 ms | 50 ms | 5 ms | + +Chardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload. + +> Stats are generated using 400+ files using default parameters. More details on used files, see GHA workflows. +> And yes, these results might change at any time. The dataset can be updated to include more files. +> The actual delays heavily depends on your CPU capabilities. The factors should remain the same. +> Keep in mind that the stats are generous and that Chardet accuracy vs our is measured using Chardet initial capability +> (eg. Supported Encoding) Challenge-them if you want. + +## ✨ Installation + +Using pip: + +```sh +pip install charset-normalizer -U +``` + +## 🚀 Basic Usage + +### CLI +This package comes with a CLI. + +``` +usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD] + file [file ...] + +The Real First Universal Charset Detector. Discover originating encoding used +on text file. Normalize text to unicode. + +positional arguments: + files File(s) to be analysed + +optional arguments: + -h, --help show this help message and exit + -v, --verbose Display complementary information about file if any. + Stdout will contain logs about the detection process. + -a, --with-alternative + Output complementary possibilities if any. Top-level + JSON WILL be a list. + -n, --normalize Permit to normalize input file. If not set, program + does not write anything. + -m, --minimal Only output the charset detected to STDOUT. Disabling + JSON output. + -r, --replace Replace file when trying to normalize it instead of + creating a new one. + -f, --force Replace file without asking if you are sure, use this + flag with caution. + -t THRESHOLD, --threshold THRESHOLD + Define a custom maximum amount of chaos allowed in + decoded content. 0. <= chaos <= 1. + --version Show version information and exit. +``` + +```bash +normalizer ./data/sample.1.fr.srt +``` + +or + +```bash +python -m charset_normalizer ./data/sample.1.fr.srt +``` + +🎉 Since version 1.4.0 the CLI produce easily usable stdout result in JSON format. + +```json +{ + "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt", + "encoding": "cp1252", + "encoding_aliases": [ + "1252", + "windows_1252" + ], + "alternative_encodings": [ + "cp1254", + "cp1256", + "cp1258", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + "mbcs" + ], + "language": "French", + "alphabets": [ + "Basic Latin", + "Latin-1 Supplement" + ], + "has_sig_or_bom": false, + "chaos": 0.149, + "coherence": 97.152, + "unicode_path": null, + "is_preferred": true +} +``` + +### Python +*Just print out normalized text* +```python +from charset_normalizer import from_path + +results = from_path('./my_subtitle.srt') + +print(str(results.best())) +``` + +*Upgrade your code without effort* +```python +from charset_normalizer import detect +``` + +The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible. + +See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/) + +## 😇 Why + +When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a +reliable alternative using a completely different method. Also! I never back down on a good challenge! + +I **don't care** about the **originating charset** encoding, because **two different tables** can +produce **two identical rendered string.** +What I want is to get readable text, the best I can. + +In a way, **I'm brute forcing text decoding.** How cool is that ? 😎 + +Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode. + +## 🍰 How + + - Discard all charset encoding table that could not fit the binary content. + - Measure noise, or the mess once opened (by chunks) with a corresponding charset encoding. + - Extract matches with the lowest mess detected. + - Additionally, we measure coherence / probe for a language. + +**Wait a minute**, what is noise/mess and coherence according to **YOU ?** + +*Noise :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then +**I established** some ground rules about **what is obvious** when **it seems like** a mess. + I know that my interpretation of what is noise is probably incomplete, feel free to contribute in order to + improve or rewrite it. + +*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought +that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design. + +## ⚡ Known limitations + + - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters)) + - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content. + +## ⚠️ About Python EOLs + +**If you are running:** + +- Python >=2.7,<3.5: Unsupported +- Python 3.5: charset-normalizer < 2.1 +- Python 3.6: charset-normalizer < 3.1 +- Python 3.7: charset-normalizer < 4.0 + +Upgrade your Python interpreter as soon as possible. + +## 👤 Contributing + +Contributions, issues and feature requests are very much welcome.
    +Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute. + +## 📝 License + +Copyright © [Ahmed TAHRI @Ousret](https://github.com/Ousret).
    +This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. + +Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/) + +## 💼 For Enterprise + +Professional support for charset-normalizer is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-charset-normalizer?utm_source=pypi-charset-normalizer&utm_medium=readme + +# Changelog +All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [3.3.2](https://github.com/Ousret/charset_normalizer/compare/3.3.1...3.3.2) (2023-10-31) + +### Fixed +- Unintentional memory usage regression when using large payload that match several encoding (#376) +- Regression on some detection case showcased in the documentation (#371) + +### Added +- Noise (md) probe that identify malformed arabic representation due to the presence of letters in isolated form (credit to my wife) + +## [3.3.1](https://github.com/Ousret/charset_normalizer/compare/3.3.0...3.3.1) (2023-10-22) + +### Changed +- Optional mypyc compilation upgraded to version 1.6.1 for Python >= 3.8 +- Improved the general detection reliability based on reports from the community + +## [3.3.0](https://github.com/Ousret/charset_normalizer/compare/3.2.0...3.3.0) (2023-09-30) + +### Added +- Allow to execute the CLI (e.g. normalizer) through `python -m charset_normalizer.cli` or `python -m charset_normalizer` +- Support for 9 forgotten encoding that are supported by Python but unlisted in `encoding.aliases` as they have no alias (#323) + +### Removed +- (internal) Redundant utils.is_ascii function and unused function is_private_use_only +- (internal) charset_normalizer.assets is moved inside charset_normalizer.constant + +### Changed +- (internal) Unicode code blocks in constants are updated using the latest v15.0.0 definition to improve detection +- Optional mypyc compilation upgraded to version 1.5.1 for Python >= 3.8 + +### Fixed +- Unable to properly sort CharsetMatch when both chaos/noise and coherence were close due to an unreachable condition in \_\_lt\_\_ (#350) + +## [3.2.0](https://github.com/Ousret/charset_normalizer/compare/3.1.0...3.2.0) (2023-06-07) + +### Changed +- Typehint for function `from_path` no longer enforce `PathLike` as its first argument +- Minor improvement over the global detection reliability + +### Added +- Introduce function `is_binary` that relies on main capabilities, and optimized to detect binaries +- Propagate `enable_fallback` argument throughout `from_bytes`, `from_path`, and `from_fp` that allow a deeper control over the detection (default True) +- Explicit support for Python 3.12 + +### Fixed +- Edge case detection failure where a file would contain 'very-long' camel cased word (Issue #289) + +## [3.1.0](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) (2023-03-06) + +### Added +- Argument `should_rename_legacy` for legacy function `detect` and disregard any new arguments without errors (PR #262) + +### Removed +- Support for Python 3.6 (PR #260) + +### Changed +- Optional speedup provided by mypy/c 1.0.1 + +## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18) + +### Fixed +- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233) + +### Changed +- Speedup provided by mypy/c 0.990 on Python >= 3.7 + +## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it +- Sphinx warnings when generating the documentation + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' + +## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21) + +### Added +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Removed +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) + +### Fixed +- Sphinx warnings when generating the documentation + +## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15) + +### Changed +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Removed +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19) + +### Deprecated +- Function `normalize` scheduled for removal in 3.0 + +### Changed +- Removed useless call to decode in fn is_unprintable (#206) + +### Fixed +- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204) + +## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19) + +### Added +- Output the Unicode table version when running the CLI with `--version` (PR #194) + +### Changed +- Re-use decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175) +- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183) + +### Fixed +- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175) +- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181) + +### Removed +- Support for Python 3.5 (PR #192) + +### Deprecated +- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194) + +## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12) + +### Fixed +- ASCII miss-detection on rare cases (PR #170) + +## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30) + +### Added +- Explicit support for Python 3.11 (PR #164) + +### Changed +- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165) + +## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04) + +### Fixed +- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154) + +### Changed +- Skipping the language-detection (CD) on ASCII (PR #155) + +## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03) + +### Changed +- Moderating the logging impact (since 2.0.8) for specific environments (PR #147) + +### Fixed +- Wrong logging level applied when setting kwarg `explain` to True (PR #146) + +## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24) +### Changed +- Improvement over Vietnamese detection (PR #126) +- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124) +- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122) +- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129) +- Code style as refactored by Sourcery-AI (PR #131) +- Minor adjustment on the MD around european words (PR #133) +- Remove and replace SRTs from assets / tests (PR #139) +- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135) + +### Fixed +- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137) +- Avoid using too insignificant chunk (PR #137) + +### Added +- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141) + +## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11) +### Added +- Add support for Kazakh (Cyrillic) language detection (PR #109) + +### Changed +- Further, improve inferring the language from a given single-byte code page (PR #112) +- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116) +- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113) +- Various detection improvement (MD+CD) (PR #117) + +### Removed +- Remove redundant logging entry about detected language(s) (PR #115) + +### Fixed +- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102) + +## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18) +### Fixed +- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100) +- Fix CLI crash when using --minimal output in certain cases (PR #103) + +### Changed +- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101) + +## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14) +### Changed +- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81) +- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82) +- The Unicode detection is slightly improved (PR #93) +- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91) + +### Removed +- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92) + +### Fixed +- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95) +- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96) +- The MANIFEST.in was not exhaustive (PR #78) + +## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30) +### Fixed +- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70) +- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68) +- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72) +- Submatch factoring could be wrong in rare edge cases (PR #72) +- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72) +- Fix line endings from CRLF to LF for certain project files (PR #67) + +### Changed +- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76) +- Allow fallback on specified encoding if any (PR #71) + +## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16) +### Changed +- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63) +- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64) + +## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15) +### Fixed +- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) + +### Changed +- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57) + +## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13) +### Fixed +- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55) +- Using explain=False permanently disable the verbose output in the current runtime (PR #47) +- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47) +- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52) + +### Changed +- Public function normalize default args values were not aligned with from_bytes (PR #53) + +### Added +- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47) + +## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02) +### Changed +- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet. +- Accent has been made on UTF-8 detection, should perform rather instantaneous. +- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible. +- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time) +- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+ +- utf_7 detection has been reinstated. + +### Removed +- This package no longer require anything when used with Python 3.5 (Dropped cached_property) +- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, Volapük, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian. +- The exception hook on UnicodeDecodeError has been removed. + +### Deprecated +- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0 + +### Fixed +- The CLI output used the relative path of the file(s). Should be absolute. + +## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28) +### Fixed +- Logger configuration/usage no longer conflict with others (PR #44) + +## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21) +### Removed +- Using standard logging instead of using the package loguru. +- Dropping nose test framework in favor of the maintained pytest. +- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text. +- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version. +- Stop support for UTF-7 that does not contain a SIG. +- Dropping PrettyTable, replaced with pure JSON output in CLI. + +### Fixed +- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process. +- Not searching properly for the BOM when trying utf32/16 parent codec. + +### Changed +- Improving the package final size by compressing frequencies.json. +- Huge improvement over the larges payload. + +### Added +- CLI now produces JSON consumable output. +- Return ASCII if given sequences fit. Given reasonable confidence. + +## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13) + +### Fixed +- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40) + +## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12) + +### Fixed +- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39) + +## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12) + +### Fixed +- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38) + +## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09) + +### Changed +- Amend the previous release to allow prettytable 2.0 (PR #35) + +## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08) + +### Fixed +- Fix error while using the package with a python pre-release interpreter (PR #33) + +### Changed +- Dependencies refactoring, constraints revised. + +### Added +- Add python 3.9 and 3.10 to the supported interpreters + +MIT License + +Copyright (c) 2019 TAHRI Ahmed R. + +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. diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/RECORD b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/RECORD new file mode 100644 index 00000000..4c867207 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/RECORD @@ -0,0 +1,35 @@ +../../bin/normalizer,sha256=6aG74SaxwG1KrkPqAr3EW34FjJKm9NfiL3Zc7LBZ0HE,236 +charset_normalizer-3.3.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +charset_normalizer-3.3.2.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070 +charset_normalizer-3.3.2.dist-info/METADATA,sha256=cfLhl5A6SI-F0oclm8w8ux9wshL1nipdeCdVnYb4AaA,33550 +charset_normalizer-3.3.2.dist-info/RECORD,, +charset_normalizer-3.3.2.dist-info/WHEEL,sha256=4ZiCdXIWMxJyEClivrQv1QAHZpQh8kVYU92_ZAVwaok,152 +charset_normalizer-3.3.2.dist-info/entry_points.txt,sha256=ADSTKrkXZ3hhdOVFi6DcUEHQRS0xfxDIE_pEz4wLIXA,65 +charset_normalizer-3.3.2.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 +charset_normalizer/__init__.py,sha256=UzI3xC8PhmcLRMzSgPb6minTmRq0kWznnCBJ8ZCc2XI,1577 +charset_normalizer/__main__.py,sha256=JxY8bleaENOFlLRb9HfoeZCzAMnn2A1oGR5Xm2eyqg0,73 +charset_normalizer/__pycache__/__init__.cpython-312.pyc,, +charset_normalizer/__pycache__/__main__.cpython-312.pyc,, +charset_normalizer/__pycache__/api.cpython-312.pyc,, +charset_normalizer/__pycache__/cd.cpython-312.pyc,, +charset_normalizer/__pycache__/constant.cpython-312.pyc,, +charset_normalizer/__pycache__/legacy.cpython-312.pyc,, +charset_normalizer/__pycache__/md.cpython-312.pyc,, +charset_normalizer/__pycache__/models.cpython-312.pyc,, +charset_normalizer/__pycache__/utils.cpython-312.pyc,, +charset_normalizer/__pycache__/version.cpython-312.pyc,, +charset_normalizer/api.py,sha256=WOlWjy6wT8SeMYFpaGbXZFN1TMXa-s8vZYfkL4G29iQ,21097 +charset_normalizer/cd.py,sha256=xwZliZcTQFA3jU0c00PRiu9MNxXTFxQkFLWmMW24ZzI,12560 +charset_normalizer/cli/__init__.py,sha256=D5ERp8P62llm2FuoMzydZ7d9rs8cvvLXqE-1_6oViPc,100 +charset_normalizer/cli/__main__.py,sha256=2F-xURZJzo063Ye-2RLJ2wcmURpbKeAzKwpiws65dAs,9744 +charset_normalizer/cli/__pycache__/__init__.cpython-312.pyc,, +charset_normalizer/cli/__pycache__/__main__.cpython-312.pyc,, +charset_normalizer/constant.py,sha256=p0IsOVcEbPWYPOdWhnhRbjK1YVBy6fs05C5vKC-zoxU,40481 +charset_normalizer/legacy.py,sha256=T-QuVMsMeDiQEk8WSszMrzVJg_14AMeSkmHdRYhdl1k,2071 +charset_normalizer/md.cpython-312-x86_64-linux-gnu.so,sha256=W654QTU3QZI6eWJ0fanScAr0_O6sL0I61fyRSdC-39Y,16064 +charset_normalizer/md.py,sha256=NkSuVLK13_a8c7BxZ4cGIQ5vOtGIWOdh22WZEvjp-7U,19624 +charset_normalizer/md__mypyc.cpython-312-x86_64-linux-gnu.so,sha256=IlObIV4dmRhFV8V7H-zK4rTxPzTSi9JmrWZD26JQfxI,272640 +charset_normalizer/models.py,sha256=I5i0s4aKCCgLPY2tUY3pwkgFA-BUbbNxQ7hVkVTt62s,11624 +charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/utils.py,sha256=teiosMqzKjXyAHXnGdjSBOgnBZwx-SkBbCLrx0UXy8M,11894 +charset_normalizer/version.py,sha256=iHKUfHD3kDRSyrh_BN2ojh43TA5-UZQjvbVIEFfpHDs,79 diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/WHEEL b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/WHEEL new file mode 100644 index 00000000..d1b3f1da --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: false +Tag: cp312-cp312-manylinux_2_17_x86_64 +Tag: cp312-cp312-manylinux2014_x86_64 + diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/entry_points.txt b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/entry_points.txt new file mode 100644 index 00000000..65619e73 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +normalizer = charset_normalizer.cli:cli_detect diff --git a/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/top_level.txt b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/top_level.txt new file mode 100644 index 00000000..66958f0a --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer-3.3.2.dist-info/top_level.txt @@ -0,0 +1 @@ +charset_normalizer diff --git a/dist/ba_data/python-site-packages/charset_normalizer/__init__.py b/dist/ba_data/python-site-packages/charset_normalizer/__init__.py new file mode 100644 index 00000000..55991fc3 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/__init__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +""" +Charset-Normalizer +~~~~~~~~~~~~~~ +The Real First Universal Charset Detector. +A library that helps you read text from an unknown charset encoding. +Motivated by chardet, This package is trying to resolve the issue by taking a new approach. +All IANA character set names for which the Python core library provides codecs are supported. + +Basic usage: + >>> from charset_normalizer import from_bytes + >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8')) + >>> best_guess = results.best() + >>> str(best_guess) + 'Bсеки човек има право на образование. Oбразованието!' + +Others methods and usages are available - see the full documentation +at . +:copyright: (c) 2021 by Ahmed TAHRI +:license: MIT, see LICENSE for more details. +""" +import logging + +from .api import from_bytes, from_fp, from_path, is_binary +from .legacy import detect +from .models import CharsetMatch, CharsetMatches +from .utils import set_logging_handler +from .version import VERSION, __version__ + +__all__ = ( + "from_fp", + "from_path", + "from_bytes", + "is_binary", + "detect", + "CharsetMatch", + "CharsetMatches", + "__version__", + "VERSION", + "set_logging_handler", +) + +# Attach a NullHandler to the top level logger by default +# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library + +logging.getLogger("charset_normalizer").addHandler(logging.NullHandler()) diff --git a/dist/ba_data/python-site-packages/charset_normalizer/__main__.py b/dist/ba_data/python-site-packages/charset_normalizer/__main__.py new file mode 100644 index 00000000..beae2ef7 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/__main__.py @@ -0,0 +1,4 @@ +from .cli import cli_detect + +if __name__ == "__main__": + cli_detect() diff --git a/dist/ba_data/python-site-packages/charset_normalizer/api.py b/dist/ba_data/python-site-packages/charset_normalizer/api.py new file mode 100644 index 00000000..0ba08e3a --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/api.py @@ -0,0 +1,626 @@ +import logging +from os import PathLike +from typing import BinaryIO, List, Optional, Set, Union + +from .cd import ( + coherence_ratio, + encoding_languages, + mb_encoding_languages, + merge_coherence_ratios, +) +from .constant import IANA_SUPPORTED, TOO_BIG_SEQUENCE, TOO_SMALL_SEQUENCE, TRACE +from .md import mess_ratio +from .models import CharsetMatch, CharsetMatches +from .utils import ( + any_specified_encoding, + cut_sequence_chunks, + iana_name, + identify_sig_or_bom, + is_cp_similar, + is_multi_byte_encoding, + should_strip_sig_or_bom, +) + +# Will most likely be controversial +# logging.addLevelName(TRACE, "TRACE") +logger = logging.getLogger("charset_normalizer") +explain_handler = logging.StreamHandler() +explain_handler.setFormatter( + logging.Formatter("%(asctime)s | %(levelname)s | %(message)s") +) + + +def from_bytes( + sequences: Union[bytes, bytearray], + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.2, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> CharsetMatches: + """ + Given a raw bytes sequence, return the best possibles charset usable to render str objects. + If there is no results, it is a strong indicator that the source is binary/not text. + By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. + And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. + + The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page + but never take it for granted. Can improve the performance. + + You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that + purpose. + + This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. + By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' + toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. + Custom logging format and handler can be set manually. + """ + + if not isinstance(sequences, (bytearray, bytes)): + raise TypeError( + "Expected object of type bytes or bytearray, got: {0}".format( + type(sequences) + ) + ) + + if explain: + previous_logger_level: int = logger.level + logger.addHandler(explain_handler) + logger.setLevel(TRACE) + + length: int = len(sequences) + + if length == 0: + logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.") + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level or logging.WARNING) + return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) + + if cp_isolation is not None: + logger.log( + TRACE, + "cp_isolation is set. use this flag for debugging purpose. " + "limited list of encoding allowed : %s.", + ", ".join(cp_isolation), + ) + cp_isolation = [iana_name(cp, False) for cp in cp_isolation] + else: + cp_isolation = [] + + if cp_exclusion is not None: + logger.log( + TRACE, + "cp_exclusion is set. use this flag for debugging purpose. " + "limited list of encoding excluded : %s.", + ", ".join(cp_exclusion), + ) + cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] + else: + cp_exclusion = [] + + if length <= (chunk_size * steps): + logger.log( + TRACE, + "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", + steps, + chunk_size, + length, + ) + steps = 1 + chunk_size = length + + if steps > 1 and length / steps < chunk_size: + chunk_size = int(length / steps) + + is_too_small_sequence: bool = len(sequences) < TOO_SMALL_SEQUENCE + is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE + + if is_too_small_sequence: + logger.log( + TRACE, + "Trying to detect encoding from a tiny portion of ({}) byte(s).".format( + length + ), + ) + elif is_too_large_sequence: + logger.log( + TRACE, + "Using lazy str decoding because the payload is quite large, ({}) byte(s).".format( + length + ), + ) + + prioritized_encodings: List[str] = [] + + specified_encoding: Optional[str] = ( + any_specified_encoding(sequences) if preemptive_behaviour else None + ) + + if specified_encoding is not None: + prioritized_encodings.append(specified_encoding) + logger.log( + TRACE, + "Detected declarative mark in sequence. Priority +1 given for %s.", + specified_encoding, + ) + + tested: Set[str] = set() + tested_but_hard_failure: List[str] = [] + tested_but_soft_failure: List[str] = [] + + fallback_ascii: Optional[CharsetMatch] = None + fallback_u8: Optional[CharsetMatch] = None + fallback_specified: Optional[CharsetMatch] = None + + results: CharsetMatches = CharsetMatches() + + sig_encoding, sig_payload = identify_sig_or_bom(sequences) + + if sig_encoding is not None: + prioritized_encodings.append(sig_encoding) + logger.log( + TRACE, + "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", + len(sig_payload), + sig_encoding, + ) + + prioritized_encodings.append("ascii") + + if "utf_8" not in prioritized_encodings: + prioritized_encodings.append("utf_8") + + for encoding_iana in prioritized_encodings + IANA_SUPPORTED: + if cp_isolation and encoding_iana not in cp_isolation: + continue + + if cp_exclusion and encoding_iana in cp_exclusion: + continue + + if encoding_iana in tested: + continue + + tested.add(encoding_iana) + + decoded_payload: Optional[str] = None + bom_or_sig_available: bool = sig_encoding == encoding_iana + strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom( + encoding_iana + ) + + if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", + encoding_iana, + ) + continue + if encoding_iana in {"utf_7"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.", + encoding_iana, + ) + continue + + try: + is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana) + except (ModuleNotFoundError, ImportError): + logger.log( + TRACE, + "Encoding %s does not provide an IncrementalDecoder", + encoding_iana, + ) + continue + + try: + if is_too_large_sequence and is_multi_byte_decoder is False: + str( + sequences[: int(50e4)] + if strip_sig_or_bom is False + else sequences[len(sig_payload) : int(50e4)], + encoding=encoding_iana, + ) + else: + decoded_payload = str( + sequences + if strip_sig_or_bom is False + else sequences[len(sig_payload) :], + encoding=encoding_iana, + ) + except (UnicodeDecodeError, LookupError) as e: + if not isinstance(e, LookupError): + logger.log( + TRACE, + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + similar_soft_failure_test: bool = False + + for encoding_soft_failed in tested_but_soft_failure: + if is_cp_similar(encoding_iana, encoding_soft_failed): + similar_soft_failure_test = True + break + + if similar_soft_failure_test: + logger.log( + TRACE, + "%s is deemed too similar to code page %s and was consider unsuited already. Continuing!", + encoding_iana, + encoding_soft_failed, + ) + continue + + r_ = range( + 0 if not bom_or_sig_available else len(sig_payload), + length, + int(length / steps), + ) + + multi_byte_bonus: bool = ( + is_multi_byte_decoder + and decoded_payload is not None + and len(decoded_payload) < length + ) + + if multi_byte_bonus: + logger.log( + TRACE, + "Code page %s is a multi byte encoding table and it appear that at least one character " + "was encoded using n-bytes.", + encoding_iana, + ) + + max_chunk_gave_up: int = int(len(r_) / 4) + + max_chunk_gave_up = max(max_chunk_gave_up, 2) + early_stop_count: int = 0 + lazy_str_hard_failure = False + + md_chunks: List[str] = [] + md_ratios = [] + + try: + for chunk in cut_sequence_chunks( + sequences, + encoding_iana, + r_, + chunk_size, + bom_or_sig_available, + strip_sig_or_bom, + sig_payload, + is_multi_byte_decoder, + decoded_payload, + ): + md_chunks.append(chunk) + + md_ratios.append( + mess_ratio( + chunk, + threshold, + explain is True and 1 <= len(cp_isolation) <= 2, + ) + ) + + if md_ratios[-1] >= threshold: + early_stop_count += 1 + + if (early_stop_count >= max_chunk_gave_up) or ( + bom_or_sig_available and strip_sig_or_bom is False + ): + break + except ( + UnicodeDecodeError + ) as e: # Lazy str loading may have missed something there + logger.log( + TRACE, + "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + early_stop_count = max_chunk_gave_up + lazy_str_hard_failure = True + + # We might want to check the sequence again with the whole content + # Only if initial MD tests passes + if ( + not lazy_str_hard_failure + and is_too_large_sequence + and not is_multi_byte_decoder + ): + try: + sequences[int(50e3) :].decode(encoding_iana, errors="strict") + except UnicodeDecodeError as e: + logger.log( + TRACE, + "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 + if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: + tested_but_soft_failure.append(encoding_iana) + logger.log( + TRACE, + "%s was excluded because of initial chaos probing. Gave up %i time(s). " + "Computed mean chaos is %f %%.", + encoding_iana, + early_stop_count, + round(mean_mess_ratio * 100, ndigits=3), + ) + # Preparing those fallbacks in case we got nothing. + if ( + enable_fallback + and encoding_iana in ["ascii", "utf_8", specified_encoding] + and not lazy_str_hard_failure + ): + fallback_entry = CharsetMatch( + sequences, encoding_iana, threshold, False, [], decoded_payload + ) + if encoding_iana == specified_encoding: + fallback_specified = fallback_entry + elif encoding_iana == "ascii": + fallback_ascii = fallback_entry + else: + fallback_u8 = fallback_entry + continue + + logger.log( + TRACE, + "%s passed initial chaos probing. Mean measured chaos is %f %%", + encoding_iana, + round(mean_mess_ratio * 100, ndigits=3), + ) + + if not is_multi_byte_decoder: + target_languages: List[str] = encoding_languages(encoding_iana) + else: + target_languages = mb_encoding_languages(encoding_iana) + + if target_languages: + logger.log( + TRACE, + "{} should target any language(s) of {}".format( + encoding_iana, str(target_languages) + ), + ) + + cd_ratios = [] + + # We shall skip the CD when its about ASCII + # Most of the time its not relevant to run "language-detection" on it. + if encoding_iana != "ascii": + for chunk in md_chunks: + chunk_languages = coherence_ratio( + chunk, + language_threshold, + ",".join(target_languages) if target_languages else None, + ) + + cd_ratios.append(chunk_languages) + + cd_ratios_merged = merge_coherence_ratios(cd_ratios) + + if cd_ratios_merged: + logger.log( + TRACE, + "We detected language {} using {}".format( + cd_ratios_merged, encoding_iana + ), + ) + + results.append( + CharsetMatch( + sequences, + encoding_iana, + mean_mess_ratio, + bom_or_sig_available, + cd_ratios_merged, + decoded_payload, + ) + ) + + if ( + encoding_iana in [specified_encoding, "ascii", "utf_8"] + and mean_mess_ratio < 0.1 + ): + logger.debug( + "Encoding detection: %s is most likely the one.", encoding_iana + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if encoding_iana == sig_encoding: + logger.debug( + "Encoding detection: %s is most likely the one as we detected a BOM or SIG within " + "the beginning of the sequence.", + encoding_iana, + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if len(results) == 0: + if fallback_u8 or fallback_ascii or fallback_specified: + logger.log( + TRACE, + "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.", + ) + + if fallback_specified: + logger.debug( + "Encoding detection: %s will be used as a fallback match", + fallback_specified.encoding, + ) + results.append(fallback_specified) + elif ( + (fallback_u8 and fallback_ascii is None) + or ( + fallback_u8 + and fallback_ascii + and fallback_u8.fingerprint != fallback_ascii.fingerprint + ) + or (fallback_u8 is not None) + ): + logger.debug("Encoding detection: utf_8 will be used as a fallback match") + results.append(fallback_u8) + elif fallback_ascii: + logger.debug("Encoding detection: ascii will be used as a fallback match") + results.append(fallback_ascii) + + if results: + logger.debug( + "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.", + results.best().encoding, # type: ignore + len(results) - 1, + ) + else: + logger.debug("Encoding detection: Unable to determine any suitable charset.") + + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + + return results + + +def from_fp( + fp: BinaryIO, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but using a file pointer that is already ready. + Will not close the file pointer. + """ + return from_bytes( + fp.read(), + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + enable_fallback, + ) + + +def from_path( + path: Union[str, bytes, PathLike], # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. + Can raise IOError. + """ + with open(path, "rb") as fp: + return from_fp( + fp, + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + enable_fallback, + ) + + +def is_binary( + fp_or_path_or_payload: Union[PathLike, str, BinaryIO, bytes], # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = False, +) -> bool: + """ + Detect if the given input (file, bytes, or path) points to a binary file. aka. not a string. + Based on the same main heuristic algorithms and default kwargs at the sole exception that fallbacks match + are disabled to be stricter around ASCII-compatible but unlikely to be a string. + """ + if isinstance(fp_or_path_or_payload, (str, PathLike)): + guesses = from_path( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + elif isinstance( + fp_or_path_or_payload, + ( + bytes, + bytearray, + ), + ): + guesses = from_bytes( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + else: + guesses = from_fp( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + + return not guesses diff --git a/dist/ba_data/python-site-packages/charset_normalizer/cd.py b/dist/ba_data/python-site-packages/charset_normalizer/cd.py new file mode 100644 index 00000000..4ea6760c --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/cd.py @@ -0,0 +1,395 @@ +import importlib +from codecs import IncrementalDecoder +from collections import Counter +from functools import lru_cache +from typing import Counter as TypeCounter, Dict, List, Optional, Tuple + +from .constant import ( + FREQUENCIES, + KO_NAMES, + LANGUAGE_SUPPORTED_COUNT, + TOO_SMALL_SEQUENCE, + ZH_NAMES, +) +from .md import is_suspiciously_successive_range +from .models import CoherenceMatches +from .utils import ( + is_accentuated, + is_latin, + is_multi_byte_encoding, + is_unicode_range_secondary, + unicode_range, +) + + +def encoding_unicode_range(iana_name: str) -> List[str]: + """ + Return associated unicode ranges in a single byte code page. + """ + if is_multi_byte_encoding(iana_name): + raise IOError("Function not supported on multi-byte code page") + + decoder = importlib.import_module( + "encodings.{}".format(iana_name) + ).IncrementalDecoder + + p: IncrementalDecoder = decoder(errors="ignore") + seen_ranges: Dict[str, int] = {} + character_count: int = 0 + + for i in range(0x40, 0xFF): + chunk: str = p.decode(bytes([i])) + + if chunk: + character_range: Optional[str] = unicode_range(chunk) + + if character_range is None: + continue + + if is_unicode_range_secondary(character_range) is False: + if character_range not in seen_ranges: + seen_ranges[character_range] = 0 + seen_ranges[character_range] += 1 + character_count += 1 + + return sorted( + [ + character_range + for character_range in seen_ranges + if seen_ranges[character_range] / character_count >= 0.15 + ] + ) + + +def unicode_range_languages(primary_range: str) -> List[str]: + """ + Return inferred languages used with a unicode range. + """ + languages: List[str] = [] + + for language, characters in FREQUENCIES.items(): + for character in characters: + if unicode_range(character) == primary_range: + languages.append(language) + break + + return languages + + +@lru_cache() +def encoding_languages(iana_name: str) -> List[str]: + """ + Single-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + unicode_ranges: List[str] = encoding_unicode_range(iana_name) + primary_range: Optional[str] = None + + for specified_range in unicode_ranges: + if "Latin" not in specified_range: + primary_range = specified_range + break + + if primary_range is None: + return ["Latin Based"] + + return unicode_range_languages(primary_range) + + +@lru_cache() +def mb_encoding_languages(iana_name: str) -> List[str]: + """ + Multi-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + if ( + iana_name.startswith("shift_") + or iana_name.startswith("iso2022_jp") + or iana_name.startswith("euc_j") + or iana_name == "cp932" + ): + return ["Japanese"] + if iana_name.startswith("gb") or iana_name in ZH_NAMES: + return ["Chinese"] + if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES: + return ["Korean"] + + return [] + + +@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT) +def get_target_features(language: str) -> Tuple[bool, bool]: + """ + Determine main aspects from a supported language if it contains accents and if is pure Latin. + """ + target_have_accents: bool = False + target_pure_latin: bool = True + + for character in FREQUENCIES[language]: + if not target_have_accents and is_accentuated(character): + target_have_accents = True + if target_pure_latin and is_latin(character) is False: + target_pure_latin = False + + return target_have_accents, target_pure_latin + + +def alphabet_languages( + characters: List[str], ignore_non_latin: bool = False +) -> List[str]: + """ + Return associated languages associated to given characters. + """ + languages: List[Tuple[str, float]] = [] + + source_have_accents = any(is_accentuated(character) for character in characters) + + for language, language_characters in FREQUENCIES.items(): + target_have_accents, target_pure_latin = get_target_features(language) + + if ignore_non_latin and target_pure_latin is False: + continue + + if target_have_accents is False and source_have_accents: + continue + + character_count: int = len(language_characters) + + character_match_count: int = len( + [c for c in language_characters if c in characters] + ) + + ratio: float = character_match_count / character_count + + if ratio >= 0.2: + languages.append((language, ratio)) + + languages = sorted(languages, key=lambda x: x[1], reverse=True) + + return [compatible_language[0] for compatible_language in languages] + + +def characters_popularity_compare( + language: str, ordered_characters: List[str] +) -> float: + """ + Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. + The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). + Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.) + """ + if language not in FREQUENCIES: + raise ValueError("{} not available".format(language)) + + character_approved_count: int = 0 + FREQUENCIES_language_set = set(FREQUENCIES[language]) + + ordered_characters_count: int = len(ordered_characters) + target_language_characters_count: int = len(FREQUENCIES[language]) + + large_alphabet: bool = target_language_characters_count > 26 + + for character, character_rank in zip( + ordered_characters, range(0, ordered_characters_count) + ): + if character not in FREQUENCIES_language_set: + continue + + character_rank_in_language: int = FREQUENCIES[language].index(character) + expected_projection_ratio: float = ( + target_language_characters_count / ordered_characters_count + ) + character_rank_projection: int = int(character_rank * expected_projection_ratio) + + if ( + large_alphabet is False + and abs(character_rank_projection - character_rank_in_language) > 4 + ): + continue + + if ( + large_alphabet is True + and abs(character_rank_projection - character_rank_in_language) + < target_language_characters_count / 3 + ): + character_approved_count += 1 + continue + + characters_before_source: List[str] = FREQUENCIES[language][ + 0:character_rank_in_language + ] + characters_after_source: List[str] = FREQUENCIES[language][ + character_rank_in_language: + ] + characters_before: List[str] = ordered_characters[0:character_rank] + characters_after: List[str] = ordered_characters[character_rank:] + + before_match_count: int = len( + set(characters_before) & set(characters_before_source) + ) + + after_match_count: int = len( + set(characters_after) & set(characters_after_source) + ) + + if len(characters_before_source) == 0 and before_match_count <= 4: + character_approved_count += 1 + continue + + if len(characters_after_source) == 0 and after_match_count <= 4: + character_approved_count += 1 + continue + + if ( + before_match_count / len(characters_before_source) >= 0.4 + or after_match_count / len(characters_after_source) >= 0.4 + ): + character_approved_count += 1 + continue + + return character_approved_count / len(ordered_characters) + + +def alpha_unicode_split(decoded_sequence: str) -> List[str]: + """ + Given a decoded text sequence, return a list of str. Unicode range / alphabet separation. + Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list; + One containing the latin letters and the other hebrew. + """ + layers: Dict[str, str] = {} + + for character in decoded_sequence: + if character.isalpha() is False: + continue + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + layer_target_range: Optional[str] = None + + for discovered_range in layers: + if ( + is_suspiciously_successive_range(discovered_range, character_range) + is False + ): + layer_target_range = discovered_range + break + + if layer_target_range is None: + layer_target_range = character_range + + if layer_target_range not in layers: + layers[layer_target_range] = character.lower() + continue + + layers[layer_target_range] += character.lower() + + return list(layers.values()) + + +def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches: + """ + This function merge results previously given by the function coherence_ratio. + The return type is the same as coherence_ratio. + """ + per_language_ratios: Dict[str, List[float]] = {} + for result in results: + for sub_result in result: + language, ratio = sub_result + if language not in per_language_ratios: + per_language_ratios[language] = [ratio] + continue + per_language_ratios[language].append(ratio) + + merge = [ + ( + language, + round( + sum(per_language_ratios[language]) / len(per_language_ratios[language]), + 4, + ), + ) + for language in per_language_ratios + ] + + return sorted(merge, key=lambda x: x[1], reverse=True) + + +def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches: + """ + We shall NOT return "English—" in CoherenceMatches because it is an alternative + of "English". This function only keeps the best match and remove the em-dash in it. + """ + index_results: Dict[str, List[float]] = dict() + + for result in results: + language, ratio = result + no_em_name: str = language.replace("—", "") + + if no_em_name not in index_results: + index_results[no_em_name] = [] + + index_results[no_em_name].append(ratio) + + if any(len(index_results[e]) > 1 for e in index_results): + filtered_results: CoherenceMatches = [] + + for language in index_results: + filtered_results.append((language, max(index_results[language]))) + + return filtered_results + + return results + + +@lru_cache(maxsize=2048) +def coherence_ratio( + decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None +) -> CoherenceMatches: + """ + Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. + A layer = Character extraction by alphabets/ranges. + """ + + results: List[Tuple[str, float]] = [] + ignore_non_latin: bool = False + + sufficient_match_count: int = 0 + + lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else [] + if "Latin Based" in lg_inclusion_list: + ignore_non_latin = True + lg_inclusion_list.remove("Latin Based") + + for layer in alpha_unicode_split(decoded_sequence): + sequence_frequencies: TypeCounter[str] = Counter(layer) + most_common = sequence_frequencies.most_common() + + character_count: int = sum(o for c, o in most_common) + + if character_count <= TOO_SMALL_SEQUENCE: + continue + + popular_character_ordered: List[str] = [c for c, o in most_common] + + for language in lg_inclusion_list or alphabet_languages( + popular_character_ordered, ignore_non_latin + ): + ratio: float = characters_popularity_compare( + language, popular_character_ordered + ) + + if ratio < threshold: + continue + elif ratio >= 0.8: + sufficient_match_count += 1 + + results.append((language, round(ratio, 4))) + + if sufficient_match_count >= 3: + break + + return sorted( + filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True + ) diff --git a/dist/ba_data/python-site-packages/charset_normalizer/cli/__init__.py b/dist/ba_data/python-site-packages/charset_normalizer/cli/__init__.py new file mode 100644 index 00000000..d95fedfe --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/cli/__init__.py @@ -0,0 +1,6 @@ +from .__main__ import cli_detect, query_yes_no + +__all__ = ( + "cli_detect", + "query_yes_no", +) diff --git a/dist/ba_data/python-site-packages/charset_normalizer/cli/__main__.py b/dist/ba_data/python-site-packages/charset_normalizer/cli/__main__.py new file mode 100644 index 00000000..f4bcbaac --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/cli/__main__.py @@ -0,0 +1,296 @@ +import argparse +import sys +from json import dumps +from os.path import abspath, basename, dirname, join, realpath +from platform import python_version +from typing import List, Optional +from unicodedata import unidata_version + +import charset_normalizer.md as md_module +from charset_normalizer import from_fp +from charset_normalizer.models import CliDetectionResult +from charset_normalizer.version import __version__ + + +def query_yes_no(question: str, default: str = "yes") -> bool: + """Ask a yes/no question via input() and return their answer. + + "question" is a string that is presented to the user. + "default" is the presumed answer if the user just hits . + It must be "yes" (the default), "no" or None (meaning + an answer is required of the user). + + The "answer" return value is True for "yes" or False for "no". + + Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input + """ + valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} + if default is None: + prompt = " [y/n] " + elif default == "yes": + prompt = " [Y/n] " + elif default == "no": + prompt = " [y/N] " + else: + raise ValueError("invalid default answer: '%s'" % default) + + while True: + sys.stdout.write(question + prompt) + choice = input().lower() + if default is not None and choice == "": + return valid[default] + elif choice in valid: + return valid[choice] + else: + sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") + + +def cli_detect(argv: Optional[List[str]] = None) -> int: + """ + CLI assistant using ARGV and ArgumentParser + :param argv: + :return: 0 if everything is fine, anything else equal trouble + """ + parser = argparse.ArgumentParser( + description="The Real First Universal Charset Detector. " + "Discover originating encoding used on text file. " + "Normalize text to unicode." + ) + + parser.add_argument( + "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed" + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + default=False, + dest="verbose", + help="Display complementary information about file if any. " + "Stdout will contain logs about the detection process.", + ) + parser.add_argument( + "-a", + "--with-alternative", + action="store_true", + default=False, + dest="alternatives", + help="Output complementary possibilities if any. Top-level JSON WILL be a list.", + ) + parser.add_argument( + "-n", + "--normalize", + action="store_true", + default=False, + dest="normalize", + help="Permit to normalize input file. If not set, program does not write anything.", + ) + parser.add_argument( + "-m", + "--minimal", + action="store_true", + default=False, + dest="minimal", + help="Only output the charset detected to STDOUT. Disabling JSON output.", + ) + parser.add_argument( + "-r", + "--replace", + action="store_true", + default=False, + dest="replace", + help="Replace file when trying to normalize it instead of creating a new one.", + ) + parser.add_argument( + "-f", + "--force", + action="store_true", + default=False, + dest="force", + help="Replace file without asking if you are sure, use this flag with caution.", + ) + parser.add_argument( + "-t", + "--threshold", + action="store", + default=0.2, + type=float, + dest="threshold", + help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.", + ) + parser.add_argument( + "--version", + action="version", + version="Charset-Normalizer {} - Python {} - Unicode {} - SpeedUp {}".format( + __version__, + python_version(), + unidata_version, + "OFF" if md_module.__file__.lower().endswith(".py") else "ON", + ), + help="Show version information and exit.", + ) + + args = parser.parse_args(argv) + + if args.replace is True and args.normalize is False: + print("Use --replace in addition of --normalize only.", file=sys.stderr) + return 1 + + if args.force is True and args.replace is False: + print("Use --force in addition of --replace only.", file=sys.stderr) + return 1 + + if args.threshold < 0.0 or args.threshold > 1.0: + print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr) + return 1 + + x_ = [] + + for my_file in args.files: + matches = from_fp(my_file, threshold=args.threshold, explain=args.verbose) + + best_guess = matches.best() + + if best_guess is None: + print( + 'Unable to identify originating encoding for "{}". {}'.format( + my_file.name, + "Maybe try increasing maximum amount of chaos." + if args.threshold < 1.0 + else "", + ), + file=sys.stderr, + ) + x_.append( + CliDetectionResult( + abspath(my_file.name), + None, + [], + [], + "Unknown", + [], + False, + 1.0, + 0.0, + None, + True, + ) + ) + else: + x_.append( + CliDetectionResult( + abspath(my_file.name), + best_guess.encoding, + best_guess.encoding_aliases, + [ + cp + for cp in best_guess.could_be_from_charset + if cp != best_guess.encoding + ], + best_guess.language, + best_guess.alphabets, + best_guess.bom, + best_guess.percent_chaos, + best_guess.percent_coherence, + None, + True, + ) + ) + + if len(matches) > 1 and args.alternatives: + for el in matches: + if el != best_guess: + x_.append( + CliDetectionResult( + abspath(my_file.name), + el.encoding, + el.encoding_aliases, + [ + cp + for cp in el.could_be_from_charset + if cp != el.encoding + ], + el.language, + el.alphabets, + el.bom, + el.percent_chaos, + el.percent_coherence, + None, + False, + ) + ) + + if args.normalize is True: + if best_guess.encoding.startswith("utf") is True: + print( + '"{}" file does not need to be normalized, as it already came from unicode.'.format( + my_file.name + ), + file=sys.stderr, + ) + if my_file.closed is False: + my_file.close() + continue + + dir_path = dirname(realpath(my_file.name)) + file_name = basename(realpath(my_file.name)) + + o_: List[str] = file_name.split(".") + + if args.replace is False: + o_.insert(-1, best_guess.encoding) + if my_file.closed is False: + my_file.close() + elif ( + args.force is False + and query_yes_no( + 'Are you sure to normalize "{}" by replacing it ?'.format( + my_file.name + ), + "no", + ) + is False + ): + if my_file.closed is False: + my_file.close() + continue + + try: + x_[0].unicode_path = join(dir_path, ".".join(o_)) + + with open(x_[0].unicode_path, "w", encoding="utf-8") as fp: + fp.write(str(best_guess)) + except IOError as e: + print(str(e), file=sys.stderr) + if my_file.closed is False: + my_file.close() + return 2 + + if my_file.closed is False: + my_file.close() + + if args.minimal is False: + print( + dumps( + [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__, + ensure_ascii=True, + indent=4, + ) + ) + else: + for my_file in args.files: + print( + ", ".join( + [ + el.encoding or "undefined" + for el in x_ + if el.path == abspath(my_file.name) + ] + ) + ) + + return 0 + + +if __name__ == "__main__": + cli_detect() diff --git a/dist/ba_data/python-site-packages/charset_normalizer/constant.py b/dist/ba_data/python-site-packages/charset_normalizer/constant.py new file mode 100644 index 00000000..86349046 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/constant.py @@ -0,0 +1,1995 @@ +# -*- coding: utf-8 -*- +from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE +from encodings.aliases import aliases +from re import IGNORECASE, compile as re_compile +from typing import Dict, List, Set, Union + +# Contain for each eligible encoding a list of/item bytes SIG/BOM +ENCODING_MARKS: Dict[str, Union[bytes, List[bytes]]] = { + "utf_8": BOM_UTF8, + "utf_7": [ + b"\x2b\x2f\x76\x38", + b"\x2b\x2f\x76\x39", + b"\x2b\x2f\x76\x2b", + b"\x2b\x2f\x76\x2f", + b"\x2b\x2f\x76\x38\x2d", + ], + "gb18030": b"\x84\x31\x95\x33", + "utf_32": [BOM_UTF32_BE, BOM_UTF32_LE], + "utf_16": [BOM_UTF16_BE, BOM_UTF16_LE], +} + +TOO_SMALL_SEQUENCE: int = 32 +TOO_BIG_SEQUENCE: int = int(10e6) + +UTF8_MAXIMAL_ALLOCATION: int = 1_112_064 + +# Up-to-date Unicode ucd/15.0.0 +UNICODE_RANGES_COMBINED: Dict[str, range] = { + "Control character": range(32), + "Basic Latin": range(32, 128), + "Latin-1 Supplement": range(128, 256), + "Latin Extended-A": range(256, 384), + "Latin Extended-B": range(384, 592), + "IPA Extensions": range(592, 688), + "Spacing Modifier Letters": range(688, 768), + "Combining Diacritical Marks": range(768, 880), + "Greek and Coptic": range(880, 1024), + "Cyrillic": range(1024, 1280), + "Cyrillic Supplement": range(1280, 1328), + "Armenian": range(1328, 1424), + "Hebrew": range(1424, 1536), + "Arabic": range(1536, 1792), + "Syriac": range(1792, 1872), + "Arabic Supplement": range(1872, 1920), + "Thaana": range(1920, 1984), + "NKo": range(1984, 2048), + "Samaritan": range(2048, 2112), + "Mandaic": range(2112, 2144), + "Syriac Supplement": range(2144, 2160), + "Arabic Extended-B": range(2160, 2208), + "Arabic Extended-A": range(2208, 2304), + "Devanagari": range(2304, 2432), + "Bengali": range(2432, 2560), + "Gurmukhi": range(2560, 2688), + "Gujarati": range(2688, 2816), + "Oriya": range(2816, 2944), + "Tamil": range(2944, 3072), + "Telugu": range(3072, 3200), + "Kannada": range(3200, 3328), + "Malayalam": range(3328, 3456), + "Sinhala": range(3456, 3584), + "Thai": range(3584, 3712), + "Lao": range(3712, 3840), + "Tibetan": range(3840, 4096), + "Myanmar": range(4096, 4256), + "Georgian": range(4256, 4352), + "Hangul Jamo": range(4352, 4608), + "Ethiopic": range(4608, 4992), + "Ethiopic Supplement": range(4992, 5024), + "Cherokee": range(5024, 5120), + "Unified Canadian Aboriginal Syllabics": range(5120, 5760), + "Ogham": range(5760, 5792), + "Runic": range(5792, 5888), + "Tagalog": range(5888, 5920), + "Hanunoo": range(5920, 5952), + "Buhid": range(5952, 5984), + "Tagbanwa": range(5984, 6016), + "Khmer": range(6016, 6144), + "Mongolian": range(6144, 6320), + "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6400), + "Limbu": range(6400, 6480), + "Tai Le": range(6480, 6528), + "New Tai Lue": range(6528, 6624), + "Khmer Symbols": range(6624, 6656), + "Buginese": range(6656, 6688), + "Tai Tham": range(6688, 6832), + "Combining Diacritical Marks Extended": range(6832, 6912), + "Balinese": range(6912, 7040), + "Sundanese": range(7040, 7104), + "Batak": range(7104, 7168), + "Lepcha": range(7168, 7248), + "Ol Chiki": range(7248, 7296), + "Cyrillic Extended-C": range(7296, 7312), + "Georgian Extended": range(7312, 7360), + "Sundanese Supplement": range(7360, 7376), + "Vedic Extensions": range(7376, 7424), + "Phonetic Extensions": range(7424, 7552), + "Phonetic Extensions Supplement": range(7552, 7616), + "Combining Diacritical Marks Supplement": range(7616, 7680), + "Latin Extended Additional": range(7680, 7936), + "Greek Extended": range(7936, 8192), + "General Punctuation": range(8192, 8304), + "Superscripts and Subscripts": range(8304, 8352), + "Currency Symbols": range(8352, 8400), + "Combining Diacritical Marks for Symbols": range(8400, 8448), + "Letterlike Symbols": range(8448, 8528), + "Number Forms": range(8528, 8592), + "Arrows": range(8592, 8704), + "Mathematical Operators": range(8704, 8960), + "Miscellaneous Technical": range(8960, 9216), + "Control Pictures": range(9216, 9280), + "Optical Character Recognition": range(9280, 9312), + "Enclosed Alphanumerics": range(9312, 9472), + "Box Drawing": range(9472, 9600), + "Block Elements": range(9600, 9632), + "Geometric Shapes": range(9632, 9728), + "Miscellaneous Symbols": range(9728, 9984), + "Dingbats": range(9984, 10176), + "Miscellaneous Mathematical Symbols-A": range(10176, 10224), + "Supplemental Arrows-A": range(10224, 10240), + "Braille Patterns": range(10240, 10496), + "Supplemental Arrows-B": range(10496, 10624), + "Miscellaneous Mathematical Symbols-B": range(10624, 10752), + "Supplemental Mathematical Operators": range(10752, 11008), + "Miscellaneous Symbols and Arrows": range(11008, 11264), + "Glagolitic": range(11264, 11360), + "Latin Extended-C": range(11360, 11392), + "Coptic": range(11392, 11520), + "Georgian Supplement": range(11520, 11568), + "Tifinagh": range(11568, 11648), + "Ethiopic Extended": range(11648, 11744), + "Cyrillic Extended-A": range(11744, 11776), + "Supplemental Punctuation": range(11776, 11904), + "CJK Radicals Supplement": range(11904, 12032), + "Kangxi Radicals": range(12032, 12256), + "Ideographic Description Characters": range(12272, 12288), + "CJK Symbols and Punctuation": range(12288, 12352), + "Hiragana": range(12352, 12448), + "Katakana": range(12448, 12544), + "Bopomofo": range(12544, 12592), + "Hangul Compatibility Jamo": range(12592, 12688), + "Kanbun": range(12688, 12704), + "Bopomofo Extended": range(12704, 12736), + "CJK Strokes": range(12736, 12784), + "Katakana Phonetic Extensions": range(12784, 12800), + "Enclosed CJK Letters and Months": range(12800, 13056), + "CJK Compatibility": range(13056, 13312), + "CJK Unified Ideographs Extension A": range(13312, 19904), + "Yijing Hexagram Symbols": range(19904, 19968), + "CJK Unified Ideographs": range(19968, 40960), + "Yi Syllables": range(40960, 42128), + "Yi Radicals": range(42128, 42192), + "Lisu": range(42192, 42240), + "Vai": range(42240, 42560), + "Cyrillic Extended-B": range(42560, 42656), + "Bamum": range(42656, 42752), + "Modifier Tone Letters": range(42752, 42784), + "Latin Extended-D": range(42784, 43008), + "Syloti Nagri": range(43008, 43056), + "Common Indic Number Forms": range(43056, 43072), + "Phags-pa": range(43072, 43136), + "Saurashtra": range(43136, 43232), + "Devanagari Extended": range(43232, 43264), + "Kayah Li": range(43264, 43312), + "Rejang": range(43312, 43360), + "Hangul Jamo Extended-A": range(43360, 43392), + "Javanese": range(43392, 43488), + "Myanmar Extended-B": range(43488, 43520), + "Cham": range(43520, 43616), + "Myanmar Extended-A": range(43616, 43648), + "Tai Viet": range(43648, 43744), + "Meetei Mayek Extensions": range(43744, 43776), + "Ethiopic Extended-A": range(43776, 43824), + "Latin Extended-E": range(43824, 43888), + "Cherokee Supplement": range(43888, 43968), + "Meetei Mayek": range(43968, 44032), + "Hangul Syllables": range(44032, 55216), + "Hangul Jamo Extended-B": range(55216, 55296), + "High Surrogates": range(55296, 56192), + "High Private Use Surrogates": range(56192, 56320), + "Low Surrogates": range(56320, 57344), + "Private Use Area": range(57344, 63744), + "CJK Compatibility Ideographs": range(63744, 64256), + "Alphabetic Presentation Forms": range(64256, 64336), + "Arabic Presentation Forms-A": range(64336, 65024), + "Variation Selectors": range(65024, 65040), + "Vertical Forms": range(65040, 65056), + "Combining Half Marks": range(65056, 65072), + "CJK Compatibility Forms": range(65072, 65104), + "Small Form Variants": range(65104, 65136), + "Arabic Presentation Forms-B": range(65136, 65280), + "Halfwidth and Fullwidth Forms": range(65280, 65520), + "Specials": range(65520, 65536), + "Linear B Syllabary": range(65536, 65664), + "Linear B Ideograms": range(65664, 65792), + "Aegean Numbers": range(65792, 65856), + "Ancient Greek Numbers": range(65856, 65936), + "Ancient Symbols": range(65936, 66000), + "Phaistos Disc": range(66000, 66048), + "Lycian": range(66176, 66208), + "Carian": range(66208, 66272), + "Coptic Epact Numbers": range(66272, 66304), + "Old Italic": range(66304, 66352), + "Gothic": range(66352, 66384), + "Old Permic": range(66384, 66432), + "Ugaritic": range(66432, 66464), + "Old Persian": range(66464, 66528), + "Deseret": range(66560, 66640), + "Shavian": range(66640, 66688), + "Osmanya": range(66688, 66736), + "Osage": range(66736, 66816), + "Elbasan": range(66816, 66864), + "Caucasian Albanian": range(66864, 66928), + "Vithkuqi": range(66928, 67008), + "Linear A": range(67072, 67456), + "Latin Extended-F": range(67456, 67520), + "Cypriot Syllabary": range(67584, 67648), + "Imperial Aramaic": range(67648, 67680), + "Palmyrene": range(67680, 67712), + "Nabataean": range(67712, 67760), + "Hatran": range(67808, 67840), + "Phoenician": range(67840, 67872), + "Lydian": range(67872, 67904), + "Meroitic Hieroglyphs": range(67968, 68000), + "Meroitic Cursive": range(68000, 68096), + "Kharoshthi": range(68096, 68192), + "Old South Arabian": range(68192, 68224), + "Old North Arabian": range(68224, 68256), + "Manichaean": range(68288, 68352), + "Avestan": range(68352, 68416), + "Inscriptional Parthian": range(68416, 68448), + "Inscriptional Pahlavi": range(68448, 68480), + "Psalter Pahlavi": range(68480, 68528), + "Old Turkic": range(68608, 68688), + "Old Hungarian": range(68736, 68864), + "Hanifi Rohingya": range(68864, 68928), + "Rumi Numeral Symbols": range(69216, 69248), + "Yezidi": range(69248, 69312), + "Arabic Extended-C": range(69312, 69376), + "Old Sogdian": range(69376, 69424), + "Sogdian": range(69424, 69488), + "Old Uyghur": range(69488, 69552), + "Chorasmian": range(69552, 69600), + "Elymaic": range(69600, 69632), + "Brahmi": range(69632, 69760), + "Kaithi": range(69760, 69840), + "Sora Sompeng": range(69840, 69888), + "Chakma": range(69888, 69968), + "Mahajani": range(69968, 70016), + "Sharada": range(70016, 70112), + "Sinhala Archaic Numbers": range(70112, 70144), + "Khojki": range(70144, 70224), + "Multani": range(70272, 70320), + "Khudawadi": range(70320, 70400), + "Grantha": range(70400, 70528), + "Newa": range(70656, 70784), + "Tirhuta": range(70784, 70880), + "Siddham": range(71040, 71168), + "Modi": range(71168, 71264), + "Mongolian Supplement": range(71264, 71296), + "Takri": range(71296, 71376), + "Ahom": range(71424, 71504), + "Dogra": range(71680, 71760), + "Warang Citi": range(71840, 71936), + "Dives Akuru": range(71936, 72032), + "Nandinagari": range(72096, 72192), + "Zanabazar Square": range(72192, 72272), + "Soyombo": range(72272, 72368), + "Unified Canadian Aboriginal Syllabics Extended-A": range(72368, 72384), + "Pau Cin Hau": range(72384, 72448), + "Devanagari Extended-A": range(72448, 72544), + "Bhaiksuki": range(72704, 72816), + "Marchen": range(72816, 72896), + "Masaram Gondi": range(72960, 73056), + "Gunjala Gondi": range(73056, 73136), + "Makasar": range(73440, 73472), + "Kawi": range(73472, 73568), + "Lisu Supplement": range(73648, 73664), + "Tamil Supplement": range(73664, 73728), + "Cuneiform": range(73728, 74752), + "Cuneiform Numbers and Punctuation": range(74752, 74880), + "Early Dynastic Cuneiform": range(74880, 75088), + "Cypro-Minoan": range(77712, 77824), + "Egyptian Hieroglyphs": range(77824, 78896), + "Egyptian Hieroglyph Format Controls": range(78896, 78944), + "Anatolian Hieroglyphs": range(82944, 83584), + "Bamum Supplement": range(92160, 92736), + "Mro": range(92736, 92784), + "Tangsa": range(92784, 92880), + "Bassa Vah": range(92880, 92928), + "Pahawh Hmong": range(92928, 93072), + "Medefaidrin": range(93760, 93856), + "Miao": range(93952, 94112), + "Ideographic Symbols and Punctuation": range(94176, 94208), + "Tangut": range(94208, 100352), + "Tangut Components": range(100352, 101120), + "Khitan Small Script": range(101120, 101632), + "Tangut Supplement": range(101632, 101760), + "Kana Extended-B": range(110576, 110592), + "Kana Supplement": range(110592, 110848), + "Kana Extended-A": range(110848, 110896), + "Small Kana Extension": range(110896, 110960), + "Nushu": range(110960, 111360), + "Duployan": range(113664, 113824), + "Shorthand Format Controls": range(113824, 113840), + "Znamenny Musical Notation": range(118528, 118736), + "Byzantine Musical Symbols": range(118784, 119040), + "Musical Symbols": range(119040, 119296), + "Ancient Greek Musical Notation": range(119296, 119376), + "Kaktovik Numerals": range(119488, 119520), + "Mayan Numerals": range(119520, 119552), + "Tai Xuan Jing Symbols": range(119552, 119648), + "Counting Rod Numerals": range(119648, 119680), + "Mathematical Alphanumeric Symbols": range(119808, 120832), + "Sutton SignWriting": range(120832, 121520), + "Latin Extended-G": range(122624, 122880), + "Glagolitic Supplement": range(122880, 122928), + "Cyrillic Extended-D": range(122928, 123024), + "Nyiakeng Puachue Hmong": range(123136, 123216), + "Toto": range(123536, 123584), + "Wancho": range(123584, 123648), + "Nag Mundari": range(124112, 124160), + "Ethiopic Extended-B": range(124896, 124928), + "Mende Kikakui": range(124928, 125152), + "Adlam": range(125184, 125280), + "Indic Siyaq Numbers": range(126064, 126144), + "Ottoman Siyaq Numbers": range(126208, 126288), + "Arabic Mathematical Alphabetic Symbols": range(126464, 126720), + "Mahjong Tiles": range(126976, 127024), + "Domino Tiles": range(127024, 127136), + "Playing Cards": range(127136, 127232), + "Enclosed Alphanumeric Supplement": range(127232, 127488), + "Enclosed Ideographic Supplement": range(127488, 127744), + "Miscellaneous Symbols and Pictographs": range(127744, 128512), + "Emoticons range(Emoji)": range(128512, 128592), + "Ornamental Dingbats": range(128592, 128640), + "Transport and Map Symbols": range(128640, 128768), + "Alchemical Symbols": range(128768, 128896), + "Geometric Shapes Extended": range(128896, 129024), + "Supplemental Arrows-C": range(129024, 129280), + "Supplemental Symbols and Pictographs": range(129280, 129536), + "Chess Symbols": range(129536, 129648), + "Symbols and Pictographs Extended-A": range(129648, 129792), + "Symbols for Legacy Computing": range(129792, 130048), + "CJK Unified Ideographs Extension B": range(131072, 173792), + "CJK Unified Ideographs Extension C": range(173824, 177984), + "CJK Unified Ideographs Extension D": range(177984, 178208), + "CJK Unified Ideographs Extension E": range(178208, 183984), + "CJK Unified Ideographs Extension F": range(183984, 191472), + "CJK Compatibility Ideographs Supplement": range(194560, 195104), + "CJK Unified Ideographs Extension G": range(196608, 201552), + "CJK Unified Ideographs Extension H": range(201552, 205744), + "Tags": range(917504, 917632), + "Variation Selectors Supplement": range(917760, 918000), + "Supplementary Private Use Area-A": range(983040, 1048576), + "Supplementary Private Use Area-B": range(1048576, 1114112), +} + + +UNICODE_SECONDARY_RANGE_KEYWORD: List[str] = [ + "Supplement", + "Extended", + "Extensions", + "Modifier", + "Marks", + "Punctuation", + "Symbols", + "Forms", + "Operators", + "Miscellaneous", + "Drawing", + "Block", + "Shapes", + "Supplemental", + "Tags", +] + +RE_POSSIBLE_ENCODING_INDICATION = re_compile( + r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", + IGNORECASE, +) + +IANA_NO_ALIASES = [ + "cp720", + "cp737", + "cp856", + "cp874", + "cp875", + "cp1006", + "koi8_r", + "koi8_t", + "koi8_u", +] + +IANA_SUPPORTED: List[str] = sorted( + filter( + lambda x: x.endswith("_codec") is False + and x not in {"rot_13", "tactis", "mbcs"}, + list(set(aliases.values())) + IANA_NO_ALIASES, + ) +) + +IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED) + +# pre-computed code page that are similar using the function cp_similarity. +IANA_SUPPORTED_SIMILAR: Dict[str, List[str]] = { + "cp037": ["cp1026", "cp1140", "cp273", "cp500"], + "cp1026": ["cp037", "cp1140", "cp273", "cp500"], + "cp1125": ["cp866"], + "cp1140": ["cp037", "cp1026", "cp273", "cp500"], + "cp1250": ["iso8859_2"], + "cp1251": ["kz1048", "ptcp154"], + "cp1252": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1253": ["iso8859_7"], + "cp1254": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1257": ["iso8859_13"], + "cp273": ["cp037", "cp1026", "cp1140", "cp500"], + "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], + "cp500": ["cp037", "cp1026", "cp1140", "cp273"], + "cp850": ["cp437", "cp857", "cp858", "cp865"], + "cp857": ["cp850", "cp858", "cp865"], + "cp858": ["cp437", "cp850", "cp857", "cp865"], + "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], + "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], + "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], + "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], + "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], + "cp866": ["cp1125"], + "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], + "iso8859_11": ["tis_620"], + "iso8859_13": ["cp1257"], + "iso8859_14": [ + "iso8859_10", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_15": [ + "cp1252", + "cp1254", + "iso8859_10", + "iso8859_14", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_16": [ + "iso8859_14", + "iso8859_15", + "iso8859_2", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], + "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], + "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], + "iso8859_7": ["cp1253"], + "iso8859_9": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "latin_1", + ], + "kz1048": ["cp1251", "ptcp154"], + "latin_1": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "iso8859_9", + ], + "mac_iceland": ["mac_roman", "mac_turkish"], + "mac_roman": ["mac_iceland", "mac_turkish"], + "mac_turkish": ["mac_iceland", "mac_roman"], + "ptcp154": ["cp1251", "kz1048"], + "tis_620": ["iso8859_11"], +} + + +CHARDET_CORRESPONDENCE: Dict[str, str] = { + "iso2022_kr": "ISO-2022-KR", + "iso2022_jp": "ISO-2022-JP", + "euc_kr": "EUC-KR", + "tis_620": "TIS-620", + "utf_32": "UTF-32", + "euc_jp": "EUC-JP", + "koi8_r": "KOI8-R", + "iso8859_1": "ISO-8859-1", + "iso8859_2": "ISO-8859-2", + "iso8859_5": "ISO-8859-5", + "iso8859_6": "ISO-8859-6", + "iso8859_7": "ISO-8859-7", + "iso8859_8": "ISO-8859-8", + "utf_16": "UTF-16", + "cp855": "IBM855", + "mac_cyrillic": "MacCyrillic", + "gb2312": "GB2312", + "gb18030": "GB18030", + "cp932": "CP932", + "cp866": "IBM866", + "utf_8": "utf-8", + "utf_8_sig": "UTF-8-SIG", + "shift_jis": "SHIFT_JIS", + "big5": "Big5", + "cp1250": "windows-1250", + "cp1251": "windows-1251", + "cp1252": "Windows-1252", + "cp1253": "windows-1253", + "cp1255": "windows-1255", + "cp1256": "windows-1256", + "cp1254": "Windows-1254", + "cp949": "CP949", +} + + +COMMON_SAFE_ASCII_CHARACTERS: Set[str] = { + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", +} + + +KO_NAMES: Set[str] = {"johab", "cp949", "euc_kr"} +ZH_NAMES: Set[str] = {"big5", "cp950", "big5hkscs", "hz"} + +# Logging LEVEL below DEBUG +TRACE: int = 5 + + +# Language label that contain the em dash "—" +# character are to be considered alternative seq to origin +FREQUENCIES: Dict[str, List[str]] = { + "English": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "u", + "m", + "f", + "p", + "g", + "w", + "y", + "b", + "v", + "k", + "x", + "j", + "z", + "q", + ], + "English—": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "m", + "u", + "f", + "p", + "g", + "w", + "b", + "y", + "v", + "k", + "j", + "x", + "z", + "q", + ], + "German": [ + "e", + "n", + "i", + "r", + "s", + "t", + "a", + "d", + "h", + "u", + "l", + "g", + "o", + "c", + "m", + "b", + "f", + "k", + "w", + "z", + "p", + "v", + "ü", + "ä", + "ö", + "j", + ], + "French": [ + "e", + "a", + "s", + "n", + "i", + "t", + "r", + "l", + "u", + "o", + "d", + "c", + "p", + "m", + "é", + "v", + "g", + "f", + "b", + "h", + "q", + "à", + "x", + "è", + "y", + "j", + ], + "Dutch": [ + "e", + "n", + "a", + "i", + "r", + "t", + "o", + "d", + "s", + "l", + "g", + "h", + "v", + "m", + "u", + "k", + "c", + "p", + "b", + "w", + "j", + "z", + "f", + "y", + "x", + "ë", + ], + "Italian": [ + "e", + "i", + "a", + "o", + "n", + "l", + "t", + "r", + "s", + "c", + "d", + "u", + "p", + "m", + "g", + "v", + "f", + "b", + "z", + "h", + "q", + "è", + "à", + "k", + "y", + "ò", + ], + "Polish": [ + "a", + "i", + "o", + "e", + "n", + "r", + "z", + "w", + "s", + "c", + "t", + "k", + "y", + "d", + "p", + "m", + "u", + "l", + "j", + "ł", + "g", + "b", + "h", + "ą", + "ę", + "ó", + ], + "Spanish": [ + "e", + "a", + "o", + "n", + "s", + "r", + "i", + "l", + "d", + "t", + "c", + "u", + "m", + "p", + "b", + "g", + "v", + "f", + "y", + "ó", + "h", + "q", + "í", + "j", + "z", + "á", + ], + "Russian": [ + "о", + "а", + "е", + "и", + "н", + "с", + "т", + "р", + "в", + "л", + "к", + "м", + "д", + "п", + "у", + "г", + "я", + "ы", + "з", + "б", + "й", + "ь", + "ч", + "х", + "ж", + "ц", + ], + # Jap-Kanji + "Japanese": [ + "人", + "一", + "大", + "亅", + "丁", + "丨", + "竹", + "笑", + "口", + "日", + "今", + "二", + "彳", + "行", + "十", + "土", + "丶", + "寸", + "寺", + "時", + "乙", + "丿", + "乂", + "气", + "気", + "冂", + "巾", + "亠", + "市", + "目", + "儿", + "見", + "八", + "小", + "凵", + "県", + "月", + "彐", + "門", + "間", + "木", + "東", + "山", + "出", + "本", + "中", + "刀", + "分", + "耳", + "又", + "取", + "最", + "言", + "田", + "心", + "思", + "刂", + "前", + "京", + "尹", + "事", + "生", + "厶", + "云", + "会", + "未", + "来", + "白", + "冫", + "楽", + "灬", + "馬", + "尸", + "尺", + "駅", + "明", + "耂", + "者", + "了", + "阝", + "都", + "高", + "卜", + "占", + "厂", + "广", + "店", + "子", + "申", + "奄", + "亻", + "俺", + "上", + "方", + "冖", + "学", + "衣", + "艮", + "食", + "自", + ], + # Jap-Katakana + "Japanese—": [ + "ー", + "ン", + "ス", + "・", + "ル", + "ト", + "リ", + "イ", + "ア", + "ラ", + "ッ", + "ク", + "ド", + "シ", + "レ", + "ジ", + "タ", + "フ", + "ロ", + "カ", + "テ", + "マ", + "ィ", + "グ", + "バ", + "ム", + "プ", + "オ", + "コ", + "デ", + "ニ", + "ウ", + "メ", + "サ", + "ビ", + "ナ", + "ブ", + "ャ", + "エ", + "ュ", + "チ", + "キ", + "ズ", + "ダ", + "パ", + "ミ", + "ェ", + "ョ", + "ハ", + "セ", + "ベ", + "ガ", + "モ", + "ツ", + "ネ", + "ボ", + "ソ", + "ノ", + "ァ", + "ヴ", + "ワ", + "ポ", + "ペ", + "ピ", + "ケ", + "ゴ", + "ギ", + "ザ", + "ホ", + "ゲ", + "ォ", + "ヤ", + "ヒ", + "ユ", + "ヨ", + "ヘ", + "ゼ", + "ヌ", + "ゥ", + "ゾ", + "ヶ", + "ヂ", + "ヲ", + "ヅ", + "ヵ", + "ヱ", + "ヰ", + "ヮ", + "ヽ", + "゠", + "ヾ", + "ヷ", + "ヿ", + "ヸ", + "ヹ", + "ヺ", + ], + # Jap-Hiragana + "Japanese——": [ + "の", + "に", + "る", + "た", + "と", + "は", + "し", + "い", + "を", + "で", + "て", + "が", + "な", + "れ", + "か", + "ら", + "さ", + "っ", + "り", + "す", + "あ", + "も", + "こ", + "ま", + "う", + "く", + "よ", + "き", + "ん", + "め", + "お", + "け", + "そ", + "つ", + "だ", + "や", + "え", + "ど", + "わ", + "ち", + "み", + "せ", + "じ", + "ば", + "へ", + "び", + "ず", + "ろ", + "ほ", + "げ", + "む", + "べ", + "ひ", + "ょ", + "ゆ", + "ぶ", + "ご", + "ゃ", + "ね", + "ふ", + "ぐ", + "ぎ", + "ぼ", + "ゅ", + "づ", + "ざ", + "ぞ", + "ぬ", + "ぜ", + "ぱ", + "ぽ", + "ぷ", + "ぴ", + "ぃ", + "ぁ", + "ぇ", + "ぺ", + "ゞ", + "ぢ", + "ぉ", + "ぅ", + "ゐ", + "ゝ", + "ゑ", + "゛", + "゜", + "ゎ", + "ゔ", + "゚", + "ゟ", + "゙", + "ゕ", + "ゖ", + ], + "Portuguese": [ + "a", + "e", + "o", + "s", + "i", + "r", + "d", + "n", + "t", + "m", + "u", + "c", + "l", + "p", + "g", + "v", + "b", + "f", + "h", + "ã", + "q", + "é", + "ç", + "á", + "z", + "í", + ], + "Swedish": [ + "e", + "a", + "n", + "r", + "t", + "s", + "i", + "l", + "d", + "o", + "m", + "k", + "g", + "v", + "h", + "f", + "u", + "p", + "ä", + "c", + "b", + "ö", + "å", + "y", + "j", + "x", + ], + "Chinese": [ + "的", + "一", + "是", + "不", + "了", + "在", + "人", + "有", + "我", + "他", + "这", + "个", + "们", + "中", + "来", + "上", + "大", + "为", + "和", + "国", + "地", + "到", + "以", + "说", + "时", + "要", + "就", + "出", + "会", + "可", + "也", + "你", + "对", + "生", + "能", + "而", + "子", + "那", + "得", + "于", + "着", + "下", + "自", + "之", + "年", + "过", + "发", + "后", + "作", + "里", + "用", + "道", + "行", + "所", + "然", + "家", + "种", + "事", + "成", + "方", + "多", + "经", + "么", + "去", + "法", + "学", + "如", + "都", + "同", + "现", + "当", + "没", + "动", + "面", + "起", + "看", + "定", + "天", + "分", + "还", + "进", + "好", + "小", + "部", + "其", + "些", + "主", + "样", + "理", + "心", + "她", + "本", + "前", + "开", + "但", + "因", + "只", + "从", + "想", + "实", + ], + "Ukrainian": [ + "о", + "а", + "н", + "і", + "и", + "р", + "в", + "т", + "е", + "с", + "к", + "л", + "у", + "д", + "м", + "п", + "з", + "я", + "ь", + "б", + "г", + "й", + "ч", + "х", + "ц", + "ї", + ], + "Norwegian": [ + "e", + "r", + "n", + "t", + "a", + "s", + "i", + "o", + "l", + "d", + "g", + "k", + "m", + "v", + "f", + "p", + "u", + "b", + "h", + "å", + "y", + "j", + "ø", + "c", + "æ", + "w", + ], + "Finnish": [ + "a", + "i", + "n", + "t", + "e", + "s", + "l", + "o", + "u", + "k", + "ä", + "m", + "r", + "v", + "j", + "h", + "p", + "y", + "d", + "ö", + "g", + "c", + "b", + "f", + "w", + "z", + ], + "Vietnamese": [ + "n", + "h", + "t", + "i", + "c", + "g", + "a", + "o", + "u", + "m", + "l", + "r", + "à", + "đ", + "s", + "e", + "v", + "p", + "b", + "y", + "ư", + "d", + "á", + "k", + "ộ", + "ế", + ], + "Czech": [ + "o", + "e", + "a", + "n", + "t", + "s", + "i", + "l", + "v", + "r", + "k", + "d", + "u", + "m", + "p", + "í", + "c", + "h", + "z", + "á", + "y", + "j", + "b", + "ě", + "é", + "ř", + ], + "Hungarian": [ + "e", + "a", + "t", + "l", + "s", + "n", + "k", + "r", + "i", + "o", + "z", + "á", + "é", + "g", + "m", + "b", + "y", + "v", + "d", + "h", + "u", + "p", + "j", + "ö", + "f", + "c", + ], + "Korean": [ + "이", + "다", + "에", + "의", + "는", + "로", + "하", + "을", + "가", + "고", + "지", + "서", + "한", + "은", + "기", + "으", + "년", + "대", + "사", + "시", + "를", + "리", + "도", + "인", + "스", + "일", + ], + "Indonesian": [ + "a", + "n", + "e", + "i", + "r", + "t", + "u", + "s", + "d", + "k", + "m", + "l", + "g", + "p", + "b", + "o", + "h", + "y", + "j", + "c", + "w", + "f", + "v", + "z", + "x", + "q", + ], + "Turkish": [ + "a", + "e", + "i", + "n", + "r", + "l", + "ı", + "k", + "d", + "t", + "s", + "m", + "y", + "u", + "o", + "b", + "ü", + "ş", + "v", + "g", + "z", + "h", + "c", + "p", + "ç", + "ğ", + ], + "Romanian": [ + "e", + "i", + "a", + "r", + "n", + "t", + "u", + "l", + "o", + "c", + "s", + "d", + "p", + "m", + "ă", + "f", + "v", + "î", + "g", + "b", + "ș", + "ț", + "z", + "h", + "â", + "j", + ], + "Farsi": [ + "ا", + "ی", + "ر", + "د", + "ن", + "ه", + "و", + "م", + "ت", + "ب", + "س", + "ل", + "ک", + "ش", + "ز", + "ف", + "گ", + "ع", + "خ", + "ق", + "ج", + "آ", + "پ", + "ح", + "ط", + "ص", + ], + "Arabic": [ + "ا", + "ل", + "ي", + "م", + "و", + "ن", + "ر", + "ت", + "ب", + "ة", + "ع", + "د", + "س", + "ف", + "ه", + "ك", + "ق", + "أ", + "ح", + "ج", + "ش", + "ط", + "ص", + "ى", + "خ", + "إ", + ], + "Danish": [ + "e", + "r", + "n", + "t", + "a", + "i", + "s", + "d", + "l", + "o", + "g", + "m", + "k", + "f", + "v", + "u", + "b", + "h", + "p", + "å", + "y", + "ø", + "æ", + "c", + "j", + "w", + ], + "Serbian": [ + "а", + "и", + "о", + "е", + "н", + "р", + "с", + "у", + "т", + "к", + "ј", + "в", + "д", + "м", + "п", + "л", + "г", + "з", + "б", + "a", + "i", + "e", + "o", + "n", + "ц", + "ш", + ], + "Lithuanian": [ + "i", + "a", + "s", + "o", + "r", + "e", + "t", + "n", + "u", + "k", + "m", + "l", + "p", + "v", + "d", + "j", + "g", + "ė", + "b", + "y", + "ų", + "š", + "ž", + "c", + "ą", + "į", + ], + "Slovene": [ + "e", + "a", + "i", + "o", + "n", + "r", + "s", + "l", + "t", + "j", + "v", + "k", + "d", + "p", + "m", + "u", + "z", + "b", + "g", + "h", + "č", + "c", + "š", + "ž", + "f", + "y", + ], + "Slovak": [ + "o", + "a", + "e", + "n", + "i", + "r", + "v", + "t", + "s", + "l", + "k", + "d", + "m", + "p", + "u", + "c", + "h", + "j", + "b", + "z", + "á", + "y", + "ý", + "í", + "č", + "é", + ], + "Hebrew": [ + "י", + "ו", + "ה", + "ל", + "ר", + "ב", + "ת", + "מ", + "א", + "ש", + "נ", + "ע", + "ם", + "ד", + "ק", + "ח", + "פ", + "ס", + "כ", + "ג", + "ט", + "צ", + "ן", + "ז", + "ך", + ], + "Bulgarian": [ + "а", + "и", + "о", + "е", + "н", + "т", + "р", + "с", + "в", + "л", + "к", + "д", + "п", + "м", + "з", + "г", + "я", + "ъ", + "у", + "б", + "ч", + "ц", + "й", + "ж", + "щ", + "х", + ], + "Croatian": [ + "a", + "i", + "o", + "e", + "n", + "r", + "j", + "s", + "t", + "u", + "k", + "l", + "v", + "d", + "m", + "p", + "g", + "z", + "b", + "c", + "č", + "h", + "š", + "ž", + "ć", + "f", + ], + "Hindi": [ + "क", + "र", + "स", + "न", + "त", + "म", + "ह", + "प", + "य", + "ल", + "व", + "ज", + "द", + "ग", + "ब", + "श", + "ट", + "अ", + "ए", + "थ", + "भ", + "ड", + "च", + "ध", + "ष", + "इ", + ], + "Estonian": [ + "a", + "i", + "e", + "s", + "t", + "l", + "u", + "n", + "o", + "k", + "r", + "d", + "m", + "v", + "g", + "p", + "j", + "h", + "ä", + "b", + "õ", + "ü", + "f", + "c", + "ö", + "y", + ], + "Thai": [ + "า", + "น", + "ร", + "อ", + "ก", + "เ", + "ง", + "ม", + "ย", + "ล", + "ว", + "ด", + "ท", + "ส", + "ต", + "ะ", + "ป", + "บ", + "ค", + "ห", + "แ", + "จ", + "พ", + "ช", + "ข", + "ใ", + ], + "Greek": [ + "α", + "τ", + "ο", + "ι", + "ε", + "ν", + "ρ", + "σ", + "κ", + "η", + "π", + "ς", + "υ", + "μ", + "λ", + "ί", + "ό", + "ά", + "γ", + "έ", + "δ", + "ή", + "ω", + "χ", + "θ", + "ύ", + ], + "Tamil": [ + "க", + "த", + "ப", + "ட", + "ர", + "ம", + "ல", + "ன", + "வ", + "ற", + "ய", + "ள", + "ச", + "ந", + "இ", + "ண", + "அ", + "ஆ", + "ழ", + "ங", + "எ", + "உ", + "ஒ", + "ஸ", + ], + "Kazakh": [ + "а", + "ы", + "е", + "н", + "т", + "р", + "л", + "і", + "д", + "с", + "м", + "қ", + "к", + "о", + "б", + "и", + "у", + "ғ", + "ж", + "ң", + "з", + "ш", + "й", + "п", + "г", + "ө", + ], +} + +LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) diff --git a/dist/ba_data/python-site-packages/charset_normalizer/legacy.py b/dist/ba_data/python-site-packages/charset_normalizer/legacy.py new file mode 100644 index 00000000..43aad21a --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/legacy.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, Optional, Union +from warnings import warn + +from .api import from_bytes +from .constant import CHARDET_CORRESPONDENCE + + +def detect( + byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any +) -> Dict[str, Optional[Union[str, float]]]: + """ + chardet legacy method + Detect the encoding of the given byte string. It should be mostly backward-compatible. + Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it) + This function is deprecated and should be used to migrate your project easily, consult the documentation for + further information. Not planned for removal. + + :param byte_str: The byte sequence to examine. + :param should_rename_legacy: Should we rename legacy encodings + to their more modern equivalents? + """ + if len(kwargs): + warn( + f"charset-normalizer disregard arguments '{','.join(list(kwargs.keys()))}' in legacy function detect()" + ) + + if not isinstance(byte_str, (bytearray, bytes)): + raise TypeError( # pragma: nocover + "Expected object of type bytes or bytearray, got: " + "{0}".format(type(byte_str)) + ) + + if isinstance(byte_str, bytearray): + byte_str = bytes(byte_str) + + r = from_bytes(byte_str).best() + + encoding = r.encoding if r is not None else None + language = r.language if r is not None and r.language != "Unknown" else "" + confidence = 1.0 - r.chaos if r is not None else None + + # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process + # but chardet does return 'utf-8-sig' and it is a valid codec name. + if r is not None and encoding == "utf_8" and r.bom: + encoding += "_sig" + + if should_rename_legacy is False and encoding in CHARDET_CORRESPONDENCE: + encoding = CHARDET_CORRESPONDENCE[encoding] + + return { + "encoding": encoding, + "language": language, + "confidence": confidence, + } diff --git a/dist/ba_data/python-site-packages/charset_normalizer/md.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/charset_normalizer/md.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..3d0b46ae Binary files /dev/null and b/dist/ba_data/python-site-packages/charset_normalizer/md.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/charset_normalizer/md.py b/dist/ba_data/python-site-packages/charset_normalizer/md.py new file mode 100644 index 00000000..77897aae --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/md.py @@ -0,0 +1,615 @@ +from functools import lru_cache +from logging import getLogger +from typing import List, Optional + +from .constant import ( + COMMON_SAFE_ASCII_CHARACTERS, + TRACE, + UNICODE_SECONDARY_RANGE_KEYWORD, +) +from .utils import ( + is_accentuated, + is_arabic, + is_arabic_isolated_form, + is_case_variable, + is_cjk, + is_emoticon, + is_hangul, + is_hiragana, + is_katakana, + is_latin, + is_punctuation, + is_separator, + is_symbol, + is_thai, + is_unprintable, + remove_accent, + unicode_range, +) + + +class MessDetectorPlugin: + """ + Base abstract class used for mess detection plugins. + All detectors MUST extend and implement given methods. + """ + + def eligible(self, character: str) -> bool: + """ + Determine if given character should be fed in. + """ + raise NotImplementedError # pragma: nocover + + def feed(self, character: str) -> None: + """ + The main routine to be executed upon character. + Insert the logic in witch the text would be considered chaotic. + """ + raise NotImplementedError # pragma: nocover + + def reset(self) -> None: # pragma: no cover + """ + Permit to reset the plugin to the initial state. + """ + raise NotImplementedError + + @property + def ratio(self) -> float: + """ + Compute the chaos ratio based on what your feed() has seen. + Must NOT be lower than 0.; No restriction gt 0. + """ + raise NotImplementedError # pragma: nocover + + +class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._punctuation_count: int = 0 + self._symbol_count: int = 0 + self._character_count: int = 0 + + self._last_printable_char: Optional[str] = None + self._frenzy_symbol_in_word: bool = False + + def eligible(self, character: str) -> bool: + return character.isprintable() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if ( + character != self._last_printable_char + and character not in COMMON_SAFE_ASCII_CHARACTERS + ): + if is_punctuation(character): + self._punctuation_count += 1 + elif ( + character.isdigit() is False + and is_symbol(character) + and is_emoticon(character) is False + ): + self._symbol_count += 2 + + self._last_printable_char = character + + def reset(self) -> None: # pragma: no cover + self._punctuation_count = 0 + self._character_count = 0 + self._symbol_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + ratio_of_punctuation: float = ( + self._punctuation_count + self._symbol_count + ) / self._character_count + + return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 + + +class TooManyAccentuatedPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._character_count: int = 0 + self._accentuated_count: int = 0 + + def eligible(self, character: str) -> bool: + return character.isalpha() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if is_accentuated(character): + self._accentuated_count += 1 + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._accentuated_count = 0 + + @property + def ratio(self) -> float: + if self._character_count < 8: + return 0.0 + + ratio_of_accentuation: float = self._accentuated_count / self._character_count + return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 + + +class UnprintablePlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._unprintable_count: int = 0 + self._character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if is_unprintable(character): + self._unprintable_count += 1 + self._character_count += 1 + + def reset(self) -> None: # pragma: no cover + self._unprintable_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._unprintable_count * 8) / self._character_count + + +class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._successive_count: int = 0 + self._character_count: int = 0 + + self._last_latin_character: Optional[str] = None + + def eligible(self, character: str) -> bool: + return character.isalpha() and is_latin(character) + + def feed(self, character: str) -> None: + self._character_count += 1 + if ( + self._last_latin_character is not None + and is_accentuated(character) + and is_accentuated(self._last_latin_character) + ): + if character.isupper() and self._last_latin_character.isupper(): + self._successive_count += 1 + # Worse if its the same char duplicated with different accent. + if remove_accent(character) == remove_accent(self._last_latin_character): + self._successive_count += 1 + self._last_latin_character = character + + def reset(self) -> None: # pragma: no cover + self._successive_count = 0 + self._character_count = 0 + self._last_latin_character = None + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._successive_count * 2) / self._character_count + + +class SuspiciousRange(MessDetectorPlugin): + def __init__(self) -> None: + self._suspicious_successive_range_count: int = 0 + self._character_count: int = 0 + self._last_printable_seen: Optional[str] = None + + def eligible(self, character: str) -> bool: + return character.isprintable() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if ( + character.isspace() + or is_punctuation(character) + or character in COMMON_SAFE_ASCII_CHARACTERS + ): + self._last_printable_seen = None + return + + if self._last_printable_seen is None: + self._last_printable_seen = character + return + + unicode_range_a: Optional[str] = unicode_range(self._last_printable_seen) + unicode_range_b: Optional[str] = unicode_range(character) + + if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): + self._suspicious_successive_range_count += 1 + + self._last_printable_seen = character + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._suspicious_successive_range_count = 0 + self._last_printable_seen = None + + @property + def ratio(self) -> float: + if self._character_count <= 24: + return 0.0 + + ratio_of_suspicious_range_usage: float = ( + self._suspicious_successive_range_count * 2 + ) / self._character_count + + return ratio_of_suspicious_range_usage + + +class SuperWeirdWordPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._word_count: int = 0 + self._bad_word_count: int = 0 + self._foreign_long_count: int = 0 + + self._is_current_word_bad: bool = False + self._foreign_long_watch: bool = False + + self._character_count: int = 0 + self._bad_character_count: int = 0 + + self._buffer: str = "" + self._buffer_accent_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character.isalpha(): + self._buffer += character + if is_accentuated(character): + self._buffer_accent_count += 1 + if ( + self._foreign_long_watch is False + and (is_latin(character) is False or is_accentuated(character)) + and is_cjk(character) is False + and is_hangul(character) is False + and is_katakana(character) is False + and is_hiragana(character) is False + and is_thai(character) is False + ): + self._foreign_long_watch = True + return + if not self._buffer: + return + if ( + character.isspace() or is_punctuation(character) or is_separator(character) + ) and self._buffer: + self._word_count += 1 + buffer_length: int = len(self._buffer) + + self._character_count += buffer_length + + if buffer_length >= 4: + if self._buffer_accent_count / buffer_length > 0.34: + self._is_current_word_bad = True + # Word/Buffer ending with an upper case accentuated letter are so rare, + # that we will consider them all as suspicious. Same weight as foreign_long suspicious. + if ( + is_accentuated(self._buffer[-1]) + and self._buffer[-1].isupper() + and all(_.isupper() for _ in self._buffer) is False + ): + self._foreign_long_count += 1 + self._is_current_word_bad = True + if buffer_length >= 24 and self._foreign_long_watch: + camel_case_dst = [ + i + for c, i in zip(self._buffer, range(0, buffer_length)) + if c.isupper() + ] + probable_camel_cased: bool = False + + if camel_case_dst and (len(camel_case_dst) / buffer_length <= 0.3): + probable_camel_cased = True + + if not probable_camel_cased: + self._foreign_long_count += 1 + self._is_current_word_bad = True + + if self._is_current_word_bad: + self._bad_word_count += 1 + self._bad_character_count += len(self._buffer) + self._is_current_word_bad = False + + self._foreign_long_watch = False + self._buffer = "" + self._buffer_accent_count = 0 + elif ( + character not in {"<", ">", "-", "=", "~", "|", "_"} + and character.isdigit() is False + and is_symbol(character) + ): + self._is_current_word_bad = True + self._buffer += character + + def reset(self) -> None: # pragma: no cover + self._buffer = "" + self._is_current_word_bad = False + self._foreign_long_watch = False + self._bad_word_count = 0 + self._word_count = 0 + self._character_count = 0 + self._bad_character_count = 0 + self._foreign_long_count = 0 + + @property + def ratio(self) -> float: + if self._word_count <= 10 and self._foreign_long_count == 0: + return 0.0 + + return self._bad_character_count / self._character_count + + +class CjkInvalidStopPlugin(MessDetectorPlugin): + """ + GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and + can be easily detected. Searching for the overuse of '丅' and '丄'. + """ + + def __init__(self) -> None: + self._wrong_stop_count: int = 0 + self._cjk_character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character in {"丅", "丄"}: + self._wrong_stop_count += 1 + return + if is_cjk(character): + self._cjk_character_count += 1 + + def reset(self) -> None: # pragma: no cover + self._wrong_stop_count = 0 + self._cjk_character_count = 0 + + @property + def ratio(self) -> float: + if self._cjk_character_count < 16: + return 0.0 + return self._wrong_stop_count / self._cjk_character_count + + +class ArchaicUpperLowerPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._buf: bool = False + + self._character_count_since_last_sep: int = 0 + + self._successive_upper_lower_count: int = 0 + self._successive_upper_lower_count_final: int = 0 + + self._character_count: int = 0 + + self._last_alpha_seen: Optional[str] = None + self._current_ascii_only: bool = True + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + is_concerned = character.isalpha() and is_case_variable(character) + chunk_sep = is_concerned is False + + if chunk_sep and self._character_count_since_last_sep > 0: + if ( + self._character_count_since_last_sep <= 64 + and character.isdigit() is False + and self._current_ascii_only is False + ): + self._successive_upper_lower_count_final += ( + self._successive_upper_lower_count + ) + + self._successive_upper_lower_count = 0 + self._character_count_since_last_sep = 0 + self._last_alpha_seen = None + self._buf = False + self._character_count += 1 + self._current_ascii_only = True + + return + + if self._current_ascii_only is True and character.isascii() is False: + self._current_ascii_only = False + + if self._last_alpha_seen is not None: + if (character.isupper() and self._last_alpha_seen.islower()) or ( + character.islower() and self._last_alpha_seen.isupper() + ): + if self._buf is True: + self._successive_upper_lower_count += 2 + self._buf = False + else: + self._buf = True + else: + self._buf = False + + self._character_count += 1 + self._character_count_since_last_sep += 1 + self._last_alpha_seen = character + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._character_count_since_last_sep = 0 + self._successive_upper_lower_count = 0 + self._successive_upper_lower_count_final = 0 + self._last_alpha_seen = None + self._buf = False + self._current_ascii_only = True + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return self._successive_upper_lower_count_final / self._character_count + + +class ArabicIsolatedFormPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._character_count: int = 0 + self._isolated_form_count: int = 0 + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._isolated_form_count = 0 + + def eligible(self, character: str) -> bool: + return is_arabic(character) + + def feed(self, character: str) -> None: + self._character_count += 1 + + if is_arabic_isolated_form(character): + self._isolated_form_count += 1 + + @property + def ratio(self) -> float: + if self._character_count < 8: + return 0.0 + + isolated_form_usage: float = self._isolated_form_count / self._character_count + + return isolated_form_usage + + +@lru_cache(maxsize=1024) +def is_suspiciously_successive_range( + unicode_range_a: Optional[str], unicode_range_b: Optional[str] +) -> bool: + """ + Determine if two Unicode range seen next to each other can be considered as suspicious. + """ + if unicode_range_a is None or unicode_range_b is None: + return True + + if unicode_range_a == unicode_range_b: + return False + + if "Latin" in unicode_range_a and "Latin" in unicode_range_b: + return False + + if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b: + return False + + # Latin characters can be accompanied with a combining diacritical mark + # eg. Vietnamese. + if ("Latin" in unicode_range_a or "Latin" in unicode_range_b) and ( + "Combining" in unicode_range_a or "Combining" in unicode_range_b + ): + return False + + keywords_range_a, keywords_range_b = unicode_range_a.split( + " " + ), unicode_range_b.split(" ") + + for el in keywords_range_a: + if el in UNICODE_SECONDARY_RANGE_KEYWORD: + continue + if el in keywords_range_b: + return False + + # Japanese Exception + range_a_jp_chars, range_b_jp_chars = ( + unicode_range_a + in ( + "Hiragana", + "Katakana", + ), + unicode_range_b in ("Hiragana", "Katakana"), + ) + if (range_a_jp_chars or range_b_jp_chars) and ( + "CJK" in unicode_range_a or "CJK" in unicode_range_b + ): + return False + if range_a_jp_chars and range_b_jp_chars: + return False + + if "Hangul" in unicode_range_a or "Hangul" in unicode_range_b: + if "CJK" in unicode_range_a or "CJK" in unicode_range_b: + return False + if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin": + return False + + # Chinese/Japanese use dedicated range for punctuation and/or separators. + if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or ( + unicode_range_a in ["Katakana", "Hiragana"] + and unicode_range_b in ["Katakana", "Hiragana"] + ): + if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b: + return False + if "Forms" in unicode_range_a or "Forms" in unicode_range_b: + return False + if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin": + return False + + return True + + +@lru_cache(maxsize=2048) +def mess_ratio( + decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False +) -> float: + """ + Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. + """ + + detectors: List[MessDetectorPlugin] = [ + md_class() for md_class in MessDetectorPlugin.__subclasses__() + ] + + length: int = len(decoded_sequence) + 1 + + mean_mess_ratio: float = 0.0 + + if length < 512: + intermediary_mean_mess_ratio_calc: int = 32 + elif length <= 1024: + intermediary_mean_mess_ratio_calc = 64 + else: + intermediary_mean_mess_ratio_calc = 128 + + for character, index in zip(decoded_sequence + "\n", range(length)): + for detector in detectors: + if detector.eligible(character): + detector.feed(character) + + if ( + index > 0 and index % intermediary_mean_mess_ratio_calc == 0 + ) or index == length - 1: + mean_mess_ratio = sum(dt.ratio for dt in detectors) + + if mean_mess_ratio >= maximum_threshold: + break + + if debug: + logger = getLogger("charset_normalizer") + + logger.log( + TRACE, + "Mess-detector extended-analysis start. " + f"intermediary_mean_mess_ratio_calc={intermediary_mean_mess_ratio_calc} mean_mess_ratio={mean_mess_ratio} " + f"maximum_threshold={maximum_threshold}", + ) + + if len(decoded_sequence) > 16: + logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}") + logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}") + + for dt in detectors: # pragma: nocover + logger.log(TRACE, f"{dt.__class__}: {dt.ratio}") + + return round(mean_mess_ratio, 3) diff --git a/dist/ba_data/python-site-packages/charset_normalizer/md__mypyc.cpython-312-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/charset_normalizer/md__mypyc.cpython-312-x86_64-linux-gnu.so new file mode 100644 index 00000000..e3044d9a Binary files /dev/null and b/dist/ba_data/python-site-packages/charset_normalizer/md__mypyc.cpython-312-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/charset_normalizer/models.py b/dist/ba_data/python-site-packages/charset_normalizer/models.py new file mode 100644 index 00000000..a760b9c5 --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/models.py @@ -0,0 +1,340 @@ +from encodings.aliases import aliases +from hashlib import sha256 +from json import dumps +from typing import Any, Dict, Iterator, List, Optional, Tuple, Union + +from .constant import TOO_BIG_SEQUENCE +from .utils import iana_name, is_multi_byte_encoding, unicode_range + + +class CharsetMatch: + def __init__( + self, + payload: bytes, + guessed_encoding: str, + mean_mess_ratio: float, + has_sig_or_bom: bool, + languages: "CoherenceMatches", + decoded_payload: Optional[str] = None, + ): + self._payload: bytes = payload + + self._encoding: str = guessed_encoding + self._mean_mess_ratio: float = mean_mess_ratio + self._languages: CoherenceMatches = languages + self._has_sig_or_bom: bool = has_sig_or_bom + self._unicode_ranges: Optional[List[str]] = None + + self._leaves: List[CharsetMatch] = [] + self._mean_coherence_ratio: float = 0.0 + + self._output_payload: Optional[bytes] = None + self._output_encoding: Optional[str] = None + + self._string: Optional[str] = decoded_payload + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CharsetMatch): + raise TypeError( + "__eq__ cannot be invoked on {} and {}.".format( + str(other.__class__), str(self.__class__) + ) + ) + return self.encoding == other.encoding and self.fingerprint == other.fingerprint + + def __lt__(self, other: object) -> bool: + """ + Implemented to make sorted available upon CharsetMatches items. + """ + if not isinstance(other, CharsetMatch): + raise ValueError + + chaos_difference: float = abs(self.chaos - other.chaos) + coherence_difference: float = abs(self.coherence - other.coherence) + + # Below 1% difference --> Use Coherence + if chaos_difference < 0.01 and coherence_difference > 0.02: + return self.coherence > other.coherence + elif chaos_difference < 0.01 and coherence_difference <= 0.02: + # When having a difficult decision, use the result that decoded as many multi-byte as possible. + # preserve RAM usage! + if len(self._payload) >= TOO_BIG_SEQUENCE: + return self.chaos < other.chaos + return self.multi_byte_usage > other.multi_byte_usage + + return self.chaos < other.chaos + + @property + def multi_byte_usage(self) -> float: + return 1.0 - (len(str(self)) / len(self.raw)) + + def __str__(self) -> str: + # Lazy Str Loading + if self._string is None: + self._string = str(self._payload, self._encoding, "strict") + return self._string + + def __repr__(self) -> str: + return "".format(self.encoding, self.fingerprint) + + def add_submatch(self, other: "CharsetMatch") -> None: + if not isinstance(other, CharsetMatch) or other == self: + raise ValueError( + "Unable to add instance <{}> as a submatch of a CharsetMatch".format( + other.__class__ + ) + ) + + other._string = None # Unload RAM usage; dirty trick. + self._leaves.append(other) + + @property + def encoding(self) -> str: + return self._encoding + + @property + def encoding_aliases(self) -> List[str]: + """ + Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855. + """ + also_known_as: List[str] = [] + for u, p in aliases.items(): + if self.encoding == u: + also_known_as.append(p) + elif self.encoding == p: + also_known_as.append(u) + return also_known_as + + @property + def bom(self) -> bool: + return self._has_sig_or_bom + + @property + def byte_order_mark(self) -> bool: + return self._has_sig_or_bom + + @property + def languages(self) -> List[str]: + """ + Return the complete list of possible languages found in decoded sequence. + Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'. + """ + return [e[0] for e in self._languages] + + @property + def language(self) -> str: + """ + Most probable language found in decoded sequence. If none were detected or inferred, the property will return + "Unknown". + """ + if not self._languages: + # Trying to infer the language based on the given encoding + # Its either English or we should not pronounce ourselves in certain cases. + if "ascii" in self.could_be_from_charset: + return "English" + + # doing it there to avoid circular import + from charset_normalizer.cd import encoding_languages, mb_encoding_languages + + languages = ( + mb_encoding_languages(self.encoding) + if is_multi_byte_encoding(self.encoding) + else encoding_languages(self.encoding) + ) + + if len(languages) == 0 or "Latin Based" in languages: + return "Unknown" + + return languages[0] + + return self._languages[0][0] + + @property + def chaos(self) -> float: + return self._mean_mess_ratio + + @property + def coherence(self) -> float: + if not self._languages: + return 0.0 + return self._languages[0][1] + + @property + def percent_chaos(self) -> float: + return round(self.chaos * 100, ndigits=3) + + @property + def percent_coherence(self) -> float: + return round(self.coherence * 100, ndigits=3) + + @property + def raw(self) -> bytes: + """ + Original untouched bytes. + """ + return self._payload + + @property + def submatch(self) -> List["CharsetMatch"]: + return self._leaves + + @property + def has_submatch(self) -> bool: + return len(self._leaves) > 0 + + @property + def alphabets(self) -> List[str]: + if self._unicode_ranges is not None: + return self._unicode_ranges + # list detected ranges + detected_ranges: List[Optional[str]] = [ + unicode_range(char) for char in str(self) + ] + # filter and sort + self._unicode_ranges = sorted(list({r for r in detected_ranges if r})) + return self._unicode_ranges + + @property + def could_be_from_charset(self) -> List[str]: + """ + The complete list of encoding that output the exact SAME str result and therefore could be the originating + encoding. + This list does include the encoding available in property 'encoding'. + """ + return [self._encoding] + [m.encoding for m in self._leaves] + + def output(self, encoding: str = "utf_8") -> bytes: + """ + Method to get re-encoded bytes payload using given target encoding. Default to UTF-8. + Any errors will be simply ignored by the encoder NOT replaced. + """ + if self._output_encoding is None or self._output_encoding != encoding: + self._output_encoding = encoding + self._output_payload = str(self).encode(encoding, "replace") + + return self._output_payload # type: ignore + + @property + def fingerprint(self) -> str: + """ + Retrieve the unique SHA256 computed using the transformed (re-encoded) payload. Not the original one. + """ + return sha256(self.output()).hexdigest() + + +class CharsetMatches: + """ + Container with every CharsetMatch items ordered by default from most probable to the less one. + Act like a list(iterable) but does not implements all related methods. + """ + + def __init__(self, results: Optional[List[CharsetMatch]] = None): + self._results: List[CharsetMatch] = sorted(results) if results else [] + + def __iter__(self) -> Iterator[CharsetMatch]: + yield from self._results + + def __getitem__(self, item: Union[int, str]) -> CharsetMatch: + """ + Retrieve a single item either by its position or encoding name (alias may be used here). + Raise KeyError upon invalid index or encoding not present in results. + """ + if isinstance(item, int): + return self._results[item] + if isinstance(item, str): + item = iana_name(item, False) + for result in self._results: + if item in result.could_be_from_charset: + return result + raise KeyError + + def __len__(self) -> int: + return len(self._results) + + def __bool__(self) -> bool: + return len(self._results) > 0 + + def append(self, item: CharsetMatch) -> None: + """ + Insert a single match. Will be inserted accordingly to preserve sort. + Can be inserted as a submatch. + """ + if not isinstance(item, CharsetMatch): + raise ValueError( + "Cannot append instance '{}' to CharsetMatches".format( + str(item.__class__) + ) + ) + # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) + if len(item.raw) <= TOO_BIG_SEQUENCE: + for match in self._results: + if match.fingerprint == item.fingerprint and match.chaos == item.chaos: + match.add_submatch(item) + return + self._results.append(item) + self._results = sorted(self._results) + + def best(self) -> Optional["CharsetMatch"]: + """ + Simply return the first match. Strict equivalent to matches[0]. + """ + if not self._results: + return None + return self._results[0] + + def first(self) -> Optional["CharsetMatch"]: + """ + Redundant method, call the method best(). Kept for BC reasons. + """ + return self.best() + + +CoherenceMatch = Tuple[str, float] +CoherenceMatches = List[CoherenceMatch] + + +class CliDetectionResult: + def __init__( + self, + path: str, + encoding: Optional[str], + encoding_aliases: List[str], + alternative_encodings: List[str], + language: str, + alphabets: List[str], + has_sig_or_bom: bool, + chaos: float, + coherence: float, + unicode_path: Optional[str], + is_preferred: bool, + ): + self.path: str = path + self.unicode_path: Optional[str] = unicode_path + self.encoding: Optional[str] = encoding + self.encoding_aliases: List[str] = encoding_aliases + self.alternative_encodings: List[str] = alternative_encodings + self.language: str = language + self.alphabets: List[str] = alphabets + self.has_sig_or_bom: bool = has_sig_or_bom + self.chaos: float = chaos + self.coherence: float = coherence + self.is_preferred: bool = is_preferred + + @property + def __dict__(self) -> Dict[str, Any]: # type: ignore + return { + "path": self.path, + "encoding": self.encoding, + "encoding_aliases": self.encoding_aliases, + "alternative_encodings": self.alternative_encodings, + "language": self.language, + "alphabets": self.alphabets, + "has_sig_or_bom": self.has_sig_or_bom, + "chaos": self.chaos, + "coherence": self.coherence, + "unicode_path": self.unicode_path, + "is_preferred": self.is_preferred, + } + + def to_json(self) -> str: + return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/dist/ba_data/python-site-packages/charset_normalizer/py.typed b/dist/ba_data/python-site-packages/charset_normalizer/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dist/ba_data/python-site-packages/charset_normalizer/utils.py b/dist/ba_data/python-site-packages/charset_normalizer/utils.py new file mode 100644 index 00000000..e5cbbf4c --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/utils.py @@ -0,0 +1,421 @@ +import importlib +import logging +import unicodedata +from codecs import IncrementalDecoder +from encodings.aliases import aliases +from functools import lru_cache +from re import findall +from typing import Generator, List, Optional, Set, Tuple, Union + +from _multibytecodec import MultibyteIncrementalDecoder + +from .constant import ( + ENCODING_MARKS, + IANA_SUPPORTED_SIMILAR, + RE_POSSIBLE_ENCODING_INDICATION, + UNICODE_RANGES_COMBINED, + UNICODE_SECONDARY_RANGE_KEYWORD, + UTF8_MAXIMAL_ALLOCATION, +) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_accentuated(character: str) -> bool: + try: + description: str = unicodedata.name(character) + except ValueError: + return False + return ( + "WITH GRAVE" in description + or "WITH ACUTE" in description + or "WITH CEDILLA" in description + or "WITH DIAERESIS" in description + or "WITH CIRCUMFLEX" in description + or "WITH TILDE" in description + or "WITH MACRON" in description + or "WITH RING ABOVE" in description + ) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def remove_accent(character: str) -> str: + decomposed: str = unicodedata.decomposition(character) + if not decomposed: + return character + + codes: List[str] = decomposed.split(" ") + + return chr(int(codes[0], 16)) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def unicode_range(character: str) -> Optional[str]: + """ + Retrieve the Unicode range official name from a single character. + """ + character_ord: int = ord(character) + + for range_name, ord_range in UNICODE_RANGES_COMBINED.items(): + if character_ord in ord_range: + return range_name + + return None + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_latin(character: str) -> bool: + try: + description: str = unicodedata.name(character) + except ValueError: + return False + return "LATIN" in description + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_punctuation(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "P" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Punctuation" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_symbol(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "S" in character_category or "N" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Forms" in character_range and character_category != "Lo" + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_emoticon(character: str) -> bool: + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Emoticons" in character_range or "Pictographs" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_separator(character: str) -> bool: + if character.isspace() or character in {"|", "+", "<", ">"}: + return True + + character_category: str = unicodedata.category(character) + + return "Z" in character_category or character_category in {"Po", "Pd", "Pc"} + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_case_variable(character: str) -> bool: + return character.islower() != character.isupper() + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_cjk(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "CJK" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_hiragana(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "HIRAGANA" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_katakana(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "KATAKANA" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_hangul(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "HANGUL" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_thai(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "THAI" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_arabic(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "ARABIC" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_arabic_isolated_form(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "ARABIC" in character_name and "ISOLATED FORM" in character_name + + +@lru_cache(maxsize=len(UNICODE_RANGES_COMBINED)) +def is_unicode_range_secondary(range_name: str) -> bool: + return any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_unprintable(character: str) -> bool: + return ( + character.isspace() is False # includes \n \t \r \v + and character.isprintable() is False + and character != "\x1A" # Why? Its the ASCII substitute character. + and character != "\ufeff" # bug discovered in Python, + # Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space. + ) + + +def any_specified_encoding(sequence: bytes, search_zone: int = 8192) -> Optional[str]: + """ + Extract using ASCII-only decoder any specified encoding in the first n-bytes. + """ + if not isinstance(sequence, bytes): + raise TypeError + + seq_len: int = len(sequence) + + results: List[str] = findall( + RE_POSSIBLE_ENCODING_INDICATION, + sequence[: min(seq_len, search_zone)].decode("ascii", errors="ignore"), + ) + + if len(results) == 0: + return None + + for specified_encoding in results: + specified_encoding = specified_encoding.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + for encoding_alias, encoding_iana in aliases.items(): + if encoding_alias == specified_encoding: + return encoding_iana + if encoding_iana == specified_encoding: + return encoding_iana + + return None + + +@lru_cache(maxsize=128) +def is_multi_byte_encoding(name: str) -> bool: + """ + Verify is a specific encoding is a multi byte one based on it IANA name + """ + return name in { + "utf_8", + "utf_8_sig", + "utf_16", + "utf_16_be", + "utf_16_le", + "utf_32", + "utf_32_le", + "utf_32_be", + "utf_7", + } or issubclass( + importlib.import_module("encodings.{}".format(name)).IncrementalDecoder, + MultibyteIncrementalDecoder, + ) + + +def identify_sig_or_bom(sequence: bytes) -> Tuple[Optional[str], bytes]: + """ + Identify and extract SIG/BOM in given sequence. + """ + + for iana_encoding in ENCODING_MARKS: + marks: Union[bytes, List[bytes]] = ENCODING_MARKS[iana_encoding] + + if isinstance(marks, bytes): + marks = [marks] + + for mark in marks: + if sequence.startswith(mark): + return iana_encoding, mark + + return None, b"" + + +def should_strip_sig_or_bom(iana_encoding: str) -> bool: + return iana_encoding not in {"utf_16", "utf_32"} + + +def iana_name(cp_name: str, strict: bool = True) -> str: + cp_name = cp_name.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + for encoding_alias, encoding_iana in aliases.items(): + if cp_name in [encoding_alias, encoding_iana]: + return encoding_iana + + if strict: + raise ValueError("Unable to retrieve IANA for '{}'".format(cp_name)) + + return cp_name + + +def range_scan(decoded_sequence: str) -> List[str]: + ranges: Set[str] = set() + + for character in decoded_sequence: + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + ranges.add(character_range) + + return list(ranges) + + +def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: + if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): + return 0.0 + + decoder_a = importlib.import_module( + "encodings.{}".format(iana_name_a) + ).IncrementalDecoder + decoder_b = importlib.import_module( + "encodings.{}".format(iana_name_b) + ).IncrementalDecoder + + id_a: IncrementalDecoder = decoder_a(errors="ignore") + id_b: IncrementalDecoder = decoder_b(errors="ignore") + + character_match_count: int = 0 + + for i in range(255): + to_be_decoded: bytes = bytes([i]) + if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded): + character_match_count += 1 + + return character_match_count / 254 + + +def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: + """ + Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using + the function cp_similarity. + """ + return ( + iana_name_a in IANA_SUPPORTED_SIMILAR + and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] + ) + + +def set_logging_handler( + name: str = "charset_normalizer", + level: int = logging.INFO, + format_string: str = "%(asctime)s | %(levelname)s | %(message)s", +) -> None: + logger = logging.getLogger(name) + logger.setLevel(level) + + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(format_string)) + logger.addHandler(handler) + + +def cut_sequence_chunks( + sequences: bytes, + encoding_iana: str, + offsets: range, + chunk_size: int, + bom_or_sig_available: bool, + strip_sig_or_bom: bool, + sig_payload: bytes, + is_multi_byte_decoder: bool, + decoded_payload: Optional[str] = None, +) -> Generator[str, None, None]: + if decoded_payload and is_multi_byte_decoder is False: + for i in offsets: + chunk = decoded_payload[i : i + chunk_size] + if not chunk: + break + yield chunk + else: + for i in offsets: + chunk_end = i + chunk_size + if chunk_end > len(sequences) + 8: + continue + + cut_sequence = sequences[i : i + chunk_size] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode( + encoding_iana, + errors="ignore" if is_multi_byte_decoder else "strict", + ) + + # multi-byte bad cutting detector and adjustment + # not the cleanest way to perform that fix but clever enough for now. + if is_multi_byte_decoder and i > 0: + chunk_partial_size_chk: int = min(chunk_size, 16) + + if ( + decoded_payload + and chunk[:chunk_partial_size_chk] not in decoded_payload + ): + for j in range(i, i - 4, -1): + cut_sequence = sequences[j:chunk_end] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode(encoding_iana, errors="ignore") + + if chunk[:chunk_partial_size_chk] in decoded_payload: + break + + yield chunk diff --git a/dist/ba_data/python-site-packages/charset_normalizer/version.py b/dist/ba_data/python-site-packages/charset_normalizer/version.py new file mode 100644 index 00000000..5a4da4ff --- /dev/null +++ b/dist/ba_data/python-site-packages/charset_normalizer/version.py @@ -0,0 +1,6 @@ +""" +Expose version +""" + +__version__ = "3.3.2" +VERSION = __version__.split(".") diff --git a/dist/ba_data/python-site-packages/click-8.1.7.dist-info/INSTALLER b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/click-8.1.7.dist-info/LICENSE.rst b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 00000000..d12a8491 --- /dev/null +++ b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/ba_data/python-site-packages/click-8.1.7.dist-info/METADATA b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 00000000..7a6bbb24 --- /dev/null +++ b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Chat: https://discord.gg/pallets diff --git a/dist/ba_data/python-site-packages/click-8.1.7.dist-info/RECORD b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 00000000..95ff8c6c --- /dev/null +++ b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +click/__pycache__/__init__.cpython-312.pyc,, +click/__pycache__/_compat.cpython-312.pyc,, +click/__pycache__/_termui_impl.cpython-312.pyc,, +click/__pycache__/_textwrap.cpython-312.pyc,, +click/__pycache__/_winconsole.cpython-312.pyc,, +click/__pycache__/core.cpython-312.pyc,, +click/__pycache__/decorators.cpython-312.pyc,, +click/__pycache__/exceptions.cpython-312.pyc,, +click/__pycache__/formatting.cpython-312.pyc,, +click/__pycache__/globals.cpython-312.pyc,, +click/__pycache__/parser.cpython-312.pyc,, +click/__pycache__/shell_completion.cpython-312.pyc,, +click/__pycache__/termui.cpython-312.pyc,, +click/__pycache__/testing.cpython-312.pyc,, +click/__pycache__/types.cpython-312.pyc,, +click/__pycache__/utils.cpython-312.pyc,, +click/_compat.py,sha256=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/dist/ba_data/python-site-packages/click-8.1.7.dist-info/WHEEL b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 00000000..2c08da08 --- /dev/null +++ b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dist/ba_data/python-site-packages/click-8.1.7.dist-info/top_level.txt b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 00000000..dca9a909 --- /dev/null +++ b/dist/ba_data/python-site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/dist/ba_data/python-site-packages/click/__init__.py b/dist/ba_data/python-site-packages/click/__init__.py index 35176c73..9a1dab04 100644 --- a/dist/ba_data/python-site-packages/click/__init__.py +++ b/dist/ba_data/python-site-packages/click/__init__.py @@ -41,7 +41,6 @@ from .termui import confirm as confirm from .termui import echo_via_pager as echo_via_pager from .termui import edit as edit -from .termui import get_terminal_size as get_terminal_size from .termui import getchar as getchar from .termui import launch as launch from .termui import pause as pause @@ -68,8 +67,7 @@ from .utils import format_filename as format_filename from .utils import get_app_dir as get_app_dir from .utils import get_binary_stream as get_binary_stream -from .utils import get_os_args as get_os_args from .utils import get_text_stream as get_text_stream from .utils import open_file as open_file -__version__ = "8.0.4" +__version__ = "8.1.7" diff --git a/dist/ba_data/python-site-packages/click/_compat.py b/dist/ba_data/python-site-packages/click/_compat.py index 766d286b..23f88665 100644 --- a/dist/ba_data/python-site-packages/click/_compat.py +++ b/dist/ba_data/python-site-packages/click/_compat.py @@ -7,20 +7,11 @@ from weakref import WeakKeyDictionary CYGWIN = sys.platform.startswith("cygwin") -MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version) -# Determine local App Engine environment, per Google's own suggestion -APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get( - "SERVER_SOFTWARE", "" -) -WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2 +WIN = sys.platform.startswith("win") auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None _ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") -def get_filesystem_encoding() -> str: - return sys.getfilesystemencoding() or sys.getdefaultencoding() - - def _make_text_stream( stream: t.BinaryIO, encoding: t.Optional[str], @@ -50,7 +41,7 @@ def is_ascii_encoding(encoding: str) -> bool: return False -def get_best_encoding(stream: t.IO) -> str: +def get_best_encoding(stream: t.IO[t.Any]) -> str: """Returns the default stream encoding if not found.""" rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() if is_ascii_encoding(rv): @@ -153,7 +144,7 @@ def seekable(self) -> bool: return True -def _is_binary_reader(stream: t.IO, default: bool = False) -> bool: +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: try: return isinstance(stream.read(0), bytes) except Exception: @@ -162,7 +153,7 @@ def _is_binary_reader(stream: t.IO, default: bool = False) -> bool: # closed. In this case, we assume the default. -def _is_binary_writer(stream: t.IO, default: bool = False) -> bool: +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: try: stream.write(b"") except Exception: @@ -175,7 +166,7 @@ def _is_binary_writer(stream: t.IO, default: bool = False) -> bool: return True -def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]: +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: # We need to figure out if the given stream is already binary. # This can happen because the official docs recommend detaching # the streams to get binary streams. Some code might do this, so @@ -193,7 +184,7 @@ def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]: return None -def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]: +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: # We need to figure out if the given stream is already binary. # This can happen because the official docs recommend detaching # the streams to get binary streams. Some code might do this, so @@ -241,11 +232,11 @@ def _is_compatible_text_stream( def _force_correct_text_stream( - text_stream: t.IO, + text_stream: t.IO[t.Any], encoding: t.Optional[str], errors: t.Optional[str], - is_binary: t.Callable[[t.IO, bool], bool], - find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], force_readable: bool = False, force_writable: bool = False, ) -> t.TextIO: @@ -287,7 +278,7 @@ def _force_correct_text_stream( def _force_correct_text_reader( - text_reader: t.IO, + text_reader: t.IO[t.Any], encoding: t.Optional[str], errors: t.Optional[str], force_readable: bool = False, @@ -303,7 +294,7 @@ def _force_correct_text_reader( def _force_correct_text_writer( - text_writer: t.IO, + text_writer: t.IO[t.Any], encoding: t.Optional[str], errors: t.Optional[str], force_writable: bool = False, @@ -367,11 +358,11 @@ def get_text_stderr( def _wrap_io_open( - file: t.Union[str, os.PathLike, int], + file: t.Union[str, "os.PathLike[str]", int], mode: str, encoding: t.Optional[str], errors: t.Optional[str], -) -> t.IO: +) -> t.IO[t.Any]: """Handles not passing ``encoding`` and ``errors`` in binary mode.""" if "b" in mode: return open(file, mode) @@ -380,13 +371,14 @@ def _wrap_io_open( def open_stream( - filename: str, + filename: "t.Union[str, os.PathLike[str]]", mode: str = "r", encoding: t.Optional[str] = None, errors: t.Optional[str] = "strict", atomic: bool = False, -) -> t.Tuple[t.IO, bool]: +) -> t.Tuple[t.IO[t.Any], bool]: binary = "b" in mode + filename = os.fspath(filename) # Standard streams first. These are simple because they ignore the # atomic flag. Use fsdecode to handle Path("-"). @@ -456,11 +448,11 @@ def open_stream( f = _wrap_io_open(fd, mode, encoding, errors) af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) - return t.cast(t.IO, af), True + return t.cast(t.IO[t.Any], af), True class _AtomicFile: - def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: self._f = f self._tmp_filename = tmp_filename self._real_filename = real_filename @@ -483,7 +475,7 @@ def __getattr__(self, name: str) -> t.Any: def __enter__(self) -> "_AtomicFile": return self - def __exit__(self, exc_type, exc_value, tb): # type: ignore + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: self.close(delete=exc_type is not None) def __repr__(self) -> str: @@ -494,7 +486,7 @@ def strip_ansi(value: str) -> str: return _ansi_re.sub("", value) -def _is_jupyter_kernel_output(stream: t.IO) -> bool: +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): stream = stream._stream @@ -502,7 +494,7 @@ def _is_jupyter_kernel_output(stream: t.IO) -> bool: def should_strip_ansi( - stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None ) -> bool: if color is None: if stream is None: @@ -524,7 +516,7 @@ def _get_argv_encoding() -> str: _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() - def auto_wrap_for_ansi( + def auto_wrap_for_ansi( # noqa: F811 stream: t.TextIO, color: t.Optional[bool] = None ) -> t.TextIO: """Support ANSI color and style codes on Windows by wrapping a @@ -564,7 +556,7 @@ def _safe_write(s): else: def _get_argv_encoding() -> str: - return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding() + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() def _get_windows_console_stream( f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] @@ -576,7 +568,7 @@ def term_len(x: str) -> int: return len(strip_ansi(x)) -def isatty(stream: t.IO) -> bool: +def isatty(stream: t.IO[t.Any]) -> bool: try: return stream.isatty() except Exception: @@ -584,12 +576,17 @@ def isatty(stream: t.IO) -> bool: def _make_cached_stream_func( - src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO] -) -> t.Callable[[], t.TextIO]: + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() - def func() -> t.TextIO: + def func() -> t.Optional[t.TextIO]: stream = src_func() + + if stream is None: + return None + try: rv = cache.get(stream) except Exception: diff --git a/dist/ba_data/python-site-packages/click/_termui_impl.py b/dist/ba_data/python-site-packages/click/_termui_impl.py index 4b979bcc..f7446577 100644 --- a/dist/ba_data/python-site-packages/click/_termui_impl.py +++ b/dist/ba_data/python-site-packages/click/_termui_impl.py @@ -10,6 +10,8 @@ import time import typing as t from gettext import gettext as _ +from io import StringIO +from types import TracebackType from ._compat import _default_text_stdout from ._compat import CYGWIN @@ -59,15 +61,22 @@ def __init__( self.show_percent = show_percent self.show_pos = show_pos self.item_show_func = item_show_func - self.label = label or "" + self.label: str = label or "" + if file is None: file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + self.file = file self.color = color self.update_min_steps = update_min_steps self._completed_intervals = 0 - self.width = width - self.autowidth = width == 0 + self.width: int = width + self.autowidth: bool = width == 0 if length is None: from operator import length_hint @@ -80,25 +89,32 @@ def __init__( if length is None: raise TypeError("iterable or length is required") iterable = t.cast(t.Iterable[V], range(length)) - self.iter = iter(iterable) + self.iter: t.Iterable[V] = iter(iterable) self.length = length self.pos = 0 self.avg: t.List[float] = [] + self.last_eta: float + self.start: float self.start = self.last_eta = time.time() - self.eta_known = False - self.finished = False + self.eta_known: bool = False + self.finished: bool = False self.max_width: t.Optional[int] = None - self.entered = False + self.entered: bool = False self.current_item: t.Optional[V] = None - self.is_hidden = not isatty(self.file) + self.is_hidden: bool = not isatty(self.file) self._last_line: t.Optional[str] = None - def __enter__(self) -> "ProgressBar": + def __enter__(self) -> "ProgressBar[V]": self.entered = True self.render_progress() return self - def __exit__(self, exc_type, exc_value, tb): # type: ignore + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: self.render_finish() def __iter__(self) -> t.Iterator[V]: @@ -344,6 +360,12 @@ def generator(self) -> t.Iterator[V]: def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: """Decide what method to use for paging through text.""" stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + if not isatty(sys.stdin) or not isatty(stdout): return _nullpager(stdout, generator, color) pager_cmd = (os.environ.get("PAGER", None) or "").strip() diff --git a/dist/ba_data/python-site-packages/click/_unicodefun.py b/dist/ba_data/python-site-packages/click/_unicodefun.py deleted file mode 100644 index 9cb30c38..00000000 --- a/dist/ba_data/python-site-packages/click/_unicodefun.py +++ /dev/null @@ -1,100 +0,0 @@ -import codecs -import os -from gettext import gettext as _ - - -def _verify_python_env() -> None: - """Ensures that the environment is good for Unicode.""" - try: - from locale import getpreferredencoding - - fs_enc = codecs.lookup(getpreferredencoding()).name - except Exception: - fs_enc = "ascii" - - if fs_enc != "ascii": - return - - extra = [ - _( - "Click will abort further execution because Python was" - " configured to use ASCII as encoding for the environment." - " Consult https://click.palletsprojects.com/unicode-support/" - " for mitigation steps." - ) - ] - - if os.name == "posix": - import subprocess - - try: - rv = subprocess.Popen( - ["locale", "-a"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - encoding="ascii", - errors="replace", - ).communicate()[0] - except OSError: - rv = "" - - good_locales = set() - has_c_utf8 = False - - for line in rv.splitlines(): - locale = line.strip() - - if locale.lower().endswith((".utf-8", ".utf8")): - good_locales.add(locale) - - if locale.lower() in ("c.utf8", "c.utf-8"): - has_c_utf8 = True - - if not good_locales: - extra.append( - _( - "Additional information: on this system no suitable" - " UTF-8 locales were discovered. This most likely" - " requires resolving by reconfiguring the locale" - " system." - ) - ) - elif has_c_utf8: - extra.append( - _( - "This system supports the C.UTF-8 locale which is" - " recommended. You might be able to resolve your" - " issue by exporting the following environment" - " variables:" - ) - ) - extra.append(" export LC_ALL=C.UTF-8\n export LANG=C.UTF-8") - else: - extra.append( - _( - "This system lists some UTF-8 supporting locales" - " that you can pick from. The following suitable" - " locales were discovered: {locales}" - ).format(locales=", ".join(sorted(good_locales))) - ) - - bad_locale = None - - for env_locale in os.environ.get("LC_ALL"), os.environ.get("LANG"): - if env_locale and env_locale.lower().endswith((".utf-8", ".utf8")): - bad_locale = env_locale - - if env_locale is not None: - break - - if bad_locale is not None: - extra.append( - _( - "Click discovered that you exported a UTF-8 locale" - " but the locale system could not pick up from it" - " because it does not exist. The exported locale is" - " {locale!r} but it is not supported." - ).format(locale=bad_locale) - ) - - raise RuntimeError("\n\n".join(extra)) diff --git a/dist/ba_data/python-site-packages/click/core.py b/dist/ba_data/python-site-packages/click/core.py index 6d8cace9..cc65e896 100644 --- a/dist/ba_data/python-site-packages/click/core.py +++ b/dist/ba_data/python-site-packages/click/core.py @@ -7,14 +7,13 @@ from collections import abc from contextlib import contextmanager from contextlib import ExitStack -from functools import partial from functools import update_wrapper from gettext import gettext as _ from gettext import ngettext from itertools import repeat +from types import TracebackType from . import types -from ._unicodefun import _verify_python_env from .exceptions import Abort from .exceptions import BadParameter from .exceptions import ClickException @@ -224,9 +223,14 @@ class Context: codes are used in texts that Click prints which is by default not the case. This for instance would affect help output. - :param show_default: Show defaults for all options. If not set, - defaults to the value from a parent context. Overrides an - option's ``show_default`` argument. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. .. versionchanged:: 8.0 The ``show_default`` parameter defaults to the value from the @@ -260,7 +264,7 @@ def __init__( info_name: t.Optional[str] = None, obj: t.Optional[t.Any] = None, auto_envvar_prefix: t.Optional[str] = None, - default_map: t.Optional[t.Dict[str, t.Any]] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, terminal_width: t.Optional[int] = None, max_content_width: t.Optional[int] = None, resilient_parsing: bool = False, @@ -288,6 +292,8 @@ def __init__( #: must be never propagated to another arguments. This is used #: to implement nested parsing. self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() if obj is None and parent is not None: obj = parent.obj @@ -305,7 +311,7 @@ def __init__( ): default_map = parent.default_map.get(info_name) - self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map #: This flag indicates if a subcommand is going to be executed. A #: group callback can use this information to figure out if it's @@ -449,7 +455,12 @@ def __enter__(self) -> "Context": push_context(self) return self - def __exit__(self, exc_type, exc_value, tb): # type: ignore + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: self._depth -= 1 if self._depth == 0: self.close() @@ -700,12 +711,30 @@ def _make_sub_context(self, command: "Command") -> "Context": """ return type(self)(command, info_name=command.name, parent=self) + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload def invoke( __self, # noqa: B902 - __callback: t.Union["Command", t.Callable[..., t.Any]], + __callback: "Command", *args: t.Any, **kwargs: t.Any, ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: """Invokes a command callback in exactly the way it expects. There are two ways to invoke this method: @@ -733,7 +762,7 @@ def invoke( "The given command does not have a callback that can be invoked." ) else: - __callback = other_cmd.callback + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) ctx = __self._make_sub_context(other_cmd) @@ -838,7 +867,7 @@ class BaseCommand: def __init__( self, name: t.Optional[str], - context_settings: t.Optional[t.Dict[str, t.Any]] = None, + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, ) -> None: #: the name the command thinks it has. Upon registering a command #: on a :class:`Group` the group will default the command name @@ -850,7 +879,7 @@ def __init__( context_settings = {} #: an optional dictionary with defaults passed to the context. - self.context_settings: t.Dict[str, t.Any] = context_settings + self.context_settings: t.MutableMapping[str, t.Any] = context_settings def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: """Gather information that could be useful for a tool generating @@ -892,7 +921,7 @@ def make_context( :param info_name: the info name for this invocation. Generally this is the most descriptive name for the script or command. For the toplevel script it's usually - the name of the script, for commands below it it's + the name of the script, for commands below it's the name of the command. :param args: the arguments to parse as list of strings. :param parent: the parent context if available. @@ -925,7 +954,7 @@ def invoke(self, ctx: Context) -> t.Any: """Given a context, this invokes the command. The default implementation is raising a not implemented error. """ - raise NotImplementedError("Base commands are not invokable by default") + raise NotImplementedError("Base commands are not invocable by default") def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: """Return a list of completions for the incomplete value. Looks @@ -1029,10 +1058,6 @@ def main( .. versionchanged:: 3.0 Added the ``standalone_mode`` parameter. """ - # Verify that the environment is configured correctly, or reject - # further execution to avoid a broken script. - _verify_python_env() - if args is None: args = sys.argv[1:] @@ -1061,9 +1086,9 @@ def main( # even always obvious that `rv` indicates success/failure # by its truthiness/falsiness ctx.exit() - except (EOFError, KeyboardInterrupt): + except (EOFError, KeyboardInterrupt) as e: echo(file=sys.stderr) - raise Abort() from None + raise Abort() from e except ClickException as e: if not standalone_mode: raise @@ -1097,7 +1122,7 @@ def main( def _main_shell_completion( self, - ctx_args: t.Dict[str, t.Any], + ctx_args: t.MutableMapping[str, t.Any], prog_name: str, complete_var: t.Optional[str] = None, ) -> None: @@ -1109,9 +1134,13 @@ def _main_shell_completion( :param complete_var: Name of the environment variable that holds the completion instruction. Defaults to ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). """ if complete_var is None: - complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper() + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() instruction = os.environ.get(complete_var) @@ -1133,13 +1162,6 @@ class Command(BaseCommand): Click. A basic command handles command line parsing and might dispatch more parsing to commands nested below it. - .. versionchanged:: 2.0 - Added the `context_settings` parameter. - .. versionchanged:: 8.0 - Added repr showing the command name - .. versionchanged:: 7.1 - Added the `no_args_is_help` parameter. - :param name: the name of the command to use unless a group overrides it. :param context_settings: an optional dictionary with defaults that are passed to the context object. @@ -1161,12 +1183,26 @@ class Command(BaseCommand): :param deprecated: issues a message indicating that the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. """ def __init__( self, name: t.Optional[str], - context_settings: t.Optional[t.Dict[str, t.Any]] = None, + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, callback: t.Optional[t.Callable[..., t.Any]] = None, params: t.Optional[t.List["Parameter"]] = None, help: t.Optional[str] = None, @@ -1186,12 +1222,6 @@ def __init__( #: should show up in the help page and execute. Eager parameters #: will automatically be handled before non eager ones. self.params: t.List["Parameter"] = params or [] - - # if a form feed (page break) is found in the help text, truncate help - # text to the content preceding the first form feed - if help and "\f" in help: - help = help.split("\f", 1)[0] - self.help = help self.epilog = epilog self.options_metavar = options_metavar @@ -1299,10 +1329,12 @@ def get_short_help_str(self, limit: int = 45) -> str: """Gets short help for the command or makes it by shortening the long help string. """ - text = self.short_help or "" - - if not text and self.help: + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: text = make_default_short_help(self.help, limit) + else: + text = "" if self.deprecated: text = _("(Deprecated) {text}").format(text=text) @@ -1328,7 +1360,11 @@ def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: """Writes the help text to the formatter if it exists.""" - text = self.help or "" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" if self.deprecated: text = _("(Deprecated) {text}").format(text=text) @@ -1354,9 +1390,11 @@ def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: """Writes the epilog into the formatter if it exists.""" if self.epilog: + epilog = inspect.cleandoc(self.epilog) formatter.write_paragraph() + with formatter.indentation(): - formatter.write_text(self.epilog) + formatter.write_text(epilog) def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: if not args and self.no_args_is_help and not ctx.resilient_parsing: @@ -1379,6 +1417,7 @@ def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: ) ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) return args def invoke(self, ctx: Context) -> t.Any: @@ -1453,6 +1492,7 @@ class MultiCommand(Command): :param result_callback: The result callback to attach to this multi command. This can be set or changed later with the :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. """ allow_extra_args = True @@ -1560,7 +1600,7 @@ def decorator(f: F) -> F: return f def function(__value, *args, **kwargs): # type: ignore - inner = old_callback(__value, *args, **kwargs) # type: ignore + inner = old_callback(__value, *args, **kwargs) return f(inner, *args, **kwargs) self._result_callback = rv = update_wrapper(t.cast(F, function), f) @@ -1568,17 +1608,6 @@ def function(__value, *args, **kwargs): # type: ignore return decorator - def resultcallback(self, replace: bool = False) -> t.Callable[[F], F]: - import warnings - - warnings.warn( - "'resultcallback' has been renamed to 'result_callback'." - " The old name will be removed in Click 8.1.", - DeprecationWarning, - stacklevel=2, - ) - return self.result_callback(replace=replace) - def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: """Extra format methods for multi methods that adds all the commands after the options. @@ -1631,11 +1660,11 @@ def _process_result(value: t.Any) -> t.Any: if not ctx.protected_args: if self.invoke_without_command: # No subcommand was invoked, so the result callback is - # invoked with None for regular groups, or an empty list - # for chained groups. + # invoked with the group return value for regular + # groups, or an empty list for chained groups. with ctx: - super().invoke(ctx) - return _process_result([] if self.chain else None) + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) ctx.fail(_("Missing command.")) # Fetch args back out @@ -1762,7 +1791,7 @@ class Group(MultiCommand): :class:`BaseCommand`. .. versionchanged:: 8.0 - The ``commmands`` argument can be a list of command objects. + The ``commands`` argument can be a list of command objects. """ #: If set, this is used by the group's :meth:`command` decorator @@ -1788,7 +1817,9 @@ class Group(MultiCommand): def __init__( self, name: t.Optional[str] = None, - commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, **attrs: t.Any, ) -> None: super().__init__(name, **attrs) @@ -1799,7 +1830,7 @@ def __init__( commands = {c.name: c for c in commands if c.name is not None} #: The registered subcommands by their exported names. - self.commands: t.Dict[str, Command] = commands + self.commands: t.MutableMapping[str, Command] = commands def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: """Registers another :class:`Command` with this group. If the name @@ -1811,9 +1842,19 @@ def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: _check_multicommand(self, name, cmd, register=True) self.commands[name] = cmd + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload def command( self, *args: t.Any, **kwargs: t.Any ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: """A shortcut decorator for declaring and attaching a command to the group. This takes the same arguments as :func:`command` and immediately registers the created command with this group by @@ -1822,24 +1863,49 @@ def command( To customize the command class used, set the :attr:`command_class` attribute. + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + .. versionchanged:: 8.0 Added the :attr:`command_class` attribute. """ from .decorators import command - if self.command_class is not None and "cls" not in kwargs: + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: kwargs["cls"] = self.command_class def decorator(f: t.Callable[..., t.Any]) -> Command: - cmd = command(*args, **kwargs)(f) + cmd: Command = command(*args, **kwargs)(f) self.add_command(cmd) return cmd + if func is not None: + return decorator(func) + return decorator + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload def group( self, *args: t.Any, **kwargs: t.Any ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: """A shortcut decorator for declaring and attaching a group to the group. This takes the same arguments as :func:`group` and immediately registers the created group with this group by @@ -1848,22 +1914,37 @@ def group( To customize the group class used, set the :attr:`group_class` attribute. + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + .. versionchanged:: 8.0 Added the :attr:`group_class` attribute. """ from .decorators import group - if self.group_class is not None and "cls" not in kwargs: + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: if self.group_class is type: kwargs["cls"] = type(self) else: kwargs["cls"] = self.group_class def decorator(f: t.Callable[..., t.Any]) -> "Group": - cmd = group(*args, **kwargs)(f) + cmd: Group = group(*args, **kwargs)(f) self.add_command(cmd) return cmd + if func is not None: + return decorator(func) + return decorator def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: @@ -1878,6 +1959,9 @@ class CommandCollection(MultiCommand): commands together into one. This is a straightforward implementation that accepts a list of different multi commands as sources and provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. """ def __init__( @@ -1937,7 +2021,7 @@ class Parameter: argument. This is a list of flags or argument names. :param type: the type that should be used. Either a :class:`ParamType` - or a Python type. The later is converted into the former + or a Python type. The latter is converted into the former automatically if supported. :param required: controls if this is optional or not. :param default: the default value if omitted. This can also be a callable, @@ -2020,16 +2104,14 @@ def __init__( t.Union[t.List["CompletionItem"], t.List[str]], ] ] = None, - autocompletion: t.Optional[ - t.Callable[ - [Context, t.List[str], str], t.List[t.Union[t.Tuple[str, str], str]] - ] - ] = None, ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] self.name, self.opts, self.secondary_opts = self._parse_decls( param_decls or (), expose_value ) - self.type = types.convert_type(type, default) + self.type: types.ParamType = types.convert_type(type, default) # Default nargs to what the type tells us if we have that # information available. @@ -2048,36 +2130,6 @@ def __init__( self.is_eager = is_eager self.metavar = metavar self.envvar = envvar - - if autocompletion is not None: - import warnings - - warnings.warn( - "'autocompletion' is renamed to 'shell_complete'. The old name is" - " deprecated and will be removed in Click 8.1. See the docs about" - " 'Parameter' for information about new behavior.", - DeprecationWarning, - stacklevel=2, - ) - - def shell_complete( - ctx: Context, param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - from click.shell_completion import CompletionItem - - out = [] - - for c in autocompletion(ctx, [], incomplete): # type: ignore - if isinstance(c, tuple): - c = CompletionItem(c[0], help=c[1]) - elif isinstance(c, str): - c = CompletionItem(c) - - if c.value.startswith(incomplete): - out.append(c) - - return out - self._custom_shell_complete = shell_complete if __debug__: @@ -2247,7 +2299,7 @@ def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: if value is None: return () if self.multiple or self.nargs == -1 else None - def check_iter(value: t.Any) -> t.Iterator: + def check_iter(value: t.Any) -> t.Iterator[t.Any]: try: return _check_iter(value) except TypeError: @@ -2259,17 +2311,18 @@ def check_iter(value: t.Any) -> t.Iterator: ) from None if self.nargs == 1 or self.type.is_composite: - convert: t.Callable[[t.Any], t.Any] = partial( - self.type, param=self, ctx=ctx - ) + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + elif self.nargs == -1: - def convert(value: t.Any) -> t.Tuple: + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] return tuple(self.type(x, self, ctx) for x in check_iter(value)) else: # nargs > 1 - def convert(value: t.Any) -> t.Tuple: + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] value = tuple(check_iter(value)) if len(value) != self.nargs: @@ -2399,25 +2452,27 @@ class Option(Parameter): All other parameters are passed onwards to the parameter constructor. - :param show_default: controls if the default value should be shown on the - help page. Normally, defaults are not shown. If this - value is a string, it shows the string instead of the - value. This is particularly useful for dynamic options. - :param show_envvar: controls if an environment variable should be shown on - the help page. Normally, environment variables - are not shown. - :param prompt: if set to `True` or a non empty string then the user will be - prompted for input. If set to `True` the prompt will be the - option name capitalized. + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. :param confirmation_prompt: Prompt a second time to confirm the value if it was prompted for. Can be set to a string instead of ``True`` to customize the message. :param prompt_required: If set to ``False``, the user will be prompted for input only when the option was specified as a flag without a value. - :param hide_input: if this is `True` then the input on the prompt will be - hidden from the user. This is useful for password - input. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. :param is_flag: forces this option to act as a flag. The default is auto detection. :param flag_value: which value should be used for this flag if it's @@ -2434,6 +2489,19 @@ class Option(Parameter): context. :param help: the help string. :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. .. versionchanged:: 8.0.1 ``type`` is detected from ``flag_value`` if given. @@ -2444,7 +2512,7 @@ class Option(Parameter): def __init__( self, param_decls: t.Optional[t.Sequence[str]] = None, - show_default: t.Union[bool, str] = False, + show_default: t.Union[bool, str, None] = None, prompt: t.Union[bool, str] = False, confirmation_prompt: t.Union[bool, str] = False, prompt_required: bool = True, @@ -2461,6 +2529,9 @@ def __init__( show_envvar: bool = False, **attrs: t.Any, ) -> None: + if help: + help = inspect.cleandoc(help) + default_is_missing = "default" not in attrs super().__init__(param_decls, type=type, multiple=multiple, **attrs) @@ -2499,19 +2570,25 @@ def __init__( # flag if flag_value is set. self._flag_needs_value = flag_value is not None - if is_flag and default_is_missing: - self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False if flag_value is None: flag_value = not self.default + self.type: types.ParamType if is_flag and type is None: # Re-guess the type from the flag value instead of the # default. self.type = types.convert_type(None, flag_value) self.is_flag: bool = is_flag - self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType) + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) self.flag_value: t.Any = flag_value # Counting @@ -2711,11 +2788,18 @@ def _write_opts(opts: t.Sequence[str]) -> str: finally: ctx.resilient_parsing = resilient - show_default_is_str = isinstance(self.show_default, str) + show_default = False + show_default_is_str = False - if show_default_is_str or ( - default_value is not None and (self.show_default or ctx.show_default) - ): + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): if show_default_is_str: default_string = f"({self.show_default})" elif isinstance(default_value, (list, tuple)): @@ -2728,6 +2812,8 @@ def _write_opts(opts: t.Sequence[str]) -> str: default_string = split_opt( (self.opts if self.default else self.secondary_opts)[0] )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" else: default_string = str(default_value) @@ -2775,7 +2861,7 @@ def get_default( if self.is_flag and not self.is_bool_flag: for param in ctx.command.params: if param.name == self.name and param.default: - return param.flag_value # type: ignore + return t.cast(Option, param).flag_value return None @@ -2821,7 +2907,10 @@ def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" rv = os.environ.get(envvar) - return rv + if rv: + return rv + + return None def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) @@ -2882,7 +2971,7 @@ class Argument(Parameter): provide fewer features than options but can have infinite ``nargs`` and are required by default. - All parameters are passed onwards to the parameter constructor. + All parameters are passed onwards to the constructor of :class:`Parameter`. """ param_type_name = "argument" diff --git a/dist/ba_data/python-site-packages/click/decorators.py b/dist/ba_data/python-site-packages/click/decorators.py index 7930a169..d9bba950 100644 --- a/dist/ba_data/python-site-packages/click/decorators.py +++ b/dist/ba_data/python-site-packages/click/decorators.py @@ -13,36 +13,43 @@ from .globals import get_current_context from .utils import echo -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) -FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command]) +if t.TYPE_CHECKING: + import typing_extensions as te + P = te.ParamSpec("P") -def pass_context(f: F) -> F: +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": """Marks a callback as wanting to receive the current context object as first argument. """ - def new_func(*args, **kwargs): # type: ignore + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": return f(get_current_context(), *args, **kwargs) - return update_wrapper(t.cast(F, new_func), f) + return update_wrapper(new_func, f) -def pass_obj(f: F) -> F: +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": """Similar to :func:`pass_context`, but only pass the object on the context onwards (:attr:`Context.obj`). This is useful if that object represents the state of a nested system. """ - def new_func(*args, **kwargs): # type: ignore + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": return f(get_current_context().obj, *args, **kwargs) - return update_wrapper(t.cast(F, new_func), f) + return update_wrapper(new_func, f) def make_pass_decorator( - object_type: t.Type, ensure: bool = False -) -> "t.Callable[[F], F]": + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: """Given an object type this creates a decorator that will work similar to :func:`pass_obj` but instead of passing the object of the current context, it will find the innermost context of type @@ -65,10 +72,11 @@ def new_func(ctx, *args, **kwargs): remembered on the context if it's not there yet. """ - def decorator(f: F) -> F: - def new_func(*args, **kwargs): # type: ignore + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": ctx = get_current_context() + obj: t.Optional[T] if ensure: obj = ctx.ensure_object(object_type) else: @@ -83,14 +91,14 @@ def new_func(*args, **kwargs): # type: ignore return ctx.invoke(f, obj, *args, **kwargs) - return update_wrapper(t.cast(F, new_func), f) + return update_wrapper(new_func, f) - return decorator + return decorator # type: ignore[return-value] def pass_meta_key( key: str, *, doc_description: t.Optional[str] = None -) -> "t.Callable[[F], F]": +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": """Create a decorator that passes a key from :attr:`click.Context.meta` as the first argument to the decorated function. @@ -103,13 +111,13 @@ def pass_meta_key( .. versionadded:: 8.0 """ - def decorator(f: F) -> F: - def new_func(*args, **kwargs): # type: ignore + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: ctx = get_current_context() obj = ctx.meta[key] return ctx.invoke(f, obj, *args, **kwargs) - return update_wrapper(t.cast(F, new_func), f) + return update_wrapper(new_func, f) if doc_description is None: doc_description = f"the {key!r} key from :attr:`click.Context.meta`" @@ -118,46 +126,53 @@ def new_func(*args, **kwargs): # type: ignore f"Decorator that passes {doc_description} as the first argument" " to the decorated function." ) - return decorator + return decorator # type: ignore[return-value] + + +CmdType = t.TypeVar("CmdType", bound=Command) + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: + ... -def _make_command( - f: F, + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( name: t.Optional[str], - attrs: t.MutableMapping[str, t.Any], - cls: t.Type[Command], -) -> Command: - if isinstance(f, Command): - raise TypeError("Attempted to convert a callback into a command twice.") + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... - try: - params = f.__click_params__ # type: ignore - params.reverse() - del f.__click_params__ # type: ignore - except AttributeError: - params = [] - help = attrs.get("help") +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... - if help is None: - help = inspect.getdoc(f) - else: - help = inspect.cleandoc(help) - - attrs["help"] = help - return cls( - name=name or f.__name__.lower().replace("_", "-"), - callback=f, - params=params, - **attrs, - ) + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: + ... def command( - name: t.Optional[str] = None, - cls: t.Optional[t.Type[Command]] = None, + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, **attrs: t.Any, -) -> t.Callable[[F], Command]: +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: r"""Creates a new :class:`Command` and uses the decorated function as callback. This will also automatically attach all decorated :func:`option`\s and :func:`argument`\s as parameters to the command. @@ -167,6 +182,8 @@ def command( pass the intended name as the first argument. All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. Once decorated the function turns into a :class:`Command` instance that can be invoked as a command line utility or be attached to a @@ -176,28 +193,124 @@ def command( name with underscores replaced by dashes. :param cls: the command class to instantiate. This defaults to :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. """ - if cls is None: - cls = Command - def decorator(f: t.Callable[..., t.Any]) -> Command: - cmd = _make_command(f, name, attrs, cls) # type: ignore + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) cmd.__doc__ = f.__doc__ return cmd + if func is not None: + return decorator(func) + return decorator -def group(name: t.Optional[str] = None, **attrs: t.Any) -> t.Callable[[F], Group]: +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: + ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: """Creates a new :class:`Group` with a function as callback. This works otherwise the same as :func:`command` just that the `cls` parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. """ - attrs.setdefault("cls", Group) - return t.cast(Group, command(name, **attrs)) + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + if callable(name): + return command(cls=cls, **attrs)(name) -def _param_memo(f: FC, param: Parameter) -> None: + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: if isinstance(f, Command): f.params.append(param) else: @@ -207,44 +320,57 @@ def _param_memo(f: FC, param: Parameter) -> None: f.__click_params__.append(param) # type: ignore -def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: """Attaches an argument to the command. All positional arguments are passed as parameter declarations to :class:`Argument`; all keyword arguments are forwarded unchanged (except ``cls``). This is equivalent to creating an :class:`Argument` instance manually and attaching it to the :attr:`Command.params` list. + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + :param cls: the argument class to instantiate. This defaults to :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. """ + if cls is None: + cls = Argument def decorator(f: FC) -> FC: - ArgumentClass = attrs.pop("cls", Argument) - _param_memo(f, ArgumentClass(param_decls, **attrs)) + _param_memo(f, cls(param_decls, **attrs)) return f return decorator -def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: """Attaches an option to the command. All positional arguments are passed as parameter declarations to :class:`Option`; all keyword arguments are forwarded unchanged (except ``cls``). This is equivalent to creating an :class:`Option` instance manually and attaching it to the :attr:`Command.params` list. + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + :param cls: the option class to instantiate. This defaults to :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. """ + if cls is None: + cls = Option def decorator(f: FC) -> FC: - # Issue 926, copy attrs, so pre-defined options can re-use the same cls= - option_attrs = attrs.copy() - - if "help" in option_attrs: - option_attrs["help"] = inspect.cleandoc(option_attrs["help"]) - OptionClass = option_attrs.pop("cls", Option) - _param_memo(f, OptionClass(param_decls, **option_attrs)) + _param_memo(f, cls(param_decls, **attrs)) return f return decorator @@ -388,8 +514,7 @@ def callback(ctx: Context, param: Parameter, value: bool) -> None: ) echo( - t.cast(str, message) - % {"prog": prog_name, "package": package_name, "version": version}, + message % {"prog": prog_name, "package": package_name, "version": version}, color=ctx.color, ) ctx.exit() diff --git a/dist/ba_data/python-site-packages/click/exceptions.py b/dist/ba_data/python-site-packages/click/exceptions.py index 9e20b3eb..fe68a361 100644 --- a/dist/ba_data/python-site-packages/click/exceptions.py +++ b/dist/ba_data/python-site-packages/click/exceptions.py @@ -1,12 +1,13 @@ -import os import typing as t from gettext import gettext as _ from gettext import ngettext from ._compat import get_text_stderr from .utils import echo +from .utils import format_filename if t.TYPE_CHECKING: + from .core import Command from .core import Context from .core import Parameter @@ -36,7 +37,7 @@ def format_message(self) -> str: def __str__(self) -> str: return self.message - def show(self, file: t.Optional[t.IO] = None) -> None: + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: if file is None: file = get_text_stderr() @@ -57,9 +58,9 @@ class UsageError(ClickException): def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: super().__init__(message) self.ctx = ctx - self.cmd = self.ctx.command if self.ctx else None + self.cmd: t.Optional["Command"] = self.ctx.command if self.ctx else None - def show(self, file: t.Optional[t.IO] = None) -> None: + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: if file is None: file = get_text_stderr() color = None @@ -261,7 +262,7 @@ def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: hint = _("unknown error") super().__init__(hint) - self.ui_filename = os.fsdecode(filename) + self.ui_filename: str = format_filename(filename) self.filename = filename def format_message(self) -> str: @@ -284,4 +285,4 @@ class Exit(RuntimeError): __slots__ = ("exit_code",) def __init__(self, code: int = 0) -> None: - self.exit_code = code + self.exit_code: int = code diff --git a/dist/ba_data/python-site-packages/click/parser.py b/dist/ba_data/python-site-packages/click/parser.py index 2d5a2ed7..5fa7adfa 100644 --- a/dist/ba_data/python-site-packages/click/parser.py +++ b/dist/ba_data/python-site-packages/click/parser.py @@ -168,7 +168,7 @@ def __init__( ): self._short_opts = [] self._long_opts = [] - self.prefixes = set() + self.prefixes: t.Set[str] = set() for opt in opts: prefix, value = split_opt(opt) @@ -194,7 +194,7 @@ def __init__( def takes_value(self) -> bool: return self.action in ("store", "append") - def process(self, value: str, state: "ParsingState") -> None: + def process(self, value: t.Any, state: "ParsingState") -> None: if self.action == "store": state.opts[self.dest] = value # type: ignore elif self.action == "store_const": @@ -272,12 +272,12 @@ def __init__(self, ctx: t.Optional["Context"] = None) -> None: #: If this is set to `False`, the parser will stop on the first #: non-option. Click uses this to implement nested subcommands #: safely. - self.allow_interspersed_args = True + self.allow_interspersed_args: bool = True #: This tells the parser how to deal with unknown options. By #: default it will error out (which is sensible), but there is a #: second mode where it will ignore it and continue processing #: after shifting all the unknown options into the resulting args. - self.ignore_unknown_options = False + self.ignore_unknown_options: bool = False if ctx is not None: self.allow_interspersed_args = ctx.allow_interspersed_args @@ -451,7 +451,7 @@ def _match_short_opt(self, arg: str, state: ParsingState) -> None: if stop: break - # If we got any unknown options we re-combinate the string of the + # If we got any unknown options we recombine the string of the # remaining options and re-attach the prefix, then report that # to the state as new larg. This way there is basic combinatorics # that can be achieved while still ignoring unknown arguments. diff --git a/dist/ba_data/python-site-packages/click/shell_completion.py b/dist/ba_data/python-site-packages/click/shell_completion.py index 1e9df6f9..dc9e00b9 100644 --- a/dist/ba_data/python-site-packages/click/shell_completion.py +++ b/dist/ba_data/python-site-packages/click/shell_completion.py @@ -16,7 +16,7 @@ def shell_complete( cli: BaseCommand, - ctx_args: t.Dict[str, t.Any], + ctx_args: t.MutableMapping[str, t.Any], prog_name: str, complete_var: str, instruction: str, @@ -80,9 +80,9 @@ def __init__( help: t.Optional[str] = None, **kwargs: t.Any, ) -> None: - self.value = value - self.type = type - self.help = help + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help self._info = kwargs def __getattr__(self, name: str) -> t.Any: @@ -157,17 +157,19 @@ def __getattr__(self, name: str) -> t.Any: fi } -compdef %(complete_func)s %(prog_name)s; +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi """ _SOURCE_FISH = """\ function %(complete_func)s; - set -l response; - - for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ COMP_CWORD=(commandline -t) %(prog_name)s); - set response $response $value; - end; for completion in $response; set -l metadata (string split "," $completion); @@ -214,7 +216,7 @@ class ShellComplete: def __init__( self, cli: BaseCommand, - ctx_args: t.Dict[str, t.Any], + ctx_args: t.MutableMapping[str, t.Any], prog_name: str, complete_var: str, ) -> None: @@ -228,7 +230,7 @@ def func_name(self) -> str: """The name of the shell function defined by the completion script. """ - safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII) + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) return f"_{safe_name}_completion" def source_vars(self) -> t.Dict[str, t.Any]: @@ -299,11 +301,12 @@ class BashComplete(ShellComplete): name = "bash" source_template = _SOURCE_BASH - def _check_version(self) -> None: + @staticmethod + def _check_version() -> None: import subprocess output = subprocess.run( - ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE + ["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE ) match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) @@ -311,15 +314,17 @@ def _check_version(self) -> None: major, minor = match.groups() if major < "4" or major == "4" and minor < "4": - raise RuntimeError( + echo( _( "Shell completion is not supported for Bash" " versions older than 4.4." - ) + ), + err=True, ) else: - raise RuntimeError( - _("Couldn't detect Bash version, shell completion is not supported.") + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, ) def source(self) -> str: @@ -389,6 +394,9 @@ def format_completion(self, item: CompletionItem) -> str: return f"{item.type},{item.value}" +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + _available_shells: t.Dict[str, t.Type[ShellComplete]] = { "bash": BashComplete, "fish": FishComplete, @@ -397,8 +405,8 @@ def format_completion(self, item: CompletionItem) -> str: def add_completion_class( - cls: t.Type[ShellComplete], name: t.Optional[str] = None -) -> None: + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: """Register a :class:`ShellComplete` subclass under the given name. The name will be provided by the completion instruction environment variable during completion. @@ -413,6 +421,8 @@ def add_completion_class( _available_shells[name] = cls + return cls + def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: """Look up a registered :class:`ShellComplete` subclass by the name @@ -436,7 +446,8 @@ def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: return False assert param.name is not None - value = ctx.params[param.name] + # Will be None if expose_value is False. + value = ctx.params.get(param.name) return ( param.nargs == -1 or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE @@ -448,17 +459,16 @@ def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: ) -def _start_of_option(value: str) -> bool: +def _start_of_option(ctx: Context, value: str) -> bool: """Check if the value looks like the start of an option.""" if not value: return False c = value[0] - # Allow "/" since that starts a path. - return not c.isalnum() and c != "/" + return c in ctx._opt_prefixes -def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: """Determine if the given parameter is an option that needs a value. :param args: List of complete args before the incomplete value. @@ -467,7 +477,7 @@ def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: if not isinstance(param, Option): return False - if param.is_flag: + if param.is_flag or param.count: return False last_option = None @@ -476,14 +486,17 @@ def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: if index + 1 > param.nargs: break - if _start_of_option(arg): + if _start_of_option(ctx, arg): last_option = arg return last_option is not None and last_option in param.opts def _resolve_context( - cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str] + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], ) -> Context: """Produce the context hierarchy starting with the command and traversing the complete arguments. This only follows the commands, @@ -510,6 +523,8 @@ def _resolve_context( ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) args = ctx.protected_args + ctx.args else: + sub_ctx = ctx + while args: name, cmd, args = command.resolve_command(ctx, args) @@ -551,7 +566,7 @@ def _resolve_incomplete( # split and discard the "=" to make completion easier. if incomplete == "=": incomplete = "" - elif "=" in incomplete and _start_of_option(incomplete): + elif "=" in incomplete and _start_of_option(ctx, incomplete): name, _, incomplete = incomplete.partition("=") args.append(name) @@ -559,7 +574,7 @@ def _resolve_incomplete( # even if they start with the option character. If it hasn't been # given and the incomplete arg looks like an option, the current # command will provide option name completions. - if "--" not in args and _start_of_option(incomplete): + if "--" not in args and _start_of_option(ctx, incomplete): return ctx.command, incomplete params = ctx.command.get_params(ctx) @@ -567,7 +582,7 @@ def _resolve_incomplete( # If the last complete arg is an option name with an incomplete # value, the option will provide value completions. for param in params: - if _is_incomplete_option(args, param): + if _is_incomplete_option(ctx, args, param): return param, incomplete # It's not an option name or value. The first argument without a diff --git a/dist/ba_data/python-site-packages/click/termui.py b/dist/ba_data/python-site-packages/click/termui.py index 07b5257c..db7a4b28 100644 --- a/dist/ba_data/python-site-packages/click/termui.py +++ b/dist/ba_data/python-site-packages/click/termui.py @@ -1,14 +1,12 @@ import inspect import io import itertools -import os import sys import typing as t from gettext import gettext as _ from ._compat import isatty from ._compat import strip_ansi -from ._compat import WIN from .exceptions import Abort from .exceptions import UsageError from .globals import resolve_color_default @@ -73,7 +71,7 @@ def _build_prompt( def _format_default(default: t.Any) -> t.Any: if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): - return default.name # type: ignore + return default.name return default @@ -181,7 +179,8 @@ def prompt_func(text: str) -> str: return result while True: value2 = prompt_func(confirmation_prompt) - if value2: + is_empty = not value and not value2 + if value2 or is_empty: break if value == value2: return result @@ -249,26 +248,6 @@ def confirm( return rv -def get_terminal_size() -> os.terminal_size: - """Returns the current size of the terminal as tuple in the form - ``(width, height)`` in columns and rows. - - .. deprecated:: 8.0 - Will be removed in Click 8.1. Use - :func:`shutil.get_terminal_size` instead. - """ - import shutil - import warnings - - warnings.warn( - "'click.get_terminal_size()' is deprecated and will be removed" - " in Click 8.1. Use 'shutil.get_terminal_size()' instead.", - DeprecationWarning, - stacklevel=2, - ) - return shutil.get_terminal_size() - - def echo_via_pager( text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], color: t.Optional[bool] = None, @@ -462,10 +441,9 @@ def clear() -> None: """ if not isatty(sys.stdout): return - if WIN: - os.system("cls") - else: - sys.stdout.write("\033[2J\033[1;1H") + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) def _interpret_color( diff --git a/dist/ba_data/python-site-packages/click/testing.py b/dist/ba_data/python-site-packages/click/testing.py index e395c2ed..e0df0d2a 100644 --- a/dist/ba_data/python-site-packages/click/testing.py +++ b/dist/ba_data/python-site-packages/click/testing.py @@ -79,11 +79,11 @@ def mode(self) -> str: def make_input_stream( - input: t.Optional[t.Union[str, bytes, t.IO]], charset: str + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]], charset: str ) -> t.BinaryIO: # Is already an input stream. if hasattr(input, "read"): - rv = _find_binary_reader(t.cast(t.IO, input)) + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) if rv is not None: return rv @@ -95,7 +95,7 @@ def make_input_stream( elif isinstance(input, str): input = input.encode(charset) - return io.BytesIO(t.cast(bytes, input)) + return io.BytesIO(input) class Result: @@ -183,7 +183,7 @@ def __init__( mix_stderr: bool = True, ) -> None: self.charset = charset - self.env = env or {} + self.env: t.Mapping[str, t.Optional[str]] = env or {} self.echo_stdin = echo_stdin self.mix_stderr = mix_stderr @@ -206,7 +206,7 @@ def make_env( @contextlib.contextmanager def isolation( self, - input: t.Optional[t.Union[str, bytes, t.IO]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, color: bool = False, ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: @@ -301,7 +301,7 @@ def _getchar(echo: bool) -> str: default_color = color def should_strip_ansi( - stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None ) -> bool: if color is None: return not default_color @@ -350,7 +350,7 @@ def invoke( self, cli: "BaseCommand", args: t.Optional[t.Union[str, t.Sequence[str]]] = None, - input: t.Optional[t.Union[str, bytes, t.IO]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, catch_exceptions: bool = True, color: bool = False, @@ -449,7 +449,7 @@ def invoke( @contextlib.contextmanager def isolated_filesystem( - self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None ) -> t.Iterator[str]: """A context manager that creates a temporary directory and changes the current working directory to it. This isolates tests @@ -464,11 +464,11 @@ def isolated_filesystem( Added the ``temp_dir`` parameter. """ cwd = os.getcwd() - dt = tempfile.mkdtemp(dir=temp_dir) # type: ignore[type-var] + dt = tempfile.mkdtemp(dir=temp_dir) os.chdir(dt) try: - yield t.cast(str, dt) + yield dt finally: os.chdir(cwd) diff --git a/dist/ba_data/python-site-packages/click/types.py b/dist/ba_data/python-site-packages/click/types.py index 550c6ff6..2b1d1797 100644 --- a/dist/ba_data/python-site-packages/click/types.py +++ b/dist/ba_data/python-site-packages/click/types.py @@ -1,14 +1,15 @@ import os import stat +import sys import typing as t from datetime import datetime from gettext import gettext as _ from gettext import ngettext from ._compat import _get_argv_encoding -from ._compat import get_filesystem_encoding from ._compat import open_stream from .exceptions import BadParameter +from .utils import format_filename from .utils import LazyFile from .utils import safecall @@ -63,7 +64,14 @@ def to_info_dict(self) -> t.Dict[str, t.Any]: # The class name without the "ParamType" suffix. param_type = type(self).__name__.partition("ParamType")[0] param_type = param_type.partition("ParameterType")[0] - return {"param_type": param_type, "name": self.name} + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} def __call__( self, @@ -155,7 +163,7 @@ def arity(self) -> int: # type: ignore class FuncParamType(ParamType): def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: - self.name = func.__name__ + self.name: str = func.__name__ self.func = func def to_info_dict(self) -> t.Dict[str, t.Any]: @@ -200,7 +208,7 @@ def convert( try: value = value.decode(enc) except UnicodeError: - fs_enc = get_filesystem_encoding() + fs_enc = sys.getfilesystemencoding() if fs_enc != enc: try: value = value.decode(fs_enc) @@ -346,7 +354,11 @@ class DateTime(ParamType): name = "datetime" def __init__(self, formats: t.Optional[t.Sequence[str]] = None): - self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"] + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] def to_info_dict(self) -> t.Dict[str, t.Any]: info_dict = super().to_info_dict() @@ -390,7 +402,7 @@ def __repr__(self) -> str: class _NumberParamTypeBase(ParamType): - _number_class: t.ClassVar[t.Type] + _number_class: t.ClassVar[t.Type[t.Any]] def convert( self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] @@ -655,7 +667,7 @@ class File(ParamType): """ name = "filename" - envvar_list_splitter = os.path.pathsep + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep def __init__( self, @@ -676,36 +688,38 @@ def to_info_dict(self) -> t.Dict[str, t.Any]: info_dict.update(mode=self.mode, encoding=self.encoding) return info_dict - def resolve_lazy_flag(self, value: t.Any) -> bool: + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: if self.lazy is not None: return self.lazy - if value == "-": + if os.fspath(value) == "-": return False elif "w" in self.mode: return True return False def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - try: - if hasattr(value, "read") or hasattr(value, "write"): - return value + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + try: lazy = self.resolve_lazy_flag(value) if lazy: - f: t.IO = t.cast( - t.IO, - LazyFile( - value, self.mode, self.encoding, self.errors, atomic=self.atomic - ), + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic ) if ctx is not None: - ctx.call_on_close(f.close_intelligently) # type: ignore + ctx.call_on_close(lf.close_intelligently) - return f + return t.cast(t.IO[t.Any], lf) f, should_close = open_stream( value, self.mode, self.encoding, self.errors, atomic=self.atomic @@ -724,7 +738,7 @@ def convert( return f except OSError as e: # noqa: B014 - self.fail(f"{os.fsdecode(value)!r}: {e.strerror}", param, ctx) + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) def shell_complete( self, ctx: "Context", param: "Parameter", incomplete: str @@ -743,6 +757,10 @@ def shell_complete( return [CompletionItem(incomplete, type="file")] +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + class Path(ParamType): """The ``Path`` type is similar to the :class:`File` type, but returns the filename instead of an open file. Various checks can be @@ -753,8 +771,9 @@ class Path(ParamType): exist, then all further checks are silently skipped. :param file_okay: Allow a file as a value. :param dir_okay: Allow a directory as a value. - :param writable: The file or directory must be writable. - :param readable: The file or directory must be readable. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. :param resolve_path: Make the value absolute and resolve any symlinks. A ``~`` is not expanded, as this is supposed to be done by the shell only. @@ -765,14 +784,17 @@ class Path(ParamType): ``None``, keep Python's default, which is ``str``. Useful to convert to :class:`pathlib.Path`. + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + .. versionchanged:: 8.0 - Allow passing ``type=pathlib.Path``. + Allow passing ``path_type=pathlib.Path``. .. versionchanged:: 6.0 Added the ``allow_dash`` parameter. """ - envvar_list_splitter = os.path.pathsep + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep def __init__( self, @@ -783,19 +805,21 @@ def __init__( readable: bool = True, resolve_path: bool = False, allow_dash: bool = False, - path_type: t.Optional[t.Type] = None, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, ): self.exists = exists self.file_okay = file_okay self.dir_okay = dir_okay - self.writable = writable self.readable = readable + self.writable = writable + self.executable = executable self.resolve_path = resolve_path self.allow_dash = allow_dash self.type = path_type if self.file_okay and not self.dir_okay: - self.name = _("file") + self.name: str = _("file") elif self.dir_okay and not self.file_okay: self.name = _("directory") else: @@ -813,20 +837,25 @@ def to_info_dict(self) -> t.Dict[str, t.Any]: ) return info_dict - def coerce_path_result(self, rv: t.Any) -> t.Any: - if self.type is not None and not isinstance(rv, self.type): + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): if self.type is str: - rv = os.fsdecode(rv) + return os.fsdecode(value) elif self.type is bytes: - rv = os.fsencode(rv) + return os.fsencode(value) else: - rv = self.type(rv) + return t.cast("os.PathLike[str]", self.type(value)) - return rv + return value def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": rv = value is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") @@ -846,7 +875,7 @@ def convert( return self.coerce_path_result(rv) self.fail( _("{name} {filename!r} does not exist.").format( - name=self.name.title(), filename=os.fsdecode(value) + name=self.name.title(), filename=format_filename(value) ), param, ctx, @@ -855,31 +884,42 @@ def convert( if not self.file_okay and stat.S_ISREG(st.st_mode): self.fail( _("{name} {filename!r} is a file.").format( - name=self.name.title(), filename=os.fsdecode(value) + name=self.name.title(), filename=format_filename(value) ), param, ctx, ) if not self.dir_okay and stat.S_ISDIR(st.st_mode): self.fail( - _("{name} {filename!r} is a directory.").format( - name=self.name.title(), filename=os.fsdecode(value) + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) ), param, ctx, ) + if self.writable and not os.access(rv, os.W_OK): self.fail( _("{name} {filename!r} is not writable.").format( - name=self.name.title(), filename=os.fsdecode(value) + name=self.name.title(), filename=format_filename(value) ), param, ctx, ) - if self.readable and not os.access(rv, os.R_OK): + + if self.executable and not os.access(value, os.X_OK): self.fail( - _("{name} {filename!r} is not readable.").format( - name=self.name.title(), filename=os.fsdecode(value) + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) ), param, ctx, @@ -920,8 +960,8 @@ class Tuple(CompositeParamType): :param types: a list of types that should be used for the tuple items. """ - def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None: - self.types = [convert_type(ty) for ty in types] + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] def to_info_dict(self) -> t.Dict[str, t.Any]: info_dict = super().to_info_dict() diff --git a/dist/ba_data/python-site-packages/click/utils.py b/dist/ba_data/python-site-packages/click/utils.py index 8dd3a00c..d536434f 100644 --- a/dist/ba_data/python-site-packages/click/utils.py +++ b/dist/ba_data/python-site-packages/click/utils.py @@ -1,15 +1,16 @@ import os +import re import sys import typing as t from functools import update_wrapper from types import ModuleType +from types import TracebackType from ._compat import _default_text_stderr from ._compat import _default_text_stdout from ._compat import _find_binary_writer from ._compat import auto_wrap_for_ansi from ._compat import binary_streams -from ._compat import get_filesystem_encoding from ._compat import open_stream from ._compat import should_strip_ansi from ._compat import strip_ansi @@ -20,30 +21,33 @@ if t.TYPE_CHECKING: import typing_extensions as te -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + P = te.ParamSpec("P") + +R = t.TypeVar("R") def _posixify(name: str) -> str: return "-".join(name.split()).lower() -def safecall(func: F) -> F: +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": """Wraps a function so that it swallows exceptions.""" - def wrapper(*args, **kwargs): # type: ignore + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: try: return func(*args, **kwargs) except Exception: pass + return None - return update_wrapper(t.cast(F, wrapper), func) + return update_wrapper(wrapper, func) def make_str(value: t.Any) -> str: """Converts a value into a valid string.""" if isinstance(value, bytes): try: - return value.decode(get_filesystem_encoding()) + return value.decode(sys.getfilesystemencoding()) except UnicodeError: return value.decode("utf-8", "replace") return str(value) @@ -108,20 +112,21 @@ class LazyFile: def __init__( self, - filename: str, + filename: t.Union[str, "os.PathLike[str]"], mode: str = "r", encoding: t.Optional[str] = None, errors: t.Optional[str] = "strict", atomic: bool = False, ): - self.name = filename + self.name: str = os.fspath(filename) self.mode = mode self.encoding = encoding self.errors = errors self.atomic = atomic - self._f: t.Optional[t.IO] + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool - if filename == "-": + if self.name == "-": self._f, self.should_close = open_stream(filename, mode, encoding, errors) else: if "r" in mode: @@ -138,9 +143,9 @@ def __getattr__(self, name: str) -> t.Any: def __repr__(self) -> str: if self._f is not None: return repr(self._f) - return f"" + return f"" - def open(self) -> t.IO: + def open(self) -> t.IO[t.Any]: """Opens the file if it's not yet open. This call might fail with a :exc:`FileError`. Not handling this error will produce an error that Click shows. @@ -173,7 +178,12 @@ def close_intelligently(self) -> None: def __enter__(self) -> "LazyFile": return self - def __exit__(self, exc_type, exc_value, tb): # type: ignore + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: self.close_intelligently() def __iter__(self) -> t.Iterator[t.AnyStr]: @@ -182,8 +192,8 @@ def __iter__(self) -> t.Iterator[t.AnyStr]: class KeepOpenFile: - def __init__(self, file: t.IO) -> None: - self._file = file + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file def __getattr__(self, name: str) -> t.Any: return getattr(self._file, name) @@ -191,7 +201,12 @@ def __getattr__(self, name: str) -> t.Any: def __enter__(self) -> "KeepOpenFile": return self - def __exit__(self, exc_type, exc_value, tb): # type: ignore + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: pass def __repr__(self) -> str: @@ -252,6 +267,11 @@ def echo( else: file = _default_text_stdout() + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + # Convert non bytes/text into the native string type. if message is not None and not isinstance(message, (str, bytes, bytearray)): out: t.Optional[t.Union[str, bytes]] = str(message) @@ -339,7 +359,7 @@ def open_file( errors: t.Optional[str] = "strict", lazy: bool = False, atomic: bool = False, -) -> t.IO: +) -> t.IO[t.Any]: """Open a file, with extra behavior to handle ``'-'`` to indicate a standard stream, lazy open on write, and atomic write. Similar to the behavior of the :class:`~click.File` param type. @@ -369,43 +389,39 @@ def open_file( .. versionadded:: 3.0 """ if lazy: - return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic)) + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) if not should_close: - f = t.cast(t.IO, KeepOpenFile(f)) + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) return f -def get_os_args() -> t.Sequence[str]: - """Returns the argument part of ``sys.argv``, removing the first - value which is the name of the script. - - .. deprecated:: 8.0 - Will be removed in Click 8.1. Access ``sys.argv[1:]`` directly - instead. - """ - import warnings +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. - warnings.warn( - "'get_os_args' is deprecated and will be removed in Click 8.1." - " Access 'sys.argv[1:]' directly instead.", - DeprecationWarning, - stacklevel=2, - ) - return sys.argv[1:] + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict". This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: -def format_filename( - filename: t.Union[str, bytes, os.PathLike], shorten: bool = False -) -> str: - """Formats a filename for user display. The main purpose of this - function is to ensure that the filename can be displayed at all. This - will decode the filename to unicode if necessary in a way that it will - not fail. Optionally, it can shorten the filename to not include the - full path to the filename. + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. :param filename: formats a filename for UI display. This will also convert the filename into unicode without failing. @@ -414,8 +430,17 @@ def format_filename( """ if shorten: filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) - return os.fsdecode(filename) + return filename def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: @@ -443,7 +468,7 @@ def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) :param app_name: the application name. This should be properly capitalized and can contain whitespace. :param roaming: controls if the folder should be roaming or not on Windows. - Has no affect otherwise. + Has no effect otherwise. :param force_posix: if this is set to `True` then on any POSIX system the folder will be stored in the home folder with a leading dot instead of the XDG config home or darwin's @@ -476,7 +501,7 @@ class PacifyFlushWrapper: pipe, all calls and attributes are proxied. """ - def __init__(self, wrapped: t.IO) -> None: + def __init__(self, wrapped: t.IO[t.Any]) -> None: self.wrapped = wrapped def flush(self) -> None: @@ -493,7 +518,7 @@ def __getattr__(self, attr: str) -> t.Any: def _detect_program_name( - path: t.Optional[str] = None, _main: ModuleType = sys.modules["__main__"] + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None ) -> str: """Determine the command used to run the program, for use in help text. If a file or entry point was executed, the file name is @@ -515,13 +540,17 @@ def _detect_program_name( :meta private: """ + if _main is None: + _main = sys.modules["__main__"] + if not path: path = sys.argv[0] # The value of __package__ indicates how Python was called. It may # not exist if a setuptools script is installed as an egg. It may be # set incorrectly for entry points created with pip on Windows. - if getattr(_main, "__package__", None) is None or ( + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( os.name == "nt" and _main.__package__ == "" and not os.path.exists(path) @@ -555,7 +584,7 @@ def _expand_args( See :func:`glob.glob`, :func:`os.path.expanduser`, and :func:`os.path.expandvars`. - This intended for use on Windows, where the shell does not do any + This is intended for use on Windows, where the shell does not do any expansion. It may not exactly match what a Unix shell would do. :param args: List of command line arguments to expand. @@ -563,6 +592,10 @@ def _expand_args( :param env: Expand environment variables. :param glob_recursive: ``**`` matches directories recursively. + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + .. versionadded:: 8.0 :meta private: @@ -578,7 +611,10 @@ def _expand_args( if env: arg = os.path.expandvars(arg) - matches = glob(arg, recursive=glob_recursive) + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] if not matches: out.append(arg) diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/INSTALLER b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE new file mode 100644 index 00000000..b11f379e --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE @@ -0,0 +1,3 @@ +This software is made available under the terms of *either* of the licenses +found in LICENSE.APACHE or LICENSE.BSD. Contributions to cryptography are made +under the terms of *both* these licenses. diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE.APACHE b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE.APACHE new file mode 100644 index 00000000..62589edd --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE.APACHE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE.BSD b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE.BSD new file mode 100644 index 00000000..ec1a29d3 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/LICENSE.BSD @@ -0,0 +1,27 @@ +Copyright (c) Individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of PyCA Cryptography nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/METADATA b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/METADATA new file mode 100644 index 00000000..1f779733 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/METADATA @@ -0,0 +1,135 @@ +Metadata-Version: 2.1 +Name: cryptography +Version: 42.0.7 +Summary: cryptography is a package which provides cryptographic recipes and primitives to Python developers. +Author-email: The Python Cryptographic Authority and individual contributors +License: Apache-2.0 OR BSD-3-Clause +Project-URL: homepage, https://github.com/pyca/cryptography +Project-URL: documentation, https://cryptography.io/ +Project-URL: source, https://github.com/pyca/cryptography/ +Project-URL: issues, https://github.com/pyca/cryptography/issues +Project-URL: changelog, https://cryptography.io/en/latest/changelog/ +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: License :: OSI Approved :: BSD License +Classifier: Natural Language :: English +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: POSIX +Classifier: Operating System :: POSIX :: BSD +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: Microsoft :: Windows +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Security :: Cryptography +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE +License-File: LICENSE.APACHE +License-File: LICENSE.BSD +Requires-Dist: cffi >=1.12 ; platform_python_implementation != "PyPy" +Provides-Extra: docs +Requires-Dist: sphinx >=5.3.0 ; extra == 'docs' +Requires-Dist: sphinx-rtd-theme >=1.1.1 ; extra == 'docs' +Provides-Extra: docstest +Requires-Dist: pyenchant >=1.6.11 ; extra == 'docstest' +Requires-Dist: readme-renderer ; extra == 'docstest' +Requires-Dist: sphinxcontrib-spelling >=4.0.1 ; extra == 'docstest' +Provides-Extra: nox +Requires-Dist: nox ; extra == 'nox' +Provides-Extra: pep8test +Requires-Dist: ruff ; extra == 'pep8test' +Requires-Dist: mypy ; extra == 'pep8test' +Requires-Dist: check-sdist ; extra == 'pep8test' +Requires-Dist: click ; extra == 'pep8test' +Provides-Extra: sdist +Requires-Dist: build ; extra == 'sdist' +Provides-Extra: ssh +Requires-Dist: bcrypt >=3.1.5 ; extra == 'ssh' +Provides-Extra: test +Requires-Dist: pytest >=6.2.0 ; extra == 'test' +Requires-Dist: pytest-benchmark ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' +Requires-Dist: pytest-xdist ; extra == 'test' +Requires-Dist: pretend ; extra == 'test' +Requires-Dist: certifi ; extra == 'test' +Provides-Extra: test-randomorder +Requires-Dist: pytest-randomly ; extra == 'test-randomorder' + +pyca/cryptography +================= + +.. image:: https://img.shields.io/pypi/v/cryptography.svg + :target: https://pypi.org/project/cryptography/ + :alt: Latest Version + +.. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest + :target: https://cryptography.io + :alt: Latest Docs + +.. image:: https://github.com/pyca/cryptography/workflows/CI/badge.svg?branch=main + :target: https://github.com/pyca/cryptography/actions?query=workflow%3ACI+branch%3Amain + + +``cryptography`` is a package which provides cryptographic recipes and +primitives to Python developers. Our goal is for it to be your "cryptographic +standard library". It supports Python 3.7+ and PyPy3 7.3.11+. + +``cryptography`` includes both high level recipes and low level interfaces to +common cryptographic algorithms such as symmetric ciphers, message digests, and +key derivation functions. For example, to encrypt something with +``cryptography``'s high level symmetric encryption recipe: + +.. code-block:: pycon + + >>> from cryptography.fernet import Fernet + >>> # Put this somewhere safe! + >>> key = Fernet.generate_key() + >>> f = Fernet(key) + >>> token = f.encrypt(b"A really secret message. Not for prying eyes.") + >>> token + b'...' + >>> f.decrypt(token) + b'A really secret message. Not for prying eyes.' + +You can find more information in the `documentation`_. + +You can install ``cryptography`` with: + +.. code-block:: console + + $ pip install cryptography + +For full details see `the installation documentation`_. + +Discussion +~~~~~~~~~~ + +If you run into bugs, you can file them in our `issue tracker`_. + +We maintain a `cryptography-dev`_ mailing list for development discussion. + +You can also join ``#pyca`` on ``irc.libera.chat`` to ask questions or get +involved. + +Security +~~~~~~~~ + +Need to report a security issue? Please consult our `security reporting`_ +documentation. + + +.. _`documentation`: https://cryptography.io/ +.. _`the installation documentation`: https://cryptography.io/en/latest/installation/ +.. _`issue tracker`: https://github.com/pyca/cryptography/issues +.. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev +.. _`security reporting`: https://cryptography.io/en/latest/security/ diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/RECORD b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/RECORD new file mode 100644 index 00000000..9c9e60e1 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/RECORD @@ -0,0 +1,171 @@ +cryptography-42.0.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +cryptography-42.0.7.dist-info/LICENSE,sha256=Pgx8CRqUi4JTO6mP18u0BDLW8amsv4X1ki0vmak65rs,197 +cryptography-42.0.7.dist-info/LICENSE.APACHE,sha256=qsc7MUj20dcRHbyjIJn2jSbGRMaBOuHk8F9leaomY_4,11360 +cryptography-42.0.7.dist-info/LICENSE.BSD,sha256=YCxMdILeZHndLpeTzaJ15eY9dz2s0eymiSMqtwCPtPs,1532 +cryptography-42.0.7.dist-info/METADATA,sha256=pNnzX-lb7FSppPg9V_gspY5eaRTv9rZ5IaTA45BzD-w,5295 +cryptography-42.0.7.dist-info/RECORD,, +cryptography-42.0.7.dist-info/WHEEL,sha256=fEuQ8QlbrrJCrqZHpLEt4l5e2x7mPqr9tlylZpVIKhY,112 +cryptography-42.0.7.dist-info/top_level.txt,sha256=KNaT-Sn2K4uxNaEbe6mYdDn3qWDMlp4y-MtWfB73nJc,13 +cryptography/__about__.py,sha256=LQGMBOUoJMoUWaehVZlolfa2ksqExrEG39Ii4p8BHUo,445 +cryptography/__init__.py,sha256=iVPlBlXWTJyiFeRedxcbMPhyHB34viOM10d72vGnWuE,364 +cryptography/__pycache__/__about__.cpython-312.pyc,, +cryptography/__pycache__/__init__.cpython-312.pyc,, +cryptography/__pycache__/exceptions.cpython-312.pyc,, +cryptography/__pycache__/fernet.cpython-312.pyc,, +cryptography/__pycache__/utils.cpython-312.pyc,, +cryptography/exceptions.py,sha256=835EWILc2fwxw-gyFMriciC2SqhViETB10LBSytnDIc,1087 +cryptography/fernet.py,sha256=aPj82w-Z_1GBXUtWRUsZdVbMwRo5Mbjj0wkA9wG4rkw,6696 +cryptography/hazmat/__init__.py,sha256=5IwrLWrVp0AjEr_4FdWG_V057NSJGY_W4egNNsuct0g,455 +cryptography/hazmat/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/__pycache__/_oid.cpython-312.pyc,, +cryptography/hazmat/_oid.py,sha256=0DhT6N-ziZzlQp05iPKOsy5wdPMayiKdrSg_yZfWLzc,14460 +cryptography/hazmat/backends/__init__.py,sha256=O5jvKFQdZnXhKeqJ-HtulaEL9Ni7mr1mDzZY5kHlYhI,361 +cryptography/hazmat/backends/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/backends/openssl/__init__.py,sha256=p3jmJfnCag9iE5sdMrN6VvVEu55u46xaS_IjoI0SrmA,305 +cryptography/hazmat/backends/openssl/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/backends/openssl/__pycache__/aead.cpython-312.pyc,, +cryptography/hazmat/backends/openssl/__pycache__/backend.cpython-312.pyc,, +cryptography/hazmat/backends/openssl/__pycache__/ciphers.cpython-312.pyc,, +cryptography/hazmat/backends/openssl/__pycache__/decode_asn1.cpython-312.pyc,, +cryptography/hazmat/backends/openssl/aead.py,sha256=UBNLqkicUo2ve7q-q8R49IgVOYlDMmSPtbPUK2qdMbM,8176 +cryptography/hazmat/backends/openssl/backend.py,sha256=b2WZB12RovKi_VL_ZS1NNsBETii_FBVp1xG_KrkuI2k,32654 +cryptography/hazmat/backends/openssl/ciphers.py,sha256=MwBbBauaUjNiaja25oZKt7vI9bRGXfF5lK1p-8AQ67U,10353 +cryptography/hazmat/backends/openssl/decode_asn1.py,sha256=kz6gys8wuJhrx4QyU6enYx7UatNHr0LB3TI1jH3oQ54,1148 +cryptography/hazmat/bindings/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180 +cryptography/hazmat/bindings/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/bindings/_rust.abi3.so,sha256=9byAHtYQr52IEhZorXZpYLdY4JbnYF1RxkBFylNfLbU,10465160 +cryptography/hazmat/bindings/_rust/__init__.pyi,sha256=djseHBlzUqDJ7JUc2J51OT_7CLm_Lz0EyVQ55o3udUI,495 +cryptography/hazmat/bindings/_rust/_openssl.pyi,sha256=mpNJLuYLbCVrd5i33FBTmWwL_55Dw7JPkSLlSX9Q7oI,230 +cryptography/hazmat/bindings/_rust/asn1.pyi,sha256=8w-f89ls0pb7BAbt1E0Pvkd59NGtTFItLtFK8ZJGbkk,556 +cryptography/hazmat/bindings/_rust/exceptions.pyi,sha256=exXr2xw_0pB1kk93cYbM3MohbzoUkjOms1ZMUi0uQZE,640 +cryptography/hazmat/bindings/_rust/ocsp.pyi,sha256=qUA2x7lwbG_Z7wJ_wUxsBFJ71arjoX-nnkZAw4nVDeQ,860 +cryptography/hazmat/bindings/_rust/openssl/__init__.pyi,sha256=LOxBeyjBgwa_hmCflzhsOfCQKDvScU04cUTS4HrMErg,1098 +cryptography/hazmat/bindings/_rust/openssl/aead.pyi,sha256=ZNsO1H8Q9ixQO9Db7qtkboWKM5fycWY_ZeyGXb3scHg,1737 +cryptography/hazmat/bindings/_rust/openssl/cmac.pyi,sha256=nPH0X57RYpsAkRowVpjQiHE566ThUTx7YXrsadmrmHk,564 +cryptography/hazmat/bindings/_rust/openssl/dh.pyi,sha256=Z3TC-G04-THtSdAOPLM1h2G7ml5bda1ElZUcn5wpuhk,1564 +cryptography/hazmat/bindings/_rust/openssl/dsa.pyi,sha256=qBtkgj2albt2qFcnZ9UDrhzoNhCVO7HTby5VSf1EXMI,1299 +cryptography/hazmat/bindings/_rust/openssl/ec.pyi,sha256=zJy0pRa5n-_p2dm45PxECB_-B6SVZyNKfjxFDpPqT38,1691 +cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi,sha256=OJsrblS2nHptZctva-pAKFL5q8yPEAkhmjPZpJ6TA94,493 +cryptography/hazmat/bindings/_rust/openssl/ed448.pyi,sha256=SkPHK2HdbYN02TVQEUOgW3iTdiEY7HBE4DijpdkAzmk,475 +cryptography/hazmat/bindings/_rust/openssl/hashes.pyi,sha256=J8HoN0GdtPcjRAfNHr5Elva_nkmQfq63L75_z9dd8Uc,573 +cryptography/hazmat/bindings/_rust/openssl/hmac.pyi,sha256=ZmLJ73pmxcZFC1XosWEiXMRYtvJJor3ZLdCQOJu85Cw,662 +cryptography/hazmat/bindings/_rust/openssl/kdf.pyi,sha256=wPS5c7NLspM2632II0I4iH1RSxZvSRtBOVqmpyQATfk,544 +cryptography/hazmat/bindings/_rust/openssl/keys.pyi,sha256=9nFfZ0USUxHtPvqJmvWewz27so3qlQxxTEt2d904msI,980 +cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi,sha256=9iogF7Q4i81IkOS-IMXp6HvxFF_3cNy_ucrAjVQnn14,540 +cryptography/hazmat/bindings/_rust/openssl/rsa.pyi,sha256=2OQCNSXkxgc-3uw1xiCCloIQTV6p9_kK79Yu0rhZgPc,1364 +cryptography/hazmat/bindings/_rust/openssl/x25519.pyi,sha256=2BKdbrddM_9SMUpdvHKGhb9MNjURCarPxccbUDzHeoA,484 +cryptography/hazmat/bindings/_rust/openssl/x448.pyi,sha256=AoRMWNvCJTiH5L-lkIkCdPlrPLUdJvvfXpIvf1GmxpM,466 +cryptography/hazmat/bindings/_rust/pkcs7.pyi,sha256=WfJXBDgmsOg1ui1U3wclgL-xpmbcFNq6lt6fY6yxy8w,619 +cryptography/hazmat/bindings/_rust/x509.pyi,sha256=KqsM2W3tg4MpzxjI4eL9Jbsm7pQwvJ4_-xDE7wA1x3w,3001 +cryptography/hazmat/bindings/openssl/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180 +cryptography/hazmat/bindings/openssl/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/bindings/openssl/__pycache__/_conditional.cpython-312.pyc,, +cryptography/hazmat/bindings/openssl/__pycache__/binding.cpython-312.pyc,, +cryptography/hazmat/bindings/openssl/_conditional.py,sha256=oa0XaChiNaxqSmwwWE4gWgP0oHJk_AqXqHVe3sm9TbE,6290 +cryptography/hazmat/bindings/openssl/binding.py,sha256=gujA75kQ8NAXXBSNNP2eAPn8gpEmhv99wqS03ck2b-0,4935 +cryptography/hazmat/primitives/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180 +cryptography/hazmat/primitives/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/_asymmetric.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/_cipheralgorithm.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/_serialization.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/cmac.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/constant_time.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/hashes.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/hmac.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/keywrap.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/padding.cpython-312.pyc,, +cryptography/hazmat/primitives/__pycache__/poly1305.cpython-312.pyc,, +cryptography/hazmat/primitives/_asymmetric.py,sha256=RhgcouUB6HTiFDBrR1LxqkMjpUxIiNvQ1r_zJjRG6qQ,532 +cryptography/hazmat/primitives/_cipheralgorithm.py,sha256=u7ryLG_HivCXn-ulKM-h_eVWMzlobeg0K45Udflk7Gg,1072 +cryptography/hazmat/primitives/_serialization.py,sha256=qrozc8fw2WZSbjk3DAlSl3ResxpauwJ74ZgGoUL-mj0,5142 +cryptography/hazmat/primitives/asymmetric/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180 +cryptography/hazmat/primitives/asymmetric/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/dh.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/dsa.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/ec.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/ed25519.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/ed448.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/padding.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/rsa.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/types.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/utils.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/x25519.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/__pycache__/x448.cpython-312.pyc,, +cryptography/hazmat/primitives/asymmetric/dh.py,sha256=OOCjMClH1Bf14Sy7jAdwzEeCxFPb8XUe2qePbExvXwc,3420 +cryptography/hazmat/primitives/asymmetric/dsa.py,sha256=xBwdf0pZOgvqjUKcO7Q0L3NxwalYj0SJDUqThemhSmI,3945 +cryptography/hazmat/primitives/asymmetric/ec.py,sha256=W6nLb4Oho3BI3OsTR_nUI4WRHCbikTrqVOjQQYjV5vs,9704 +cryptography/hazmat/primitives/asymmetric/ed25519.py,sha256=kl63fg7myuMjNTmMoVFeH6iVr0x5FkjNmggxIRTloJk,3423 +cryptography/hazmat/primitives/asymmetric/ed448.py,sha256=2UzEDzzfkPn83UFVFlMZfIMbAixxY09WmQyrwinWTn8,3456 +cryptography/hazmat/primitives/asymmetric/padding.py,sha256=eZcvUqVLbe3u48SunLdeniaPlV4-k6pwBl67OW4jSy8,2885 +cryptography/hazmat/primitives/asymmetric/rsa.py,sha256=HToE4M5VJbGZS_2SbJ11kIGhtQ8D3GozW59sWEzrfZ4,6799 +cryptography/hazmat/primitives/asymmetric/types.py,sha256=LnsOJym-wmPUJ7Knu_7bCNU3kIiELCd6krOaW_JU08I,2996 +cryptography/hazmat/primitives/asymmetric/utils.py,sha256=DPTs6T4F-UhwzFQTh-1fSEpQzazH2jf2xpIro3ItF4o,790 +cryptography/hazmat/primitives/asymmetric/x25519.py,sha256=VGYuRdIYuVBtizpFdNWd2bTrT10JRa1admQdBr08xz8,3341 +cryptography/hazmat/primitives/asymmetric/x448.py,sha256=GKKJBqYLr03VewMF18bXIM941aaWcZIQ4rC02GLLEmw,3374 +cryptography/hazmat/primitives/ciphers/__init__.py,sha256=kAyb9NSczqTrCWj0HEoVp3Cxo7AHW8ibPFQz-ZHsOtA,680 +cryptography/hazmat/primitives/ciphers/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/primitives/ciphers/__pycache__/aead.cpython-312.pyc,, +cryptography/hazmat/primitives/ciphers/__pycache__/algorithms.cpython-312.pyc,, +cryptography/hazmat/primitives/ciphers/__pycache__/base.cpython-312.pyc,, +cryptography/hazmat/primitives/ciphers/__pycache__/modes.cpython-312.pyc,, +cryptography/hazmat/primitives/ciphers/aead.py,sha256=V6UKsIPNZQh0cfd8hpXx3ZzztQ-JQ9ChBMMN1ZTZXJ0,5540 +cryptography/hazmat/primitives/ciphers/algorithms.py,sha256=rNsvAJZIft8o0yan5Z62hJ-xoEM_Y6BYBkFs4jnnR2s,5120 +cryptography/hazmat/primitives/ciphers/base.py,sha256=4VktSqxhRjigjNQ3m2BiQQDo-1bYqCxXpddphJukoMI,8445 +cryptography/hazmat/primitives/ciphers/modes.py,sha256=Kw1419ZCUBNbbxd7BctwPp6i8rwnOvvifdXokrx_bYM,8317 +cryptography/hazmat/primitives/cmac.py,sha256=sz_s6H_cYnOvx-VNWdIKhRhe3Ymp8z8J0D3CBqOX3gg,338 +cryptography/hazmat/primitives/constant_time.py,sha256=xdunWT0nf8OvKdcqUhhlFKayGp4_PgVJRU2W1wLSr_A,422 +cryptography/hazmat/primitives/hashes.py,sha256=HCFCsR8p7OEWt1YA7oRbqgKHXOuZnrspkVrniU_B2uU,5091 +cryptography/hazmat/primitives/hmac.py,sha256=RpB3z9z5skirCQrm7zQbtnp9pLMnAjrlTUvKqF5aDDc,423 +cryptography/hazmat/primitives/kdf/__init__.py,sha256=4XibZnrYq4hh5xBjWiIXzaYW6FKx8hPbVaa_cB9zS64,750 +cryptography/hazmat/primitives/kdf/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/__pycache__/concatkdf.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/__pycache__/hkdf.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/__pycache__/kbkdf.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/__pycache__/pbkdf2.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/__pycache__/scrypt.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/__pycache__/x963kdf.cpython-312.pyc,, +cryptography/hazmat/primitives/kdf/concatkdf.py,sha256=bcn4NGXse-EsFl7nlU83e5ilop7TSHcX-CJJS107W80,3686 +cryptography/hazmat/primitives/kdf/hkdf.py,sha256=uhN5L87w4JvtAqQcPh_Ji2TPSc18IDThpaYJiHOWy3A,3015 +cryptography/hazmat/primitives/kdf/kbkdf.py,sha256=C3koAdtF_fwyvbhQA88AYbi3YOrUZ_7eaIM4DkWrfyM,9072 +cryptography/hazmat/primitives/kdf/pbkdf2.py,sha256=1CCH9Q5gXUpnZd3c8d8bCXgpJ3s2hZZGBnuG7FH1waM,2012 +cryptography/hazmat/primitives/kdf/scrypt.py,sha256=4QONhjxA_ZtuQtQ7QV3FnbB8ftrFnM52B4HPfV7hFys,2354 +cryptography/hazmat/primitives/kdf/x963kdf.py,sha256=wCpWmwQjZ2vAu2rlk3R_PX0nINl8WGXYBmlyMOC5iPw,1992 +cryptography/hazmat/primitives/keywrap.py,sha256=kHqtc56YvpTNEi6q1ifoHKXmY4SWqllBv-eBfqMpvuE,5650 +cryptography/hazmat/primitives/padding.py,sha256=g4qonAgYADkMArKt2MXD1XlnGd4ET_Rf5YDADwb_v8Q,6148 +cryptography/hazmat/primitives/poly1305.py,sha256=P5EPQV-RB_FJPahpg01u0Ts4S_PnAmsroxIGXbGeRRo,355 +cryptography/hazmat/primitives/serialization/__init__.py,sha256=6ZlL3EicEzoGdMOat86w8y_XICCnlHdCjFI97rMxRDg,1653 +cryptography/hazmat/primitives/serialization/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/primitives/serialization/__pycache__/base.cpython-312.pyc,, +cryptography/hazmat/primitives/serialization/__pycache__/pkcs12.cpython-312.pyc,, +cryptography/hazmat/primitives/serialization/__pycache__/pkcs7.cpython-312.pyc,, +cryptography/hazmat/primitives/serialization/__pycache__/ssh.cpython-312.pyc,, +cryptography/hazmat/primitives/serialization/base.py,sha256=ikq5MJIwp_oUnjiaBco_PmQwOTYuGi-XkYUYHKy8Vo0,615 +cryptography/hazmat/primitives/serialization/pkcs12.py,sha256=jtMcM-At_GZFRD5oSlOGHOE1OcosroWIvmkzrEsv75Q,6599 +cryptography/hazmat/primitives/serialization/pkcs7.py,sha256=uaWAdWggcM087zL1ltQc5fFhpXFFbBNn_2cyQK8toZ4,7488 +cryptography/hazmat/primitives/serialization/ssh.py,sha256=7JjL4ZWcOliyAOJdnlnWi_0nNlLtOrAoj6AqWHdrLNg,50051 +cryptography/hazmat/primitives/twofactor/__init__.py,sha256=tmMZGB-g4IU1r7lIFqASU019zr0uPp_wEBYcwdDCKCA,258 +cryptography/hazmat/primitives/twofactor/__pycache__/__init__.cpython-312.pyc,, +cryptography/hazmat/primitives/twofactor/__pycache__/hotp.cpython-312.pyc,, +cryptography/hazmat/primitives/twofactor/__pycache__/totp.cpython-312.pyc,, +cryptography/hazmat/primitives/twofactor/hotp.py,sha256=l1YdRMIhfPIuHKkA66keBDHhNbnBAlh6-O44P-OHIK8,2976 +cryptography/hazmat/primitives/twofactor/totp.py,sha256=v0y0xKwtYrP83ypOo5Ofd441RJLOkaFfjmp554jo5F0,1450 +cryptography/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +cryptography/utils.py,sha256=8fNXSfKvDgaji9M_m4lVXHFTVdIDP32GhlXzUBYDBHE,4033 +cryptography/x509/__init__.py,sha256=zaKuAaluw0p-lQm4RGK3_NBAG9V_UW6nhv_1m_ppugI,7924 +cryptography/x509/__pycache__/__init__.cpython-312.pyc,, +cryptography/x509/__pycache__/base.cpython-312.pyc,, +cryptography/x509/__pycache__/certificate_transparency.cpython-312.pyc,, +cryptography/x509/__pycache__/extensions.cpython-312.pyc,, +cryptography/x509/__pycache__/general_name.cpython-312.pyc,, +cryptography/x509/__pycache__/name.cpython-312.pyc,, +cryptography/x509/__pycache__/ocsp.cpython-312.pyc,, +cryptography/x509/__pycache__/oid.cpython-312.pyc,, +cryptography/x509/__pycache__/verification.cpython-312.pyc,, +cryptography/x509/base.py,sha256=U2ZTy4BMQKiQ7YwncAnfKffRv7KSzWaMvbbgMlO8blk,36933 +cryptography/x509/certificate_transparency.py,sha256=6HvzAD0dlSQVxy6tnDhGj0-pisp1MaJ9bxQNRr92inI,2261 +cryptography/x509/extensions.py,sha256=YU9R9IGt2tFl3zM7T2LI3dzQvKyvMhZxT2JgqCrZ3SE,66345 +cryptography/x509/general_name.py,sha256=sP_rV11Qlpsk4x3XXGJY_Mv0Q_s9dtjeLckHsjpLQoQ,7836 +cryptography/x509/name.py,sha256=85k7lJRtXnWTsVfsJXHNiWnDrsbW0OJ54np2opaBV28,14609 +cryptography/x509/ocsp.py,sha256=7Na0PAyA6nSyApTGd-QZ9Nfw2uyUS_PDVQx5XUw1xmU,18126 +cryptography/x509/oid.py,sha256=fFosjGsnIB_w_0YrzZv1ggkSVwZl7xmY0zofKZNZkDA,829 +cryptography/x509/verification.py,sha256=mPg6AUQDxK5wgGerP_hkFWD1Wj6l7lAt2IxpizZzekA,668 diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/WHEEL b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/WHEEL new file mode 100644 index 00000000..40d9d7a8 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: false +Tag: cp39-abi3-manylinux_2_28_x86_64 + diff --git a/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/top_level.txt b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/top_level.txt new file mode 100644 index 00000000..0d38bc5e --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography-42.0.7.dist-info/top_level.txt @@ -0,0 +1 @@ +cryptography diff --git a/dist/ba_data/python-site-packages/cryptography/__about__.py b/dist/ba_data/python-site-packages/cryptography/__about__.py index a77b057b..2462fc9e 100644 --- a/dist/ba_data/python-site-packages/cryptography/__about__.py +++ b/dist/ba_data/python-site-packages/cryptography/__about__.py @@ -10,8 +10,8 @@ "__copyright__", ] -__version__ = "41.0.1" +__version__ = "42.0.7" __author__ = "The Python Cryptographic Authority and individual contributors" -__copyright__ = f"Copyright 2013-2023 {__author__}" +__copyright__ = f"Copyright 2013-2024 {__author__}" diff --git a/dist/ba_data/python-site-packages/cryptography/exceptions.py b/dist/ba_data/python-site-packages/cryptography/exceptions.py index 47fdd18e..fe125ea9 100644 --- a/dist/ba_data/python-site-packages/cryptography/exceptions.py +++ b/dist/ba_data/python-site-packages/cryptography/exceptions.py @@ -15,9 +15,7 @@ class UnsupportedAlgorithm(Exception): - def __init__( - self, message: str, reason: typing.Optional[_Reasons] = None - ) -> None: + def __init__(self, message: str, reason: _Reasons | None = None) -> None: super().__init__(message) self._reason = reason @@ -44,7 +42,7 @@ class InvalidSignature(Exception): class InternalError(Exception): def __init__( - self, msg: str, err_code: typing.List[rust_openssl.OpenSSLError] + self, msg: str, err_code: list[rust_openssl.OpenSSLError] ) -> None: super().__init__(msg) self.err_code = err_code diff --git a/dist/ba_data/python-site-packages/cryptography/fernet.py b/dist/ba_data/python-site-packages/cryptography/fernet.py index ad8fb40b..35ce1131 100644 --- a/dist/ba_data/python-site-packages/cryptography/fernet.py +++ b/dist/ba_data/python-site-packages/cryptography/fernet.py @@ -27,7 +27,7 @@ class InvalidToken(Exception): class Fernet: def __init__( self, - key: typing.Union[bytes, str], + key: bytes | str, backend: typing.Any = None, ) -> None: try: @@ -80,9 +80,7 @@ def _encrypt_from_parts( hmac = h.finalize() return base64.urlsafe_b64encode(basic_parts + hmac) - def decrypt( - self, token: typing.Union[bytes, str], ttl: typing.Optional[int] = None - ) -> bytes: + def decrypt(self, token: bytes | str, ttl: int | None = None) -> bytes: timestamp, data = Fernet._get_unverified_token_data(token) if ttl is None: time_info = None @@ -91,7 +89,7 @@ def decrypt( return self._decrypt_data(data, timestamp, time_info) def decrypt_at_time( - self, token: typing.Union[bytes, str], ttl: int, current_time: int + self, token: bytes | str, ttl: int, current_time: int ) -> bytes: if ttl is None: raise ValueError( @@ -100,16 +98,14 @@ def decrypt_at_time( timestamp, data = Fernet._get_unverified_token_data(token) return self._decrypt_data(data, timestamp, (ttl, current_time)) - def extract_timestamp(self, token: typing.Union[bytes, str]) -> int: + def extract_timestamp(self, token: bytes | str) -> int: timestamp, data = Fernet._get_unverified_token_data(token) # Verify the token was not tampered with. self._verify_signature(data) return timestamp @staticmethod - def _get_unverified_token_data( - token: typing.Union[bytes, str] - ) -> typing.Tuple[int, bytes]: + def _get_unverified_token_data(token: bytes | str) -> tuple[int, bytes]: if not isinstance(token, (str, bytes)): raise TypeError("token must be bytes or str") @@ -139,7 +135,7 @@ def _decrypt_data( self, data: bytes, timestamp: int, - time_info: typing.Optional[typing.Tuple[int, int]], + time_info: tuple[int, int] | None, ) -> bytes: if time_info is not None: ttl, current_time = time_info @@ -186,7 +182,7 @@ def encrypt(self, msg: bytes) -> bytes: def encrypt_at_time(self, msg: bytes, current_time: int) -> bytes: return self._fernets[0].encrypt_at_time(msg, current_time) - def rotate(self, msg: typing.Union[bytes, str]) -> bytes: + def rotate(self, msg: bytes | str) -> bytes: timestamp, data = Fernet._get_unverified_token_data(msg) for f in self._fernets: try: @@ -200,9 +196,7 @@ def rotate(self, msg: typing.Union[bytes, str]) -> bytes: iv = os.urandom(16) return self._fernets[0]._encrypt_from_parts(p, timestamp, iv) - def decrypt( - self, msg: typing.Union[bytes, str], ttl: typing.Optional[int] = None - ) -> bytes: + def decrypt(self, msg: bytes | str, ttl: int | None = None) -> bytes: for f in self._fernets: try: return f.decrypt(msg, ttl) @@ -211,7 +205,7 @@ def decrypt( raise InvalidToken def decrypt_at_time( - self, msg: typing.Union[bytes, str], ttl: int, current_time: int + self, msg: bytes | str, ttl: int, current_time: int ) -> bytes: for f in self._fernets: try: diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py b/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py index 01d4b340..c5d062c1 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py @@ -4,8 +4,6 @@ from __future__ import annotations -import typing - from cryptography.hazmat.bindings._rust import ( ObjectIdentifier as ObjectIdentifier, ) @@ -60,6 +58,7 @@ class NameOID: LOCALITY_NAME = ObjectIdentifier("2.5.4.7") STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8") STREET_ADDRESS = ObjectIdentifier("2.5.4.9") + ORGANIZATION_IDENTIFIER = ObjectIdentifier("2.5.4.97") ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10") ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11") SERIAL_NUMBER = ObjectIdentifier("2.5.4.5") @@ -123,9 +122,7 @@ class SignatureAlgorithmOID: GOSTR3410_2012_WITH_3411_2012_512 = ObjectIdentifier("1.2.643.7.1.1.3.3") -_SIG_OIDS_TO_HASH: typing.Dict[ - ObjectIdentifier, typing.Optional[hashes.HashAlgorithm] -] = { +_SIG_OIDS_TO_HASH: dict[ObjectIdentifier, hashes.HashAlgorithm | None] = { SignatureAlgorithmOID.RSA_WITH_MD5: hashes.MD5(), SignatureAlgorithmOID.RSA_WITH_SHA1: hashes.SHA1(), SignatureAlgorithmOID._RSA_WITH_SHA1: hashes.SHA1(), @@ -282,7 +279,7 @@ class AttributeOID: ExtensionOID.EXTENDED_KEY_USAGE: "extendedKeyUsage", ExtensionOID.FRESHEST_CRL: "freshestCRL", ExtensionOID.INHIBIT_ANY_POLICY: "inhibitAnyPolicy", - ExtensionOID.ISSUING_DISTRIBUTION_POINT: ("issuingDistributionPoint"), + ExtensionOID.ISSUING_DISTRIBUTION_POINT: "issuingDistributionPoint", ExtensionOID.AUTHORITY_INFORMATION_ACCESS: "authorityInfoAccess", ExtensionOID.SUBJECT_INFORMATION_ACCESS: "subjectInfoAccess", ExtensionOID.OCSP_NO_CHECK: "OCSPNoCheck", diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py index b36f535f..f1d99010 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py @@ -13,213 +13,41 @@ from cryptography.hazmat.primitives.ciphers.aead import ( AESCCM, AESGCM, - AESOCB3, - AESSIV, - ChaCha20Poly1305, ) - _AEADTypes = typing.Union[ - AESCCM, AESGCM, AESOCB3, AESSIV, ChaCha20Poly1305 - ] - - -def _is_evp_aead_supported_cipher( - backend: Backend, cipher: _AEADTypes -) -> bool: - """ - Checks whether the given cipher is supported through - EVP_AEAD rather than the normal OpenSSL EVP_CIPHER API. - """ - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - - return backend._lib.Cryptography_HAS_EVP_AEAD and isinstance( - cipher, ChaCha20Poly1305 - ) + _AEADTypes = typing.Union[AESCCM, AESGCM] def _aead_cipher_supported(backend: Backend, cipher: _AEADTypes) -> bool: - if _is_evp_aead_supported_cipher(backend, cipher): - return True - else: - cipher_name = _evp_cipher_cipher_name(cipher) - if backend._fips_enabled and cipher_name not in backend._fips_aead: - return False - # SIV isn't loaded through get_cipherbyname but instead a new fetch API - # only available in 3.0+. But if we know we're on 3.0+ then we know - # it's supported. - if cipher_name.endswith(b"-siv"): - return backend._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER == 1 - else: - return ( - backend._lib.EVP_get_cipherbyname(cipher_name) - != backend._ffi.NULL - ) - - -def _aead_create_ctx( - backend: Backend, - cipher: _AEADTypes, - key: bytes, -): - if _is_evp_aead_supported_cipher(backend, cipher): - return _evp_aead_create_ctx(backend, cipher, key) - else: - return _evp_cipher_create_ctx(backend, cipher, key) - + cipher_name = _evp_cipher_cipher_name(cipher) -def _encrypt( - backend: Backend, - cipher: _AEADTypes, - nonce: bytes, - data: bytes, - associated_data: typing.List[bytes], - tag_length: int, - ctx: typing.Any = None, -) -> bytes: - if _is_evp_aead_supported_cipher(backend, cipher): - return _evp_aead_encrypt( - backend, cipher, nonce, data, associated_data, tag_length, ctx - ) - else: - return _evp_cipher_encrypt( - backend, cipher, nonce, data, associated_data, tag_length, ctx - ) + return backend._lib.EVP_get_cipherbyname(cipher_name) != backend._ffi.NULL -def _decrypt( +def _encrypt( backend: Backend, cipher: _AEADTypes, nonce: bytes, data: bytes, - associated_data: typing.List[bytes], + associated_data: list[bytes], tag_length: int, - ctx: typing.Any = None, ) -> bytes: - if _is_evp_aead_supported_cipher(backend, cipher): - return _evp_aead_decrypt( - backend, cipher, nonce, data, associated_data, tag_length, ctx - ) - else: - return _evp_cipher_decrypt( - backend, cipher, nonce, data, associated_data, tag_length, ctx - ) - - -def _evp_aead_create_ctx( - backend: Backend, - cipher: _AEADTypes, - key: bytes, - tag_len: typing.Optional[int] = None, -): - aead_cipher = _evp_aead_get_cipher(backend, cipher) - assert aead_cipher is not None - key_ptr = backend._ffi.from_buffer(key) - tag_len = ( - backend._lib.EVP_AEAD_DEFAULT_TAG_LENGTH - if tag_len is None - else tag_len - ) - ctx = backend._lib.Cryptography_EVP_AEAD_CTX_new( - aead_cipher, key_ptr, len(key), tag_len - ) - backend.openssl_assert(ctx != backend._ffi.NULL) - ctx = backend._ffi.gc(ctx, backend._lib.EVP_AEAD_CTX_free) - return ctx - - -def _evp_aead_get_cipher(backend: Backend, cipher: _AEADTypes): - from cryptography.hazmat.primitives.ciphers.aead import ( - ChaCha20Poly1305, + return _evp_cipher_encrypt( + backend, cipher, nonce, data, associated_data, tag_length ) - # Currently only ChaCha20-Poly1305 is supported using this API - assert isinstance(cipher, ChaCha20Poly1305) - return backend._lib.EVP_aead_chacha20_poly1305() - -def _evp_aead_encrypt( +def _decrypt( backend: Backend, cipher: _AEADTypes, nonce: bytes, data: bytes, - associated_data: typing.List[bytes], + associated_data: list[bytes], tag_length: int, - ctx: typing.Any, ) -> bytes: - assert ctx is not None - - aead_cipher = _evp_aead_get_cipher(backend, cipher) - assert aead_cipher is not None - - out_len = backend._ffi.new("size_t *") - # max_out_len should be in_len plus the result of - # EVP_AEAD_max_overhead. - max_out_len = len(data) + backend._lib.EVP_AEAD_max_overhead(aead_cipher) - out_buf = backend._ffi.new("uint8_t[]", max_out_len) - data_ptr = backend._ffi.from_buffer(data) - nonce_ptr = backend._ffi.from_buffer(nonce) - aad = b"".join(associated_data) - aad_ptr = backend._ffi.from_buffer(aad) - - res = backend._lib.EVP_AEAD_CTX_seal( - ctx, - out_buf, - out_len, - max_out_len, - nonce_ptr, - len(nonce), - data_ptr, - len(data), - aad_ptr, - len(aad), + return _evp_cipher_decrypt( + backend, cipher, nonce, data, associated_data, tag_length ) - backend.openssl_assert(res == 1) - encrypted_data = backend._ffi.buffer(out_buf, out_len[0])[:] - return encrypted_data - - -def _evp_aead_decrypt( - backend: Backend, - cipher: _AEADTypes, - nonce: bytes, - data: bytes, - associated_data: typing.List[bytes], - tag_length: int, - ctx: typing.Any, -) -> bytes: - if len(data) < tag_length: - raise InvalidTag - - assert ctx is not None - - out_len = backend._ffi.new("size_t *") - # max_out_len should at least in_len - max_out_len = len(data) - out_buf = backend._ffi.new("uint8_t[]", max_out_len) - data_ptr = backend._ffi.from_buffer(data) - nonce_ptr = backend._ffi.from_buffer(nonce) - aad = b"".join(associated_data) - aad_ptr = backend._ffi.from_buffer(aad) - - res = backend._lib.EVP_AEAD_CTX_open( - ctx, - out_buf, - out_len, - max_out_len, - nonce_ptr, - len(nonce), - data_ptr, - len(data), - aad_ptr, - len(aad), - ) - - if res == 0: - backend._consume_errors() - raise InvalidTag - - decrypted_data = backend._ffi.buffer(out_buf, out_len[0])[:] - return decrypted_data _ENCRYPT = 1 @@ -230,69 +58,27 @@ def _evp_cipher_cipher_name(cipher: _AEADTypes) -> bytes: from cryptography.hazmat.primitives.ciphers.aead import ( AESCCM, AESGCM, - AESOCB3, - AESSIV, - ChaCha20Poly1305, ) - if isinstance(cipher, ChaCha20Poly1305): - return b"chacha20-poly1305" - elif isinstance(cipher, AESCCM): + if isinstance(cipher, AESCCM): return f"aes-{len(cipher._key) * 8}-ccm".encode("ascii") - elif isinstance(cipher, AESOCB3): - return f"aes-{len(cipher._key) * 8}-ocb".encode("ascii") - elif isinstance(cipher, AESSIV): - return f"aes-{len(cipher._key) * 8 // 2}-siv".encode("ascii") else: assert isinstance(cipher, AESGCM) return f"aes-{len(cipher._key) * 8}-gcm".encode("ascii") def _evp_cipher(cipher_name: bytes, backend: Backend): - if cipher_name.endswith(b"-siv"): - evp_cipher = backend._lib.EVP_CIPHER_fetch( - backend._ffi.NULL, - cipher_name, - backend._ffi.NULL, - ) - backend.openssl_assert(evp_cipher != backend._ffi.NULL) - evp_cipher = backend._ffi.gc(evp_cipher, backend._lib.EVP_CIPHER_free) - else: - evp_cipher = backend._lib.EVP_get_cipherbyname(cipher_name) - backend.openssl_assert(evp_cipher != backend._ffi.NULL) - + evp_cipher = backend._lib.EVP_get_cipherbyname(cipher_name) + backend.openssl_assert(evp_cipher != backend._ffi.NULL) return evp_cipher -def _evp_cipher_create_ctx( - backend: Backend, - cipher: _AEADTypes, - key: bytes, -): - ctx = backend._lib.EVP_CIPHER_CTX_new() - backend.openssl_assert(ctx != backend._ffi.NULL) - ctx = backend._ffi.gc(ctx, backend._lib.EVP_CIPHER_CTX_free) - cipher_name = _evp_cipher_cipher_name(cipher) - evp_cipher = _evp_cipher(cipher_name, backend) - key_ptr = backend._ffi.from_buffer(key) - res = backend._lib.EVP_CipherInit_ex( - ctx, - evp_cipher, - backend._ffi.NULL, - key_ptr, - backend._ffi.NULL, - 0, - ) - backend.openssl_assert(res != 0) - return ctx - - def _evp_cipher_aead_setup( backend: Backend, cipher_name: bytes, key: bytes, nonce: bytes, - tag: typing.Optional[bytes], + tag: bytes | None, tag_len: int, operation: int, ): @@ -350,21 +136,6 @@ def _evp_cipher_set_tag(backend, ctx, tag: bytes) -> None: backend.openssl_assert(res != 0) -def _evp_cipher_set_nonce_operation( - backend, ctx, nonce: bytes, operation: int -) -> None: - nonce_ptr = backend._ffi.from_buffer(nonce) - res = backend._lib.EVP_CipherInit_ex( - ctx, - backend._ffi.NULL, - backend._ffi.NULL, - backend._ffi.NULL, - nonce_ptr, - int(operation == _ENCRYPT), - ) - backend.openssl_assert(res != 0) - - def _evp_cipher_set_length(backend: Backend, ctx, data_len: int) -> None: intptr = backend._ffi.new("int *") res = backend._lib.EVP_CipherUpdate( @@ -389,10 +160,7 @@ def _evp_cipher_process_data(backend: Backend, ctx, data: bytes) -> bytes: buf = backend._ffi.new("unsigned char[]", len(data)) data_ptr = backend._ffi.from_buffer(data) res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, data_ptr, len(data)) - if res == 0: - # AES SIV can error here if the data is invalid on decrypt - backend._consume_errors() - raise InvalidTag + backend.openssl_assert(res != 0) return backend._ffi.buffer(buf, outlen[0])[:] @@ -401,25 +169,21 @@ def _evp_cipher_encrypt( cipher: _AEADTypes, nonce: bytes, data: bytes, - associated_data: typing.List[bytes], + associated_data: list[bytes], tag_length: int, - ctx: typing.Any = None, ) -> bytes: - from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESSIV - - if ctx is None: - cipher_name = _evp_cipher_cipher_name(cipher) - ctx = _evp_cipher_aead_setup( - backend, - cipher_name, - cipher._key, - nonce, - None, - tag_length, - _ENCRYPT, - ) - else: - _evp_cipher_set_nonce_operation(backend, ctx, nonce, _ENCRYPT) + from cryptography.hazmat.primitives.ciphers.aead import AESCCM + + cipher_name = _evp_cipher_cipher_name(cipher) + ctx = _evp_cipher_aead_setup( + backend, + cipher_name, + cipher._key, + nonce, + None, + tag_length, + _ENCRYPT, + ) # CCM requires us to pass the length of the data before processing # anything. @@ -445,14 +209,7 @@ def _evp_cipher_encrypt( backend.openssl_assert(res != 0) tag = backend._ffi.buffer(tag_buf)[:] - if isinstance(cipher, AESSIV): - # RFC 5297 defines the output as IV || C, where the tag we generate - # is the "IV" and C is the ciphertext. This is the opposite of our - # other AEADs, which are Ciphertext || Tag - backend.openssl_assert(len(tag) == 16) - return tag + processed_data - else: - return processed_data + tag + return processed_data + tag def _evp_cipher_decrypt( @@ -460,38 +217,26 @@ def _evp_cipher_decrypt( cipher: _AEADTypes, nonce: bytes, data: bytes, - associated_data: typing.List[bytes], + associated_data: list[bytes], tag_length: int, - ctx: typing.Any = None, ) -> bytes: - from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESSIV + from cryptography.hazmat.primitives.ciphers.aead import AESCCM if len(data) < tag_length: raise InvalidTag - if isinstance(cipher, AESSIV): - # RFC 5297 defines the output as IV || C, where the tag we generate - # is the "IV" and C is the ciphertext. This is the opposite of our - # other AEADs, which are Ciphertext || Tag - tag = data[:tag_length] - data = data[tag_length:] - else: - tag = data[-tag_length:] - data = data[:-tag_length] - if ctx is None: - cipher_name = _evp_cipher_cipher_name(cipher) - ctx = _evp_cipher_aead_setup( - backend, - cipher_name, - cipher._key, - nonce, - tag, - tag_length, - _DECRYPT, - ) - else: - _evp_cipher_set_nonce_operation(backend, ctx, nonce, _DECRYPT) - _evp_cipher_set_tag(backend, ctx, tag) + tag = data[-tag_length:] + data = data[:-tag_length] + cipher_name = _evp_cipher_cipher_name(cipher) + ctx = _evp_cipher_aead_setup( + backend, + cipher_name, + cipher._key, + nonce, + tag, + tag_length, + _DECRYPT, + ) # CCM requires us to pass the length of the data before processing # anything. diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py index 02d51094..d83b89c6 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py @@ -8,35 +8,17 @@ import contextlib import itertools import typing -from contextlib import contextmanager from cryptography import utils, x509 -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.backends.openssl import aead from cryptography.hazmat.backends.openssl.ciphers import _CipherContext -from cryptography.hazmat.backends.openssl.cmac import _CMACContext -from cryptography.hazmat.backends.openssl.ec import ( - _EllipticCurvePrivateKey, - _EllipticCurvePublicKey, -) -from cryptography.hazmat.backends.openssl.rsa import ( - _RSAPrivateKey, - _RSAPublicKey, -) from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.bindings.openssl import binding from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding -from cryptography.hazmat.primitives.asymmetric import ( - dh, - dsa, - ec, - ed448, - ed25519, - rsa, - x448, - x25519, -) +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils from cryptography.hazmat.primitives.asymmetric.padding import ( MGF1, OAEP, @@ -45,10 +27,8 @@ ) from cryptography.hazmat.primitives.asymmetric.types import ( PrivateKeyTypes, - PublicKeyTypes, ) from cryptography.hazmat.primitives.ciphers import ( - BlockCipherAlgorithm, CipherAlgorithm, ) from cryptography.hazmat.primitives.ciphers.algorithms import ( @@ -76,7 +56,6 @@ XTS, Mode, ) -from cryptography.hazmat.primitives.serialization import ssh from cryptography.hazmat.primitives.serialization.pkcs12 import ( PBES, PKCS12Certificate, @@ -104,7 +83,7 @@ class Backend: # disallowed algorithms are still present in OpenSSL. They just error if # you try to use them. To avoid that we allowlist the algorithms in # FIPS 140-3. This isn't ideal, but FIPS 140-3 is trash so here we are. - _fips_aead = { + _fips_aead: typing.ClassVar[set[bytes]] = { b"aes-128-ccm", b"aes-192-ccm", b"aes-256-ccm", @@ -149,28 +128,25 @@ def __init__(self) -> None: self._lib = self._binding.lib self._fips_enabled = rust_openssl.is_fips_enabled() - self._cipher_registry: typing.Dict[ - typing.Tuple[typing.Type[CipherAlgorithm], typing.Type[Mode]], + self._cipher_registry: dict[ + tuple[type[CipherAlgorithm], type[Mode]], typing.Callable, ] = {} self._register_default_ciphers() - self._dh_types = [self._lib.EVP_PKEY_DH] - if self._lib.Cryptography_HAS_EVP_PKEY_DHX: - self._dh_types.append(self._lib.EVP_PKEY_DHX) def __repr__(self) -> str: return "".format( self.openssl_version_text(), self._fips_enabled, - self._binding._legacy_provider_loaded, + rust_openssl._legacy_provider_loaded, ) def openssl_assert( self, ok: bool, - errors: typing.Optional[typing.List[rust_openssl.OpenSSLError]] = None, + errors: list[rust_openssl.OpenSSLError] | None = None, ) -> None: - return binding._openssl_assert(self._lib, ok, errors=errors) + return binding._openssl_assert(ok, errors=errors) def _enable_fips(self) -> None: # This function enables FIPS mode for OpenSSL 3.0.0 on installs that @@ -194,10 +170,10 @@ def openssl_version_number(self) -> int: return self._lib.OpenSSL_version_num() def _evp_md_from_algorithm(self, algorithm: hashes.HashAlgorithm): - if algorithm.name == "blake2b" or algorithm.name == "blake2s": - alg = "{}{}".format( - algorithm.name, algorithm.digest_size * 8 - ).encode("ascii") + if algorithm.name in ("blake2b", "blake2s"): + alg = f"{algorithm.name}{algorithm.digest_size * 8}".encode( + "ascii" + ) else: alg = algorithm.name.encode("ascii") @@ -255,9 +231,7 @@ def cipher_supported(self, cipher: CipherAlgorithm, mode: Mode) -> bool: def register_cipher_adapter(self, cipher_cls, mode_cls, adapter) -> None: if (cipher_cls, mode_cls) in self._cipher_registry: raise ValueError( - "Duplicate registration for: {} {}.".format( - cipher_cls, mode_cls - ) + f"Duplicate registration for: {cipher_cls} {mode_cls}." ) self._cipher_registry[cipher_cls, mode_cls] = adapter @@ -284,11 +258,17 @@ def _register_default_ciphers(self) -> None: self.register_cipher_adapter( TripleDES, ECB, GetCipherByName("des-ede3") ) + # ChaCha20 uses the Long Name "chacha20" in OpenSSL, but in LibreSSL + # it uses "chacha" self.register_cipher_adapter( - ChaCha20, type(None), GetCipherByName("chacha20") + ChaCha20, + type(None), + GetCipherByName( + "chacha" if self._lib.CRYPTOGRAPHY_IS_LIBRESSL else "chacha20" + ), ) self.register_cipher_adapter(AES, XTS, _get_xts_cipher) - for mode_cls in [ECB, CBC, OFB, CFB, CTR]: + for mode_cls in [ECB, CBC, OFB, CFB, CTR, GCM]: self.register_cipher_adapter( SM4, mode_cls, GetCipherByName("sm4-{mode.name}") ) @@ -297,7 +277,7 @@ def _register_default_ciphers(self) -> None: # we get an EVP_CIPHER * in the _CipherContext __init__, but OpenSSL 3 # will return a valid pointer even though the cipher is unavailable. if ( - self._binding._legacy_provider_loaded + rust_openssl._legacy_provider_loaded or not self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER ): for mode_cls in [CBC, CFB, OFB, ECB]: @@ -342,56 +322,9 @@ def create_symmetric_decryption_ctx( def pbkdf2_hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool: return self.hmac_supported(algorithm) - def _consume_errors(self) -> typing.List[rust_openssl.OpenSSLError]: + def _consume_errors(self) -> list[rust_openssl.OpenSSLError]: return rust_openssl.capture_error_stack() - def _bn_to_int(self, bn) -> int: - assert bn != self._ffi.NULL - self.openssl_assert(not self._lib.BN_is_negative(bn)) - - bn_num_bytes = self._lib.BN_num_bytes(bn) - bin_ptr = self._ffi.new("unsigned char[]", bn_num_bytes) - bin_len = self._lib.BN_bn2bin(bn, bin_ptr) - # A zero length means the BN has value 0 - self.openssl_assert(bin_len >= 0) - val = int.from_bytes(self._ffi.buffer(bin_ptr)[:bin_len], "big") - return val - - def _int_to_bn(self, num: int): - """ - Converts a python integer to a BIGNUM. The returned BIGNUM will not - be garbage collected (to support adding them to structs that take - ownership of the object). Be sure to register it for GC if it will - be discarded after use. - """ - binary = num.to_bytes(int(num.bit_length() / 8.0 + 1), "big") - bn_ptr = self._lib.BN_bin2bn(binary, len(binary), self._ffi.NULL) - self.openssl_assert(bn_ptr != self._ffi.NULL) - return bn_ptr - - def generate_rsa_private_key( - self, public_exponent: int, key_size: int - ) -> rsa.RSAPrivateKey: - rsa._verify_rsa_parameters(public_exponent, key_size) - - rsa_cdata = self._lib.RSA_new() - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - - bn = self._int_to_bn(public_exponent) - bn = self._ffi.gc(bn, self._lib.BN_free) - - res = self._lib.RSA_generate_key_ex( - rsa_cdata, key_size, bn, self._ffi.NULL - ) - self.openssl_assert(res == 1) - evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) - - # We can skip RSA key validation here since we just generated the key - return _RSAPrivateKey( - self, rsa_cdata, evp_pkey, unsafe_skip_rsa_key_validation=True - ) - def generate_rsa_parameters_supported( self, public_exponent: int, key_size: int ) -> bool: @@ -401,74 +334,6 @@ def generate_rsa_parameters_supported( and key_size >= 512 ) - def load_rsa_private_numbers( - self, - numbers: rsa.RSAPrivateNumbers, - unsafe_skip_rsa_key_validation: bool, - ) -> rsa.RSAPrivateKey: - rsa._check_private_key_components( - numbers.p, - numbers.q, - numbers.d, - numbers.dmp1, - numbers.dmq1, - numbers.iqmp, - numbers.public_numbers.e, - numbers.public_numbers.n, - ) - rsa_cdata = self._lib.RSA_new() - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - p = self._int_to_bn(numbers.p) - q = self._int_to_bn(numbers.q) - d = self._int_to_bn(numbers.d) - dmp1 = self._int_to_bn(numbers.dmp1) - dmq1 = self._int_to_bn(numbers.dmq1) - iqmp = self._int_to_bn(numbers.iqmp) - e = self._int_to_bn(numbers.public_numbers.e) - n = self._int_to_bn(numbers.public_numbers.n) - res = self._lib.RSA_set0_factors(rsa_cdata, p, q) - self.openssl_assert(res == 1) - res = self._lib.RSA_set0_key(rsa_cdata, n, e, d) - self.openssl_assert(res == 1) - res = self._lib.RSA_set0_crt_params(rsa_cdata, dmp1, dmq1, iqmp) - self.openssl_assert(res == 1) - evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) - - return _RSAPrivateKey( - self, - rsa_cdata, - evp_pkey, - unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, - ) - - def load_rsa_public_numbers( - self, numbers: rsa.RSAPublicNumbers - ) -> rsa.RSAPublicKey: - rsa._check_public_key_components(numbers.e, numbers.n) - rsa_cdata = self._lib.RSA_new() - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - e = self._int_to_bn(numbers.e) - n = self._int_to_bn(numbers.n) - res = self._lib.RSA_set0_key(rsa_cdata, n, e, self._ffi.NULL) - self.openssl_assert(res == 1) - evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) - - return _RSAPublicKey(self, rsa_cdata, evp_pkey) - - def _create_evp_pkey_gc(self): - evp_pkey = self._lib.EVP_PKEY_new() - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return evp_pkey - - def _rsa_cdata_to_evp_pkey(self, rsa_cdata): - evp_pkey = self._create_evp_pkey_gc() - res = self._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) - self.openssl_assert(res == 1) - return evp_pkey - def _bytes_to_bio(self, data: bytes) -> _MemoryBIO: """ Return a _MemoryBIO namedtuple of (BIO, char*). @@ -504,145 +369,6 @@ def _read_mem_bio(self, bio) -> bytes: bio_data = self._ffi.buffer(buf[0], buf_len)[:] return bio_data - def _evp_pkey_to_private_key( - self, evp_pkey, unsafe_skip_rsa_key_validation: bool - ) -> PrivateKeyTypes: - """ - Return the appropriate type of PrivateKey given an evp_pkey cdata - pointer. - """ - - key_type = self._lib.EVP_PKEY_id(evp_pkey) - - if key_type == self._lib.EVP_PKEY_RSA: - rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - return _RSAPrivateKey( - self, - rsa_cdata, - evp_pkey, - unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, - ) - elif ( - key_type == self._lib.EVP_PKEY_RSA_PSS - and not self._lib.CRYPTOGRAPHY_IS_LIBRESSL - and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL - and not self._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E - ): - # At the moment the way we handle RSA PSS keys is to strip the - # PSS constraints from them and treat them as normal RSA keys - # Unfortunately the RSA * itself tracks this data so we need to - # extract, serialize, and reload it without the constraints. - rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - bio = self._create_mem_bio_gc() - res = self._lib.i2d_RSAPrivateKey_bio(bio, rsa_cdata) - self.openssl_assert(res == 1) - return self.load_der_private_key( - self._read_mem_bio(bio), - password=None, - unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, - ) - elif key_type == self._lib.EVP_PKEY_DSA: - return rust_openssl.dsa.private_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == self._lib.EVP_PKEY_EC: - ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) - self.openssl_assert(ec_cdata != self._ffi.NULL) - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) - elif key_type in self._dh_types: - return rust_openssl.dh.private_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): - # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return rust_openssl.ed25519.private_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): - # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return rust_openssl.x448.private_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == self._lib.EVP_PKEY_X25519: - return rust_openssl.x25519.private_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): - # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return rust_openssl.ed448.private_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - else: - raise UnsupportedAlgorithm("Unsupported key type.") - - def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: - """ - Return the appropriate type of PublicKey given an evp_pkey cdata - pointer. - """ - - key_type = self._lib.EVP_PKEY_id(evp_pkey) - - if key_type == self._lib.EVP_PKEY_RSA: - rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - return _RSAPublicKey(self, rsa_cdata, evp_pkey) - elif ( - key_type == self._lib.EVP_PKEY_RSA_PSS - and not self._lib.CRYPTOGRAPHY_IS_LIBRESSL - and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL - and not self._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E - ): - rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) - self.openssl_assert(rsa_cdata != self._ffi.NULL) - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - bio = self._create_mem_bio_gc() - res = self._lib.i2d_RSAPublicKey_bio(bio, rsa_cdata) - self.openssl_assert(res == 1) - return self.load_der_public_key(self._read_mem_bio(bio)) - elif key_type == self._lib.EVP_PKEY_DSA: - return rust_openssl.dsa.public_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == self._lib.EVP_PKEY_EC: - ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) - if ec_cdata == self._ffi.NULL: - errors = self._consume_errors() - raise ValueError("Unable to load EC key", errors) - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) - elif key_type in self._dh_types: - return rust_openssl.dh.public_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): - # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return rust_openssl.ed25519.public_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): - # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return rust_openssl.x448.public_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == self._lib.EVP_PKEY_X25519: - return rust_openssl.x25519.public_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): - # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL - return rust_openssl.ed448.public_key_from_ptr( - int(self._ffi.cast("uintptr_t", evp_pkey)) - ) - else: - raise UnsupportedAlgorithm("Unsupported key type.") - def _oaep_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool: if self._fips_enabled and isinstance(algorithm, hashes.SHA1): return False @@ -683,43 +409,6 @@ def rsa_encryption_supported(self, padding: AsymmetricPadding) -> bool: else: return self.rsa_padding_supported(padding) - def generate_dsa_parameters(self, key_size: int) -> dsa.DSAParameters: - if key_size not in (1024, 2048, 3072, 4096): - raise ValueError( - "Key size must be 1024, 2048, 3072, or 4096 bits." - ) - - return rust_openssl.dsa.generate_parameters(key_size) - - def generate_dsa_private_key( - self, parameters: dsa.DSAParameters - ) -> dsa.DSAPrivateKey: - return parameters.generate_private_key() - - def generate_dsa_private_key_and_parameters( - self, key_size: int - ) -> dsa.DSAPrivateKey: - parameters = self.generate_dsa_parameters(key_size) - return self.generate_dsa_private_key(parameters) - - def load_dsa_private_numbers( - self, numbers: dsa.DSAPrivateNumbers - ) -> dsa.DSAPrivateKey: - dsa._check_dsa_private_numbers(numbers) - return rust_openssl.dsa.from_private_numbers(numbers) - - def load_dsa_public_numbers( - self, numbers: dsa.DSAPublicNumbers - ) -> dsa.DSAPublicKey: - dsa._check_dsa_parameters(numbers.parameter_numbers) - return rust_openssl.dsa.from_public_numbers(numbers) - - def load_dsa_parameter_numbers( - self, numbers: dsa.DSAParameterNumbers - ) -> dsa.DSAParameters: - dsa._check_dsa_parameters(numbers) - return rust_openssl.dsa.from_parameter_numbers(numbers) - def dsa_supported(self) -> bool: return ( not self._lib.CRYPTOGRAPHY_IS_BORINGSSL and not self._fips_enabled @@ -735,133 +424,6 @@ def cmac_algorithm_supported(self, algorithm) -> bool: algorithm, CBC(b"\x00" * algorithm.block_size) ) - def create_cmac_ctx(self, algorithm: BlockCipherAlgorithm) -> _CMACContext: - return _CMACContext(self, algorithm) - - def load_pem_private_key( - self, - data: bytes, - password: typing.Optional[bytes], - unsafe_skip_rsa_key_validation: bool, - ) -> PrivateKeyTypes: - return self._load_key( - self._lib.PEM_read_bio_PrivateKey, - data, - password, - unsafe_skip_rsa_key_validation, - ) - - def load_pem_public_key(self, data: bytes) -> PublicKeyTypes: - mem_bio = self._bytes_to_bio(data) - # In OpenSSL 3.0.x the PEM_read_bio_PUBKEY function will invoke - # the default password callback if you pass an encrypted private - # key. This is very, very, very bad as the default callback can - # trigger an interactive console prompt, which will hang the - # Python process. We therefore provide our own callback to - # catch this and error out properly. - userdata = self._ffi.new("CRYPTOGRAPHY_PASSWORD_DATA *") - evp_pkey = self._lib.PEM_read_bio_PUBKEY( - mem_bio.bio, - self._ffi.NULL, - self._ffi.addressof( - self._lib._original_lib, "Cryptography_pem_password_cb" - ), - userdata, - ) - if evp_pkey != self._ffi.NULL: - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return self._evp_pkey_to_public_key(evp_pkey) - else: - # It's not a (RSA/DSA/ECDSA) subjectPublicKeyInfo, but we still - # need to check to see if it is a pure PKCS1 RSA public key (not - # embedded in a subjectPublicKeyInfo) - self._consume_errors() - res = self._lib.BIO_reset(mem_bio.bio) - self.openssl_assert(res == 1) - rsa_cdata = self._lib.PEM_read_bio_RSAPublicKey( - mem_bio.bio, - self._ffi.NULL, - self._ffi.addressof( - self._lib._original_lib, "Cryptography_pem_password_cb" - ), - userdata, - ) - if rsa_cdata != self._ffi.NULL: - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) - return _RSAPublicKey(self, rsa_cdata, evp_pkey) - else: - self._handle_key_loading_error() - - def load_pem_parameters(self, data: bytes) -> dh.DHParameters: - return rust_openssl.dh.from_pem_parameters(data) - - def load_der_private_key( - self, - data: bytes, - password: typing.Optional[bytes], - unsafe_skip_rsa_key_validation: bool, - ) -> PrivateKeyTypes: - # OpenSSL has a function called d2i_AutoPrivateKey that in theory - # handles this automatically, however it doesn't handle encrypted - # private keys. Instead we try to load the key two different ways. - # First we'll try to load it as a traditional key. - bio_data = self._bytes_to_bio(data) - key = self._evp_pkey_from_der_traditional_key(bio_data, password) - if key: - return self._evp_pkey_to_private_key( - key, unsafe_skip_rsa_key_validation - ) - else: - # Finally we try to load it with the method that handles encrypted - # PKCS8 properly. - return self._load_key( - self._lib.d2i_PKCS8PrivateKey_bio, - data, - password, - unsafe_skip_rsa_key_validation, - ) - - def _evp_pkey_from_der_traditional_key(self, bio_data, password): - key = self._lib.d2i_PrivateKey_bio(bio_data.bio, self._ffi.NULL) - if key != self._ffi.NULL: - key = self._ffi.gc(key, self._lib.EVP_PKEY_free) - if password is not None: - raise TypeError( - "Password was given but private key is not encrypted." - ) - - return key - else: - self._consume_errors() - return None - - def load_der_public_key(self, data: bytes) -> PublicKeyTypes: - mem_bio = self._bytes_to_bio(data) - evp_pkey = self._lib.d2i_PUBKEY_bio(mem_bio.bio, self._ffi.NULL) - if evp_pkey != self._ffi.NULL: - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - return self._evp_pkey_to_public_key(evp_pkey) - else: - # It's not a (RSA/DSA/ECDSA) subjectPublicKeyInfo, but we still - # need to check to see if it is a pure PKCS1 RSA public key (not - # embedded in a subjectPublicKeyInfo) - self._consume_errors() - res = self._lib.BIO_reset(mem_bio.bio) - self.openssl_assert(res == 1) - rsa_cdata = self._lib.d2i_RSAPublicKey_bio( - mem_bio.bio, self._ffi.NULL - ) - if rsa_cdata != self._ffi.NULL: - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) - return _RSAPublicKey(self, rsa_cdata, evp_pkey) - else: - self._handle_key_loading_error() - - def load_der_parameters(self, data: bytes) -> dh.DHParameters: - return rust_openssl.dh.from_der_parameters(data) - def _cert2ossl(self, cert: x509.Certificate) -> typing.Any: data = cert.public_bytes(serialization.Encoding.DER) mem_bio = self._bytes_to_bio(data) @@ -891,61 +453,9 @@ def _key2ossl(self, key: PKCS12PrivateKeyTypes) -> typing.Any: self.openssl_assert(evp_pkey != self._ffi.NULL) return self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - def _load_key( - self, openssl_read_func, data, password, unsafe_skip_rsa_key_validation - ) -> PrivateKeyTypes: - mem_bio = self._bytes_to_bio(data) - - userdata = self._ffi.new("CRYPTOGRAPHY_PASSWORD_DATA *") - if password is not None: - utils._check_byteslike("password", password) - password_ptr = self._ffi.from_buffer(password) - userdata.password = password_ptr - userdata.length = len(password) - - evp_pkey = openssl_read_func( - mem_bio.bio, - self._ffi.NULL, - self._ffi.addressof( - self._lib._original_lib, "Cryptography_pem_password_cb" - ), - userdata, - ) - - if evp_pkey == self._ffi.NULL: - if userdata.error != 0: - self._consume_errors() - if userdata.error == -1: - raise TypeError( - "Password was not given but private key is encrypted" - ) - else: - assert userdata.error == -2 - raise ValueError( - "Passwords longer than {} bytes are not supported " - "by this backend.".format(userdata.maxsize - 1) - ) - else: - self._handle_key_loading_error() - - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - - if password is not None and userdata.called == 0: - raise TypeError( - "Password was given but private key is not encrypted." - ) - - assert ( - password is not None and userdata.called == 1 - ) or password is None - - return self._evp_pkey_to_private_key( - evp_pkey, unsafe_skip_rsa_key_validation - ) - - def _handle_key_loading_error(self) -> typing.NoReturn: - errors = self._consume_errors() - + def _handle_key_loading_error( + self, errors: list[rust_openssl.OpenSSLError] + ) -> typing.NoReturn: if not errors: raise ValueError( "Could not deserialize key data. The data may be in an " @@ -990,20 +500,12 @@ def _handle_key_loading_error(self) -> typing.NoReturn: ) def elliptic_curve_supported(self, curve: ec.EllipticCurve) -> bool: - try: - curve_nid = self._elliptic_curve_to_nid(curve) - except UnsupportedAlgorithm: - curve_nid = self._lib.NID_undef - - group = self._lib.EC_GROUP_new_by_curve_name(curve_nid) - - if group == self._ffi.NULL: - self._consume_errors() + if self._fips_enabled and not isinstance( + curve, self._fips_ecdh_curves + ): return False - else: - self.openssl_assert(curve_nid != self._lib.NID_undef) - self._lib.EC_GROUP_free(group) - return True + + return rust_openssl.ec.curve_supported(curve) def elliptic_curve_signature_algorithm_supported( self, @@ -1014,512 +516,28 @@ def elliptic_curve_signature_algorithm_supported( if not isinstance(signature_algorithm, ec.ECDSA): return False - return self.elliptic_curve_supported(curve) - - def generate_elliptic_curve_private_key( - self, curve: ec.EllipticCurve - ) -> ec.EllipticCurvePrivateKey: - """ - Generate a new private key on the named curve. - """ - - if self.elliptic_curve_supported(curve): - ec_cdata = self._ec_key_new_by_curve(curve) - - res = self._lib.EC_KEY_generate_key(ec_cdata) - self.openssl_assert(res == 1) - - evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) - - return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) - else: - raise UnsupportedAlgorithm( - f"Backend object does not support {curve.name}.", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, - ) - - def load_elliptic_curve_private_numbers( - self, numbers: ec.EllipticCurvePrivateNumbers - ) -> ec.EllipticCurvePrivateKey: - public = numbers.public_numbers - - ec_cdata = self._ec_key_new_by_curve(public.curve) - - private_value = self._ffi.gc( - self._int_to_bn(numbers.private_value), self._lib.BN_clear_free + return self.elliptic_curve_supported(curve) and ( + isinstance(signature_algorithm.algorithm, asym_utils.Prehashed) + or self.hash_supported(signature_algorithm.algorithm) ) - res = self._lib.EC_KEY_set_private_key(ec_cdata, private_value) - if res != 1: - self._consume_errors() - raise ValueError("Invalid EC key.") - - with self._tmp_bn_ctx() as bn_ctx: - self._ec_key_set_public_key_affine_coordinates( - ec_cdata, public.x, public.y, bn_ctx - ) - # derive the expected public point and compare it to the one we - # just set based on the values we were given. If they don't match - # this isn't a valid key pair. - group = self._lib.EC_KEY_get0_group(ec_cdata) - self.openssl_assert(group != self._ffi.NULL) - set_point = backend._lib.EC_KEY_get0_public_key(ec_cdata) - self.openssl_assert(set_point != self._ffi.NULL) - computed_point = self._lib.EC_POINT_new(group) - self.openssl_assert(computed_point != self._ffi.NULL) - computed_point = self._ffi.gc( - computed_point, self._lib.EC_POINT_free - ) - res = self._lib.EC_POINT_mul( - group, - computed_point, - private_value, - self._ffi.NULL, - self._ffi.NULL, - bn_ctx, - ) - self.openssl_assert(res == 1) - if ( - self._lib.EC_POINT_cmp( - group, set_point, computed_point, bn_ctx - ) - != 0 - ): - raise ValueError("Invalid EC key.") - - evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) - - return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) - - def load_elliptic_curve_public_numbers( - self, numbers: ec.EllipticCurvePublicNumbers - ) -> ec.EllipticCurvePublicKey: - ec_cdata = self._ec_key_new_by_curve(numbers.curve) - with self._tmp_bn_ctx() as bn_ctx: - self._ec_key_set_public_key_affine_coordinates( - ec_cdata, numbers.x, numbers.y, bn_ctx - ) - evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) - - return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) - - def load_elliptic_curve_public_bytes( - self, curve: ec.EllipticCurve, point_bytes: bytes - ) -> ec.EllipticCurvePublicKey: - ec_cdata = self._ec_key_new_by_curve(curve) - group = self._lib.EC_KEY_get0_group(ec_cdata) - self.openssl_assert(group != self._ffi.NULL) - point = self._lib.EC_POINT_new(group) - self.openssl_assert(point != self._ffi.NULL) - point = self._ffi.gc(point, self._lib.EC_POINT_free) - with self._tmp_bn_ctx() as bn_ctx: - res = self._lib.EC_POINT_oct2point( - group, point, point_bytes, len(point_bytes), bn_ctx - ) - if res != 1: - self._consume_errors() - raise ValueError("Invalid public bytes for the given curve") - - res = self._lib.EC_KEY_set_public_key(ec_cdata, point) - self.openssl_assert(res == 1) - evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) - return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) - - def derive_elliptic_curve_private_key( - self, private_value: int, curve: ec.EllipticCurve - ) -> ec.EllipticCurvePrivateKey: - ec_cdata = self._ec_key_new_by_curve(curve) - - group = self._lib.EC_KEY_get0_group(ec_cdata) - self.openssl_assert(group != self._ffi.NULL) - - point = self._lib.EC_POINT_new(group) - self.openssl_assert(point != self._ffi.NULL) - point = self._ffi.gc(point, self._lib.EC_POINT_free) - - value = self._int_to_bn(private_value) - value = self._ffi.gc(value, self._lib.BN_clear_free) - - with self._tmp_bn_ctx() as bn_ctx: - res = self._lib.EC_POINT_mul( - group, point, value, self._ffi.NULL, self._ffi.NULL, bn_ctx - ) - self.openssl_assert(res == 1) - - bn_x = self._lib.BN_CTX_get(bn_ctx) - bn_y = self._lib.BN_CTX_get(bn_ctx) - - res = self._lib.EC_POINT_get_affine_coordinates( - group, point, bn_x, bn_y, bn_ctx - ) - if res != 1: - self._consume_errors() - raise ValueError("Unable to derive key from private_value") - - res = self._lib.EC_KEY_set_public_key(ec_cdata, point) - self.openssl_assert(res == 1) - private = self._int_to_bn(private_value) - private = self._ffi.gc(private, self._lib.BN_clear_free) - res = self._lib.EC_KEY_set_private_key(ec_cdata, private) - self.openssl_assert(res == 1) - - evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) - - return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) - - def _ec_key_new_by_curve(self, curve: ec.EllipticCurve): - curve_nid = self._elliptic_curve_to_nid(curve) - return self._ec_key_new_by_curve_nid(curve_nid) - - def _ec_key_new_by_curve_nid(self, curve_nid: int): - ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) - self.openssl_assert(ec_cdata != self._ffi.NULL) - return self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) def elliptic_curve_exchange_algorithm_supported( self, algorithm: ec.ECDH, curve: ec.EllipticCurve ) -> bool: - if self._fips_enabled and not isinstance( - curve, self._fips_ecdh_curves - ): - return False - return self.elliptic_curve_supported(curve) and isinstance( algorithm, ec.ECDH ) - def _ec_cdata_to_evp_pkey(self, ec_cdata): - evp_pkey = self._create_evp_pkey_gc() - res = self._lib.EVP_PKEY_set1_EC_KEY(evp_pkey, ec_cdata) - self.openssl_assert(res == 1) - return evp_pkey - - def _elliptic_curve_to_nid(self, curve: ec.EllipticCurve) -> int: - """ - Get the NID for a curve name. - """ - - curve_aliases = {"secp192r1": "prime192v1", "secp256r1": "prime256v1"} - - curve_name = curve_aliases.get(curve.name, curve.name) - - curve_nid = self._lib.OBJ_sn2nid(curve_name.encode()) - if curve_nid == self._lib.NID_undef: - raise UnsupportedAlgorithm( - f"{curve.name} is not a supported elliptic curve", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, - ) - return curve_nid - - @contextmanager - def _tmp_bn_ctx(self): - bn_ctx = self._lib.BN_CTX_new() - self.openssl_assert(bn_ctx != self._ffi.NULL) - bn_ctx = self._ffi.gc(bn_ctx, self._lib.BN_CTX_free) - self._lib.BN_CTX_start(bn_ctx) - try: - yield bn_ctx - finally: - self._lib.BN_CTX_end(bn_ctx) - - def _ec_key_set_public_key_affine_coordinates( - self, - ec_cdata, - x: int, - y: int, - bn_ctx, - ) -> None: - """ - Sets the public key point in the EC_KEY context to the affine x and y - values. - """ - - if x < 0 or y < 0: - raise ValueError( - "Invalid EC key. Both x and y must be non-negative." - ) - - x = self._ffi.gc(self._int_to_bn(x), self._lib.BN_free) - y = self._ffi.gc(self._int_to_bn(y), self._lib.BN_free) - group = self._lib.EC_KEY_get0_group(ec_cdata) - self.openssl_assert(group != self._ffi.NULL) - point = self._lib.EC_POINT_new(group) - self.openssl_assert(point != self._ffi.NULL) - point = self._ffi.gc(point, self._lib.EC_POINT_free) - res = self._lib.EC_POINT_set_affine_coordinates( - group, point, x, y, bn_ctx - ) - if res != 1: - self._consume_errors() - raise ValueError("Invalid EC key.") - res = self._lib.EC_KEY_set_public_key(ec_cdata, point) - self.openssl_assert(res == 1) - - def _private_key_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - key, - evp_pkey, - cdata, - ) -> bytes: - # validate argument types - if not isinstance(encoding, serialization.Encoding): - raise TypeError("encoding must be an item from the Encoding enum") - if not isinstance(format, serialization.PrivateFormat): - raise TypeError( - "format must be an item from the PrivateFormat enum" - ) - if not isinstance( - encryption_algorithm, serialization.KeySerializationEncryption - ): - raise TypeError( - "Encryption algorithm must be a KeySerializationEncryption " - "instance" - ) - - # validate password - if isinstance(encryption_algorithm, serialization.NoEncryption): - password = b"" - elif isinstance( - encryption_algorithm, serialization.BestAvailableEncryption - ): - password = encryption_algorithm.password - if len(password) > 1023: - raise ValueError( - "Passwords longer than 1023 bytes are not supported by " - "this backend" - ) - elif ( - isinstance( - encryption_algorithm, serialization._KeySerializationEncryption - ) - and encryption_algorithm._format - is format - is serialization.PrivateFormat.OpenSSH - ): - password = encryption_algorithm.password - else: - raise ValueError("Unsupported encryption type") - - # PKCS8 + PEM/DER - if format is serialization.PrivateFormat.PKCS8: - if encoding is serialization.Encoding.PEM: - write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey - elif encoding is serialization.Encoding.DER: - write_bio = self._lib.i2d_PKCS8PrivateKey_bio - else: - raise ValueError("Unsupported encoding for PKCS8") - return self._private_key_bytes_via_bio( - write_bio, evp_pkey, password - ) - - # TraditionalOpenSSL + PEM/DER - if format is serialization.PrivateFormat.TraditionalOpenSSL: - if self._fips_enabled and not isinstance( - encryption_algorithm, serialization.NoEncryption - ): - raise ValueError( - "Encrypted traditional OpenSSL format is not " - "supported in FIPS mode." - ) - key_type = self._lib.EVP_PKEY_id(evp_pkey) - - if encoding is serialization.Encoding.PEM: - if key_type == self._lib.EVP_PKEY_RSA: - write_bio = self._lib.PEM_write_bio_RSAPrivateKey - else: - assert key_type == self._lib.EVP_PKEY_EC - write_bio = self._lib.PEM_write_bio_ECPrivateKey - return self._private_key_bytes_via_bio( - write_bio, cdata, password - ) - - if encoding is serialization.Encoding.DER: - if password: - raise ValueError( - "Encryption is not supported for DER encoded " - "traditional OpenSSL keys" - ) - if key_type == self._lib.EVP_PKEY_RSA: - write_bio = self._lib.i2d_RSAPrivateKey_bio - else: - assert key_type == self._lib.EVP_PKEY_EC - write_bio = self._lib.i2d_ECPrivateKey_bio - return self._bio_func_output(write_bio, cdata) - - raise ValueError("Unsupported encoding for TraditionalOpenSSL") - - # OpenSSH + PEM - if format is serialization.PrivateFormat.OpenSSH: - if encoding is serialization.Encoding.PEM: - return ssh._serialize_ssh_private_key( - key, password, encryption_algorithm - ) - - raise ValueError( - "OpenSSH private key format can only be used" - " with PEM encoding" - ) - - # Anything that key-specific code was supposed to handle earlier, - # like Raw. - raise ValueError("format is invalid with this key") - - def _private_key_bytes_via_bio( - self, write_bio, evp_pkey, password - ) -> bytes: - if not password: - evp_cipher = self._ffi.NULL - else: - # This is a curated value that we will update over time. - evp_cipher = self._lib.EVP_get_cipherbyname(b"aes-256-cbc") - - return self._bio_func_output( - write_bio, - evp_pkey, - evp_cipher, - password, - len(password), - self._ffi.NULL, - self._ffi.NULL, - ) - - def _bio_func_output(self, write_bio, *args) -> bytes: - bio = self._create_mem_bio_gc() - res = write_bio(bio, *args) - self.openssl_assert(res == 1) - return self._read_mem_bio(bio) - - def _public_key_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - key, - evp_pkey, - cdata, - ) -> bytes: - if not isinstance(encoding, serialization.Encoding): - raise TypeError("encoding must be an item from the Encoding enum") - if not isinstance(format, serialization.PublicFormat): - raise TypeError( - "format must be an item from the PublicFormat enum" - ) - - # SubjectPublicKeyInfo + PEM/DER - if format is serialization.PublicFormat.SubjectPublicKeyInfo: - if encoding is serialization.Encoding.PEM: - write_bio = self._lib.PEM_write_bio_PUBKEY - elif encoding is serialization.Encoding.DER: - write_bio = self._lib.i2d_PUBKEY_bio - else: - raise ValueError( - "SubjectPublicKeyInfo works only with PEM or DER encoding" - ) - return self._bio_func_output(write_bio, evp_pkey) - - # PKCS1 + PEM/DER - if format is serialization.PublicFormat.PKCS1: - # Only RSA is supported here. - key_type = self._lib.EVP_PKEY_id(evp_pkey) - if key_type != self._lib.EVP_PKEY_RSA: - raise ValueError("PKCS1 format is supported only for RSA keys") - - if encoding is serialization.Encoding.PEM: - write_bio = self._lib.PEM_write_bio_RSAPublicKey - elif encoding is serialization.Encoding.DER: - write_bio = self._lib.i2d_RSAPublicKey_bio - else: - raise ValueError("PKCS1 works only with PEM or DER encoding") - return self._bio_func_output(write_bio, cdata) - - # OpenSSH + OpenSSH - if format is serialization.PublicFormat.OpenSSH: - if encoding is serialization.Encoding.OpenSSH: - return ssh.serialize_ssh_public_key(key) - - raise ValueError( - "OpenSSH format must be used with OpenSSH encoding" - ) - - # Anything that key-specific code was supposed to handle earlier, - # like Raw, CompressedPoint, UncompressedPoint - raise ValueError("format is invalid with this key") - def dh_supported(self) -> bool: return not self._lib.CRYPTOGRAPHY_IS_BORINGSSL - def generate_dh_parameters( - self, generator: int, key_size: int - ) -> dh.DHParameters: - return rust_openssl.dh.generate_parameters(generator, key_size) - - def generate_dh_private_key( - self, parameters: dh.DHParameters - ) -> dh.DHPrivateKey: - return parameters.generate_private_key() - - def generate_dh_private_key_and_parameters( - self, generator: int, key_size: int - ) -> dh.DHPrivateKey: - return self.generate_dh_private_key( - self.generate_dh_parameters(generator, key_size) - ) - - def load_dh_private_numbers( - self, numbers: dh.DHPrivateNumbers - ) -> dh.DHPrivateKey: - return rust_openssl.dh.from_private_numbers(numbers) - - def load_dh_public_numbers( - self, numbers: dh.DHPublicNumbers - ) -> dh.DHPublicKey: - return rust_openssl.dh.from_public_numbers(numbers) - - def load_dh_parameter_numbers( - self, numbers: dh.DHParameterNumbers - ) -> dh.DHParameters: - return rust_openssl.dh.from_parameter_numbers(numbers) - - def dh_parameters_supported( - self, p: int, g: int, q: typing.Optional[int] = None - ) -> bool: - try: - rust_openssl.dh.from_parameter_numbers( - dh.DHParameterNumbers(p=p, g=g, q=q) - ) - except ValueError: - return False - else: - return True - def dh_x942_serialization_supported(self) -> bool: return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1 - def x25519_load_public_bytes(self, data: bytes) -> x25519.X25519PublicKey: - return rust_openssl.x25519.from_public_bytes(data) - - def x25519_load_private_bytes( - self, data: bytes - ) -> x25519.X25519PrivateKey: - return rust_openssl.x25519.from_private_bytes(data) - - def x25519_generate_key(self) -> x25519.X25519PrivateKey: - return rust_openssl.x25519.generate_key() - def x25519_supported(self) -> bool: if self._fips_enabled: return False - return not self._lib.CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 - - def x448_load_public_bytes(self, data: bytes) -> x448.X448PublicKey: - return rust_openssl.x448.from_public_bytes(data) - - def x448_load_private_bytes(self, data: bytes) -> x448.X448PrivateKey: - return rust_openssl.x448.from_private_bytes(data) - - def x448_generate_key(self) -> x448.X448PrivateKey: - return rust_openssl.x448.generate_key() + return True def x448_supported(self) -> bool: if self._fips_enabled: @@ -1532,20 +550,7 @@ def x448_supported(self) -> bool: def ed25519_supported(self) -> bool: if self._fips_enabled: return False - return self._lib.CRYPTOGRAPHY_HAS_WORKING_ED25519 - - def ed25519_load_public_bytes( - self, data: bytes - ) -> ed25519.Ed25519PublicKey: - return rust_openssl.ed25519.from_public_bytes(data) - - def ed25519_load_private_bytes( - self, data: bytes - ) -> ed25519.Ed25519PrivateKey: - return rust_openssl.ed25519.from_private_bytes(data) - - def ed25519_generate_key(self) -> ed25519.Ed25519PrivateKey: - return rust_openssl.ed25519.generate_key() + return True def ed448_supported(self) -> bool: if self._fips_enabled: @@ -1555,15 +560,6 @@ def ed448_supported(self) -> bool: and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL ) - def ed448_load_public_bytes(self, data: bytes) -> ed448.Ed448PublicKey: - return rust_openssl.ed448.from_public_bytes(data) - - def ed448_load_private_bytes(self, data: bytes) -> ed448.Ed448PrivateKey: - return rust_openssl.ed448.from_private_bytes(data) - - def ed448_generate_key(self) -> ed448.Ed448PrivateKey: - return rust_openssl.ed448.generate_key() - def aead_cipher_supported(self, cipher) -> bool: return aead._aead_cipher_supported(self, cipher) @@ -1598,11 +594,11 @@ def _zeroed_null_terminated_buf(self, data): self._zero_data(self._ffi.cast("uint8_t *", buf), data_len) def load_key_and_certificates_from_pkcs12( - self, data: bytes, password: typing.Optional[bytes] - ) -> typing.Tuple[ - typing.Optional[PrivateKeyTypes], - typing.Optional[x509.Certificate], - typing.List[x509.Certificate], + self, data: bytes, password: bytes | None + ) -> tuple[ + PrivateKeyTypes | None, + x509.Certificate | None, + list[x509.Certificate], ]: pkcs12 = self.load_pkcs12(data, password) return ( @@ -1612,7 +608,7 @@ def load_key_and_certificates_from_pkcs12( ) def load_pkcs12( - self, data: bytes, password: typing.Optional[bytes] + self, data: bytes, password: bytes | None ) -> PKCS12KeyAndCertificates: if password is not None: utils._check_byteslike("password", password) @@ -1643,8 +639,9 @@ def load_pkcs12( evp_pkey = self._ffi.gc(evp_pkey_ptr[0], self._lib.EVP_PKEY_free) # We don't support turning off RSA key validation when loading # PKCS12 keys - key = self._evp_pkey_to_private_key( - evp_pkey, unsafe_skip_rsa_key_validation=False + key = rust_openssl.keys.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)), + unsafe_skip_rsa_key_validation=False, ) if x509_ptr[0] != self._ffi.NULL: @@ -1688,10 +685,10 @@ def load_pkcs12( def serialize_key_and_certificates_to_pkcs12( self, - name: typing.Optional[bytes], - key: typing.Optional[PKCS12PrivateKeyTypes], - cert: typing.Optional[x509.Certificate], - cas: typing.Optional[typing.List[_PKCS12CATypes]], + name: bytes | None, + key: PKCS12PrivateKeyTypes | None, + cert: x509.Certificate | None, + cas: list[_PKCS12CATypes] | None, encryption_algorithm: serialization.KeySerializationEncryption, ) -> bytes: password = None @@ -1821,6 +818,15 @@ def serialize_key_and_certificates_to_pkcs12( mac_iter, 0, ) + if p12 == self._ffi.NULL: + errors = self._consume_errors() + raise ValueError( + ( + "Failed to create PKCS12 (does the key match the " + "certificate?)" + ), + errors, + ) if ( self._lib.Cryptography_HAS_PKCS12_SET_MAC @@ -1847,60 +853,17 @@ def serialize_key_and_certificates_to_pkcs12( def poly1305_supported(self) -> bool: if self._fips_enabled: return False - return self._lib.Cryptography_HAS_POLY1305 == 1 + elif ( + self._lib.CRYPTOGRAPHY_IS_BORINGSSL + or self._lib.CRYPTOGRAPHY_IS_LIBRESSL + ): + return True + else: + return self._lib.Cryptography_HAS_POLY1305 == 1 def pkcs7_supported(self) -> bool: return not self._lib.CRYPTOGRAPHY_IS_BORINGSSL - def load_pem_pkcs7_certificates( - self, data: bytes - ) -> typing.List[x509.Certificate]: - utils._check_bytes("data", data) - bio = self._bytes_to_bio(data) - p7 = self._lib.PEM_read_bio_PKCS7( - bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL - ) - if p7 == self._ffi.NULL: - self._consume_errors() - raise ValueError("Unable to parse PKCS7 data") - - p7 = self._ffi.gc(p7, self._lib.PKCS7_free) - return self._load_pkcs7_certificates(p7) - - def load_der_pkcs7_certificates( - self, data: bytes - ) -> typing.List[x509.Certificate]: - utils._check_bytes("data", data) - bio = self._bytes_to_bio(data) - p7 = self._lib.d2i_PKCS7_bio(bio.bio, self._ffi.NULL) - if p7 == self._ffi.NULL: - self._consume_errors() - raise ValueError("Unable to parse PKCS7 data") - - p7 = self._ffi.gc(p7, self._lib.PKCS7_free) - return self._load_pkcs7_certificates(p7) - - def _load_pkcs7_certificates(self, p7) -> typing.List[x509.Certificate]: - nid = self._lib.OBJ_obj2nid(p7.type) - self.openssl_assert(nid != self._lib.NID_undef) - if nid != self._lib.NID_pkcs7_signed: - raise UnsupportedAlgorithm( - "Only basic signed structures are currently supported. NID" - " for this data was {}".format(nid), - _Reasons.UNSUPPORTED_SERIALIZATION, - ) - - sk_x509 = p7.d.sign.cert - num = self._lib.sk_X509_num(sk_x509) - certs = [] - for i in range(num): - x509 = self._lib.sk_X509_value(sk_x509, i) - self.openssl_assert(x509 != self._ffi.NULL) - cert = self._ossl2cert(x509) - certs.append(cert) - - return certs - class GetCipherByName: def __init__(self, fmt: str): diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py index bc42adbd..3916b1a5 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py @@ -17,14 +17,14 @@ class _CipherContext: _ENCRYPT = 1 _DECRYPT = 0 - _MAX_CHUNK_SIZE = 2**30 - 1 + _MAX_CHUNK_SIZE = 2**29 def __init__(self, backend: Backend, cipher, mode, operation: int) -> None: self._backend = backend self._cipher = cipher self._mode = mode self._operation = operation - self._tag: typing.Optional[bytes] = None + self._tag: bytes | None = None if isinstance(self._cipher, ciphers.BlockCipherAlgorithm): self._block_size_bytes = self._cipher.block_size // 8 @@ -149,8 +149,9 @@ def update_into(self, data: bytes, buf: bytes) -> int: total_data_len = len(data) if len(buf) < (total_data_len + self._block_size_bytes - 1): raise ValueError( - "buffer must be at least {} bytes for this " - "payload".format(len(data) + self._block_size_bytes - 1) + "buffer must be at least {} bytes for this payload".format( + len(data) + self._block_size_bytes - 1 + ) ) data_processed = 0 @@ -277,5 +278,5 @@ def authenticate_additional_data(self, data: bytes) -> None: self._backend.openssl_assert(res != 0) @property - def tag(self) -> typing.Optional[bytes]: + def tag(self) -> bytes | None: return self._tag diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/cmac.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/cmac.py deleted file mode 100644 index bdd7fec6..00000000 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/cmac.py +++ /dev/null @@ -1,89 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import ( - InvalidSignature, - UnsupportedAlgorithm, - _Reasons, -) -from cryptography.hazmat.primitives import constant_time -from cryptography.hazmat.primitives.ciphers.modes import CBC - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - from cryptography.hazmat.primitives import ciphers - - -class _CMACContext: - def __init__( - self, - backend: Backend, - algorithm: ciphers.BlockCipherAlgorithm, - ctx=None, - ) -> None: - if not backend.cmac_algorithm_supported(algorithm): - raise UnsupportedAlgorithm( - "This backend does not support CMAC.", - _Reasons.UNSUPPORTED_CIPHER, - ) - - self._backend = backend - self._key = algorithm.key - self._algorithm = algorithm - self._output_length = algorithm.block_size // 8 - - if ctx is None: - registry = self._backend._cipher_registry - adapter = registry[type(algorithm), CBC] - - evp_cipher = adapter(self._backend, algorithm, CBC) - - ctx = self._backend._lib.CMAC_CTX_new() - - self._backend.openssl_assert(ctx != self._backend._ffi.NULL) - ctx = self._backend._ffi.gc(ctx, self._backend._lib.CMAC_CTX_free) - - key_ptr = self._backend._ffi.from_buffer(self._key) - res = self._backend._lib.CMAC_Init( - ctx, - key_ptr, - len(self._key), - evp_cipher, - self._backend._ffi.NULL, - ) - self._backend.openssl_assert(res == 1) - - self._ctx = ctx - - def update(self, data: bytes) -> None: - res = self._backend._lib.CMAC_Update(self._ctx, data, len(data)) - self._backend.openssl_assert(res == 1) - - def finalize(self) -> bytes: - buf = self._backend._ffi.new("unsigned char[]", self._output_length) - length = self._backend._ffi.new("size_t *", self._output_length) - res = self._backend._lib.CMAC_Final(self._ctx, buf, length) - self._backend.openssl_assert(res == 1) - - self._ctx = None - - return self._backend._ffi.buffer(buf)[:] - - def copy(self) -> _CMACContext: - copied_ctx = self._backend._lib.CMAC_CTX_new() - copied_ctx = self._backend._ffi.gc( - copied_ctx, self._backend._lib.CMAC_CTX_free - ) - res = self._backend._lib.CMAC_CTX_copy(copied_ctx, self._ctx) - self._backend.openssl_assert(res == 1) - return _CMACContext(self._backend, self._algorithm, ctx=copied_ctx) - - def verify(self, signature: bytes) -> None: - digest = self.finalize() - if not constant_time.bytes_eq(digest, signature): - raise InvalidSignature("Signature did not match digest.") diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ec.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ec.py deleted file mode 100644 index 9821bd19..00000000 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ec.py +++ /dev/null @@ -1,328 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import typing - -from cryptography.exceptions import ( - InvalidSignature, - UnsupportedAlgorithm, - _Reasons, -) -from cryptography.hazmat.backends.openssl.utils import ( - _calculate_digest_and_algorithm, - _evp_pkey_derive, -) -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import ec - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -def _check_signature_algorithm( - signature_algorithm: ec.EllipticCurveSignatureAlgorithm, -) -> None: - if not isinstance(signature_algorithm, ec.ECDSA): - raise UnsupportedAlgorithm( - "Unsupported elliptic curve signature algorithm.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, - ) - - -def _ec_key_curve_sn(backend: Backend, ec_key) -> str: - group = backend._lib.EC_KEY_get0_group(ec_key) - backend.openssl_assert(group != backend._ffi.NULL) - - nid = backend._lib.EC_GROUP_get_curve_name(group) - # The following check is to find EC keys with unnamed curves and raise - # an error for now. - if nid == backend._lib.NID_undef: - raise ValueError( - "ECDSA keys with explicit parameters are unsupported at this time" - ) - - # This is like the above check, but it also catches the case where you - # explicitly encoded a curve with the same parameters as a named curve. - # Don't do that. - if ( - not backend._lib.CRYPTOGRAPHY_IS_LIBRESSL - and backend._lib.EC_GROUP_get_asn1_flag(group) == 0 - ): - raise ValueError( - "ECDSA keys with explicit parameters are unsupported at this time" - ) - - curve_name = backend._lib.OBJ_nid2sn(nid) - backend.openssl_assert(curve_name != backend._ffi.NULL) - - sn = backend._ffi.string(curve_name).decode("ascii") - return sn - - -def _mark_asn1_named_ec_curve(backend: Backend, ec_cdata): - """ - Set the named curve flag on the EC_KEY. This causes OpenSSL to - serialize EC keys along with their curve OID which makes - deserialization easier. - """ - - backend._lib.EC_KEY_set_asn1_flag( - ec_cdata, backend._lib.OPENSSL_EC_NAMED_CURVE - ) - - -def _check_key_infinity(backend: Backend, ec_cdata) -> None: - point = backend._lib.EC_KEY_get0_public_key(ec_cdata) - backend.openssl_assert(point != backend._ffi.NULL) - group = backend._lib.EC_KEY_get0_group(ec_cdata) - backend.openssl_assert(group != backend._ffi.NULL) - if backend._lib.EC_POINT_is_at_infinity(group, point): - raise ValueError( - "Cannot load an EC public key where the point is at infinity" - ) - - -def _sn_to_elliptic_curve(backend: Backend, sn: str) -> ec.EllipticCurve: - try: - return ec._CURVE_TYPES[sn]() - except KeyError: - raise UnsupportedAlgorithm( - f"{sn} is not a supported elliptic curve", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, - ) - - -def _ecdsa_sig_sign( - backend: Backend, private_key: _EllipticCurvePrivateKey, data: bytes -) -> bytes: - max_size = backend._lib.ECDSA_size(private_key._ec_key) - backend.openssl_assert(max_size > 0) - - sigbuf = backend._ffi.new("unsigned char[]", max_size) - siglen_ptr = backend._ffi.new("unsigned int[]", 1) - res = backend._lib.ECDSA_sign( - 0, data, len(data), sigbuf, siglen_ptr, private_key._ec_key - ) - backend.openssl_assert(res == 1) - return backend._ffi.buffer(sigbuf)[: siglen_ptr[0]] - - -def _ecdsa_sig_verify( - backend: Backend, - public_key: _EllipticCurvePublicKey, - signature: bytes, - data: bytes, -) -> None: - res = backend._lib.ECDSA_verify( - 0, data, len(data), signature, len(signature), public_key._ec_key - ) - if res != 1: - backend._consume_errors() - raise InvalidSignature - - -class _EllipticCurvePrivateKey(ec.EllipticCurvePrivateKey): - def __init__(self, backend: Backend, ec_key_cdata, evp_pkey): - self._backend = backend - self._ec_key = ec_key_cdata - self._evp_pkey = evp_pkey - - sn = _ec_key_curve_sn(backend, ec_key_cdata) - self._curve = _sn_to_elliptic_curve(backend, sn) - _mark_asn1_named_ec_curve(backend, ec_key_cdata) - _check_key_infinity(backend, ec_key_cdata) - - @property - def curve(self) -> ec.EllipticCurve: - return self._curve - - @property - def key_size(self) -> int: - return self.curve.key_size - - def exchange( - self, algorithm: ec.ECDH, peer_public_key: ec.EllipticCurvePublicKey - ) -> bytes: - if not ( - self._backend.elliptic_curve_exchange_algorithm_supported( - algorithm, self.curve - ) - ): - raise UnsupportedAlgorithm( - "This backend does not support the ECDH algorithm.", - _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, - ) - - if peer_public_key.curve.name != self.curve.name: - raise ValueError( - "peer_public_key and self are not on the same curve" - ) - - return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key) - - def public_key(self) -> ec.EllipticCurvePublicKey: - group = self._backend._lib.EC_KEY_get0_group(self._ec_key) - self._backend.openssl_assert(group != self._backend._ffi.NULL) - - curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group) - public_ec_key = self._backend._ec_key_new_by_curve_nid(curve_nid) - - point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) - self._backend.openssl_assert(point != self._backend._ffi.NULL) - - res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point) - self._backend.openssl_assert(res == 1) - - evp_pkey = self._backend._ec_cdata_to_evp_pkey(public_ec_key) - - return _EllipticCurvePublicKey(self._backend, public_ec_key, evp_pkey) - - def private_numbers(self) -> ec.EllipticCurvePrivateNumbers: - bn = self._backend._lib.EC_KEY_get0_private_key(self._ec_key) - private_value = self._backend._bn_to_int(bn) - return ec.EllipticCurvePrivateNumbers( - private_value=private_value, - public_numbers=self.public_key().public_numbers(), - ) - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - return self._backend._private_key_bytes( - encoding, - format, - encryption_algorithm, - self, - self._evp_pkey, - self._ec_key, - ) - - def sign( - self, - data: bytes, - signature_algorithm: ec.EllipticCurveSignatureAlgorithm, - ) -> bytes: - _check_signature_algorithm(signature_algorithm) - data, _ = _calculate_digest_and_algorithm( - data, - signature_algorithm.algorithm, - ) - return _ecdsa_sig_sign(self._backend, self, data) - - -class _EllipticCurvePublicKey(ec.EllipticCurvePublicKey): - def __init__(self, backend: Backend, ec_key_cdata, evp_pkey): - self._backend = backend - self._ec_key = ec_key_cdata - self._evp_pkey = evp_pkey - - sn = _ec_key_curve_sn(backend, ec_key_cdata) - self._curve = _sn_to_elliptic_curve(backend, sn) - _mark_asn1_named_ec_curve(backend, ec_key_cdata) - _check_key_infinity(backend, ec_key_cdata) - - @property - def curve(self) -> ec.EllipticCurve: - return self._curve - - @property - def key_size(self) -> int: - return self.curve.key_size - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _EllipticCurvePublicKey): - return NotImplemented - - return ( - self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) - == 1 - ) - - def public_numbers(self) -> ec.EllipticCurvePublicNumbers: - group = self._backend._lib.EC_KEY_get0_group(self._ec_key) - self._backend.openssl_assert(group != self._backend._ffi.NULL) - - point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) - self._backend.openssl_assert(point != self._backend._ffi.NULL) - - with self._backend._tmp_bn_ctx() as bn_ctx: - bn_x = self._backend._lib.BN_CTX_get(bn_ctx) - bn_y = self._backend._lib.BN_CTX_get(bn_ctx) - - res = self._backend._lib.EC_POINT_get_affine_coordinates( - group, point, bn_x, bn_y, bn_ctx - ) - self._backend.openssl_assert(res == 1) - - x = self._backend._bn_to_int(bn_x) - y = self._backend._bn_to_int(bn_y) - - return ec.EllipticCurvePublicNumbers(x=x, y=y, curve=self._curve) - - def _encode_point(self, format: serialization.PublicFormat) -> bytes: - if format is serialization.PublicFormat.CompressedPoint: - conversion = self._backend._lib.POINT_CONVERSION_COMPRESSED - else: - assert format is serialization.PublicFormat.UncompressedPoint - conversion = self._backend._lib.POINT_CONVERSION_UNCOMPRESSED - - group = self._backend._lib.EC_KEY_get0_group(self._ec_key) - self._backend.openssl_assert(group != self._backend._ffi.NULL) - point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) - self._backend.openssl_assert(point != self._backend._ffi.NULL) - with self._backend._tmp_bn_ctx() as bn_ctx: - buflen = self._backend._lib.EC_POINT_point2oct( - group, point, conversion, self._backend._ffi.NULL, 0, bn_ctx - ) - self._backend.openssl_assert(buflen > 0) - buf = self._backend._ffi.new("char[]", buflen) - res = self._backend._lib.EC_POINT_point2oct( - group, point, conversion, buf, buflen, bn_ctx - ) - self._backend.openssl_assert(buflen == res) - - return self._backend._ffi.buffer(buf)[:] - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - if ( - encoding is serialization.Encoding.X962 - or format is serialization.PublicFormat.CompressedPoint - or format is serialization.PublicFormat.UncompressedPoint - ): - if encoding is not serialization.Encoding.X962 or format not in ( - serialization.PublicFormat.CompressedPoint, - serialization.PublicFormat.UncompressedPoint, - ): - raise ValueError( - "X962 encoding must be used with CompressedPoint or " - "UncompressedPoint format" - ) - - return self._encode_point(format) - else: - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, None - ) - - def verify( - self, - signature: bytes, - data: bytes, - signature_algorithm: ec.EllipticCurveSignatureAlgorithm, - ) -> None: - _check_signature_algorithm(signature_algorithm) - data, _ = _calculate_digest_and_algorithm( - data, - signature_algorithm.algorithm, - ) - _ecdsa_sig_verify(self._backend, self, signature, data) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/rsa.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/rsa.py deleted file mode 100644 index ef27d4ea..00000000 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/rsa.py +++ /dev/null @@ -1,599 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import threading -import typing - -from cryptography.exceptions import ( - InvalidSignature, - UnsupportedAlgorithm, - _Reasons, -) -from cryptography.hazmat.backends.openssl.utils import ( - _calculate_digest_and_algorithm, -) -from cryptography.hazmat.primitives import hashes, serialization -from cryptography.hazmat.primitives.asymmetric import utils as asym_utils -from cryptography.hazmat.primitives.asymmetric.padding import ( - MGF1, - OAEP, - PSS, - AsymmetricPadding, - PKCS1v15, - _Auto, - _DigestLength, - _MaxLength, - calculate_max_pss_salt_length, -) -from cryptography.hazmat.primitives.asymmetric.rsa import ( - RSAPrivateKey, - RSAPrivateNumbers, - RSAPublicKey, - RSAPublicNumbers, -) - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -def _get_rsa_pss_salt_length( - backend: Backend, - pss: PSS, - key: typing.Union[RSAPrivateKey, RSAPublicKey], - hash_algorithm: hashes.HashAlgorithm, -) -> int: - salt = pss._salt_length - - if isinstance(salt, _MaxLength): - return calculate_max_pss_salt_length(key, hash_algorithm) - elif isinstance(salt, _DigestLength): - return hash_algorithm.digest_size - elif isinstance(salt, _Auto): - if isinstance(key, RSAPrivateKey): - raise ValueError( - "PSS salt length can only be set to AUTO when verifying" - ) - return backend._lib.RSA_PSS_SALTLEN_AUTO - else: - return salt - - -def _enc_dec_rsa( - backend: Backend, - key: typing.Union[_RSAPrivateKey, _RSAPublicKey], - data: bytes, - padding: AsymmetricPadding, -) -> bytes: - if not isinstance(padding, AsymmetricPadding): - raise TypeError("Padding must be an instance of AsymmetricPadding.") - - if isinstance(padding, PKCS1v15): - padding_enum = backend._lib.RSA_PKCS1_PADDING - elif isinstance(padding, OAEP): - padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING - - if not isinstance(padding._mgf, MGF1): - raise UnsupportedAlgorithm( - "Only MGF1 is supported by this backend.", - _Reasons.UNSUPPORTED_MGF, - ) - - if not backend.rsa_padding_supported(padding): - raise UnsupportedAlgorithm( - "This combination of padding and hash algorithm is not " - "supported by this backend.", - _Reasons.UNSUPPORTED_PADDING, - ) - - else: - raise UnsupportedAlgorithm( - f"{padding.name} is not supported by this backend.", - _Reasons.UNSUPPORTED_PADDING, - ) - - return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding) - - -def _enc_dec_rsa_pkey_ctx( - backend: Backend, - key: typing.Union[_RSAPrivateKey, _RSAPublicKey], - data: bytes, - padding_enum: int, - padding: AsymmetricPadding, -) -> bytes: - init: typing.Callable[[typing.Any], int] - crypt: typing.Callable[[typing.Any, typing.Any, int, bytes, int], int] - if isinstance(key, _RSAPublicKey): - init = backend._lib.EVP_PKEY_encrypt_init - crypt = backend._lib.EVP_PKEY_encrypt - else: - init = backend._lib.EVP_PKEY_decrypt_init - crypt = backend._lib.EVP_PKEY_decrypt - - pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL) - backend.openssl_assert(pkey_ctx != backend._ffi.NULL) - pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) - res = init(pkey_ctx) - backend.openssl_assert(res == 1) - res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum) - backend.openssl_assert(res > 0) - buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey) - backend.openssl_assert(buf_size > 0) - if isinstance(padding, OAEP): - mgf1_md = backend._evp_md_non_null_from_algorithm( - padding._mgf._algorithm - ) - res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md) - backend.openssl_assert(res > 0) - oaep_md = backend._evp_md_non_null_from_algorithm(padding._algorithm) - res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md) - backend.openssl_assert(res > 0) - - if ( - isinstance(padding, OAEP) - and padding._label is not None - and len(padding._label) > 0 - ): - # set0_rsa_oaep_label takes ownership of the char * so we need to - # copy it into some new memory - labelptr = backend._lib.OPENSSL_malloc(len(padding._label)) - backend.openssl_assert(labelptr != backend._ffi.NULL) - backend._ffi.memmove(labelptr, padding._label, len(padding._label)) - res = backend._lib.EVP_PKEY_CTX_set0_rsa_oaep_label( - pkey_ctx, labelptr, len(padding._label) - ) - backend.openssl_assert(res == 1) - - outlen = backend._ffi.new("size_t *", buf_size) - buf = backend._ffi.new("unsigned char[]", buf_size) - # Everything from this line onwards is written with the goal of being as - # constant-time as is practical given the constraints of Python and our - # API. See Bleichenbacher's '98 attack on RSA, and its many many variants. - # As such, you should not attempt to change this (particularly to "clean it - # up") without understanding why it was written this way (see - # Chesterton's Fence), and without measuring to verify you have not - # introduced observable time differences. - res = crypt(pkey_ctx, buf, outlen, data, len(data)) - resbuf = backend._ffi.buffer(buf)[: outlen[0]] - backend._lib.ERR_clear_error() - if res <= 0: - raise ValueError("Encryption/decryption failed.") - return resbuf - - -def _rsa_sig_determine_padding( - backend: Backend, - key: typing.Union[_RSAPrivateKey, _RSAPublicKey], - padding: AsymmetricPadding, - algorithm: typing.Optional[hashes.HashAlgorithm], -) -> int: - if not isinstance(padding, AsymmetricPadding): - raise TypeError("Expected provider of AsymmetricPadding.") - - pkey_size = backend._lib.EVP_PKEY_size(key._evp_pkey) - backend.openssl_assert(pkey_size > 0) - - if isinstance(padding, PKCS1v15): - # Hash algorithm is ignored for PKCS1v15-padding, may be None. - padding_enum = backend._lib.RSA_PKCS1_PADDING - elif isinstance(padding, PSS): - if not isinstance(padding._mgf, MGF1): - raise UnsupportedAlgorithm( - "Only MGF1 is supported by this backend.", - _Reasons.UNSUPPORTED_MGF, - ) - - # PSS padding requires a hash algorithm - if not isinstance(algorithm, hashes.HashAlgorithm): - raise TypeError("Expected instance of hashes.HashAlgorithm.") - - # Size of key in bytes - 2 is the maximum - # PSS signature length (salt length is checked later) - if pkey_size - algorithm.digest_size - 2 < 0: - raise ValueError( - "Digest too large for key size. Use a larger " - "key or different digest." - ) - - padding_enum = backend._lib.RSA_PKCS1_PSS_PADDING - else: - raise UnsupportedAlgorithm( - f"{padding.name} is not supported by this backend.", - _Reasons.UNSUPPORTED_PADDING, - ) - - return padding_enum - - -# Hash algorithm can be absent (None) to initialize the context without setting -# any message digest algorithm. This is currently only valid for the PKCS1v15 -# padding type, where it means that the signature data is encoded/decoded -# as provided, without being wrapped in a DigestInfo structure. -def _rsa_sig_setup( - backend: Backend, - padding: AsymmetricPadding, - algorithm: typing.Optional[hashes.HashAlgorithm], - key: typing.Union[_RSAPublicKey, _RSAPrivateKey], - init_func: typing.Callable[[typing.Any], int], -): - padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm) - pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL) - backend.openssl_assert(pkey_ctx != backend._ffi.NULL) - pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) - res = init_func(pkey_ctx) - if res != 1: - errors = backend._consume_errors() - raise ValueError("Unable to sign/verify with this key", errors) - - if algorithm is not None: - evp_md = backend._evp_md_non_null_from_algorithm(algorithm) - res = backend._lib.EVP_PKEY_CTX_set_signature_md(pkey_ctx, evp_md) - if res <= 0: - backend._consume_errors() - raise UnsupportedAlgorithm( - "{} is not supported by this backend for RSA signing.".format( - algorithm.name - ), - _Reasons.UNSUPPORTED_HASH, - ) - res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum) - if res <= 0: - backend._consume_errors() - raise UnsupportedAlgorithm( - "{} is not supported for the RSA signature operation.".format( - padding.name - ), - _Reasons.UNSUPPORTED_PADDING, - ) - if isinstance(padding, PSS): - assert isinstance(algorithm, hashes.HashAlgorithm) - res = backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen( - pkey_ctx, - _get_rsa_pss_salt_length(backend, padding, key, algorithm), - ) - backend.openssl_assert(res > 0) - - mgf1_md = backend._evp_md_non_null_from_algorithm( - padding._mgf._algorithm - ) - res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md) - backend.openssl_assert(res > 0) - - return pkey_ctx - - -def _rsa_sig_sign( - backend: Backend, - padding: AsymmetricPadding, - algorithm: hashes.HashAlgorithm, - private_key: _RSAPrivateKey, - data: bytes, -) -> bytes: - pkey_ctx = _rsa_sig_setup( - backend, - padding, - algorithm, - private_key, - backend._lib.EVP_PKEY_sign_init, - ) - buflen = backend._ffi.new("size_t *") - res = backend._lib.EVP_PKEY_sign( - pkey_ctx, backend._ffi.NULL, buflen, data, len(data) - ) - backend.openssl_assert(res == 1) - buf = backend._ffi.new("unsigned char[]", buflen[0]) - res = backend._lib.EVP_PKEY_sign(pkey_ctx, buf, buflen, data, len(data)) - if res != 1: - errors = backend._consume_errors() - raise ValueError( - "Digest or salt length too long for key size. Use a larger key " - "or shorter salt length if you are specifying a PSS salt", - errors, - ) - - return backend._ffi.buffer(buf)[:] - - -def _rsa_sig_verify( - backend: Backend, - padding: AsymmetricPadding, - algorithm: hashes.HashAlgorithm, - public_key: _RSAPublicKey, - signature: bytes, - data: bytes, -) -> None: - pkey_ctx = _rsa_sig_setup( - backend, - padding, - algorithm, - public_key, - backend._lib.EVP_PKEY_verify_init, - ) - res = backend._lib.EVP_PKEY_verify( - pkey_ctx, signature, len(signature), data, len(data) - ) - # The previous call can return negative numbers in the event of an - # error. This is not a signature failure but we need to fail if it - # occurs. - backend.openssl_assert(res >= 0) - if res == 0: - backend._consume_errors() - raise InvalidSignature - - -def _rsa_sig_recover( - backend: Backend, - padding: AsymmetricPadding, - algorithm: typing.Optional[hashes.HashAlgorithm], - public_key: _RSAPublicKey, - signature: bytes, -) -> bytes: - pkey_ctx = _rsa_sig_setup( - backend, - padding, - algorithm, - public_key, - backend._lib.EVP_PKEY_verify_recover_init, - ) - - # Attempt to keep the rest of the code in this function as constant/time - # as possible. See the comment in _enc_dec_rsa_pkey_ctx. Note that the - # buflen parameter is used even though its value may be undefined in the - # error case. Due to the tolerant nature of Python slicing this does not - # trigger any exceptions. - maxlen = backend._lib.EVP_PKEY_size(public_key._evp_pkey) - backend.openssl_assert(maxlen > 0) - buf = backend._ffi.new("unsigned char[]", maxlen) - buflen = backend._ffi.new("size_t *", maxlen) - res = backend._lib.EVP_PKEY_verify_recover( - pkey_ctx, buf, buflen, signature, len(signature) - ) - resbuf = backend._ffi.buffer(buf)[: buflen[0]] - backend._lib.ERR_clear_error() - # Assume that all parameter errors are handled during the setup phase and - # any error here is due to invalid signature. - if res != 1: - raise InvalidSignature - return resbuf - - -class _RSAPrivateKey(RSAPrivateKey): - _evp_pkey: object - _rsa_cdata: object - _key_size: int - - def __init__( - self, - backend: Backend, - rsa_cdata, - evp_pkey, - *, - unsafe_skip_rsa_key_validation: bool, - ): - res: int - # RSA_check_key is slower in OpenSSL 3.0.0 due to improved - # primality checking. In normal use this is unlikely to be a problem - # since users don't load new keys constantly, but for TESTING we've - # added an init arg that allows skipping the checks. You should not - # use this in production code unless you understand the consequences. - if not unsafe_skip_rsa_key_validation: - res = backend._lib.RSA_check_key(rsa_cdata) - if res != 1: - errors = backend._consume_errors() - raise ValueError("Invalid private key", errors) - # 2 is prime and passes an RSA key check, so we also check - # if p and q are odd just to be safe. - p = backend._ffi.new("BIGNUM **") - q = backend._ffi.new("BIGNUM **") - backend._lib.RSA_get0_factors(rsa_cdata, p, q) - backend.openssl_assert(p[0] != backend._ffi.NULL) - backend.openssl_assert(q[0] != backend._ffi.NULL) - p_odd = backend._lib.BN_is_odd(p[0]) - q_odd = backend._lib.BN_is_odd(q[0]) - if p_odd != 1 or q_odd != 1: - errors = backend._consume_errors() - raise ValueError("Invalid private key", errors) - - self._backend = backend - self._rsa_cdata = rsa_cdata - self._evp_pkey = evp_pkey - # Used for lazy blinding - self._blinded = False - self._blinding_lock = threading.Lock() - - n = self._backend._ffi.new("BIGNUM **") - self._backend._lib.RSA_get0_key( - self._rsa_cdata, - n, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - ) - self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) - self._key_size = self._backend._lib.BN_num_bits(n[0]) - - def _enable_blinding(self) -> None: - # If you call blind on an already blinded RSA key OpenSSL will turn - # it off and back on, which is a performance hit we want to avoid. - if not self._blinded: - with self._blinding_lock: - self._non_threadsafe_enable_blinding() - - def _non_threadsafe_enable_blinding(self) -> None: - # This is only a separate function to allow for testing to cover both - # branches. It should never be invoked except through _enable_blinding. - # Check if it's not True again in case another thread raced past the - # first non-locked check. - if not self._blinded: - res = self._backend._lib.RSA_blinding_on( - self._rsa_cdata, self._backend._ffi.NULL - ) - self._backend.openssl_assert(res == 1) - self._blinded = True - - @property - def key_size(self) -> int: - return self._key_size - - def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes: - self._enable_blinding() - key_size_bytes = (self.key_size + 7) // 8 - if key_size_bytes != len(ciphertext): - raise ValueError("Ciphertext length must be equal to key size.") - - return _enc_dec_rsa(self._backend, self, ciphertext, padding) - - def public_key(self) -> RSAPublicKey: - ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata) - self._backend.openssl_assert(ctx != self._backend._ffi.NULL) - ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free) - evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx) - return _RSAPublicKey(self._backend, ctx, evp_pkey) - - def private_numbers(self) -> RSAPrivateNumbers: - n = self._backend._ffi.new("BIGNUM **") - e = self._backend._ffi.new("BIGNUM **") - d = self._backend._ffi.new("BIGNUM **") - p = self._backend._ffi.new("BIGNUM **") - q = self._backend._ffi.new("BIGNUM **") - dmp1 = self._backend._ffi.new("BIGNUM **") - dmq1 = self._backend._ffi.new("BIGNUM **") - iqmp = self._backend._ffi.new("BIGNUM **") - self._backend._lib.RSA_get0_key(self._rsa_cdata, n, e, d) - self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(e[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(d[0] != self._backend._ffi.NULL) - self._backend._lib.RSA_get0_factors(self._rsa_cdata, p, q) - self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(q[0] != self._backend._ffi.NULL) - self._backend._lib.RSA_get0_crt_params( - self._rsa_cdata, dmp1, dmq1, iqmp - ) - self._backend.openssl_assert(dmp1[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(dmq1[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(iqmp[0] != self._backend._ffi.NULL) - return RSAPrivateNumbers( - p=self._backend._bn_to_int(p[0]), - q=self._backend._bn_to_int(q[0]), - d=self._backend._bn_to_int(d[0]), - dmp1=self._backend._bn_to_int(dmp1[0]), - dmq1=self._backend._bn_to_int(dmq1[0]), - iqmp=self._backend._bn_to_int(iqmp[0]), - public_numbers=RSAPublicNumbers( - e=self._backend._bn_to_int(e[0]), - n=self._backend._bn_to_int(n[0]), - ), - ) - - def private_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PrivateFormat, - encryption_algorithm: serialization.KeySerializationEncryption, - ) -> bytes: - return self._backend._private_key_bytes( - encoding, - format, - encryption_algorithm, - self, - self._evp_pkey, - self._rsa_cdata, - ) - - def sign( - self, - data: bytes, - padding: AsymmetricPadding, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], - ) -> bytes: - self._enable_blinding() - data, algorithm = _calculate_digest_and_algorithm(data, algorithm) - return _rsa_sig_sign(self._backend, padding, algorithm, self, data) - - -class _RSAPublicKey(RSAPublicKey): - _evp_pkey: object - _rsa_cdata: object - _key_size: int - - def __init__(self, backend: Backend, rsa_cdata, evp_pkey): - self._backend = backend - self._rsa_cdata = rsa_cdata - self._evp_pkey = evp_pkey - - n = self._backend._ffi.new("BIGNUM **") - self._backend._lib.RSA_get0_key( - self._rsa_cdata, - n, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - ) - self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) - self._key_size = self._backend._lib.BN_num_bits(n[0]) - - @property - def key_size(self) -> int: - return self._key_size - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _RSAPublicKey): - return NotImplemented - - return ( - self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) - == 1 - ) - - def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes: - return _enc_dec_rsa(self._backend, self, plaintext, padding) - - def public_numbers(self) -> RSAPublicNumbers: - n = self._backend._ffi.new("BIGNUM **") - e = self._backend._ffi.new("BIGNUM **") - self._backend._lib.RSA_get0_key( - self._rsa_cdata, n, e, self._backend._ffi.NULL - ) - self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) - self._backend.openssl_assert(e[0] != self._backend._ffi.NULL) - return RSAPublicNumbers( - e=self._backend._bn_to_int(e[0]), - n=self._backend._bn_to_int(n[0]), - ) - - def public_bytes( - self, - encoding: serialization.Encoding, - format: serialization.PublicFormat, - ) -> bytes: - return self._backend._public_key_bytes( - encoding, format, self, self._evp_pkey, self._rsa_cdata - ) - - def verify( - self, - signature: bytes, - data: bytes, - padding: AsymmetricPadding, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], - ) -> None: - data, algorithm = _calculate_digest_and_algorithm(data, algorithm) - _rsa_sig_verify( - self._backend, padding, algorithm, self, signature, data - ) - - def recover_data_from_signature( - self, - signature: bytes, - padding: AsymmetricPadding, - algorithm: typing.Optional[hashes.HashAlgorithm], - ) -> bytes: - if isinstance(algorithm, asym_utils.Prehashed): - raise TypeError( - "Prehashed is only supported in the sign and verify methods. " - "It cannot be used with recover_data_from_signature." - ) - return _rsa_sig_recover( - self._backend, padding, algorithm, self, signature - ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/utils.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/utils.py deleted file mode 100644 index 5b404def..00000000 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/utils.py +++ /dev/null @@ -1,63 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import typing - -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric.utils import Prehashed - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.backend import Backend - - -def _evp_pkey_derive(backend: Backend, evp_pkey, peer_public_key) -> bytes: - ctx = backend._lib.EVP_PKEY_CTX_new(evp_pkey, backend._ffi.NULL) - backend.openssl_assert(ctx != backend._ffi.NULL) - ctx = backend._ffi.gc(ctx, backend._lib.EVP_PKEY_CTX_free) - res = backend._lib.EVP_PKEY_derive_init(ctx) - backend.openssl_assert(res == 1) - - if backend._lib.Cryptography_HAS_EVP_PKEY_SET_PEER_EX: - res = backend._lib.EVP_PKEY_derive_set_peer_ex( - ctx, peer_public_key._evp_pkey, 0 - ) - else: - res = backend._lib.EVP_PKEY_derive_set_peer( - ctx, peer_public_key._evp_pkey - ) - backend.openssl_assert(res == 1) - - keylen = backend._ffi.new("size_t *") - res = backend._lib.EVP_PKEY_derive(ctx, backend._ffi.NULL, keylen) - backend.openssl_assert(res == 1) - backend.openssl_assert(keylen[0] > 0) - buf = backend._ffi.new("unsigned char[]", keylen[0]) - res = backend._lib.EVP_PKEY_derive(ctx, buf, keylen) - if res != 1: - errors = backend._consume_errors() - raise ValueError("Error computing shared key.", errors) - - return backend._ffi.buffer(buf, keylen[0])[:] - - -def _calculate_digest_and_algorithm( - data: bytes, - algorithm: typing.Union[Prehashed, hashes.HashAlgorithm], -) -> typing.Tuple[bytes, hashes.HashAlgorithm]: - if not isinstance(algorithm, Prehashed): - hash_ctx = hashes.Hash(algorithm) - hash_ctx.update(data) - data = hash_ctx.finalize() - else: - algorithm = algorithm._algorithm - - if len(data) != algorithm.digest_size: - raise ValueError( - "The provided data must be the same length as the hash " - "algorithm's digest size." - ) - - return (data, algorithm) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so index 99842072..b2e81cdc 100644 Binary files a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so and b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi index 94a37a20..18a6fb87 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi @@ -2,7 +2,6 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import types import typing def check_pkcs7_padding(data: bytes) -> bool: ... @@ -16,19 +15,3 @@ class ObjectIdentifier: def _name(self) -> str: ... T = typing.TypeVar("T") - -class FixedPool(typing.Generic[T]): - def __init__( - self, - create: typing.Callable[[], T], - ) -> None: ... - def acquire(self) -> PoolAcquisition[T]: ... - -class PoolAcquisition(typing.Generic[T]): - def __enter__(self) -> T: ... - def __exit__( - self, - exc_type: typing.Optional[typing.Type[BaseException]], - exc_value: typing.Optional[BaseException], - exc_tb: typing.Optional[types.TracebackType], - ) -> None: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi index a8369ba8..35652c6a 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi @@ -2,15 +2,13 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import typing - class TestCertificate: not_after_tag: int not_before_tag: int - issuer_value_tags: typing.List[int] - subject_value_tags: typing.List[int] + issuer_value_tags: list[int] + subject_value_tags: list[int] -def decode_dss_signature(signature: bytes) -> typing.Tuple[int, int]: ... +def decode_dss_signature(signature: bytes) -> tuple[int, int]: ... def encode_dss_signature(r: int, s: int) -> bytes: ... def parse_spki_for_data(data: bytes) -> bytes: ... def test_parse_certificate(data: bytes) -> TestCertificate: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi index 4671eb9b..b15628f8 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi @@ -2,8 +2,6 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import typing - from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes from cryptography.x509.ocsp import ( @@ -19,7 +17,7 @@ def load_der_ocsp_response(data: bytes) -> OCSPResponse: ... def create_ocsp_request(builder: OCSPRequestBuilder) -> OCSPRequest: ... def create_ocsp_response( status: OCSPResponseStatus, - builder: typing.Optional[OCSPResponseBuilder], - private_key: typing.Optional[PrivateKeyTypes], - hash_algorithm: typing.Optional[hashes.HashAlgorithm], + builder: OCSPResponseBuilder | None, + private_key: PrivateKeyTypes | None, + hash_algorithm: hashes.HashAlgorithm | None, ) -> OCSPResponse: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi index 82f30d20..cc546477 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -5,14 +5,19 @@ import typing from cryptography.hazmat.bindings._rust.openssl import ( + aead, + cmac, dh, dsa, + ec, ed448, ed25519, hashes, hmac, kdf, + keys, poly1305, + rsa, x448, x25519, ) @@ -20,21 +25,28 @@ from cryptography.hazmat.bindings._rust.openssl import ( __all__ = [ "openssl_version", "raise_openssl_error", + "aead", + "cmac", "dh", "dsa", + "ec", "hashes", "hmac", "kdf", + "keys", "ed448", "ed25519", + "rsa", "poly1305", "x448", "x25519", ] +_legacy_provider_loaded: bool + def openssl_version() -> int: ... def raise_openssl_error() -> typing.NoReturn: ... -def capture_error_stack() -> typing.List[OpenSSLError]: ... +def capture_error_stack() -> list[OpenSSLError]: ... def is_fips_enabled() -> bool: ... class OpenSSLError: diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi new file mode 100644 index 00000000..81e801e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi @@ -0,0 +1,69 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +class ChaCha20Poly1305: + def __init__(self, key: bytes) -> None: ... + @staticmethod + def generate_key() -> bytes: ... + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: bytes | None, + ) -> bytes: ... + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: bytes | None, + ) -> bytes: ... + +class AESSIV: + def __init__(self, key: bytes) -> None: ... + @staticmethod + def generate_key(key_size: int) -> bytes: ... + def encrypt( + self, + data: bytes, + associated_data: list[bytes] | None, + ) -> bytes: ... + def decrypt( + self, + data: bytes, + associated_data: list[bytes] | None, + ) -> bytes: ... + +class AESOCB3: + def __init__(self, key: bytes) -> None: ... + @staticmethod + def generate_key(key_size: int) -> bytes: ... + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: bytes | None, + ) -> bytes: ... + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: bytes | None, + ) -> bytes: ... + +class AESGCMSIV: + def __init__(self, key: bytes) -> None: ... + @staticmethod + def generate_key(key_size: int) -> bytes: ... + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: bytes | None, + ) -> bytes: ... + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: bytes | None, + ) -> bytes: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi new file mode 100644 index 00000000..9c03508b --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi @@ -0,0 +1,18 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives import ciphers + +class CMAC: + def __init__( + self, + algorithm: ciphers.BlockCipherAlgorithm, + backend: typing.Any = None, + ) -> None: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def verify(self, signature: bytes) -> None: ... + def copy(self) -> CMAC: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi index bfd005d9..08733d74 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi @@ -2,6 +2,8 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import typing + from cryptography.hazmat.primitives.asymmetric import dh MIN_MODULUS_SIZE: int @@ -10,13 +12,40 @@ class DHPrivateKey: ... class DHPublicKey: ... class DHParameters: ... -def generate_parameters(generator: int, key_size: int) -> dh.DHParameters: ... -def private_key_from_ptr(ptr: int) -> dh.DHPrivateKey: ... -def public_key_from_ptr(ptr: int) -> dh.DHPublicKey: ... -def from_pem_parameters(data: bytes) -> dh.DHParameters: ... -def from_der_parameters(data: bytes) -> dh.DHParameters: ... -def from_private_numbers(numbers: dh.DHPrivateNumbers) -> dh.DHPrivateKey: ... -def from_public_numbers(numbers: dh.DHPublicNumbers) -> dh.DHPublicKey: ... -def from_parameter_numbers( - numbers: dh.DHParameterNumbers, +class DHPrivateNumbers: + def __init__(self, x: int, public_numbers: DHPublicNumbers) -> None: ... + def private_key(self, backend: typing.Any = None) -> dh.DHPrivateKey: ... + @property + def x(self) -> int: ... + @property + def public_numbers(self) -> DHPublicNumbers: ... + +class DHPublicNumbers: + def __init__( + self, y: int, parameter_numbers: DHParameterNumbers + ) -> None: ... + def public_key(self, backend: typing.Any = None) -> dh.DHPublicKey: ... + @property + def y(self) -> int: ... + @property + def parameter_numbers(self) -> DHParameterNumbers: ... + +class DHParameterNumbers: + def __init__(self, p: int, g: int, q: int | None = None) -> None: ... + def parameters(self, backend: typing.Any = None) -> dh.DHParameters: ... + @property + def p(self) -> int: ... + @property + def g(self) -> int: ... + @property + def q(self) -> int | None: ... + +def generate_parameters( + generator: int, key_size: int, backend: typing.Any = None +) -> dh.DHParameters: ... +def from_pem_parameters( + data: bytes, backend: typing.Any = None +) -> dh.DHParameters: ... +def from_der_parameters( + data: bytes, backend: typing.Any = None ) -> dh.DHParameters: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi index 5a56f256..0922a4c4 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi @@ -2,19 +2,40 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import typing + from cryptography.hazmat.primitives.asymmetric import dsa class DSAPrivateKey: ... class DSAPublicKey: ... class DSAParameters: ... +class DSAPrivateNumbers: + def __init__(self, x: int, public_numbers: DSAPublicNumbers) -> None: ... + @property + def x(self) -> int: ... + @property + def public_numbers(self) -> DSAPublicNumbers: ... + def private_key(self, backend: typing.Any = None) -> dsa.DSAPrivateKey: ... + +class DSAPublicNumbers: + def __init__( + self, y: int, parameter_numbers: DSAParameterNumbers + ) -> None: ... + @property + def y(self) -> int: ... + @property + def parameter_numbers(self) -> DSAParameterNumbers: ... + def public_key(self, backend: typing.Any = None) -> dsa.DSAPublicKey: ... + +class DSAParameterNumbers: + def __init__(self, p: int, q: int, g: int) -> None: ... + @property + def p(self) -> int: ... + @property + def q(self) -> int: ... + @property + def g(self) -> int: ... + def parameters(self, backend: typing.Any = None) -> dsa.DSAParameters: ... + def generate_parameters(key_size: int) -> dsa.DSAParameters: ... -def private_key_from_ptr(ptr: int) -> dsa.DSAPrivateKey: ... -def public_key_from_ptr(ptr: int) -> dsa.DSAPublicKey: ... -def from_private_numbers( - numbers: dsa.DSAPrivateNumbers, -) -> dsa.DSAPrivateKey: ... -def from_public_numbers(numbers: dsa.DSAPublicNumbers) -> dsa.DSAPublicKey: ... -def from_parameter_numbers( - numbers: dsa.DSAParameterNumbers, -) -> dsa.DSAParameters: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi new file mode 100644 index 00000000..5c3b7bf6 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi @@ -0,0 +1,52 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives.asymmetric import ec + +class ECPrivateKey: ... +class ECPublicKey: ... + +class EllipticCurvePrivateNumbers: + def __init__( + self, private_value: int, public_numbers: EllipticCurvePublicNumbers + ) -> None: ... + def private_key( + self, backend: typing.Any = None + ) -> ec.EllipticCurvePrivateKey: ... + @property + def private_value(self) -> int: ... + @property + def public_numbers(self) -> EllipticCurvePublicNumbers: ... + +class EllipticCurvePublicNumbers: + def __init__(self, x: int, y: int, curve: ec.EllipticCurve) -> None: ... + def public_key( + self, backend: typing.Any = None + ) -> ec.EllipticCurvePublicKey: ... + @property + def x(self) -> int: ... + @property + def y(self) -> int: ... + @property + def curve(self) -> ec.EllipticCurve: ... + def __eq__(self, other: object) -> bool: ... + +def curve_supported(curve: ec.EllipticCurve) -> bool: ... +def generate_private_key( + curve: ec.EllipticCurve, backend: typing.Any = None +) -> ec.EllipticCurvePrivateKey: ... +def from_private_numbers( + numbers: ec.EllipticCurvePrivateNumbers, +) -> ec.EllipticCurvePrivateKey: ... +def from_public_numbers( + numbers: ec.EllipticCurvePublicNumbers, +) -> ec.EllipticCurvePublicKey: ... +def from_public_bytes( + curve: ec.EllipticCurve, data: bytes +) -> ec.EllipticCurvePublicKey: ... +def derive_private_key( + private_value: int, curve: ec.EllipticCurve +) -> ec.EllipticCurvePrivateKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi index c7f127f0..5233f9a1 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi @@ -8,7 +8,5 @@ class Ed25519PrivateKey: ... class Ed25519PublicKey: ... def generate_key() -> ed25519.Ed25519PrivateKey: ... -def private_key_from_ptr(ptr: int) -> ed25519.Ed25519PrivateKey: ... -def public_key_from_ptr(ptr: int) -> ed25519.Ed25519PublicKey: ... def from_private_bytes(data: bytes) -> ed25519.Ed25519PrivateKey: ... def from_public_bytes(data: bytes) -> ed25519.Ed25519PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi index 1cf5f177..7a065203 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi @@ -8,7 +8,5 @@ class Ed448PrivateKey: ... class Ed448PublicKey: ... def generate_key() -> ed448.Ed448PrivateKey: ... -def private_key_from_ptr(ptr: int) -> ed448.Ed448PrivateKey: ... -def public_key_from_ptr(ptr: int) -> ed448.Ed448PublicKey: ... def from_private_bytes(data: bytes) -> ed448.Ed448PrivateKey: ... def from_public_bytes(data: bytes) -> ed448.Ed448PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi new file mode 100644 index 00000000..e312d51d --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi @@ -0,0 +1,37 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives.asymmetric.types import ( + PrivateKeyTypes, + PublicKeyTypes, +) + +def private_key_from_ptr( + ptr: int, + unsafe_skip_rsa_key_validation: bool, +) -> PrivateKeyTypes: ... +def load_der_private_key( + data: bytes, + password: bytes | None, + backend: typing.Any = None, + *, + unsafe_skip_rsa_key_validation: bool = False, +) -> PrivateKeyTypes: ... +def load_pem_private_key( + data: bytes, + password: bytes | None, + backend: typing.Any = None, + *, + unsafe_skip_rsa_key_validation: bool = False, +) -> PrivateKeyTypes: ... +def load_der_public_key( + data: bytes, + backend: typing.Any = None, +) -> PublicKeyTypes: ... +def load_pem_public_key( + data: bytes, + backend: typing.Any = None, +) -> PublicKeyTypes: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi new file mode 100644 index 00000000..ef7752dd --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi @@ -0,0 +1,55 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives.asymmetric import rsa + +class RSAPrivateKey: ... +class RSAPublicKey: ... + +class RSAPrivateNumbers: + def __init__( + self, + p: int, + q: int, + d: int, + dmp1: int, + dmq1: int, + iqmp: int, + public_numbers: RSAPublicNumbers, + ) -> None: ... + @property + def p(self) -> int: ... + @property + def q(self) -> int: ... + @property + def d(self) -> int: ... + @property + def dmp1(self) -> int: ... + @property + def dmq1(self) -> int: ... + @property + def iqmp(self) -> int: ... + @property + def public_numbers(self) -> RSAPublicNumbers: ... + def private_key( + self, + backend: typing.Any = None, + *, + unsafe_skip_rsa_key_validation: bool = False, + ) -> rsa.RSAPrivateKey: ... + +class RSAPublicNumbers: + def __init__(self, e: int, n: int) -> None: ... + @property + def n(self) -> int: ... + @property + def e(self) -> int: ... + def public_key(self, backend: typing.Any = None) -> rsa.RSAPublicKey: ... + +def generate_private_key( + public_exponent: int, + key_size: int, +) -> rsa.RSAPrivateKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi index 90f7cbdd..da0f3ec5 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi @@ -8,7 +8,5 @@ class X25519PrivateKey: ... class X25519PublicKey: ... def generate_key() -> x25519.X25519PrivateKey: ... -def private_key_from_ptr(ptr: int) -> x25519.X25519PrivateKey: ... -def public_key_from_ptr(ptr: int) -> x25519.X25519PublicKey: ... def from_private_bytes(data: bytes) -> x25519.X25519PrivateKey: ... def from_public_bytes(data: bytes) -> x25519.X25519PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi index d326c8d2..e51cfebe 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi @@ -8,7 +8,5 @@ class X448PrivateKey: ... class X448PublicKey: ... def generate_key() -> x448.X448PrivateKey: ... -def private_key_from_ptr(ptr: int) -> x448.X448PrivateKey: ... -def public_key_from_ptr(ptr: int) -> x448.X448PublicKey: ... def from_private_bytes(data: bytes) -> x448.X448PrivateKey: ... def from_public_bytes(data: bytes) -> x448.X448PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi index 66bd8509..a8497824 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi @@ -5,7 +5,7 @@ from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.serialization import pkcs7 def serialize_certificates( - certs: typing.List[x509.Certificate], + certs: list[x509.Certificate], encoding: serialization.Encoding, ) -> bytes: ... def sign_and_serialize( @@ -13,3 +13,9 @@ def sign_and_serialize( encoding: serialization.Encoding, options: typing.Iterable[pkcs7.PKCS7Options], ) -> bytes: ... +def load_pem_pkcs7_certificates( + data: bytes, +) -> list[x509.Certificate]: ... +def load_der_pkcs7_certificates( + data: bytes, +) -> list[x509.Certificate]: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi index 24b2f5e3..418184f8 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi @@ -2,6 +2,7 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +import datetime import typing from cryptography import x509 @@ -9,32 +10,46 @@ from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric.padding import PSS, PKCS1v15 from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes -def load_pem_x509_certificate(data: bytes) -> x509.Certificate: ... +def load_pem_x509_certificate( + data: bytes, backend: typing.Any = None +) -> x509.Certificate: ... +def load_der_x509_certificate( + data: bytes, backend: typing.Any = None +) -> x509.Certificate: ... def load_pem_x509_certificates( data: bytes, -) -> typing.List[x509.Certificate]: ... -def load_der_x509_certificate(data: bytes) -> x509.Certificate: ... -def load_pem_x509_crl(data: bytes) -> x509.CertificateRevocationList: ... -def load_der_x509_crl(data: bytes) -> x509.CertificateRevocationList: ... -def load_pem_x509_csr(data: bytes) -> x509.CertificateSigningRequest: ... -def load_der_x509_csr(data: bytes) -> x509.CertificateSigningRequest: ... +) -> list[x509.Certificate]: ... +def load_pem_x509_crl( + data: bytes, backend: typing.Any = None +) -> x509.CertificateRevocationList: ... +def load_der_x509_crl( + data: bytes, backend: typing.Any = None +) -> x509.CertificateRevocationList: ... +def load_pem_x509_csr( + data: bytes, backend: typing.Any = None +) -> x509.CertificateSigningRequest: ... +def load_der_x509_csr( + data: bytes, backend: typing.Any = None +) -> x509.CertificateSigningRequest: ... def encode_name_bytes(name: x509.Name) -> bytes: ... def encode_extension_value(extension: x509.ExtensionType) -> bytes: ... def create_x509_certificate( builder: x509.CertificateBuilder, private_key: PrivateKeyTypes, - hash_algorithm: typing.Optional[hashes.HashAlgorithm], - padding: typing.Optional[typing.Union[PKCS1v15, PSS]], + hash_algorithm: hashes.HashAlgorithm | None, + rsa_padding: PKCS1v15 | PSS | None, ) -> x509.Certificate: ... def create_x509_csr( builder: x509.CertificateSigningRequestBuilder, private_key: PrivateKeyTypes, - hash_algorithm: typing.Optional[hashes.HashAlgorithm], + hash_algorithm: hashes.HashAlgorithm | None, + rsa_padding: PKCS1v15 | PSS | None, ) -> x509.CertificateSigningRequest: ... def create_x509_crl( builder: x509.CertificateRevocationListBuilder, private_key: PrivateKeyTypes, - hash_algorithm: typing.Optional[hashes.HashAlgorithm], + hash_algorithm: hashes.HashAlgorithm | None, + rsa_padding: PKCS1v15 | PSS | None, ) -> x509.CertificateRevocationList: ... class Sct: ... @@ -42,3 +57,32 @@ class Certificate: ... class RevokedCertificate: ... class CertificateRevocationList: ... class CertificateSigningRequest: ... + +class PolicyBuilder: + def time(self, new_time: datetime.datetime) -> PolicyBuilder: ... + def store(self, new_store: Store) -> PolicyBuilder: ... + def max_chain_depth(self, new_max_chain_depth: int) -> PolicyBuilder: ... + def build_server_verifier( + self, subject: x509.verification.Subject + ) -> ServerVerifier: ... + +class ServerVerifier: + @property + def subject(self) -> x509.verification.Subject: ... + @property + def validation_time(self) -> datetime.datetime: ... + @property + def store(self) -> Store: ... + @property + def max_chain_depth(self) -> int: ... + def verify( + self, + leaf: x509.Certificate, + intermediates: list[x509.Certificate], + ) -> list[x509.Certificate]: ... + +class Store: + def __init__(self, certs: list[x509.Certificate]) -> None: ... + +class VerificationError(Exception): + pass diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py index 5e8ecd04..fc13348a 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py @@ -4,17 +4,15 @@ from __future__ import annotations -import typing - -def cryptography_has_set_cert_cb() -> typing.List[str]: +def cryptography_has_set_cert_cb() -> list[str]: return [ "SSL_CTX_set_cert_cb", "SSL_set_cert_cb", ] -def cryptography_has_ssl_st() -> typing.List[str]: +def cryptography_has_ssl_st() -> list[str]: return [ "SSL_ST_BEFORE", "SSL_ST_OK", @@ -23,72 +21,26 @@ def cryptography_has_ssl_st() -> typing.List[str]: ] -def cryptography_has_tls_st() -> typing.List[str]: +def cryptography_has_tls_st() -> list[str]: return [ "TLS_ST_BEFORE", "TLS_ST_OK", ] -def cryptography_has_evp_pkey_dhx() -> typing.List[str]: - return [ - "EVP_PKEY_DHX", - ] - - -def cryptography_has_mem_functions() -> typing.List[str]: - return [ - "Cryptography_CRYPTO_set_mem_functions", - ] - - -def cryptography_has_x509_store_ctx_get_issuer() -> typing.List[str]: - return [ - "X509_STORE_set_get_issuer", - ] - - -def cryptography_has_ed448() -> typing.List[str]: +def cryptography_has_ed448() -> list[str]: return [ "EVP_PKEY_ED448", - "NID_ED448", - ] - - -def cryptography_has_ed25519() -> typing.List[str]: - return [ - "NID_ED25519", - "EVP_PKEY_ED25519", - ] - - -def cryptography_has_poly1305() -> typing.List[str]: - return [ - "NID_poly1305", - "EVP_PKEY_POLY1305", - ] - - -def cryptography_has_evp_digestfinal_xof() -> typing.List[str]: - return [ - "EVP_DigestFinalXOF", - ] - - -def cryptography_has_fips() -> typing.List[str]: - return [ - "FIPS_mode_set", - "FIPS_mode", ] -def cryptography_has_ssl_sigalgs() -> typing.List[str]: +def cryptography_has_ssl_sigalgs() -> list[str]: return [ "SSL_CTX_set1_sigalgs_list", ] -def cryptography_has_psk() -> typing.List[str]: +def cryptography_has_psk() -> list[str]: return [ "SSL_CTX_use_psk_identity_hint", "SSL_CTX_set_psk_server_callback", @@ -96,7 +48,7 @@ def cryptography_has_psk() -> typing.List[str]: ] -def cryptography_has_psk_tlsv13() -> typing.List[str]: +def cryptography_has_psk_tlsv13() -> list[str]: return [ "SSL_CTX_set_psk_find_session_callback", "SSL_CTX_set_psk_use_session_callback", @@ -108,7 +60,7 @@ def cryptography_has_psk_tlsv13() -> typing.List[str]: ] -def cryptography_has_custom_ext() -> typing.List[str]: +def cryptography_has_custom_ext() -> list[str]: return [ "SSL_CTX_add_client_custom_ext", "SSL_CTX_add_server_custom_ext", @@ -116,7 +68,7 @@ def cryptography_has_custom_ext() -> typing.List[str]: ] -def cryptography_has_tlsv13_functions() -> typing.List[str]: +def cryptography_has_tlsv13_functions() -> list[str]: return [ "SSL_VERIFY_POST_HANDSHAKE", "SSL_CTX_set_ciphersuites", @@ -130,16 +82,7 @@ def cryptography_has_tlsv13_functions() -> typing.List[str]: ] -def cryptography_has_raw_key() -> typing.List[str]: - return [ - "EVP_PKEY_new_raw_private_key", - "EVP_PKEY_new_raw_public_key", - "EVP_PKEY_get_raw_private_key", - "EVP_PKEY_get_raw_public_key", - ] - - -def cryptography_has_engine() -> typing.List[str]: +def cryptography_has_engine() -> list[str]: return [ "ENGINE_by_id", "ENGINE_init", @@ -158,13 +101,13 @@ def cryptography_has_engine() -> typing.List[str]: ] -def cryptography_has_verified_chain() -> typing.List[str]: +def cryptography_has_verified_chain() -> list[str]: return [ "SSL_get0_verified_chain", ] -def cryptography_has_srtp() -> typing.List[str]: +def cryptography_has_srtp() -> list[str]: return [ "SSL_CTX_set_tlsext_use_srtp", "SSL_set_tlsext_use_srtp", @@ -172,7 +115,7 @@ def cryptography_has_srtp() -> typing.List[str]: ] -def cryptography_has_providers() -> typing.List[str]: +def cryptography_has_providers() -> list[str]: return [ "OSSL_PROVIDER_load", "OSSL_PROVIDER_unload", @@ -182,26 +125,25 @@ def cryptography_has_providers() -> typing.List[str]: ] -def cryptography_has_op_no_renegotiation() -> typing.List[str]: +def cryptography_has_op_no_renegotiation() -> list[str]: return [ "SSL_OP_NO_RENEGOTIATION", ] -def cryptography_has_dtls_get_data_mtu() -> typing.List[str]: +def cryptography_has_dtls_get_data_mtu() -> list[str]: return [ "DTLS_get_data_mtu", ] -def cryptography_has_300_fips() -> typing.List[str]: +def cryptography_has_300_fips() -> list[str]: return [ - "EVP_default_properties_is_fips_enabled", "EVP_default_properties_enable_fips", ] -def cryptography_has_ssl_cookie() -> typing.List[str]: +def cryptography_has_ssl_cookie() -> list[str]: return [ "SSL_OP_COOKIE_EXCHANGE", "DTLSv1_listen", @@ -210,69 +152,41 @@ def cryptography_has_ssl_cookie() -> typing.List[str]: ] -def cryptography_has_pkcs7_funcs() -> typing.List[str]: +def cryptography_has_pkcs7_funcs() -> list[str]: return [ - "SMIME_write_PKCS7", - "PEM_write_bio_PKCS7_stream", - "PKCS7_sign_add_signer", - "PKCS7_final", "PKCS7_verify", "SMIME_read_PKCS7", - "PKCS7_get0_signers", ] -def cryptography_has_bn_flags() -> typing.List[str]: +def cryptography_has_prime_checks() -> list[str]: return [ - "BN_FLG_CONSTTIME", - "BN_set_flags", "BN_prime_checks_for_size", ] -def cryptography_has_evp_pkey_dh() -> typing.List[str]: - return [ - "EVP_PKEY_set1_DH", - ] - - -def cryptography_has_300_evp_cipher() -> typing.List[str]: +def cryptography_has_300_evp_cipher() -> list[str]: return ["EVP_CIPHER_fetch", "EVP_CIPHER_free"] -def cryptography_has_unexpected_eof_while_reading() -> typing.List[str]: +def cryptography_has_unexpected_eof_while_reading() -> list[str]: return ["SSL_R_UNEXPECTED_EOF_WHILE_READING"] -def cryptography_has_pkcs12_set_mac() -> typing.List[str]: +def cryptography_has_pkcs12_set_mac() -> list[str]: return ["PKCS12_set_mac"] -def cryptography_has_ssl_op_ignore_unexpected_eof() -> typing.List[str]: +def cryptography_has_ssl_op_ignore_unexpected_eof() -> list[str]: return [ "SSL_OP_IGNORE_UNEXPECTED_EOF", ] -def cryptography_has_get_extms_support() -> typing.List[str]: +def cryptography_has_get_extms_support() -> list[str]: return ["SSL_get_extms_support"] -def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: - return ["EVP_PKEY_derive_set_peer_ex"] - - -def cryptography_has_evp_aead() -> typing.List[str]: - return [ - "EVP_aead_chacha20_poly1305", - "EVP_AEAD_CTX_free", - "EVP_AEAD_CTX_seal", - "EVP_AEAD_CTX_open", - "EVP_AEAD_max_overhead", - "Cryptography_EVP_AEAD_CTX_new", - ] - - # This is a mapping of # {condition: function-returning-names-dependent-on-that-condition} so we can # loop over them and delete unsupported names at runtime. It will be removed @@ -282,24 +196,12 @@ def cryptography_has_evp_aead() -> typing.List[str]: "Cryptography_HAS_SET_CERT_CB": cryptography_has_set_cert_cb, "Cryptography_HAS_SSL_ST": cryptography_has_ssl_st, "Cryptography_HAS_TLS_ST": cryptography_has_tls_st, - "Cryptography_HAS_EVP_PKEY_DHX": cryptography_has_evp_pkey_dhx, - "Cryptography_HAS_MEM_FUNCTIONS": cryptography_has_mem_functions, - "Cryptography_HAS_X509_STORE_CTX_GET_ISSUER": ( - cryptography_has_x509_store_ctx_get_issuer - ), "Cryptography_HAS_ED448": cryptography_has_ed448, - "Cryptography_HAS_ED25519": cryptography_has_ed25519, - "Cryptography_HAS_POLY1305": cryptography_has_poly1305, - "Cryptography_HAS_FIPS": cryptography_has_fips, "Cryptography_HAS_SIGALGS": cryptography_has_ssl_sigalgs, "Cryptography_HAS_PSK": cryptography_has_psk, "Cryptography_HAS_PSK_TLSv1_3": cryptography_has_psk_tlsv13, "Cryptography_HAS_CUSTOM_EXT": cryptography_has_custom_ext, "Cryptography_HAS_TLSv1_3_FUNCTIONS": cryptography_has_tlsv13_functions, - "Cryptography_HAS_RAW_KEY": cryptography_has_raw_key, - "Cryptography_HAS_EVP_DIGESTFINAL_XOF": ( - cryptography_has_evp_digestfinal_xof - ), "Cryptography_HAS_ENGINE": cryptography_has_engine, "Cryptography_HAS_VERIFIED_CHAIN": cryptography_has_verified_chain, "Cryptography_HAS_SRTP": cryptography_has_srtp, @@ -311,8 +213,7 @@ def cryptography_has_evp_aead() -> typing.List[str]: "Cryptography_HAS_300_FIPS": cryptography_has_300_fips, "Cryptography_HAS_SSL_COOKIE": cryptography_has_ssl_cookie, "Cryptography_HAS_PKCS7_FUNCS": cryptography_has_pkcs7_funcs, - "Cryptography_HAS_BN_FLAGS": cryptography_has_bn_flags, - "Cryptography_HAS_EVP_PKEY_DH": cryptography_has_evp_pkey_dh, + "Cryptography_HAS_PRIME_CHECKS": cryptography_has_prime_checks, "Cryptography_HAS_300_EVP_CIPHER": cryptography_has_300_evp_cipher, "Cryptography_HAS_UNEXPECTED_EOF_WHILE_READING": ( cryptography_has_unexpected_eof_while_reading @@ -322,8 +223,4 @@ def cryptography_has_evp_aead() -> typing.List[str]: cryptography_has_ssl_op_ignore_unexpected_eof ), "Cryptography_HAS_GET_EXTMS_SUPPORT": cryptography_has_get_extms_support, - "Cryptography_HAS_EVP_PKEY_SET_PEER_EX": ( - cryptography_has_evp_pkey_set_peer_ex - ), - "Cryptography_HAS_EVP_AEAD": (cryptography_has_evp_aead), } diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py index b50d6315..209fbeb7 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py @@ -18,9 +18,8 @@ def _openssl_assert( - lib, ok: bool, - errors: typing.Optional[typing.List[openssl.OpenSSLError]] = None, + errors: list[openssl.OpenSSLError] | None = None, ) -> None: if not ok: if errors is None: @@ -33,25 +32,14 @@ def _openssl_assert( "OpenSSL try disabling it before reporting a bug. Otherwise " "please file an issue at https://github.com/pyca/cryptography/" "issues with information on how to reproduce " - "this. ({!r})".format(errors), + f"this. ({errors!r})", errors, ) -def _legacy_provider_error(loaded: bool) -> None: - if not loaded: - raise RuntimeError( - "OpenSSL 3.0's legacy provider failed to load. This is a fatal " - "error by default, but cryptography supports running without " - "legacy algorithms by setting the environment variable " - "CRYPTOGRAPHY_OPENSSL_NO_LEGACY. If you did not expect this error," - " you have likely made a mistake with your OpenSSL configuration." - ) - - def build_conditional_library( lib: typing.Any, - conditional_names: typing.Dict[str, typing.Callable[[], typing.List[str]]], + conditional_names: dict[str, typing.Callable[[], list[str]]], ) -> typing.Any: conditional_lib = types.ModuleType("lib") conditional_lib._original_lib = lib # type: ignore[attr-defined] @@ -77,7 +65,6 @@ class Binding: _lib_loaded = False _init_lock = threading.Lock() _legacy_provider: typing.Any = ffi.NULL - _legacy_provider_loaded = False _default_provider: typing.Any = ffi.NULL def __init__(self) -> None: @@ -86,18 +73,18 @@ def __init__(self) -> None: def _enable_fips(self) -> None: # This function enables FIPS mode for OpenSSL 3.0.0 on installs that # have the FIPS provider installed properly. - _openssl_assert(self.lib, self.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER) + _openssl_assert(self.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER) self._base_provider = self.lib.OSSL_PROVIDER_load( self.ffi.NULL, b"base" ) - _openssl_assert(self.lib, self._base_provider != self.ffi.NULL) + _openssl_assert(self._base_provider != self.ffi.NULL) self.lib._fips_provider = self.lib.OSSL_PROVIDER_load( self.ffi.NULL, b"fips" ) - _openssl_assert(self.lib, self.lib._fips_provider != self.ffi.NULL) + _openssl_assert(self.lib._fips_provider != self.ffi.NULL) res = self.lib.EVP_default_properties_enable_fips(self.ffi.NULL, 1) - _openssl_assert(self.lib, res == 1) + _openssl_assert(res == 1) @classmethod def _ensure_ffi_initialized(cls) -> None: @@ -107,27 +94,6 @@ def _ensure_ffi_initialized(cls) -> None: _openssl.lib, CONDITIONAL_NAMES ) cls._lib_loaded = True - # As of OpenSSL 3.0.0 we must register a legacy cipher provider - # to get RC2 (needed for junk asymmetric private key - # serialization), RC4, Blowfish, IDEA, SEED, etc. These things - # are ugly legacy, but we aren't going to get rid of them - # any time soon. - if cls.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: - if not os.environ.get("CRYPTOGRAPHY_OPENSSL_NO_LEGACY"): - cls._legacy_provider = cls.lib.OSSL_PROVIDER_load( - cls.ffi.NULL, b"legacy" - ) - cls._legacy_provider_loaded = ( - cls._legacy_provider != cls.ffi.NULL - ) - _legacy_provider_error(cls._legacy_provider_loaded) - - cls._default_provider = cls.lib.OSSL_PROVIDER_load( - cls.ffi.NULL, b"default" - ) - _openssl_assert( - cls.lib, cls._default_provider != cls.ffi.NULL - ) @classmethod def init_static_locks(cls) -> None: @@ -157,7 +123,6 @@ def _verify_package_version(version: str) -> None: ) _openssl_assert( - _openssl.lib, _openssl.lib.OpenSSL_version_num() == openssl.openssl_version(), ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py index 3b880b64..9d7f5bc7 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py @@ -5,7 +5,6 @@ from __future__ import annotations import abc -import typing # This exists to break an import cycle. It is normally accessible from the # ciphers module. @@ -21,7 +20,7 @@ def name(self) -> str: @property @abc.abstractmethod - def key_sizes(self) -> typing.FrozenSet[int]: + def key_sizes(self) -> frozenset[int]: """ Valid key sizes for this algorithm in bits """ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py index 34f3fbc8..46157721 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py @@ -5,7 +5,6 @@ from __future__ import annotations import abc -import typing from cryptography import utils from cryptography.hazmat.primitives.hashes import HashAlgorithm @@ -78,9 +77,9 @@ def __init__( self, format: PrivateFormat, *, - _kdf_rounds: typing.Optional[int] = None, - _hmac_hash: typing.Optional[HashAlgorithm] = None, - _key_cert_algorithm: typing.Optional[PBES] = None, + _kdf_rounds: int | None = None, + _hmac_hash: HashAlgorithm | None = None, + _key_cert_algorithm: PBES | None = None, ) -> None: self._format = format @@ -158,9 +157,9 @@ def __init__( format: PrivateFormat, password: bytes, *, - kdf_rounds: typing.Optional[int], - hmac_hash: typing.Optional[HashAlgorithm], - key_cert_algorithm: typing.Optional[PBES], + kdf_rounds: int | None, + hmac_hash: HashAlgorithm | None, + key_cert_algorithm: PBES | None, ): self._format = format self.password = password diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py index 751bcc40..31c9748a 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py @@ -5,142 +5,16 @@ from __future__ import annotations import abc -import typing from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization +generate_parameters = rust_openssl.dh.generate_parameters -def generate_parameters( - generator: int, key_size: int, backend: typing.Any = None -) -> DHParameters: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - return ossl.generate_dh_parameters(generator, key_size) - - -class DHParameterNumbers: - def __init__(self, p: int, g: int, q: typing.Optional[int] = None) -> None: - if not isinstance(p, int) or not isinstance(g, int): - raise TypeError("p and g must be integers") - if q is not None and not isinstance(q, int): - raise TypeError("q must be integer or None") - - if g < 2: - raise ValueError("DH generator must be 2 or greater") - - if p.bit_length() < rust_openssl.dh.MIN_MODULUS_SIZE: - raise ValueError( - f"p (modulus) must be at least " - f"{rust_openssl.dh.MIN_MODULUS_SIZE}-bit" - ) - - self._p = p - self._g = g - self._q = q - - def __eq__(self, other: object) -> bool: - if not isinstance(other, DHParameterNumbers): - return NotImplemented - - return ( - self._p == other._p and self._g == other._g and self._q == other._q - ) - - def parameters(self, backend: typing.Any = None) -> DHParameters: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_dh_parameter_numbers(self) - - @property - def p(self) -> int: - return self._p - - @property - def g(self) -> int: - return self._g - - @property - def q(self) -> typing.Optional[int]: - return self._q - - -class DHPublicNumbers: - def __init__(self, y: int, parameter_numbers: DHParameterNumbers) -> None: - if not isinstance(y, int): - raise TypeError("y must be an integer.") - - if not isinstance(parameter_numbers, DHParameterNumbers): - raise TypeError( - "parameters must be an instance of DHParameterNumbers." - ) - - self._y = y - self._parameter_numbers = parameter_numbers - - def __eq__(self, other: object) -> bool: - if not isinstance(other, DHPublicNumbers): - return NotImplemented - - return ( - self._y == other._y - and self._parameter_numbers == other._parameter_numbers - ) - - def public_key(self, backend: typing.Any = None) -> DHPublicKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_dh_public_numbers(self) - - @property - def y(self) -> int: - return self._y - - @property - def parameter_numbers(self) -> DHParameterNumbers: - return self._parameter_numbers - - -class DHPrivateNumbers: - def __init__(self, x: int, public_numbers: DHPublicNumbers) -> None: - if not isinstance(x, int): - raise TypeError("x must be an integer.") - - if not isinstance(public_numbers, DHPublicNumbers): - raise TypeError( - "public_numbers must be an instance of " "DHPublicNumbers." - ) - - self._x = x - self._public_numbers = public_numbers - - def __eq__(self, other: object) -> bool: - if not isinstance(other, DHPrivateNumbers): - return NotImplemented - - return ( - self._x == other._x - and self._public_numbers == other._public_numbers - ) - - def private_key(self, backend: typing.Any = None) -> DHPrivateKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_dh_private_numbers(self) - - @property - def public_numbers(self) -> DHPublicNumbers: - return self._public_numbers - - @property - def x(self) -> int: - return self._x +DHPrivateNumbers = rust_openssl.dh.DHPrivateNumbers +DHPublicNumbers = rust_openssl.dh.DHPublicNumbers +DHParameterNumbers = rust_openssl.dh.DHParameterNumbers class DHParameters(metaclass=abc.ABCMeta): diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py index a8c52de4..6dd34c0e 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -54,7 +54,7 @@ def parameters(self) -> DSAParameters: def sign( self, data: bytes, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + algorithm: asym_utils.Prehashed | hashes.HashAlgorithm, ) -> bytes: """ Signs the data @@ -117,7 +117,7 @@ def verify( self, signature: bytes, data: bytes, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + algorithm: asym_utils.Prehashed | hashes.HashAlgorithm, ) -> None: """ Verifies the signature of the data. @@ -133,167 +133,22 @@ def __eq__(self, other: object) -> bool: DSAPublicKeyWithSerialization = DSAPublicKey DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey) - -class DSAParameterNumbers: - def __init__(self, p: int, q: int, g: int): - if ( - not isinstance(p, int) - or not isinstance(q, int) - or not isinstance(g, int) - ): - raise TypeError( - "DSAParameterNumbers p, q, and g arguments must be integers." - ) - - self._p = p - self._q = q - self._g = g - - @property - def p(self) -> int: - return self._p - - @property - def q(self) -> int: - return self._q - - @property - def g(self) -> int: - return self._g - - def parameters(self, backend: typing.Any = None) -> DSAParameters: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_dsa_parameter_numbers(self) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, DSAParameterNumbers): - return NotImplemented - - return self.p == other.p and self.q == other.q and self.g == other.g - - def __repr__(self) -> str: - return ( - "".format(self=self) - ) - - -class DSAPublicNumbers: - def __init__(self, y: int, parameter_numbers: DSAParameterNumbers): - if not isinstance(y, int): - raise TypeError("DSAPublicNumbers y argument must be an integer.") - - if not isinstance(parameter_numbers, DSAParameterNumbers): - raise TypeError( - "parameter_numbers must be a DSAParameterNumbers instance." - ) - - self._y = y - self._parameter_numbers = parameter_numbers - - @property - def y(self) -> int: - return self._y - - @property - def parameter_numbers(self) -> DSAParameterNumbers: - return self._parameter_numbers - - def public_key(self, backend: typing.Any = None) -> DSAPublicKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_dsa_public_numbers(self) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, DSAPublicNumbers): - return NotImplemented - - return ( - self.y == other.y - and self.parameter_numbers == other.parameter_numbers - ) - - def __repr__(self) -> str: - return ( - "".format(self=self) - ) - - -class DSAPrivateNumbers: - def __init__(self, x: int, public_numbers: DSAPublicNumbers): - if not isinstance(x, int): - raise TypeError("DSAPrivateNumbers x argument must be an integer.") - - if not isinstance(public_numbers, DSAPublicNumbers): - raise TypeError( - "public_numbers must be a DSAPublicNumbers instance." - ) - self._public_numbers = public_numbers - self._x = x - - @property - def x(self) -> int: - return self._x - - @property - def public_numbers(self) -> DSAPublicNumbers: - return self._public_numbers - - def private_key(self, backend: typing.Any = None) -> DSAPrivateKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_dsa_private_numbers(self) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, DSAPrivateNumbers): - return NotImplemented - - return ( - self.x == other.x and self.public_numbers == other.public_numbers - ) +DSAPrivateNumbers = rust_openssl.dsa.DSAPrivateNumbers +DSAPublicNumbers = rust_openssl.dsa.DSAPublicNumbers +DSAParameterNumbers = rust_openssl.dsa.DSAParameterNumbers def generate_parameters( key_size: int, backend: typing.Any = None ) -> DSAParameters: - from cryptography.hazmat.backends.openssl.backend import backend as ossl + if key_size not in (1024, 2048, 3072, 4096): + raise ValueError("Key size must be 1024, 2048, 3072, or 4096 bits.") - return ossl.generate_dsa_parameters(key_size) + return rust_openssl.dsa.generate_parameters(key_size) def generate_private_key( key_size: int, backend: typing.Any = None ) -> DSAPrivateKey: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.generate_dsa_private_key_and_parameters(key_size) - - -def _check_dsa_parameters(parameters: DSAParameterNumbers) -> None: - if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]: - raise ValueError( - "p must be exactly 1024, 2048, 3072, or 4096 bits long" - ) - if parameters.q.bit_length() not in [160, 224, 256]: - raise ValueError("q must be exactly 160, 224, or 256 bits long") - - if not (1 < parameters.g < parameters.p): - raise ValueError("g, p don't satisfy 1 < g < p.") - - -def _check_dsa_private_numbers(numbers: DSAPrivateNumbers) -> None: - parameters = numbers.public_numbers.parameter_numbers - _check_dsa_parameters(parameters) - if numbers.x <= 0 or numbers.x >= parameters.q: - raise ValueError("x must be > 0 and < q.") - - if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p): - raise ValueError("y must be equal to (g ** x % p).") + parameters = generate_parameters(key_size) + return parameters.generate_private_key() diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py index ddfaabf4..b612b401 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py @@ -9,6 +9,7 @@ from cryptography import utils from cryptography.hazmat._oid import ObjectIdentifier +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization, hashes from cryptography.hazmat.primitives.asymmetric import utils as asym_utils @@ -56,7 +57,7 @@ class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta): @abc.abstractmethod def algorithm( self, - ) -> typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm]: + ) -> asym_utils.Prehashed | hashes.HashAlgorithm: """ The digest algorithm used with this signature. """ @@ -121,6 +122,7 @@ def private_bytes( EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey +EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey) class EllipticCurvePublicKey(metaclass=abc.ABCMeta): @@ -171,18 +173,13 @@ def from_encoded_point( ) -> EllipticCurvePublicKey: utils._check_bytes("data", data) - if not isinstance(curve, EllipticCurve): - raise TypeError("curve must be an EllipticCurve instance") - if len(data) == 0: raise ValueError("data must not be an empty byte string") if data[0] not in [0x02, 0x03, 0x04]: raise ValueError("Unsupported elliptic curve point type") - from cryptography.hazmat.backends.openssl.backend import backend - - return backend.load_elliptic_curve_public_bytes(curve, data) + return rust_openssl.ec.from_public_bytes(curve, data) @abc.abstractmethod def __eq__(self, other: object) -> bool: @@ -192,6 +189,10 @@ def __eq__(self, other: object) -> bool: EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey +EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey) + +EllipticCurvePrivateNumbers = rust_openssl.ec.EllipticCurvePrivateNumbers +EllipticCurvePublicNumbers = rust_openssl.ec.EllipticCurvePublicNumbers class SECT571R1(EllipticCurve): @@ -289,51 +290,46 @@ class BrainpoolP512R1(EllipticCurve): key_size = 512 -_CURVE_TYPES: typing.Dict[str, typing.Type[EllipticCurve]] = { - "prime192v1": SECP192R1, - "prime256v1": SECP256R1, - "secp192r1": SECP192R1, - "secp224r1": SECP224R1, - "secp256r1": SECP256R1, - "secp384r1": SECP384R1, - "secp521r1": SECP521R1, - "secp256k1": SECP256K1, - "sect163k1": SECT163K1, - "sect233k1": SECT233K1, - "sect283k1": SECT283K1, - "sect409k1": SECT409K1, - "sect571k1": SECT571K1, - "sect163r2": SECT163R2, - "sect233r1": SECT233R1, - "sect283r1": SECT283R1, - "sect409r1": SECT409R1, - "sect571r1": SECT571R1, - "brainpoolP256r1": BrainpoolP256R1, - "brainpoolP384r1": BrainpoolP384R1, - "brainpoolP512r1": BrainpoolP512R1, +_CURVE_TYPES: dict[str, EllipticCurve] = { + "prime192v1": SECP192R1(), + "prime256v1": SECP256R1(), + "secp192r1": SECP192R1(), + "secp224r1": SECP224R1(), + "secp256r1": SECP256R1(), + "secp384r1": SECP384R1(), + "secp521r1": SECP521R1(), + "secp256k1": SECP256K1(), + "sect163k1": SECT163K1(), + "sect233k1": SECT233K1(), + "sect283k1": SECT283K1(), + "sect409k1": SECT409K1(), + "sect571k1": SECT571K1(), + "sect163r2": SECT163R2(), + "sect233r1": SECT233R1(), + "sect283r1": SECT283R1(), + "sect409r1": SECT409R1(), + "sect571r1": SECT571R1(), + "brainpoolP256r1": BrainpoolP256R1(), + "brainpoolP384r1": BrainpoolP384R1(), + "brainpoolP512r1": BrainpoolP512R1(), } class ECDSA(EllipticCurveSignatureAlgorithm): def __init__( self, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + algorithm: asym_utils.Prehashed | hashes.HashAlgorithm, ): self._algorithm = algorithm @property def algorithm( self, - ) -> typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm]: + ) -> asym_utils.Prehashed | hashes.HashAlgorithm: return self._algorithm -def generate_private_key( - curve: EllipticCurve, backend: typing.Any = None -) -> EllipticCurvePrivateKey: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.generate_elliptic_curve_private_key(curve) +generate_private_key = rust_openssl.ec.generate_private_key def derive_private_key( @@ -341,116 +337,13 @@ def derive_private_key( curve: EllipticCurve, backend: typing.Any = None, ) -> EllipticCurvePrivateKey: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - if not isinstance(private_value, int): raise TypeError("private_value must be an integer type.") if private_value <= 0: raise ValueError("private_value must be a positive integer.") - if not isinstance(curve, EllipticCurve): - raise TypeError("curve must provide the EllipticCurve interface.") - - return ossl.derive_elliptic_curve_private_key(private_value, curve) - - -class EllipticCurvePublicNumbers: - def __init__(self, x: int, y: int, curve: EllipticCurve): - if not isinstance(x, int) or not isinstance(y, int): - raise TypeError("x and y must be integers.") - - if not isinstance(curve, EllipticCurve): - raise TypeError("curve must provide the EllipticCurve interface.") - - self._y = y - self._x = x - self._curve = curve - - def public_key(self, backend: typing.Any = None) -> EllipticCurvePublicKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_elliptic_curve_public_numbers(self) - - @property - def curve(self) -> EllipticCurve: - return self._curve - - @property - def x(self) -> int: - return self._x - - @property - def y(self) -> int: - return self._y - - def __eq__(self, other: object) -> bool: - if not isinstance(other, EllipticCurvePublicNumbers): - return NotImplemented - - return ( - self.x == other.x - and self.y == other.y - and self.curve.name == other.curve.name - and self.curve.key_size == other.curve.key_size - ) - - def __hash__(self) -> int: - return hash((self.x, self.y, self.curve.name, self.curve.key_size)) - - def __repr__(self) -> str: - return ( - "".format(self) - ) - - -class EllipticCurvePrivateNumbers: - def __init__( - self, private_value: int, public_numbers: EllipticCurvePublicNumbers - ): - if not isinstance(private_value, int): - raise TypeError("private_value must be an integer.") - - if not isinstance(public_numbers, EllipticCurvePublicNumbers): - raise TypeError( - "public_numbers must be an EllipticCurvePublicNumbers " - "instance." - ) - - self._private_value = private_value - self._public_numbers = public_numbers - - def private_key( - self, backend: typing.Any = None - ) -> EllipticCurvePrivateKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_elliptic_curve_private_numbers(self) - - @property - def private_value(self) -> int: - return self._private_value - - @property - def public_numbers(self) -> EllipticCurvePublicNumbers: - return self._public_numbers - - def __eq__(self, other: object) -> bool: - if not isinstance(other, EllipticCurvePrivateNumbers): - return NotImplemented - - return ( - self.private_value == other.private_value - and self.public_numbers == other.public_numbers - ) - - def __hash__(self) -> int: - return hash((self.private_value, self.public_numbers)) + return rust_openssl.ec.derive_private_key(private_value, curve) class ECDH: @@ -480,7 +373,7 @@ class ECDH: } -def get_curve_for_oid(oid: ObjectIdentifier) -> typing.Type[EllipticCurve]: +def get_curve_for_oid(oid: ObjectIdentifier) -> type[EllipticCurve]: try: return _OID_TO_CURVE[oid] except KeyError: diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py index f26e54d2..3a26185d 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -22,7 +22,7 @@ def from_public_bytes(cls, data: bytes) -> Ed25519PublicKey: _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, ) - return backend.ed25519_load_public_bytes(data) + return rust_openssl.ed25519.from_public_bytes(data) @abc.abstractmethod def public_bytes( @@ -54,8 +54,7 @@ def __eq__(self, other: object) -> bool: """ -if hasattr(rust_openssl, "ed25519"): - Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey) +Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey) class Ed25519PrivateKey(metaclass=abc.ABCMeta): @@ -69,7 +68,7 @@ def generate(cls) -> Ed25519PrivateKey: _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, ) - return backend.ed25519_generate_key() + return rust_openssl.ed25519.generate_key() @classmethod def from_private_bytes(cls, data: bytes) -> Ed25519PrivateKey: @@ -81,7 +80,7 @@ def from_private_bytes(cls, data: bytes) -> Ed25519PrivateKey: _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, ) - return backend.ed25519_load_private_bytes(data) + return rust_openssl.ed25519.from_private_bytes(data) @abc.abstractmethod def public_key(self) -> Ed25519PublicKey: @@ -114,5 +113,4 @@ def sign(self, data: bytes) -> bytes: """ -if hasattr(rust_openssl, "x25519"): - Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey) +Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py index a9a34b25..78c82c4a 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -22,7 +22,7 @@ def from_public_bytes(cls, data: bytes) -> Ed448PublicKey: _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, ) - return backend.ed448_load_public_bytes(data) + return rust_openssl.ed448.from_public_bytes(data) @abc.abstractmethod def public_bytes( @@ -68,7 +68,8 @@ def generate(cls) -> Ed448PrivateKey: "ed448 is not supported by this version of OpenSSL.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, ) - return backend.ed448_generate_key() + + return rust_openssl.ed448.generate_key() @classmethod def from_private_bytes(cls, data: bytes) -> Ed448PrivateKey: @@ -80,7 +81,7 @@ def from_private_bytes(cls, data: bytes) -> Ed448PrivateKey: _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, ) - return backend.ed448_load_private_bytes(data) + return rust_openssl.ed448.from_private_bytes(data) @abc.abstractmethod def public_key(self) -> Ed448PublicKey: diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py index 7198808e..b4babf44 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py @@ -5,7 +5,6 @@ from __future__ import annotations import abc -import typing from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives._asymmetric import ( @@ -35,12 +34,12 @@ class PSS(AsymmetricPadding): AUTO = _Auto() DIGEST_LENGTH = _DigestLength() name = "EMSA-PSS" - _salt_length: typing.Union[int, _MaxLength, _Auto, _DigestLength] + _salt_length: int | _MaxLength | _Auto | _DigestLength def __init__( self, mgf: MGF, - salt_length: typing.Union[int, _MaxLength, _Auto, _DigestLength], + salt_length: int | _MaxLength | _Auto | _DigestLength, ) -> None: self._mgf = mgf @@ -57,6 +56,10 @@ def __init__( self._salt_length = salt_length + @property + def mgf(self) -> MGF: + return self._mgf + class OAEP(AsymmetricPadding): name = "EME-OAEP" @@ -65,7 +68,7 @@ def __init__( self, mgf: MGF, algorithm: hashes.HashAlgorithm, - label: typing.Optional[bytes], + label: bytes | None, ): if not isinstance(algorithm, hashes.HashAlgorithm): raise TypeError("Expected instance of hashes.HashAlgorithm.") @@ -74,6 +77,14 @@ def __init__( self._algorithm = algorithm self._label = label + @property + def algorithm(self) -> hashes.HashAlgorithm: + return self._algorithm + + @property + def mgf(self) -> MGF: + return self._mgf + class MGF(metaclass=abc.ABCMeta): _algorithm: hashes.HashAlgorithm @@ -90,7 +101,7 @@ def __init__(self, algorithm: hashes.HashAlgorithm): def calculate_max_pss_salt_length( - key: typing.Union[rsa.RSAPrivateKey, rsa.RSAPublicKey], + key: rsa.RSAPrivateKey | rsa.RSAPublicKey, hash_algorithm: hashes.HashAlgorithm, ) -> int: if not isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py index b740f01f..6420434d 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -8,6 +8,7 @@ import typing from math import gcd +from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization, hashes from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding from cryptography.hazmat.primitives.asymmetric import utils as asym_utils @@ -38,7 +39,7 @@ def sign( self, data: bytes, padding: AsymmetricPadding, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + algorithm: asym_utils.Prehashed | hashes.HashAlgorithm, ) -> bytes: """ Signs the data. @@ -63,6 +64,7 @@ def private_bytes( RSAPrivateKeyWithSerialization = RSAPrivateKey +RSAPrivateKey.register(rust_openssl.rsa.RSAPrivateKey) class RSAPublicKey(metaclass=abc.ABCMeta): @@ -101,7 +103,7 @@ def verify( signature: bytes, data: bytes, padding: AsymmetricPadding, - algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + algorithm: asym_utils.Prehashed | hashes.HashAlgorithm, ) -> None: """ Verifies the signature of the data. @@ -112,7 +114,7 @@ def recover_data_from_signature( self, signature: bytes, padding: AsymmetricPadding, - algorithm: typing.Optional[hashes.HashAlgorithm], + algorithm: hashes.HashAlgorithm | None, ) -> bytes: """ Recovers the original data from the signature. @@ -126,6 +128,10 @@ def __eq__(self, other: object) -> bool: RSAPublicKeyWithSerialization = RSAPublicKey +RSAPublicKey.register(rust_openssl.rsa.RSAPublicKey) + +RSAPrivateNumbers = rust_openssl.rsa.RSAPrivateNumbers +RSAPublicNumbers = rust_openssl.rsa.RSAPublicNumbers def generate_private_key( @@ -133,10 +139,8 @@ def generate_private_key( key_size: int, backend: typing.Any = None, ) -> RSAPrivateKey: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - _verify_rsa_parameters(public_exponent, key_size) - return ossl.generate_rsa_private_key(public_exponent, key_size) + return rust_openssl.rsa.generate_private_key(public_exponent, key_size) def _verify_rsa_parameters(public_exponent: int, key_size: int) -> None: @@ -150,64 +154,6 @@ def _verify_rsa_parameters(public_exponent: int, key_size: int) -> None: raise ValueError("key_size must be at least 512-bits.") -def _check_private_key_components( - p: int, - q: int, - private_exponent: int, - dmp1: int, - dmq1: int, - iqmp: int, - public_exponent: int, - modulus: int, -) -> None: - if modulus < 3: - raise ValueError("modulus must be >= 3.") - - if p >= modulus: - raise ValueError("p must be < modulus.") - - if q >= modulus: - raise ValueError("q must be < modulus.") - - if dmp1 >= modulus: - raise ValueError("dmp1 must be < modulus.") - - if dmq1 >= modulus: - raise ValueError("dmq1 must be < modulus.") - - if iqmp >= modulus: - raise ValueError("iqmp must be < modulus.") - - if private_exponent >= modulus: - raise ValueError("private_exponent must be < modulus.") - - if public_exponent < 3 or public_exponent >= modulus: - raise ValueError("public_exponent must be >= 3 and < modulus.") - - if public_exponent & 1 == 0: - raise ValueError("public_exponent must be odd.") - - if dmp1 & 1 == 0: - raise ValueError("dmp1 must be odd.") - - if dmq1 & 1 == 0: - raise ValueError("dmq1 must be odd.") - - if p * q != modulus: - raise ValueError("p*q must equal modulus.") - - -def _check_public_key_components(e: int, n: int) -> None: - if n < 3: - raise ValueError("n must be >= 3.") - - if e < 3 or e >= n: - raise ValueError("e must be >= 3 and < n.") - - if e & 1 == 0: - raise ValueError("e must be odd.") - - def _modinv(e: int, m: int) -> int: """ Modular Multiplicative Inverse. Returns x such that: (x*e) mod m == 1 @@ -250,9 +196,7 @@ def rsa_crt_dmq1(private_exponent: int, q: int) -> int: _MAX_RECOVERY_ATTEMPTS = 1000 -def rsa_recover_prime_factors( - n: int, e: int, d: int -) -> typing.Tuple[int, int]: +def rsa_recover_prime_factors(n: int, e: int, d: int) -> tuple[int, int]: """ Compute factors p and q from the private exponent d. We assume that n has no more than two factors. This function is adapted from code in PyCrypto. @@ -293,147 +237,3 @@ def rsa_recover_prime_factors( assert r == 0 p, q = sorted((p, q), reverse=True) return (p, q) - - -class RSAPrivateNumbers: - def __init__( - self, - p: int, - q: int, - d: int, - dmp1: int, - dmq1: int, - iqmp: int, - public_numbers: RSAPublicNumbers, - ): - if ( - not isinstance(p, int) - or not isinstance(q, int) - or not isinstance(d, int) - or not isinstance(dmp1, int) - or not isinstance(dmq1, int) - or not isinstance(iqmp, int) - ): - raise TypeError( - "RSAPrivateNumbers p, q, d, dmp1, dmq1, iqmp arguments must" - " all be an integers." - ) - - if not isinstance(public_numbers, RSAPublicNumbers): - raise TypeError( - "RSAPrivateNumbers public_numbers must be an RSAPublicNumbers" - " instance." - ) - - self._p = p - self._q = q - self._d = d - self._dmp1 = dmp1 - self._dmq1 = dmq1 - self._iqmp = iqmp - self._public_numbers = public_numbers - - @property - def p(self) -> int: - return self._p - - @property - def q(self) -> int: - return self._q - - @property - def d(self) -> int: - return self._d - - @property - def dmp1(self) -> int: - return self._dmp1 - - @property - def dmq1(self) -> int: - return self._dmq1 - - @property - def iqmp(self) -> int: - return self._iqmp - - @property - def public_numbers(self) -> RSAPublicNumbers: - return self._public_numbers - - def private_key( - self, - backend: typing.Any = None, - *, - unsafe_skip_rsa_key_validation: bool = False, - ) -> RSAPrivateKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_rsa_private_numbers( - self, unsafe_skip_rsa_key_validation - ) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, RSAPrivateNumbers): - return NotImplemented - - return ( - self.p == other.p - and self.q == other.q - and self.d == other.d - and self.dmp1 == other.dmp1 - and self.dmq1 == other.dmq1 - and self.iqmp == other.iqmp - and self.public_numbers == other.public_numbers - ) - - def __hash__(self) -> int: - return hash( - ( - self.p, - self.q, - self.d, - self.dmp1, - self.dmq1, - self.iqmp, - self.public_numbers, - ) - ) - - -class RSAPublicNumbers: - def __init__(self, e: int, n: int): - if not isinstance(e, int) or not isinstance(n, int): - raise TypeError("RSAPublicNumbers arguments must be integers.") - - self._e = e - self._n = n - - @property - def e(self) -> int: - return self._e - - @property - def n(self) -> int: - return self._n - - def public_key(self, backend: typing.Any = None) -> RSAPublicKey: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - return ossl.load_rsa_public_numbers(self) - - def __repr__(self) -> str: - return "".format(self) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, RSAPublicNumbers): - return NotImplemented - - return self.e == other.e and self.n == other.n - - def __hash__(self) -> int: - return hash((self.e, self.n)) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py index 699054c9..0cfa36e3 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -22,7 +22,7 @@ def from_public_bytes(cls, data: bytes) -> X25519PublicKey: _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, ) - return backend.x25519_load_public_bytes(data) + return rust_openssl.x25519.from_public_bytes(data) @abc.abstractmethod def public_bytes( @@ -48,9 +48,7 @@ def __eq__(self, other: object) -> bool: """ -# For LibreSSL -if hasattr(rust_openssl, "x25519"): - X25519PublicKey.register(rust_openssl.x25519.X25519PublicKey) +X25519PublicKey.register(rust_openssl.x25519.X25519PublicKey) class X25519PrivateKey(metaclass=abc.ABCMeta): @@ -63,7 +61,7 @@ def generate(cls) -> X25519PrivateKey: "X25519 is not supported by this version of OpenSSL.", _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, ) - return backend.x25519_generate_key() + return rust_openssl.x25519.generate_key() @classmethod def from_private_bytes(cls, data: bytes) -> X25519PrivateKey: @@ -75,12 +73,12 @@ def from_private_bytes(cls, data: bytes) -> X25519PrivateKey: _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, ) - return backend.x25519_load_private_bytes(data) + return rust_openssl.x25519.from_private_bytes(data) @abc.abstractmethod def public_key(self) -> X25519PublicKey: """ - Returns the public key assosciated with this private key + Returns the public key associated with this private key """ @abc.abstractmethod @@ -108,6 +106,4 @@ def exchange(self, peer_public_key: X25519PublicKey) -> bytes: """ -# For LibreSSL -if hasattr(rust_openssl, "x25519"): - X25519PrivateKey.register(rust_openssl.x25519.X25519PrivateKey) +X25519PrivateKey.register(rust_openssl.x25519.X25519PrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py index abf78485..86086ab4 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py @@ -22,7 +22,7 @@ def from_public_bytes(cls, data: bytes) -> X448PublicKey: _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, ) - return backend.x448_load_public_bytes(data) + return rust_openssl.x448.from_public_bytes(data) @abc.abstractmethod def public_bytes( @@ -62,7 +62,8 @@ def generate(cls) -> X448PrivateKey: "X448 is not supported by this version of OpenSSL.", _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, ) - return backend.x448_generate_key() + + return rust_openssl.x448.generate_key() @classmethod def from_private_bytes(cls, data: bytes) -> X448PrivateKey: @@ -74,7 +75,7 @@ def from_private_bytes(cls, data: bytes) -> X448PrivateKey: _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, ) - return backend.x448_load_private_bytes(data) + return rust_openssl.x448.from_private_bytes(data) @abc.abstractmethod def public_key(self) -> X448PublicKey: diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py index 957b2d22..40f1b9b7 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py @@ -5,85 +5,25 @@ from __future__ import annotations import os -import typing from cryptography import exceptions, utils from cryptography.hazmat.backends.openssl import aead from cryptography.hazmat.backends.openssl.backend import backend -from cryptography.hazmat.bindings._rust import FixedPool +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +__all__ = [ + "ChaCha20Poly1305", + "AESCCM", + "AESGCM", + "AESGCMSIV", + "AESOCB3", + "AESSIV", +] -class ChaCha20Poly1305: - _MAX_SIZE = 2**31 - 1 - - def __init__(self, key: bytes): - if not backend.aead_cipher_supported(self): - raise exceptions.UnsupportedAlgorithm( - "ChaCha20Poly1305 is not supported by this version of OpenSSL", - exceptions._Reasons.UNSUPPORTED_CIPHER, - ) - utils._check_byteslike("key", key) - - if len(key) != 32: - raise ValueError("ChaCha20Poly1305 key must be 32 bytes.") - - self._key = key - self._pool = FixedPool(self._create_fn) - - @classmethod - def generate_key(cls) -> bytes: - return os.urandom(32) - - def _create_fn(self): - return aead._aead_create_ctx(backend, self, self._key) - - def encrypt( - self, - nonce: bytes, - data: bytes, - associated_data: typing.Optional[bytes], - ) -> bytes: - if associated_data is None: - associated_data = b"" - - if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE: - # This is OverflowError to match what cffi would raise - raise OverflowError( - "Data or associated data too long. Max 2**31 - 1 bytes" - ) - - self._check_params(nonce, data, associated_data) - with self._pool.acquire() as ctx: - return aead._encrypt( - backend, self, nonce, data, [associated_data], 16, ctx - ) - - def decrypt( - self, - nonce: bytes, - data: bytes, - associated_data: typing.Optional[bytes], - ) -> bytes: - if associated_data is None: - associated_data = b"" - - self._check_params(nonce, data, associated_data) - with self._pool.acquire() as ctx: - return aead._decrypt( - backend, self, nonce, data, [associated_data], 16, ctx - ) - - def _check_params( - self, - nonce: bytes, - data: bytes, - associated_data: bytes, - ) -> None: - utils._check_byteslike("nonce", nonce) - utils._check_byteslike("data", data) - utils._check_byteslike("associated_data", associated_data) - if len(nonce) != 12: - raise ValueError("Nonce must be 12 bytes") +ChaCha20Poly1305 = rust_openssl.aead.ChaCha20Poly1305 +AESSIV = rust_openssl.aead.AESSIV +AESOCB3 = rust_openssl.aead.AESOCB3 +AESGCMSIV = rust_openssl.aead.AESGCMSIV class AESCCM: @@ -123,7 +63,7 @@ def encrypt( self, nonce: bytes, data: bytes, - associated_data: typing.Optional[bytes], + associated_data: bytes | None, ) -> bytes: if associated_data is None: associated_data = b"" @@ -144,7 +84,7 @@ def decrypt( self, nonce: bytes, data: bytes, - associated_data: typing.Optional[bytes], + associated_data: bytes | None, ) -> bytes: if associated_data is None: associated_data = b"" @@ -195,7 +135,7 @@ def encrypt( self, nonce: bytes, data: bytes, - associated_data: typing.Optional[bytes], + associated_data: bytes | None, ) -> bytes: if associated_data is None: associated_data = b"" @@ -213,7 +153,7 @@ def decrypt( self, nonce: bytes, data: bytes, - associated_data: typing.Optional[bytes], + associated_data: bytes | None, ) -> bytes: if associated_data is None: associated_data = b"" @@ -232,147 +172,3 @@ def _check_params( utils._check_byteslike("associated_data", associated_data) if len(nonce) < 8 or len(nonce) > 128: raise ValueError("Nonce must be between 8 and 128 bytes") - - -class AESOCB3: - _MAX_SIZE = 2**31 - 1 - - def __init__(self, key: bytes): - utils._check_byteslike("key", key) - if len(key) not in (16, 24, 32): - raise ValueError("AESOCB3 key must be 128, 192, or 256 bits.") - - self._key = key - - if not backend.aead_cipher_supported(self): - raise exceptions.UnsupportedAlgorithm( - "OCB3 is not supported by this version of OpenSSL", - exceptions._Reasons.UNSUPPORTED_CIPHER, - ) - - @classmethod - def generate_key(cls, bit_length: int) -> bytes: - if not isinstance(bit_length, int): - raise TypeError("bit_length must be an integer") - - if bit_length not in (128, 192, 256): - raise ValueError("bit_length must be 128, 192, or 256") - - return os.urandom(bit_length // 8) - - def encrypt( - self, - nonce: bytes, - data: bytes, - associated_data: typing.Optional[bytes], - ) -> bytes: - if associated_data is None: - associated_data = b"" - - if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE: - # This is OverflowError to match what cffi would raise - raise OverflowError( - "Data or associated data too long. Max 2**31 - 1 bytes" - ) - - self._check_params(nonce, data, associated_data) - return aead._encrypt(backend, self, nonce, data, [associated_data], 16) - - def decrypt( - self, - nonce: bytes, - data: bytes, - associated_data: typing.Optional[bytes], - ) -> bytes: - if associated_data is None: - associated_data = b"" - - self._check_params(nonce, data, associated_data) - return aead._decrypt(backend, self, nonce, data, [associated_data], 16) - - def _check_params( - self, - nonce: bytes, - data: bytes, - associated_data: bytes, - ) -> None: - utils._check_byteslike("nonce", nonce) - utils._check_byteslike("data", data) - utils._check_byteslike("associated_data", associated_data) - if len(nonce) < 12 or len(nonce) > 15: - raise ValueError("Nonce must be between 12 and 15 bytes") - - -class AESSIV: - _MAX_SIZE = 2**31 - 1 - - def __init__(self, key: bytes): - utils._check_byteslike("key", key) - if len(key) not in (32, 48, 64): - raise ValueError("AESSIV key must be 256, 384, or 512 bits.") - - self._key = key - - if not backend.aead_cipher_supported(self): - raise exceptions.UnsupportedAlgorithm( - "AES-SIV is not supported by this version of OpenSSL", - exceptions._Reasons.UNSUPPORTED_CIPHER, - ) - - @classmethod - def generate_key(cls, bit_length: int) -> bytes: - if not isinstance(bit_length, int): - raise TypeError("bit_length must be an integer") - - if bit_length not in (256, 384, 512): - raise ValueError("bit_length must be 256, 384, or 512") - - return os.urandom(bit_length // 8) - - def encrypt( - self, - data: bytes, - associated_data: typing.Optional[typing.List[bytes]], - ) -> bytes: - if associated_data is None: - associated_data = [] - - self._check_params(data, associated_data) - - if len(data) > self._MAX_SIZE or any( - len(ad) > self._MAX_SIZE for ad in associated_data - ): - # This is OverflowError to match what cffi would raise - raise OverflowError( - "Data or associated data too long. Max 2**31 - 1 bytes" - ) - - return aead._encrypt(backend, self, b"", data, associated_data, 16) - - def decrypt( - self, - data: bytes, - associated_data: typing.Optional[typing.List[bytes]], - ) -> bytes: - if associated_data is None: - associated_data = [] - - self._check_params(data, associated_data) - - return aead._decrypt(backend, self, b"", data, associated_data, 16) - - def _check_params( - self, - data: bytes, - associated_data: typing.List[bytes], - ) -> None: - utils._check_byteslike("data", data) - if len(data) == 0: - raise ValueError("data must not be zero length") - - if not isinstance(associated_data, list): - raise TypeError( - "associated_data must be a list of bytes-like objects or None" - ) - for x in associated_data: - utils._check_byteslike("associated_data elements", x) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py index 4bfc5d84..000bdcba 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -18,9 +18,7 @@ def _verify_key_size(algorithm: CipherAlgorithm, key: bytes) -> bytes: # Verify that the key size matches the expected key size if len(key) * 8 not in algorithm.key_sizes: raise ValueError( - "Invalid key size ({}) for {}.".format( - len(key) * 8, algorithm.name - ) + f"Invalid key size ({len(key) * 8}) for {algorithm.name}." ) return key @@ -106,7 +104,7 @@ def key_size(self) -> int: utils.deprecated( Blowfish, __name__, - "Blowfish has been deprecated", + "Blowfish has been deprecated and will be removed in a future release", utils.DeprecatedIn37, name="Blowfish", ) @@ -129,7 +127,7 @@ def key_size(self) -> int: utils.deprecated( CAST5, __name__, - "CAST5 has been deprecated", + "CAST5 has been deprecated and will be removed in a future release", utils.DeprecatedIn37, name="CAST5", ) @@ -164,7 +162,7 @@ def key_size(self) -> int: utils.deprecated( IDEA, __name__, - "IDEA has been deprecated", + "IDEA has been deprecated and will be removed in a future release", utils.DeprecatedIn37, name="IDEA", ) @@ -187,7 +185,7 @@ def key_size(self) -> int: utils.deprecated( SEED, __name__, - "SEED has been deprecated", + "SEED has been deprecated and will be removed in a future release", utils.DeprecatedIn37, name="SEED", ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py index 38a2ebbe..2082df66 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py @@ -141,9 +141,7 @@ def decryptor(self): def _wrap_ctx( self, ctx: _BackendCipherContext, encrypt: bool - ) -> typing.Union[ - AEADEncryptionContext, AEADDecryptionContext, CipherContext - ]: + ) -> AEADEncryptionContext | AEADDecryptionContext | CipherContext: if isinstance(self.mode, modes.ModeWithAuthenticationTag): if encrypt: return _AEADEncryptionContext(ctx) @@ -165,7 +163,7 @@ def _wrap_ctx( class _CipherContext(CipherContext): - _ctx: typing.Optional[_BackendCipherContext] + _ctx: _BackendCipherContext | None def __init__(self, ctx: _BackendCipherContext) -> None: self._ctx = ctx @@ -189,8 +187,8 @@ def finalize(self) -> bytes: class _AEADCipherContext(AEADCipherContext): - _ctx: typing.Optional[_BackendCipherContext] - _tag: typing.Optional[bytes] + _ctx: _BackendCipherContext | None + _tag: bytes | None def __init__(self, ctx: _BackendCipherContext) -> None: self._ctx = ctx @@ -252,6 +250,11 @@ class _AEADDecryptionContext(_AEADCipherContext, AEADDecryptionContext): def finalize_with_tag(self, tag: bytes) -> bytes: if self._ctx is None: raise AlreadyFinalized("Context was already finalized.") + if self._ctx._tag is not None: + raise ValueError( + "tag provided both in mode and in call with finalize_with_tag:" + " tag should only be provided once" + ) data = self._ctx.finalize_with_tag(tag) self._tag = self._ctx.tag self._ctx = None diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py index d8ea1888..712ccd3f 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py @@ -5,7 +5,6 @@ from __future__ import annotations import abc -import typing from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm, _Reasons @@ -62,7 +61,7 @@ def nonce(self) -> bytes: class ModeWithAuthenticationTag(Mode, metaclass=abc.ABCMeta): @property @abc.abstractmethod - def tag(self) -> typing.Optional[bytes]: + def tag(self) -> bytes | None: """ The value of the tag supplied to the constructor of this mode. """ @@ -225,7 +224,7 @@ class GCM(ModeWithInitializationVector, ModeWithAuthenticationTag): def __init__( self, initialization_vector: bytes, - tag: typing.Optional[bytes] = None, + tag: bytes | None = None, min_tag_length: int = 16, ): # OpenSSL 3.0.0 constrains GCM IVs to [64, 1024] bits inclusive @@ -251,7 +250,7 @@ def __init__( self._min_tag_length = min_tag_length @property - def tag(self) -> typing.Optional[bytes]: + def tag(self) -> bytes | None: return self._tag @property diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py index 8aa1d791..2c67ce22 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py @@ -4,62 +4,7 @@ from __future__ import annotations -import typing +from cryptography.hazmat.bindings._rust import openssl as rust_openssl -from cryptography import utils -from cryptography.exceptions import AlreadyFinalized -from cryptography.hazmat.primitives import ciphers - -if typing.TYPE_CHECKING: - from cryptography.hazmat.backends.openssl.cmac import _CMACContext - - -class CMAC: - _ctx: typing.Optional[_CMACContext] - _algorithm: ciphers.BlockCipherAlgorithm - - def __init__( - self, - algorithm: ciphers.BlockCipherAlgorithm, - backend: typing.Any = None, - ctx: typing.Optional[_CMACContext] = None, - ) -> None: - if not isinstance(algorithm, ciphers.BlockCipherAlgorithm): - raise TypeError("Expected instance of BlockCipherAlgorithm.") - self._algorithm = algorithm - - if ctx is None: - from cryptography.hazmat.backends.openssl.backend import ( - backend as ossl, - ) - - self._ctx = ossl.create_cmac_ctx(self._algorithm) - else: - self._ctx = ctx - - def update(self, data: bytes) -> None: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - - utils._check_bytes("data", data) - self._ctx.update(data) - - def finalize(self) -> bytes: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - digest = self._ctx.finalize() - self._ctx = None - return digest - - def verify(self, signature: bytes) -> None: - utils._check_bytes("signature", signature) - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - - ctx, self._ctx = self._ctx, None - ctx.verify(signature) - - def copy(self) -> CMAC: - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - return CMAC(self._algorithm, ctx=self._ctx.copy()) +__all__ = ["CMAC"] +CMAC = rust_openssl.cmac.CMAC diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py index b6a7ff14..c5be0c8e 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py @@ -5,7 +5,6 @@ from __future__ import annotations import abc -import typing from cryptography.hazmat.bindings._rust import openssl as rust_openssl @@ -51,7 +50,7 @@ def digest_size(self) -> int: @property @abc.abstractmethod - def block_size(self) -> typing.Optional[int]: + def block_size(self) -> int | None: """ The internal block size of the hash function, or None if the hash function does not use blocks internally (e.g. SHA3). diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py index d5ea58a9..96d9d4c0 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py @@ -19,7 +19,7 @@ def _int_to_u32be(n: int) -> bytes: def _common_args_checks( algorithm: hashes.HashAlgorithm, length: int, - otherinfo: typing.Optional[bytes], + otherinfo: bytes | None, ) -> None: max_length = algorithm.digest_size * (2**32 - 1) if length > max_length: @@ -56,7 +56,7 @@ def __init__( self, algorithm: hashes.HashAlgorithm, length: int, - otherinfo: typing.Optional[bytes], + otherinfo: bytes | None, backend: typing.Any = None, ): _common_args_checks(algorithm, length, otherinfo) @@ -87,8 +87,8 @@ def __init__( self, algorithm: hashes.HashAlgorithm, length: int, - salt: typing.Optional[bytes], - otherinfo: typing.Optional[bytes], + salt: bytes | None, + otherinfo: bytes | None, backend: typing.Any = None, ): _common_args_checks(algorithm, length, otherinfo) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py index d4768944..ee562d2f 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py @@ -17,8 +17,8 @@ def __init__( self, algorithm: hashes.HashAlgorithm, length: int, - salt: typing.Optional[bytes], - info: typing.Optional[bytes], + salt: bytes | None, + info: bytes | None, backend: typing.Any = None, ): self._algorithm = algorithm @@ -51,7 +51,7 @@ def __init__( self, algorithm: hashes.HashAlgorithm, length: int, - info: typing.Optional[bytes], + info: bytes | None, backend: typing.Any = None, ): self._algorithm = algorithm diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py index 96776382..2f41db92 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py @@ -40,12 +40,12 @@ def __init__( mode: Mode, length: int, rlen: int, - llen: typing.Optional[int], + llen: int | None, location: CounterLocation, - break_location: typing.Optional[int], - label: typing.Optional[bytes], - context: typing.Optional[bytes], - fixed: typing.Optional[bytes], + break_location: int | None, + label: bytes | None, + context: bytes | None, + fixed: bytes | None, ): assert callable(prf) @@ -181,14 +181,14 @@ def __init__( mode: Mode, length: int, rlen: int, - llen: typing.Optional[int], + llen: int | None, location: CounterLocation, - label: typing.Optional[bytes], - context: typing.Optional[bytes], - fixed: typing.Optional[bytes], + label: bytes | None, + context: bytes | None, + fixed: bytes | None, backend: typing.Any = None, *, - break_location: typing.Optional[int] = None, + break_location: int | None = None, ): if not isinstance(algorithm, hashes.HashAlgorithm): raise UnsupportedAlgorithm( @@ -239,14 +239,14 @@ def __init__( mode: Mode, length: int, rlen: int, - llen: typing.Optional[int], + llen: int | None, location: CounterLocation, - label: typing.Optional[bytes], - context: typing.Optional[bytes], - fixed: typing.Optional[bytes], + label: bytes | None, + context: bytes | None, + fixed: bytes | None, backend: typing.Any = None, *, - break_location: typing.Optional[int] = None, + break_location: int | None = None, ): if not issubclass( algorithm, ciphers.BlockCipherAlgorithm @@ -257,7 +257,7 @@ def __init__( ) self._algorithm = algorithm - self._cipher: typing.Optional[ciphers.BlockCipherAlgorithm] = None + self._cipher: ciphers.BlockCipherAlgorithm | None = None self._deriver = _KBKDFDeriver( self._prf, diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py index 17acc517..6e38366a 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py @@ -21,7 +21,7 @@ def __init__( self, algorithm: hashes.HashAlgorithm, length: int, - sharedinfo: typing.Optional[bytes], + sharedinfo: bytes | None, backend: typing.Any = None, ): max_len = algorithm.digest_size * (2**32 - 1) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py index 59b0326c..3ee152b7 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py @@ -15,7 +15,7 @@ def _wrap_core( wrapping_key: bytes, a: bytes, - r: typing.List[bytes], + r: list[bytes], ) -> bytes: # RFC 3394 Key Wrap - 2.2.1 (index method) encryptor = Cipher(AES(wrapping_key), ECB()).encryptor() @@ -58,8 +58,8 @@ def aes_key_wrap( def _unwrap_core( wrapping_key: bytes, a: bytes, - r: typing.List[bytes], -) -> typing.Tuple[bytes, typing.List[bytes]]: + r: list[bytes], +) -> tuple[bytes, list[bytes]]: # Implement RFC 3394 Key Unwrap - 2.2.2 (index method) decryptor = Cipher(AES(wrapping_key), ECB()).decryptor() n = len(r) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py index fde3094b..baceaf38 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py @@ -38,8 +38,8 @@ def _byte_padding_check(block_size: int) -> None: def _byte_padding_update( - buffer_: typing.Optional[bytes], data: bytes, block_size: int -) -> typing.Tuple[bytes, bytes]: + buffer_: bytes | None, data: bytes, block_size: int +) -> tuple[bytes, bytes]: if buffer_ is None: raise AlreadyFinalized("Context was already finalized.") @@ -56,7 +56,7 @@ def _byte_padding_update( def _byte_padding_pad( - buffer_: typing.Optional[bytes], + buffer_: bytes | None, block_size: int, paddingfn: typing.Callable[[int], bytes], ) -> bytes: @@ -68,8 +68,8 @@ def _byte_padding_pad( def _byte_unpadding_update( - buffer_: typing.Optional[bytes], data: bytes, block_size: int -) -> typing.Tuple[bytes, bytes]: + buffer_: bytes | None, data: bytes, block_size: int +) -> tuple[bytes, bytes]: if buffer_ is None: raise AlreadyFinalized("Context was already finalized.") @@ -86,7 +86,7 @@ def _byte_unpadding_update( def _byte_unpadding_check( - buffer_: typing.Optional[bytes], + buffer_: bytes | None, block_size: int, checkfn: typing.Callable[[bytes], int], ) -> bytes: @@ -118,7 +118,7 @@ def unpadder(self) -> PaddingContext: class _PKCS7PaddingContext(PaddingContext): - _buffer: typing.Optional[bytes] + _buffer: bytes | None def __init__(self, block_size: int): self.block_size = block_size @@ -143,7 +143,7 @@ def finalize(self) -> bytes: class _PKCS7UnpaddingContext(PaddingContext): - _buffer: typing.Optional[bytes] + _buffer: bytes | None def __init__(self, block_size: int): self.block_size = block_size @@ -177,7 +177,7 @@ def unpadder(self) -> PaddingContext: class _ANSIX923PaddingContext(PaddingContext): - _buffer: typing.Optional[bytes] + _buffer: bytes | None def __init__(self, block_size: int): self.block_size = block_size @@ -202,7 +202,7 @@ def finalize(self) -> bytes: class _ANSIX923UnpaddingContext(PaddingContext): - _buffer: typing.Optional[bytes] + _buffer: bytes | None def __init__(self, block_size: int): self.block_size = block_size diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py index 18a96ccf..e7c998b7 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py @@ -2,72 +2,13 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -from __future__ import annotations +from cryptography.hazmat.bindings._rust import openssl as rust_openssl -import typing +load_pem_private_key = rust_openssl.keys.load_pem_private_key +load_der_private_key = rust_openssl.keys.load_der_private_key -from cryptography.hazmat.primitives.asymmetric import dh -from cryptography.hazmat.primitives.asymmetric.types import ( - PrivateKeyTypes, - PublicKeyTypes, -) +load_pem_public_key = rust_openssl.keys.load_pem_public_key +load_der_public_key = rust_openssl.keys.load_der_public_key - -def load_pem_private_key( - data: bytes, - password: typing.Optional[bytes], - backend: typing.Any = None, - *, - unsafe_skip_rsa_key_validation: bool = False, -) -> PrivateKeyTypes: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.load_pem_private_key( - data, password, unsafe_skip_rsa_key_validation - ) - - -def load_pem_public_key( - data: bytes, backend: typing.Any = None -) -> PublicKeyTypes: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.load_pem_public_key(data) - - -def load_pem_parameters( - data: bytes, backend: typing.Any = None -) -> dh.DHParameters: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.load_pem_parameters(data) - - -def load_der_private_key( - data: bytes, - password: typing.Optional[bytes], - backend: typing.Any = None, - *, - unsafe_skip_rsa_key_validation: bool = False, -) -> PrivateKeyTypes: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.load_der_private_key( - data, password, unsafe_skip_rsa_key_validation - ) - - -def load_der_public_key( - data: bytes, backend: typing.Any = None -) -> PublicKeyTypes: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.load_der_public_key(data) - - -def load_der_parameters( - data: bytes, backend: typing.Any = None -) -> dh.DHParameters: - from cryptography.hazmat.backends.openssl.backend import backend as ossl - - return ossl.load_der_parameters(data) +load_pem_parameters = rust_openssl.dh.from_pem_parameters +load_der_parameters = rust_openssl.dh.from_der_parameters diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py index 27133a3f..006a248b 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py @@ -41,7 +41,7 @@ class PKCS12Certificate: def __init__( self, cert: x509.Certificate, - friendly_name: typing.Optional[bytes], + friendly_name: bytes | None, ): if not isinstance(cert, x509.Certificate): raise TypeError("Expecting x509.Certificate object") @@ -51,7 +51,7 @@ def __init__( self._friendly_name = friendly_name @property - def friendly_name(self) -> typing.Optional[bytes]: + def friendly_name(self) -> bytes | None: return self._friendly_name @property @@ -79,9 +79,9 @@ def __repr__(self) -> str: class PKCS12KeyAndCertificates: def __init__( self, - key: typing.Optional[PrivateKeyTypes], - cert: typing.Optional[PKCS12Certificate], - additional_certs: typing.List[PKCS12Certificate], + key: PrivateKeyTypes | None, + cert: PKCS12Certificate | None, + additional_certs: list[PKCS12Certificate], ): if key is not None and not isinstance( key, @@ -112,15 +112,15 @@ def __init__( self._additional_certs = additional_certs @property - def key(self) -> typing.Optional[PrivateKeyTypes]: + def key(self) -> PrivateKeyTypes | None: return self._key @property - def cert(self) -> typing.Optional[PKCS12Certificate]: + def cert(self) -> PKCS12Certificate | None: return self._cert @property - def additional_certs(self) -> typing.List[PKCS12Certificate]: + def additional_certs(self) -> list[PKCS12Certificate]: return self._additional_certs def __eq__(self, other: object) -> bool: @@ -145,12 +145,12 @@ def __repr__(self) -> str: def load_key_and_certificates( data: bytes, - password: typing.Optional[bytes], + password: bytes | None, backend: typing.Any = None, -) -> typing.Tuple[ - typing.Optional[PrivateKeyTypes], - typing.Optional[x509.Certificate], - typing.List[x509.Certificate], +) -> tuple[ + PrivateKeyTypes | None, + x509.Certificate | None, + list[x509.Certificate], ]: from cryptography.hazmat.backends.openssl.backend import backend as ossl @@ -159,7 +159,7 @@ def load_key_and_certificates( def load_pkcs12( data: bytes, - password: typing.Optional[bytes], + password: bytes | None, backend: typing.Any = None, ) -> PKCS12KeyAndCertificates: from cryptography.hazmat.backends.openssl.backend import backend as ossl @@ -174,10 +174,10 @@ def load_pkcs12( def serialize_key_and_certificates( - name: typing.Optional[bytes], - key: typing.Optional[PKCS12PrivateKeyTypes], - cert: typing.Optional[x509.Certificate], - cas: typing.Optional[typing.Iterable[_PKCS12CATypes]], + name: bytes | None, + key: PKCS12PrivateKeyTypes | None, + cert: x509.Certificate | None, + cas: typing.Iterable[_PKCS12CATypes] | None, encryption_algorithm: serialization.KeySerializationEncryption, ) -> bytes: if key is not None and not isinstance( diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py index 9998bcaa..bae35c5f 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -14,28 +14,14 @@ from cryptography import utils, x509 from cryptography.hazmat.bindings._rust import pkcs7 as rust_pkcs7 from cryptography.hazmat.primitives import hashes, serialization -from cryptography.hazmat.primitives.asymmetric import ec, rsa +from cryptography.hazmat.primitives.asymmetric import ec, padding, rsa from cryptography.utils import _check_byteslike +load_pem_pkcs7_certificates = rust_pkcs7.load_pem_pkcs7_certificates -def load_pem_pkcs7_certificates(data: bytes) -> typing.List[x509.Certificate]: - from cryptography.hazmat.backends.openssl.backend import backend - - return backend.load_pem_pkcs7_certificates(data) - - -def load_der_pkcs7_certificates(data: bytes) -> typing.List[x509.Certificate]: - from cryptography.hazmat.backends.openssl.backend import backend - - return backend.load_der_pkcs7_certificates(data) - - -def serialize_certificates( - certs: typing.List[x509.Certificate], - encoding: serialization.Encoding, -) -> bytes: - return rust_pkcs7.serialize_certificates(certs, encoding) +load_der_pkcs7_certificates = rust_pkcs7.load_der_pkcs7_certificates +serialize_certificates = rust_pkcs7.serialize_certificates PKCS7HashTypes = typing.Union[ hashes.SHA224, @@ -61,15 +47,16 @@ class PKCS7Options(utils.Enum): class PKCS7SignatureBuilder: def __init__( self, - data: typing.Optional[bytes] = None, - signers: typing.List[ - typing.Tuple[ + data: bytes | None = None, + signers: list[ + tuple[ x509.Certificate, PKCS7PrivateKeyTypes, PKCS7HashTypes, + padding.PSS | padding.PKCS1v15 | None, ] ] = [], - additional_certs: typing.List[x509.Certificate] = [], + additional_certs: list[x509.Certificate] = [], ): self._data = data self._signers = signers @@ -87,6 +74,8 @@ def add_signer( certificate: x509.Certificate, private_key: PKCS7PrivateKeyTypes, hash_algorithm: PKCS7HashTypes, + *, + rsa_padding: padding.PSS | padding.PKCS1v15 | None = None, ) -> PKCS7SignatureBuilder: if not isinstance( hash_algorithm, @@ -109,9 +98,18 @@ def add_signer( ): raise TypeError("Only RSA & EC keys are supported at this time.") + if rsa_padding is not None: + if not isinstance(rsa_padding, (padding.PSS, padding.PKCS1v15)): + raise TypeError("Padding must be PSS or PKCS1v15") + if not isinstance(private_key, rsa.RSAPrivateKey): + raise TypeError("Padding is only supported for RSA keys") + return PKCS7SignatureBuilder( self._data, - self._signers + [(certificate, private_key, hash_algorithm)], + [ + *self._signers, + (certificate, private_key, hash_algorithm, rsa_padding), + ], ) def add_certificate( @@ -121,7 +119,7 @@ def add_certificate( raise TypeError("certificate must be a x509.Certificate") return PKCS7SignatureBuilder( - self._data, self._signers, self._additional_certs + [certificate] + self._data, self._signers, [*self._additional_certs, certificate] ) def sign( diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py index 7725c835..f33edd55 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py @@ -87,21 +87,17 @@ def _bcrypt_kdf( @dataclass class _SSHCipher: - alg: typing.Type[algorithms.AES] + alg: type[algorithms.AES] key_len: int - mode: typing.Union[ - typing.Type[modes.CTR], - typing.Type[modes.CBC], - typing.Type[modes.GCM], - ] + mode: type[modes.CTR] | type[modes.CBC] | type[modes.GCM] block_len: int iv_len: int - tag_len: typing.Optional[int] + tag_len: int | None is_aead: bool # ciphers that are actually used in key wrapping -_SSH_CIPHERS: typing.Dict[bytes, _SSHCipher] = { +_SSH_CIPHERS: dict[bytes, _SSHCipher] = { b"aes256-ctr": _SSHCipher( alg=algorithms.AES, key_len=32, @@ -139,9 +135,7 @@ class _SSHCipher: } -def _get_ssh_key_type( - key: typing.Union[SSHPrivateKeyTypes, SSHPublicKeyTypes] -) -> bytes: +def _get_ssh_key_type(key: SSHPrivateKeyTypes | SSHPublicKeyTypes) -> bytes: if isinstance(key, ec.EllipticCurvePrivateKey): key_type = _ecdsa_key_type(key.public_key()) elif isinstance(key, ec.EllipticCurvePublicKey): @@ -192,10 +186,10 @@ def _check_empty(data: bytes) -> None: def _init_cipher( ciphername: bytes, - password: typing.Optional[bytes], + password: bytes | None, salt: bytes, rounds: int, -) -> Cipher[typing.Union[modes.CBC, modes.CTR, modes.GCM]]: +) -> Cipher[modes.CBC | modes.CTR | modes.GCM]: """Generate key + iv and return cipher.""" if not password: raise ValueError("Key is password-protected.") @@ -210,21 +204,21 @@ def _init_cipher( ) -def _get_u32(data: memoryview) -> typing.Tuple[int, memoryview]: +def _get_u32(data: memoryview) -> tuple[int, memoryview]: """Uint32""" if len(data) < 4: raise ValueError("Invalid data") return int.from_bytes(data[:4], byteorder="big"), data[4:] -def _get_u64(data: memoryview) -> typing.Tuple[int, memoryview]: +def _get_u64(data: memoryview) -> tuple[int, memoryview]: """Uint64""" if len(data) < 8: raise ValueError("Invalid data") return int.from_bytes(data[:8], byteorder="big"), data[8:] -def _get_sshstr(data: memoryview) -> typing.Tuple[memoryview, memoryview]: +def _get_sshstr(data: memoryview) -> tuple[memoryview, memoryview]: """Bytes with u32 length prefix""" n, data = _get_u32(data) if n > len(data): @@ -232,7 +226,7 @@ def _get_sshstr(data: memoryview) -> typing.Tuple[memoryview, memoryview]: return data[:n], data[n:] -def _get_mpint(data: memoryview) -> typing.Tuple[int, memoryview]: +def _get_mpint(data: memoryview) -> tuple[int, memoryview]: """Big integer.""" val, data = _get_sshstr(data) if val and val[0] > 0x7F: @@ -253,11 +247,9 @@ def _to_mpint(val: int) -> bytes: class _FragList: """Build recursive structure without data copy.""" - flist: typing.List[bytes] + flist: list[bytes] - def __init__( - self, init: typing.Optional[typing.List[bytes]] = None - ) -> None: + def __init__(self, init: list[bytes] | None = None) -> None: self.flist = [] if init: self.flist.extend(init) @@ -274,7 +266,7 @@ def put_u64(self, val: int) -> None: """Big-endian uint64""" self.flist.append(val.to_bytes(length=8, byteorder="big")) - def put_sshstr(self, val: typing.Union[bytes, _FragList]) -> None: + def put_sshstr(self, val: bytes | _FragList) -> None: """Bytes prefixed with u32 length""" if isinstance(val, (bytes, memoryview, bytearray)): self.put_u32(len(val)) @@ -323,7 +315,7 @@ def get_public(self, data: memoryview): def load_public( self, data: memoryview - ) -> typing.Tuple[rsa.RSAPublicKey, memoryview]: + ) -> tuple[rsa.RSAPublicKey, memoryview]: """Make RSA public key from data.""" (e, n), data = self.get_public(data) public_numbers = rsa.RSAPublicNumbers(e, n) @@ -332,7 +324,7 @@ def load_public( def load_private( self, data: memoryview, pubfields - ) -> typing.Tuple[rsa.RSAPrivateKey, memoryview]: + ) -> tuple[rsa.RSAPrivateKey, memoryview]: """Make RSA private key from data.""" n, data = _get_mpint(data) e, data = _get_mpint(data) @@ -385,9 +377,7 @@ class _SSHFormatDSA: mpint p, q, g, y, x """ - def get_public( - self, data: memoryview - ) -> typing.Tuple[typing.Tuple, memoryview]: + def get_public(self, data: memoryview) -> tuple[tuple, memoryview]: """DSA public fields""" p, data = _get_mpint(data) q, data = _get_mpint(data) @@ -397,7 +387,7 @@ def get_public( def load_public( self, data: memoryview - ) -> typing.Tuple[dsa.DSAPublicKey, memoryview]: + ) -> tuple[dsa.DSAPublicKey, memoryview]: """Make DSA public key from data.""" (p, q, g, y), data = self.get_public(data) parameter_numbers = dsa.DSAParameterNumbers(p, q, g) @@ -408,7 +398,7 @@ def load_public( def load_private( self, data: memoryview, pubfields - ) -> typing.Tuple[dsa.DSAPrivateKey, memoryview]: + ) -> tuple[dsa.DSAPrivateKey, memoryview]: """Make DSA private key from data.""" (p, q, g, y), data = self.get_public(data) x, data = _get_mpint(data) @@ -464,9 +454,7 @@ def __init__(self, ssh_curve_name: bytes, curve: ec.EllipticCurve): self.ssh_curve_name = ssh_curve_name self.curve = curve - def get_public( - self, data: memoryview - ) -> typing.Tuple[typing.Tuple, memoryview]: + def get_public(self, data: memoryview) -> tuple[tuple, memoryview]: """ECDSA public fields""" curve, data = _get_sshstr(data) point, data = _get_sshstr(data) @@ -478,9 +466,9 @@ def get_public( def load_public( self, data: memoryview - ) -> typing.Tuple[ec.EllipticCurvePublicKey, memoryview]: + ) -> tuple[ec.EllipticCurvePublicKey, memoryview]: """Make ECDSA public key from data.""" - (curve_name, point), data = self.get_public(data) + (_, point), data = self.get_public(data) public_key = ec.EllipticCurvePublicKey.from_encoded_point( self.curve, point.tobytes() ) @@ -488,7 +476,7 @@ def load_public( def load_private( self, data: memoryview, pubfields - ) -> typing.Tuple[ec.EllipticCurvePrivateKey, memoryview]: + ) -> tuple[ec.EllipticCurvePrivateKey, memoryview]: """Make ECDSA private key from data.""" (curve_name, point), data = self.get_public(data) secret, data = _get_mpint(data) @@ -529,16 +517,14 @@ class _SSHFormatEd25519: bytes secret_and_point """ - def get_public( - self, data: memoryview - ) -> typing.Tuple[typing.Tuple, memoryview]: + def get_public(self, data: memoryview) -> tuple[tuple, memoryview]: """Ed25519 public fields""" point, data = _get_sshstr(data) return (point,), data def load_public( self, data: memoryview - ) -> typing.Tuple[ed25519.Ed25519PublicKey, memoryview]: + ) -> tuple[ed25519.Ed25519PublicKey, memoryview]: """Make Ed25519 public key from data.""" (point,), data = self.get_public(data) public_key = ed25519.Ed25519PublicKey.from_public_bytes( @@ -548,7 +534,7 @@ def load_public( def load_private( self, data: memoryview, pubfields - ) -> typing.Tuple[ed25519.Ed25519PrivateKey, memoryview]: + ) -> tuple[ed25519.Ed25519PrivateKey, memoryview]: """Make Ed25519 private key from data.""" (point,), data = self.get_public(data) keypair, data = _get_sshstr(data) @@ -615,7 +601,7 @@ def _lookup_kformat(key_type: bytes): def load_ssh_private_key( data: bytes, - password: typing.Optional[bytes], + password: bytes | None, backend: typing.Any = None, ) -> SSHPrivateKeyTypes: """Load private key from OpenSSH custom encoding.""" @@ -698,7 +684,8 @@ def load_ssh_private_key( if key_type != pub_key_type: raise ValueError("Corrupt data: key type mismatch") private_key, edata = kformat.load_private(edata, pubfields) - comment, edata = _get_sshstr(edata) + # We don't use the comment + _, edata = _get_sshstr(edata) # yes, SSH does padding check *after* all other parsing is done. # need to follow as it writes zero-byte padding too. @@ -820,11 +807,11 @@ def __init__( _serial: int, _cctype: int, _key_id: memoryview, - _valid_principals: typing.List[bytes], + _valid_principals: list[bytes], _valid_after: int, _valid_before: int, - _critical_options: typing.Dict[bytes, bytes], - _extensions: typing.Dict[bytes, bytes], + _critical_options: dict[bytes, bytes], + _extensions: dict[bytes, bytes], _sig_type: memoryview, _sig_key: memoryview, _inner_sig_type: memoryview, @@ -876,7 +863,7 @@ def key_id(self) -> bytes: return bytes(self._key_id) @property - def valid_principals(self) -> typing.List[bytes]: + def valid_principals(self) -> list[bytes]: return self._valid_principals @property @@ -888,11 +875,11 @@ def valid_after(self) -> int: return self._valid_after @property - def critical_options(self) -> typing.Dict[bytes, bytes]: + def critical_options(self) -> dict[bytes, bytes]: return self._critical_options @property - def extensions(self) -> typing.Dict[bytes, bytes]: + def extensions(self) -> dict[bytes, bytes]: return self._extensions def signature_key(self) -> SSHCertPublicKeyTypes: @@ -954,7 +941,7 @@ def _get_ec_hash_alg(curve: ec.EllipticCurve) -> hashes.HashAlgorithm: def _load_ssh_public_identity( data: bytes, _legacy_dsa_allowed=False, -) -> typing.Union[SSHCertificate, SSHPublicKeyTypes]: +) -> SSHCertificate | SSHPublicKeyTypes: utils._check_byteslike("data", data) m = _SSH_PUBKEY_RC.match(data) @@ -1048,12 +1035,12 @@ def _load_ssh_public_identity( def load_ssh_public_identity( data: bytes, -) -> typing.Union[SSHCertificate, SSHPublicKeyTypes]: +) -> SSHCertificate | SSHPublicKeyTypes: return _load_ssh_public_identity(data) -def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: - result: typing.Dict[bytes, bytes] = {} +def _parse_exts_opts(exts_opts: memoryview) -> dict[bytes, bytes]: + result: dict[bytes, bytes] = {} last_name = None while exts_opts: name, exts_opts = _get_sshstr(exts_opts) @@ -1063,6 +1050,10 @@ def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: if last_name is not None and bname < last_name: raise ValueError("Fields not lexically sorted") value, exts_opts = _get_sshstr(exts_opts) + if len(value) > 0: + value, extra = _get_sshstr(value) + if len(extra) > 0: + raise ValueError("Unexpected extra data after value") result[bname] = bytes(value) last_name = bname return result @@ -1123,16 +1114,16 @@ def serialize_ssh_public_key(public_key: SSHPublicKeyTypes) -> bytes: class SSHCertificateBuilder: def __init__( self, - _public_key: typing.Optional[SSHCertPublicKeyTypes] = None, - _serial: typing.Optional[int] = None, - _type: typing.Optional[SSHCertificateType] = None, - _key_id: typing.Optional[bytes] = None, - _valid_principals: typing.List[bytes] = [], + _public_key: SSHCertPublicKeyTypes | None = None, + _serial: int | None = None, + _type: SSHCertificateType | None = None, + _key_id: bytes | None = None, + _valid_principals: list[bytes] = [], _valid_for_all_principals: bool = False, - _valid_before: typing.Optional[int] = None, - _valid_after: typing.Optional[int] = None, - _critical_options: typing.List[typing.Tuple[bytes, bytes]] = [], - _extensions: typing.List[typing.Tuple[bytes, bytes]] = [], + _valid_before: int | None = None, + _valid_after: int | None = None, + _critical_options: list[tuple[bytes, bytes]] = [], + _extensions: list[tuple[bytes, bytes]] = [], ): self._public_key = _public_key self._serial = _serial @@ -1233,7 +1224,7 @@ def key_id(self, key_id: bytes) -> SSHCertificateBuilder: ) def valid_principals( - self, valid_principals: typing.List[bytes] + self, valid_principals: list[bytes] ) -> SSHCertificateBuilder: if self._valid_for_all_principals: raise ValueError( @@ -1290,9 +1281,7 @@ def valid_for_all_principals(self): _extensions=self._extensions, ) - def valid_before( - self, valid_before: typing.Union[int, float] - ) -> SSHCertificateBuilder: + def valid_before(self, valid_before: int | float) -> SSHCertificateBuilder: if not isinstance(valid_before, (int, float)): raise TypeError("valid_before must be an int or float") valid_before = int(valid_before) @@ -1314,9 +1303,7 @@ def valid_before( _extensions=self._extensions, ) - def valid_after( - self, valid_after: typing.Union[int, float] - ) -> SSHCertificateBuilder: + def valid_after(self, valid_after: int | float) -> SSHCertificateBuilder: if not isinstance(valid_after, (int, float)): raise TypeError("valid_after must be an int or float") valid_after = int(valid_after) @@ -1356,7 +1343,7 @@ def add_critical_option( _valid_for_all_principals=self._valid_for_all_principals, _valid_before=self._valid_before, _valid_after=self._valid_after, - _critical_options=self._critical_options + [(name, value)], + _critical_options=[*self._critical_options, (name, value)], _extensions=self._extensions, ) @@ -1379,7 +1366,7 @@ def add_extension( _valid_before=self._valid_before, _valid_after=self._valid_after, _critical_options=self._critical_options, - _extensions=self._extensions + [(name, value)], + _extensions=[*self._extensions, (name, value)], ) def sign(self, private_key: SSHCertPrivateKeyTypes) -> SSHCertificate: @@ -1450,12 +1437,22 @@ def sign(self, private_key: SSHCertPrivateKeyTypes) -> SSHCertificate: fcrit = _FragList() for name, value in self._critical_options: fcrit.put_sshstr(name) - fcrit.put_sshstr(value) + if len(value) > 0: + foptval = _FragList() + foptval.put_sshstr(value) + fcrit.put_sshstr(foptval.tobytes()) + else: + fcrit.put_sshstr(value) f.put_sshstr(fcrit.tobytes()) fext = _FragList() for name, value in self._extensions: fext.put_sshstr(name) - fext.put_sshstr(value) + if len(value) > 0: + fextval = _FragList() + fextval.put_sshstr(value) + fext.put_sshstr(fextval.tobytes()) + else: + fext.put_sshstr(value) f.put_sshstr(fext.tobytes()) f.put_sshstr(b"") # RESERVED FIELD # encode CA public key diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py index 2067108a..af5ab6ef 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py @@ -19,8 +19,8 @@ def _generate_uri( hotp: HOTP, type_name: str, account_name: str, - issuer: typing.Optional[str], - extra_parameters: typing.List[typing.Tuple[str, int]], + issuer: str | None, + extra_parameters: list[tuple[str, int]], ) -> str: parameters = [ ("digits", hotp._length), @@ -85,7 +85,7 @@ def _dynamic_truncate(self, counter: int) -> int: return int.from_bytes(p, byteorder="big") & 0x7FFFFFFF def get_provisioning_uri( - self, account_name: str, counter: int, issuer: typing.Optional[str] + self, account_name: str, counter: int, issuer: str | None ) -> str: return _generate_uri( self, "hotp", account_name, issuer, [("counter", int(counter))] diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py index daddcea2..68a50774 100644 --- a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py @@ -30,7 +30,7 @@ def __init__( key, length, algorithm, enforce_key_length=enforce_key_length ) - def generate(self, time: typing.Union[int, float]) -> bytes: + def generate(self, time: int | float) -> bytes: counter = int(time / self._time_step) return self._hotp.generate(counter) @@ -39,7 +39,7 @@ def verify(self, totp: bytes, time: int) -> None: raise InvalidToken("Supplied TOTP value does not match.") def get_provisioning_uri( - self, account_name: str, issuer: typing.Optional[str] + self, account_name: str, issuer: str | None ) -> str: return _generate_uri( self._hotp, diff --git a/dist/ba_data/python-site-packages/cryptography/utils.py b/dist/ba_data/python-site-packages/cryptography/utils.py index 71916816..a0ec7a3c 100644 --- a/dist/ba_data/python-site-packages/cryptography/utils.py +++ b/dist/ba_data/python-site-packages/cryptography/utils.py @@ -12,7 +12,7 @@ # We use a UserWarning subclass, instead of DeprecationWarning, because CPython -# decided deprecation warnings should be invisble by default. +# decided deprecation warnings should be invisible by default. class CryptographyDeprecationWarning(UserWarning): pass @@ -24,6 +24,7 @@ class CryptographyDeprecationWarning(UserWarning): DeprecatedIn37 = CryptographyDeprecationWarning DeprecatedIn40 = CryptographyDeprecationWarning DeprecatedIn41 = CryptographyDeprecationWarning +DeprecatedIn42 = CryptographyDeprecationWarning def _check_bytes(name: str, value: bytes) -> None: @@ -38,13 +39,13 @@ def _check_byteslike(name: str, value: bytes) -> None: raise TypeError(f"{name} must be bytes-like") -def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes: +def int_to_bytes(integer: int, length: int | None = None) -> bytes: return integer.to_bytes( length or (integer.bit_length() + 7) // 8 or 1, "big" ) -def _extract_buffer_length(obj: typing.Any) -> typing.Tuple[typing.Any, int]: +def _extract_buffer_length(obj: typing.Any) -> tuple[typing.Any, int]: from cryptography.hazmat.bindings._rust import _openssl buf = _openssl.ffi.from_buffer(obj) @@ -85,15 +86,15 @@ def __delattr__(self, attr: str) -> None: delattr(self._module, attr) def __dir__(self) -> typing.Sequence[str]: - return ["_module"] + dir(self._module) + return ["_module", *dir(self._module)] def deprecated( value: object, module_name: str, message: str, - warning_class: typing.Type[Warning], - name: typing.Optional[str] = None, + warning_class: type[Warning], + name: str | None = None, ) -> _DeprecatedValue: module = sys.modules[module_name] if not isinstance(module, _ModuleWithDeprecations): diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__init__.py b/dist/ba_data/python-site-packages/cryptography/x509/__init__.py index d77694a2..931618aa 100644 --- a/dist/ba_data/python-site-packages/cryptography/x509/__init__.py +++ b/dist/ba_data/python-site-packages/cryptography/x509/__init__.py @@ -4,7 +4,7 @@ from __future__ import annotations -from cryptography.x509 import certificate_transparency +from cryptography.x509 import certificate_transparency, verification from cryptography.x509.base import ( Attribute, AttributeNotFound, @@ -171,6 +171,7 @@ __all__ = [ "certificate_transparency", + "verification", "load_pem_x509_certificate", "load_pem_x509_certificates", "load_der_x509_certificate", @@ -179,6 +180,7 @@ "load_pem_x509_crl", "load_der_x509_crl", "random_serial_number", + "verification", "Attribute", "AttributeNotFound", "Attributes", diff --git a/dist/ba_data/python-site-packages/cryptography/x509/base.py b/dist/ba_data/python-site-packages/cryptography/x509/base.py index 576385e0..89a75a23 100644 --- a/dist/ba_data/python-site-packages/cryptography/x509/base.py +++ b/dist/ba_data/python-site-packages/cryptography/x509/base.py @@ -8,6 +8,7 @@ import datetime import os import typing +import warnings from cryptography import utils from cryptography.hazmat.bindings._rust import x509 as rust_x509 @@ -60,7 +61,7 @@ def __init__(self, msg: str, oid: ObjectIdentifier) -> None: def _reject_duplicate_extension( extension: Extension[ExtensionType], - extensions: typing.List[Extension[ExtensionType]], + extensions: list[Extension[ExtensionType]], ) -> None: # This is quadratic in the number of extensions for e in extensions: @@ -70,9 +71,7 @@ def _reject_duplicate_extension( def _reject_duplicate_attribute( oid: ObjectIdentifier, - attributes: typing.List[ - typing.Tuple[ObjectIdentifier, bytes, typing.Optional[int]] - ], + attributes: list[tuple[ObjectIdentifier, bytes, int | None]], ) -> None: # This is quadratic in the number of attributes for attr_oid, _, _ in attributes: @@ -195,6 +194,13 @@ def not_valid_before(self) -> datetime.datetime: Not before time (represented as UTC datetime) """ + @property + @abc.abstractmethod + def not_valid_before_utc(self) -> datetime.datetime: + """ + Not before time (represented as a non-naive UTC datetime) + """ + @property @abc.abstractmethod def not_valid_after(self) -> datetime.datetime: @@ -202,6 +208,13 @@ def not_valid_after(self) -> datetime.datetime: Not after time (represented as UTC datetime) """ + @property + @abc.abstractmethod + def not_valid_after_utc(self) -> datetime.datetime: + """ + Not after time (represented as a non-naive UTC datetime) + """ + @property @abc.abstractmethod def issuer(self) -> Name: @@ -220,7 +233,7 @@ def subject(self) -> Name: @abc.abstractmethod def signature_hash_algorithm( self, - ) -> typing.Optional[hashes.HashAlgorithm]: + ) -> hashes.HashAlgorithm | None: """ Returns a HashAlgorithm corresponding to the type of the digest signed in the certificate. @@ -237,7 +250,7 @@ def signature_algorithm_oid(self) -> ObjectIdentifier: @abc.abstractmethod def signature_algorithm_parameters( self, - ) -> typing.Union[None, padding.PSS, padding.PKCS1v15, ec.ECDSA]: + ) -> None | padding.PSS | padding.PKCS1v15 | ec.ECDSA: """ Returns the signature algorithm parameters. """ @@ -317,6 +330,14 @@ def revocation_date(self) -> datetime.datetime: Returns the date of when this certificate was revoked. """ + @property + @abc.abstractmethod + def revocation_date_utc(self) -> datetime.datetime: + """ + Returns the date of when this certificate was revoked as a non-naive + UTC datetime. + """ + @property @abc.abstractmethod def extensions(self) -> Extensions: @@ -346,8 +367,18 @@ def serial_number(self) -> int: @property def revocation_date(self) -> datetime.datetime: + warnings.warn( + "Properties that return a naïve datetime object have been " + "deprecated. Please switch to revocation_date_utc.", + utils.DeprecatedIn42, + stacklevel=2, + ) return self._revocation_date + @property + def revocation_date_utc(self) -> datetime.datetime: + return self._revocation_date.replace(tzinfo=datetime.timezone.utc) + @property def extensions(self) -> Extensions: return self._extensions @@ -369,7 +400,7 @@ def fingerprint(self, algorithm: hashes.HashAlgorithm) -> bytes: @abc.abstractmethod def get_revoked_certificate_by_serial_number( self, serial_number: int - ) -> typing.Optional[RevokedCertificate]: + ) -> RevokedCertificate | None: """ Returns an instance of RevokedCertificate or None if the serial_number is not in the CRL. @@ -379,7 +410,7 @@ def get_revoked_certificate_by_serial_number( @abc.abstractmethod def signature_hash_algorithm( self, - ) -> typing.Optional[hashes.HashAlgorithm]: + ) -> hashes.HashAlgorithm | None: """ Returns a HashAlgorithm corresponding to the type of the digest signed in the certificate. @@ -392,6 +423,15 @@ def signature_algorithm_oid(self) -> ObjectIdentifier: Returns the ObjectIdentifier of the signature algorithm. """ + @property + @abc.abstractmethod + def signature_algorithm_parameters( + self, + ) -> None | padding.PSS | padding.PKCS1v15 | ec.ECDSA: + """ + Returns the signature algorithm parameters. + """ + @property @abc.abstractmethod def issuer(self) -> Name: @@ -401,11 +441,19 @@ def issuer(self) -> Name: @property @abc.abstractmethod - def next_update(self) -> typing.Optional[datetime.datetime]: + def next_update(self) -> datetime.datetime | None: """ Returns the date of next update for this CRL. """ + @property + @abc.abstractmethod + def next_update_utc(self) -> datetime.datetime | None: + """ + Returns the date of next update for this CRL as a non-naive UTC + datetime. + """ + @property @abc.abstractmethod def last_update(self) -> datetime.datetime: @@ -413,6 +461,14 @@ def last_update(self) -> datetime.datetime: Returns the date of last update for this CRL. """ + @property + @abc.abstractmethod + def last_update_utc(self) -> datetime.datetime: + """ + Returns the date of last update for this CRL as a non-naive UTC + datetime. + """ + @property @abc.abstractmethod def extensions(self) -> Extensions: @@ -451,13 +507,13 @@ def __getitem__(self, idx: int) -> RevokedCertificate: ... @typing.overload - def __getitem__(self, idx: slice) -> typing.List[RevokedCertificate]: + def __getitem__(self, idx: slice) -> list[RevokedCertificate]: ... @abc.abstractmethod def __getitem__( - self, idx: typing.Union[int, slice] - ) -> typing.Union[RevokedCertificate, typing.List[RevokedCertificate]]: + self, idx: int | slice + ) -> RevokedCertificate | list[RevokedCertificate]: """ Returns a revoked certificate (or slice of revoked certificates). """ @@ -510,7 +566,7 @@ def subject(self) -> Name: @abc.abstractmethod def signature_hash_algorithm( self, - ) -> typing.Optional[hashes.HashAlgorithm]: + ) -> hashes.HashAlgorithm | None: """ Returns a HashAlgorithm corresponding to the type of the digest signed in the certificate. @@ -523,6 +579,15 @@ def signature_algorithm_oid(self) -> ObjectIdentifier: Returns the ObjectIdentifier of the signature algorithm. """ + @property + @abc.abstractmethod + def signature_algorithm_parameters( + self, + ) -> None | padding.PSS | padding.PKCS1v15 | ec.ECDSA: + """ + Returns the signature algorithm parameters. + """ + @property @abc.abstractmethod def extensions(self) -> Extensions: @@ -576,60 +641,24 @@ def get_attribute_for_oid(self, oid: ObjectIdentifier) -> bytes: CertificateSigningRequest.register(rust_x509.CertificateSigningRequest) -# Backend argument preserved for API compatibility, but ignored. -def load_pem_x509_certificate( - data: bytes, backend: typing.Any = None -) -> Certificate: - return rust_x509.load_pem_x509_certificate(data) - +load_pem_x509_certificate = rust_x509.load_pem_x509_certificate +load_der_x509_certificate = rust_x509.load_der_x509_certificate -def load_pem_x509_certificates(data: bytes) -> typing.List[Certificate]: - return rust_x509.load_pem_x509_certificates(data) +load_pem_x509_certificates = rust_x509.load_pem_x509_certificates +load_pem_x509_csr = rust_x509.load_pem_x509_csr +load_der_x509_csr = rust_x509.load_der_x509_csr -# Backend argument preserved for API compatibility, but ignored. -def load_der_x509_certificate( - data: bytes, backend: typing.Any = None -) -> Certificate: - return rust_x509.load_der_x509_certificate(data) - - -# Backend argument preserved for API compatibility, but ignored. -def load_pem_x509_csr( - data: bytes, backend: typing.Any = None -) -> CertificateSigningRequest: - return rust_x509.load_pem_x509_csr(data) - - -# Backend argument preserved for API compatibility, but ignored. -def load_der_x509_csr( - data: bytes, backend: typing.Any = None -) -> CertificateSigningRequest: - return rust_x509.load_der_x509_csr(data) - - -# Backend argument preserved for API compatibility, but ignored. -def load_pem_x509_crl( - data: bytes, backend: typing.Any = None -) -> CertificateRevocationList: - return rust_x509.load_pem_x509_crl(data) - - -# Backend argument preserved for API compatibility, but ignored. -def load_der_x509_crl( - data: bytes, backend: typing.Any = None -) -> CertificateRevocationList: - return rust_x509.load_der_x509_crl(data) +load_pem_x509_crl = rust_x509.load_pem_x509_crl +load_der_x509_crl = rust_x509.load_der_x509_crl class CertificateSigningRequestBuilder: def __init__( self, - subject_name: typing.Optional[Name] = None, - extensions: typing.List[Extension[ExtensionType]] = [], - attributes: typing.List[ - typing.Tuple[ObjectIdentifier, bytes, typing.Optional[int]] - ] = [], + subject_name: Name | None = None, + extensions: list[Extension[ExtensionType]] = [], + attributes: list[tuple[ObjectIdentifier, bytes, int | None]] = [], ): """ Creates an empty X.509 certificate request (v1). @@ -664,7 +693,7 @@ def add_extension( return CertificateSigningRequestBuilder( self._subject_name, - self._extensions + [extension], + [*self._extensions, extension], self._attributes, ) @@ -673,7 +702,7 @@ def add_attribute( oid: ObjectIdentifier, value: bytes, *, - _tag: typing.Optional[_ASN1Type] = None, + _tag: _ASN1Type | None = None, ) -> CertificateSigningRequestBuilder: """ Adds an X.509 attribute with an OID and associated value. @@ -697,35 +726,46 @@ def add_attribute( return CertificateSigningRequestBuilder( self._subject_name, self._extensions, - self._attributes + [(oid, value, tag)], + [*self._attributes, (oid, value, tag)], ) def sign( self, private_key: CertificateIssuerPrivateKeyTypes, - algorithm: typing.Optional[_AllowedHashTypes], + algorithm: _AllowedHashTypes | None, backend: typing.Any = None, + *, + rsa_padding: padding.PSS | padding.PKCS1v15 | None = None, ) -> CertificateSigningRequest: """ Signs the request using the requestor's private key. """ if self._subject_name is None: raise ValueError("A CertificateSigningRequest must have a subject") - return rust_x509.create_x509_csr(self, private_key, algorithm) + + if rsa_padding is not None: + if not isinstance(rsa_padding, (padding.PSS, padding.PKCS1v15)): + raise TypeError("Padding must be PSS or PKCS1v15") + if not isinstance(private_key, rsa.RSAPrivateKey): + raise TypeError("Padding is only supported for RSA keys") + + return rust_x509.create_x509_csr( + self, private_key, algorithm, rsa_padding + ) class CertificateBuilder: - _extensions: typing.List[Extension[ExtensionType]] + _extensions: list[Extension[ExtensionType]] def __init__( self, - issuer_name: typing.Optional[Name] = None, - subject_name: typing.Optional[Name] = None, - public_key: typing.Optional[CertificatePublicKeyTypes] = None, - serial_number: typing.Optional[int] = None, - not_valid_before: typing.Optional[datetime.datetime] = None, - not_valid_after: typing.Optional[datetime.datetime] = None, - extensions: typing.List[Extension[ExtensionType]] = [], + issuer_name: Name | None = None, + subject_name: Name | None = None, + public_key: CertificatePublicKeyTypes | None = None, + serial_number: int | None = None, + not_valid_before: datetime.datetime | None = None, + not_valid_after: datetime.datetime | None = None, + extensions: list[Extension[ExtensionType]] = [], ) -> None: self._version = Version.v3 self._issuer_name = issuer_name @@ -916,18 +956,16 @@ def add_extension( self._serial_number, self._not_valid_before, self._not_valid_after, - self._extensions + [extension], + [*self._extensions, extension], ) def sign( self, private_key: CertificateIssuerPrivateKeyTypes, - algorithm: typing.Optional[_AllowedHashTypes], + algorithm: _AllowedHashTypes | None, backend: typing.Any = None, *, - rsa_padding: typing.Optional[ - typing.Union[padding.PSS, padding.PKCS1v15] - ] = None, + rsa_padding: padding.PSS | padding.PKCS1v15 | None = None, ) -> Certificate: """ Signs the certificate using the CA's private key. @@ -962,16 +1000,16 @@ def sign( class CertificateRevocationListBuilder: - _extensions: typing.List[Extension[ExtensionType]] - _revoked_certificates: typing.List[RevokedCertificate] + _extensions: list[Extension[ExtensionType]] + _revoked_certificates: list[RevokedCertificate] def __init__( self, - issuer_name: typing.Optional[Name] = None, - last_update: typing.Optional[datetime.datetime] = None, - next_update: typing.Optional[datetime.datetime] = None, - extensions: typing.List[Extension[ExtensionType]] = [], - revoked_certificates: typing.List[RevokedCertificate] = [], + issuer_name: Name | None = None, + last_update: datetime.datetime | None = None, + next_update: datetime.datetime | None = None, + extensions: list[Extension[ExtensionType]] = [], + revoked_certificates: list[RevokedCertificate] = [], ): self._issuer_name = issuer_name self._last_update = last_update @@ -1057,7 +1095,7 @@ def add_extension( self._issuer_name, self._last_update, self._next_update, - self._extensions + [extension], + [*self._extensions, extension], self._revoked_certificates, ) @@ -1075,14 +1113,16 @@ def add_revoked_certificate( self._last_update, self._next_update, self._extensions, - self._revoked_certificates + [revoked_certificate], + [*self._revoked_certificates, revoked_certificate], ) def sign( self, private_key: CertificateIssuerPrivateKeyTypes, - algorithm: typing.Optional[_AllowedHashTypes], + algorithm: _AllowedHashTypes | None, backend: typing.Any = None, + *, + rsa_padding: padding.PSS | padding.PKCS1v15 | None = None, ) -> CertificateRevocationList: if self._issuer_name is None: raise ValueError("A CRL must have an issuer name") @@ -1093,15 +1133,23 @@ def sign( if self._next_update is None: raise ValueError("A CRL must have a next update time") - return rust_x509.create_x509_crl(self, private_key, algorithm) + if rsa_padding is not None: + if not isinstance(rsa_padding, (padding.PSS, padding.PKCS1v15)): + raise TypeError("Padding must be PSS or PKCS1v15") + if not isinstance(private_key, rsa.RSAPrivateKey): + raise TypeError("Padding is only supported for RSA keys") + + return rust_x509.create_x509_crl( + self, private_key, algorithm, rsa_padding + ) class RevokedCertificateBuilder: def __init__( self, - serial_number: typing.Optional[int] = None, - revocation_date: typing.Optional[datetime.datetime] = None, - extensions: typing.List[Extension[ExtensionType]] = [], + serial_number: int | None = None, + revocation_date: datetime.datetime | None = None, + extensions: list[Extension[ExtensionType]] = [], ): self._serial_number = serial_number self._revocation_date = revocation_date @@ -1152,7 +1200,7 @@ def add_extension( return RevokedCertificateBuilder( self._serial_number, self._revocation_date, - self._extensions + [extension], + [*self._extensions, extension], ) def build(self, backend: typing.Any = None) -> RevokedCertificate: diff --git a/dist/ba_data/python-site-packages/cryptography/x509/extensions.py b/dist/ba_data/python-site-packages/cryptography/x509/extensions.py index ac99592f..c61c1f48 100644 --- a/dist/ba_data/python-site-packages/cryptography/x509/extensions.py +++ b/dist/ba_data/python-site-packages/cryptography/x509/extensions.py @@ -104,9 +104,7 @@ def public_bytes(self) -> bytes: Serializes the extension type to DER. """ raise NotImplementedError( - "public_bytes is not implemented for extension type {!r}".format( - self - ) + f"public_bytes is not implemented for extension type {self!r}" ) @@ -126,7 +124,7 @@ def get_extension_for_oid( raise ExtensionNotFound(f"No {oid} extension was found", oid) def get_extension_for_class( - self, extclass: typing.Type[ExtensionTypeVar] + self, extclass: type[ExtensionTypeVar] ) -> Extension[ExtensionTypeVar]: if extclass is UnrecognizedExtension: raise TypeError( @@ -183,9 +181,9 @@ class AuthorityKeyIdentifier(ExtensionType): def __init__( self, - key_identifier: typing.Optional[bytes], - authority_cert_issuer: typing.Optional[typing.Iterable[GeneralName]], - authority_cert_serial_number: typing.Optional[int], + key_identifier: bytes | None, + authority_cert_issuer: typing.Iterable[GeneralName] | None, + authority_cert_serial_number: int | None, ) -> None: if (authority_cert_issuer is None) != ( authority_cert_serial_number is None @@ -242,10 +240,10 @@ def from_issuer_subject_key_identifier( def __repr__(self) -> str: return ( - "".format(self) + f"" ) def __eq__(self, other: object) -> bool: @@ -269,17 +267,17 @@ def __hash__(self) -> int: ) @property - def key_identifier(self) -> typing.Optional[bytes]: + def key_identifier(self) -> bytes | None: return self._key_identifier @property def authority_cert_issuer( self, - ) -> typing.Optional[typing.List[GeneralName]]: + ) -> list[GeneralName] | None: return self._authority_cert_issuer @property - def authority_cert_serial_number(self) -> typing.Optional[int]: + def authority_cert_serial_number(self) -> int | None: return self._authority_cert_serial_number def public_bytes(self) -> bytes: @@ -431,7 +429,7 @@ def access_location(self) -> GeneralName: class BasicConstraints(ExtensionType): oid = ExtensionOID.BASIC_CONSTRAINTS - def __init__(self, ca: bool, path_length: typing.Optional[int]) -> None: + def __init__(self, ca: bool, path_length: int | None) -> None: if not isinstance(ca, bool): raise TypeError("ca must be a boolean value") @@ -453,7 +451,7 @@ def ca(self) -> bool: return self._ca @property - def path_length(self) -> typing.Optional[int]: + def path_length(self) -> int | None: return self._path_length def __repr__(self) -> str: @@ -580,10 +578,10 @@ def public_bytes(self) -> bytes: class DistributionPoint: def __init__( self, - full_name: typing.Optional[typing.Iterable[GeneralName]], - relative_name: typing.Optional[RelativeDistinguishedName], - reasons: typing.Optional[typing.FrozenSet[ReasonFlags]], - crl_issuer: typing.Optional[typing.Iterable[GeneralName]], + full_name: typing.Iterable[GeneralName] | None, + relative_name: RelativeDistinguishedName | None, + reasons: frozenset[ReasonFlags] | None, + crl_issuer: typing.Iterable[GeneralName] | None, ) -> None: if full_name and relative_name: raise ValueError( @@ -656,35 +654,31 @@ def __eq__(self, other: object) -> bool: def __hash__(self) -> int: if self.full_name is not None: - fn: typing.Optional[typing.Tuple[GeneralName, ...]] = tuple( - self.full_name - ) + fn: tuple[GeneralName, ...] | None = tuple(self.full_name) else: fn = None if self.crl_issuer is not None: - crl_issuer: typing.Optional[ - typing.Tuple[GeneralName, ...] - ] = tuple(self.crl_issuer) + crl_issuer: tuple[GeneralName, ...] | None = tuple(self.crl_issuer) else: crl_issuer = None return hash((fn, self.relative_name, self.reasons, crl_issuer)) @property - def full_name(self) -> typing.Optional[typing.List[GeneralName]]: + def full_name(self) -> list[GeneralName] | None: return self._full_name @property - def relative_name(self) -> typing.Optional[RelativeDistinguishedName]: + def relative_name(self) -> RelativeDistinguishedName | None: return self._relative_name @property - def reasons(self) -> typing.Optional[typing.FrozenSet[ReasonFlags]]: + def reasons(self) -> frozenset[ReasonFlags] | None: return self._reasons @property - def crl_issuer(self) -> typing.Optional[typing.List[GeneralName]]: + def crl_issuer(self) -> list[GeneralName] | None: return self._crl_issuer @@ -741,8 +735,8 @@ class PolicyConstraints(ExtensionType): def __init__( self, - require_explicit_policy: typing.Optional[int], - inhibit_policy_mapping: typing.Optional[int], + require_explicit_policy: int | None, + inhibit_policy_mapping: int | None, ) -> None: if require_explicit_policy is not None and not isinstance( require_explicit_policy, int @@ -790,11 +784,11 @@ def __hash__(self) -> int: ) @property - def require_explicit_policy(self) -> typing.Optional[int]: + def require_explicit_policy(self) -> int | None: return self._require_explicit_policy @property - def inhibit_policy_mapping(self) -> typing.Optional[int]: + def inhibit_policy_mapping(self) -> int | None: return self._inhibit_policy_mapping def public_bytes(self) -> bytes: @@ -836,9 +830,7 @@ class PolicyInformation: def __init__( self, policy_identifier: ObjectIdentifier, - policy_qualifiers: typing.Optional[ - typing.Iterable[typing.Union[str, UserNotice]] - ], + policy_qualifiers: typing.Iterable[str | UserNotice] | None, ) -> None: if not isinstance(policy_identifier, ObjectIdentifier): raise TypeError("policy_identifier must be an ObjectIdentifier") @@ -874,9 +866,9 @@ def __eq__(self, other: object) -> bool: def __hash__(self) -> int: if self.policy_qualifiers is not None: - pq: typing.Optional[ - typing.Tuple[typing.Union[str, UserNotice], ...] - ] = tuple(self.policy_qualifiers) + pq: tuple[str | UserNotice, ...] | None = tuple( + self.policy_qualifiers + ) else: pq = None @@ -889,15 +881,15 @@ def policy_identifier(self) -> ObjectIdentifier: @property def policy_qualifiers( self, - ) -> typing.Optional[typing.List[typing.Union[str, UserNotice]]]: + ) -> list[str | UserNotice] | None: return self._policy_qualifiers class UserNotice: def __init__( self, - notice_reference: typing.Optional[NoticeReference], - explicit_text: typing.Optional[str], + notice_reference: NoticeReference | None, + explicit_text: str | None, ) -> None: if notice_reference and not isinstance( notice_reference, NoticeReference @@ -928,18 +920,18 @@ def __hash__(self) -> int: return hash((self.notice_reference, self.explicit_text)) @property - def notice_reference(self) -> typing.Optional[NoticeReference]: + def notice_reference(self) -> NoticeReference | None: return self._notice_reference @property - def explicit_text(self) -> typing.Optional[str]: + def explicit_text(self) -> str | None: return self._explicit_text class NoticeReference: def __init__( self, - organization: typing.Optional[str], + organization: str | None, notice_numbers: typing.Iterable[int], ) -> None: self._organization = organization @@ -968,11 +960,11 @@ def __hash__(self) -> int: return hash((self.organization, tuple(self.notice_numbers))) @property - def organization(self) -> typing.Optional[str]: + def organization(self) -> str | None: return self._organization @property - def notice_numbers(self) -> typing.List[int]: + def notice_numbers(self) -> list[int]: return self._notice_numbers @@ -1213,14 +1205,14 @@ def __repr__(self) -> str: decipher_only = False return ( - "" - ).format(self, encipher_only, decipher_only) + f"" + ) def __eq__(self, other: object) -> bool: if not isinstance(other, KeyUsage): @@ -1262,8 +1254,8 @@ class NameConstraints(ExtensionType): def __init__( self, - permitted_subtrees: typing.Optional[typing.Iterable[GeneralName]], - excluded_subtrees: typing.Optional[typing.Iterable[GeneralName]], + permitted_subtrees: typing.Iterable[GeneralName] | None, + excluded_subtrees: typing.Iterable[GeneralName] | None, ) -> None: if permitted_subtrees is not None: permitted_subtrees = list(permitted_subtrees) @@ -1339,22 +1331,18 @@ def _validate_dns_name(self, tree: typing.Iterable[GeneralName]) -> None: def __repr__(self) -> str: return ( - "".format(self) + f"" ) def __hash__(self) -> int: if self.permitted_subtrees is not None: - ps: typing.Optional[typing.Tuple[GeneralName, ...]] = tuple( - self.permitted_subtrees - ) + ps: tuple[GeneralName, ...] | None = tuple(self.permitted_subtrees) else: ps = None if self.excluded_subtrees is not None: - es: typing.Optional[typing.Tuple[GeneralName, ...]] = tuple( - self.excluded_subtrees - ) + es: tuple[GeneralName, ...] | None = tuple(self.excluded_subtrees) else: es = None @@ -1363,13 +1351,13 @@ def __hash__(self) -> int: @property def permitted_subtrees( self, - ) -> typing.Optional[typing.List[GeneralName]]: + ) -> list[GeneralName] | None: return self._permitted_subtrees @property def excluded_subtrees( self, - ) -> typing.Optional[typing.List[GeneralName]]: + ) -> list[GeneralName] | None: return self._excluded_subtrees def public_bytes(self) -> bytes: @@ -1406,9 +1394,9 @@ def value(self) -> ExtensionTypeVar: def __repr__(self) -> str: return ( - "" - ).format(self) + f"" + ) def __eq__(self, other: object) -> bool: if not isinstance(other, Extension): @@ -1440,58 +1428,52 @@ def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: @typing.overload def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[UniformResourceIdentifier], - typing.Type[RFC822Name], - ], - ) -> typing.List[str]: + type: type[DNSName] + | type[UniformResourceIdentifier] + | type[RFC822Name], + ) -> list[str]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[DirectoryName], - ) -> typing.List[Name]: + type: type[DirectoryName], + ) -> list[Name]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[RegisteredID], - ) -> typing.List[ObjectIdentifier]: + type: type[RegisteredID], + ) -> list[ObjectIdentifier]: ... @typing.overload def get_values_for_type( - self, type: typing.Type[IPAddress] - ) -> typing.List[_IPAddressTypes]: + self, type: type[IPAddress] + ) -> list[_IPAddressTypes]: ... @typing.overload - def get_values_for_type( - self, type: typing.Type[OtherName] - ) -> typing.List[OtherName]: + def get_values_for_type(self, type: type[OtherName]) -> list[OtherName]: ... def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[DirectoryName], - typing.Type[IPAddress], - typing.Type[OtherName], - typing.Type[RFC822Name], - typing.Type[RegisteredID], - typing.Type[UniformResourceIdentifier], - ], - ) -> typing.Union[ - typing.List[_IPAddressTypes], - typing.List[str], - typing.List[OtherName], - typing.List[Name], - typing.List[ObjectIdentifier], - ]: + type: type[DNSName] + | type[DirectoryName] + | type[IPAddress] + | type[OtherName] + | type[RFC822Name] + | type[RegisteredID] + | type[UniformResourceIdentifier], + ) -> ( + list[_IPAddressTypes] + | list[str] + | list[OtherName] + | list[Name] + | list[ObjectIdentifier] + ): # Return the value of each GeneralName, except for OtherName instances # which we return directly because it has two important properties not # just one value. @@ -1524,58 +1506,52 @@ def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: @typing.overload def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[UniformResourceIdentifier], - typing.Type[RFC822Name], - ], - ) -> typing.List[str]: + type: type[DNSName] + | type[UniformResourceIdentifier] + | type[RFC822Name], + ) -> list[str]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[DirectoryName], - ) -> typing.List[Name]: + type: type[DirectoryName], + ) -> list[Name]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[RegisteredID], - ) -> typing.List[ObjectIdentifier]: + type: type[RegisteredID], + ) -> list[ObjectIdentifier]: ... @typing.overload def get_values_for_type( - self, type: typing.Type[IPAddress] - ) -> typing.List[_IPAddressTypes]: + self, type: type[IPAddress] + ) -> list[_IPAddressTypes]: ... @typing.overload - def get_values_for_type( - self, type: typing.Type[OtherName] - ) -> typing.List[OtherName]: + def get_values_for_type(self, type: type[OtherName]) -> list[OtherName]: ... def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[DirectoryName], - typing.Type[IPAddress], - typing.Type[OtherName], - typing.Type[RFC822Name], - typing.Type[RegisteredID], - typing.Type[UniformResourceIdentifier], - ], - ) -> typing.Union[ - typing.List[_IPAddressTypes], - typing.List[str], - typing.List[OtherName], - typing.List[Name], - typing.List[ObjectIdentifier], - ]: + type: type[DNSName] + | type[DirectoryName] + | type[IPAddress] + | type[OtherName] + | type[RFC822Name] + | type[RegisteredID] + | type[UniformResourceIdentifier], + ) -> ( + list[_IPAddressTypes] + | list[str] + | list[OtherName] + | list[Name] + | list[ObjectIdentifier] + ): return self._general_names.get_values_for_type(type) def __repr__(self) -> str: @@ -1605,58 +1581,52 @@ def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: @typing.overload def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[UniformResourceIdentifier], - typing.Type[RFC822Name], - ], - ) -> typing.List[str]: + type: type[DNSName] + | type[UniformResourceIdentifier] + | type[RFC822Name], + ) -> list[str]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[DirectoryName], - ) -> typing.List[Name]: + type: type[DirectoryName], + ) -> list[Name]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[RegisteredID], - ) -> typing.List[ObjectIdentifier]: + type: type[RegisteredID], + ) -> list[ObjectIdentifier]: ... @typing.overload def get_values_for_type( - self, type: typing.Type[IPAddress] - ) -> typing.List[_IPAddressTypes]: + self, type: type[IPAddress] + ) -> list[_IPAddressTypes]: ... @typing.overload - def get_values_for_type( - self, type: typing.Type[OtherName] - ) -> typing.List[OtherName]: + def get_values_for_type(self, type: type[OtherName]) -> list[OtherName]: ... def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[DirectoryName], - typing.Type[IPAddress], - typing.Type[OtherName], - typing.Type[RFC822Name], - typing.Type[RegisteredID], - typing.Type[UniformResourceIdentifier], - ], - ) -> typing.Union[ - typing.List[_IPAddressTypes], - typing.List[str], - typing.List[OtherName], - typing.List[Name], - typing.List[ObjectIdentifier], - ]: + type: type[DNSName] + | type[DirectoryName] + | type[IPAddress] + | type[OtherName] + | type[RFC822Name] + | type[RegisteredID] + | type[UniformResourceIdentifier], + ) -> ( + list[_IPAddressTypes] + | list[str] + | list[OtherName] + | list[Name] + | list[ObjectIdentifier] + ): return self._general_names.get_values_for_type(type) def __repr__(self) -> str: @@ -1686,58 +1656,52 @@ def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: @typing.overload def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[UniformResourceIdentifier], - typing.Type[RFC822Name], - ], - ) -> typing.List[str]: + type: type[DNSName] + | type[UniformResourceIdentifier] + | type[RFC822Name], + ) -> list[str]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[DirectoryName], - ) -> typing.List[Name]: + type: type[DirectoryName], + ) -> list[Name]: ... @typing.overload def get_values_for_type( self, - type: typing.Type[RegisteredID], - ) -> typing.List[ObjectIdentifier]: + type: type[RegisteredID], + ) -> list[ObjectIdentifier]: ... @typing.overload def get_values_for_type( - self, type: typing.Type[IPAddress] - ) -> typing.List[_IPAddressTypes]: + self, type: type[IPAddress] + ) -> list[_IPAddressTypes]: ... @typing.overload - def get_values_for_type( - self, type: typing.Type[OtherName] - ) -> typing.List[OtherName]: + def get_values_for_type(self, type: type[OtherName]) -> list[OtherName]: ... def get_values_for_type( self, - type: typing.Union[ - typing.Type[DNSName], - typing.Type[DirectoryName], - typing.Type[IPAddress], - typing.Type[OtherName], - typing.Type[RFC822Name], - typing.Type[RegisteredID], - typing.Type[UniformResourceIdentifier], - ], - ) -> typing.Union[ - typing.List[_IPAddressTypes], - typing.List[str], - typing.List[OtherName], - typing.List[Name], - typing.List[ObjectIdentifier], - ]: + type: type[DNSName] + | type[DirectoryName] + | type[IPAddress] + | type[OtherName] + | type[RFC822Name] + | type[RegisteredID] + | type[UniformResourceIdentifier], + ) -> ( + list[_IPAddressTypes] + | list[str] + | list[OtherName] + | list[Name] + | list[ObjectIdentifier] + ): return self._general_names.get_values_for_type(type) def __repr__(self) -> str: @@ -1795,9 +1759,7 @@ def __init__(self, invalidity_date: datetime.datetime) -> None: self._invalidity_date = invalidity_date def __repr__(self) -> str: - return "".format( - self._invalidity_date - ) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, InvalidityDate): @@ -1841,9 +1803,7 @@ def __init__( ) def __repr__(self) -> str: - return "".format( - list(self) - ) + return f"" def __hash__(self) -> int: return hash(tuple(self._signed_certificate_timestamps)) @@ -1967,11 +1927,11 @@ class IssuingDistributionPoint(ExtensionType): def __init__( self, - full_name: typing.Optional[typing.Iterable[GeneralName]], - relative_name: typing.Optional[RelativeDistinguishedName], + full_name: typing.Iterable[GeneralName] | None, + relative_name: RelativeDistinguishedName | None, only_contains_user_certs: bool, only_contains_ca_certs: bool, - only_some_reasons: typing.Optional[typing.FrozenSet[ReasonFlags]], + only_some_reasons: frozenset[ReasonFlags] | None, indirect_crl: bool, only_contains_attribute_certs: bool, ) -> None: @@ -2050,14 +2010,14 @@ def __init__( def __repr__(self) -> str: return ( - "".format(self) + f"{self.only_contains_attribute_certs})>" ) def __eq__(self, other: object) -> bool: @@ -2089,11 +2049,11 @@ def __hash__(self) -> int: ) @property - def full_name(self) -> typing.Optional[typing.List[GeneralName]]: + def full_name(self) -> list[GeneralName] | None: return self._full_name @property - def relative_name(self) -> typing.Optional[RelativeDistinguishedName]: + def relative_name(self) -> RelativeDistinguishedName | None: return self._relative_name @property @@ -2107,7 +2067,7 @@ def only_contains_ca_certs(self) -> bool: @property def only_some_reasons( self, - ) -> typing.Optional[typing.FrozenSet[ReasonFlags]]: + ) -> frozenset[ReasonFlags] | None: return self._only_some_reasons @property @@ -2128,8 +2088,8 @@ class MSCertificateTemplate(ExtensionType): def __init__( self, template_id: ObjectIdentifier, - major_version: typing.Optional[int], - minor_version: typing.Optional[int], + major_version: int | None, + minor_version: int | None, ) -> None: if not isinstance(template_id, ObjectIdentifier): raise TypeError("oid must be an ObjectIdentifier") @@ -2150,11 +2110,11 @@ def template_id(self) -> ObjectIdentifier: return self._template_id @property - def major_version(self) -> typing.Optional[int]: + def major_version(self) -> int | None: return self._major_version @property - def minor_version(self) -> typing.Optional[int]: + def minor_version(self) -> int | None: return self._minor_version def __repr__(self) -> str: @@ -2198,8 +2158,8 @@ def value(self) -> bytes: def __repr__(self) -> str: return ( - "".format(self) + f"" ) def __eq__(self, other: object) -> bool: diff --git a/dist/ba_data/python-site-packages/cryptography/x509/general_name.py b/dist/ba_data/python-site-packages/cryptography/x509/general_name.py index 79271afb..672f2875 100644 --- a/dist/ba_data/python-site-packages/cryptography/x509/general_name.py +++ b/dist/ba_data/python-site-packages/cryptography/x509/general_name.py @@ -269,9 +269,7 @@ def value(self) -> bytes: return self._value def __repr__(self) -> str: - return "".format( - self.type_id, self.value - ) + return f"" def __eq__(self, other: object) -> bool: if not isinstance(other, OtherName): diff --git a/dist/ba_data/python-site-packages/cryptography/x509/name.py b/dist/ba_data/python-site-packages/cryptography/x509/name.py index ff98e872..5e8ccfff 100644 --- a/dist/ba_data/python-site-packages/cryptography/x509/name.py +++ b/dist/ba_data/python-site-packages/cryptography/x509/name.py @@ -31,7 +31,7 @@ class _ASN1Type(utils.Enum): _ASN1_TYPE_TO_ENUM = {i.value: i for i in _ASN1Type} -_NAMEOID_DEFAULT_TYPE: typing.Dict[ObjectIdentifier, _ASN1Type] = { +_NAMEOID_DEFAULT_TYPE: dict[ObjectIdentifier, _ASN1Type] = { NameOID.COUNTRY_NAME: _ASN1Type.PrintableString, NameOID.JURISDICTION_COUNTRY_NAME: _ASN1Type.PrintableString, NameOID.SERIAL_NUMBER: _ASN1Type.PrintableString, @@ -60,7 +60,7 @@ class _ASN1Type(utils.Enum): _NAME_TO_NAMEOID = {v: k for k, v in _NAMEOID_TO_NAME.items()} -def _escape_dn_value(val: typing.Union[str, bytes]) -> str: +def _escape_dn_value(val: str | bytes) -> str: """Escape special characters in RFC4514 Distinguished Name value.""" if not val: @@ -112,8 +112,8 @@ class NameAttribute: def __init__( self, oid: ObjectIdentifier, - value: typing.Union[str, bytes], - _type: typing.Optional[_ASN1Type] = None, + value: str | bytes, + _type: _ASN1Type | None = None, *, _validate: bool = True, ) -> None: @@ -132,10 +132,7 @@ def __init__( if not isinstance(value, str): raise TypeError("value argument must be a str") - if ( - oid == NameOID.COUNTRY_NAME - or oid == NameOID.JURISDICTION_COUNTRY_NAME - ): + if oid in (NameOID.COUNTRY_NAME, NameOID.JURISDICTION_COUNTRY_NAME): assert isinstance(value, str) c_len = len(value.encode("utf8")) if c_len != 2 and _validate is True: @@ -145,7 +142,7 @@ def __init__( elif c_len != 2: warnings.warn( "Country names should be two characters, but the " - "attribute is {} characters in length.".format(c_len), + f"attribute is {c_len} characters in length.", stacklevel=2, ) @@ -170,7 +167,7 @@ def oid(self) -> ObjectIdentifier: return self._oid @property - def value(self) -> typing.Union[str, bytes]: + def value(self) -> str | bytes: return self._value @property @@ -182,7 +179,7 @@ def rfc4514_attribute_name(self) -> str: return _NAMEOID_TO_NAME.get(self.oid, self.oid.dotted_string) def rfc4514_string( - self, attr_name_overrides: typing.Optional[_OidNameMap] = None + self, attr_name_overrides: _OidNameMap | None = None ) -> str: """ Format as RFC4514 Distinguished Name string. @@ -208,7 +205,7 @@ def __hash__(self) -> int: return hash((self.oid, self.value)) def __repr__(self) -> str: - return "".format(self) + return f"" class RelativeDistinguishedName: @@ -228,11 +225,11 @@ def __init__(self, attributes: typing.Iterable[NameAttribute]): def get_attributes_for_oid( self, oid: ObjectIdentifier - ) -> typing.List[NameAttribute]: + ) -> list[NameAttribute]: return [i for i in self if i.oid == oid] def rfc4514_string( - self, attr_name_overrides: typing.Optional[_OidNameMap] = None + self, attr_name_overrides: _OidNameMap | None = None ) -> str: """ Format as RFC4514 Distinguished Name string. @@ -277,9 +274,7 @@ def __init__( def __init__( self, - attributes: typing.Iterable[ - typing.Union[NameAttribute, RelativeDistinguishedName] - ], + attributes: typing.Iterable[NameAttribute | RelativeDistinguishedName], ) -> None: attributes = list(attributes) if all(isinstance(x, NameAttribute) for x in attributes): @@ -301,12 +296,12 @@ def __init__( def from_rfc4514_string( cls, data: str, - attr_name_overrides: typing.Optional[_NameOidMap] = None, + attr_name_overrides: _NameOidMap | None = None, ) -> Name: return _RFC4514NameParser(data, attr_name_overrides or {}).parse() def rfc4514_string( - self, attr_name_overrides: typing.Optional[_OidNameMap] = None + self, attr_name_overrides: _OidNameMap | None = None ) -> str: """ Format as RFC4514 Distinguished Name string. @@ -325,11 +320,11 @@ def rfc4514_string( def get_attributes_for_oid( self, oid: ObjectIdentifier - ) -> typing.List[NameAttribute]: + ) -> list[NameAttribute]: return [i for i in self if i.oid == oid] @property - def rdns(self) -> typing.List[RelativeDistinguishedName]: + def rdns(self) -> list[RelativeDistinguishedName]: return self._attributes def public_bytes(self, backend: typing.Any = None) -> bytes: @@ -348,8 +343,7 @@ def __hash__(self) -> int: def __iter__(self) -> typing.Iterator[NameAttribute]: for rdn in self._attributes: - for ava in rdn: - yield ava + yield from rdn def __len__(self) -> int: return sum(len(rdn) for rdn in self._attributes) @@ -395,7 +389,7 @@ def __init__(self, data: str, attr_name_overrides: _NameOidMap) -> None: def _has_data(self) -> bool: return self._idx < len(self._data) - def _peek(self) -> typing.Optional[str]: + def _peek(self) -> str | None: if self._has_data(): return self._data[self._idx] return None diff --git a/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py b/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py index 7054795f..9751ceaf 100644 --- a/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py +++ b/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py @@ -65,9 +65,9 @@ def __init__( algorithm: hashes.HashAlgorithm, cert_status: OCSPCertStatus, this_update: datetime.datetime, - next_update: typing.Optional[datetime.datetime], - revocation_time: typing.Optional[datetime.datetime], - revocation_reason: typing.Optional[x509.ReasonFlags], + next_update: datetime.datetime | None, + revocation_time: datetime.datetime | None, + revocation_reason: x509.ReasonFlags | None, ): if not isinstance(cert, x509.Certificate) or not isinstance( issuer, x509.Certificate @@ -180,7 +180,7 @@ def certificate_status(self) -> OCSPCertStatus: @property @abc.abstractmethod - def revocation_time(self) -> typing.Optional[datetime.datetime]: + def revocation_time(self) -> datetime.datetime | None: """ The date of when the certificate was revoked or None if not revoked. @@ -188,7 +188,7 @@ def revocation_time(self) -> typing.Optional[datetime.datetime]: @property @abc.abstractmethod - def revocation_reason(self) -> typing.Optional[x509.ReasonFlags]: + def revocation_reason(self) -> x509.ReasonFlags | None: """ The reason the certificate was revoked or None if not specified or not revoked. @@ -204,7 +204,7 @@ def this_update(self) -> datetime.datetime: @property @abc.abstractmethod - def next_update(self) -> typing.Optional[datetime.datetime]: + def next_update(self) -> datetime.datetime | None: """ The time when newer information will be available """ @@ -266,7 +266,7 @@ def signature_algorithm_oid(self) -> x509.ObjectIdentifier: @abc.abstractmethod def signature_hash_algorithm( self, - ) -> typing.Optional[hashes.HashAlgorithm]: + ) -> hashes.HashAlgorithm | None: """ Returns a HashAlgorithm corresponding to the type of the digest signed """ @@ -287,7 +287,7 @@ def tbs_response_bytes(self) -> bytes: @property @abc.abstractmethod - def certificates(self) -> typing.List[x509.Certificate]: + def certificates(self) -> list[x509.Certificate]: """ A list of certificates used to help build a chain to verify the OCSP response. This situation occurs when the OCSP responder uses a delegate @@ -296,14 +296,14 @@ def certificates(self) -> typing.List[x509.Certificate]: @property @abc.abstractmethod - def responder_key_hash(self) -> typing.Optional[bytes]: + def responder_key_hash(self) -> bytes | None: """ The responder's key hash or None """ @property @abc.abstractmethod - def responder_name(self) -> typing.Optional[x509.Name]: + def responder_name(self) -> x509.Name | None: """ The responder's Name or None """ @@ -324,7 +324,7 @@ def certificate_status(self) -> OCSPCertStatus: @property @abc.abstractmethod - def revocation_time(self) -> typing.Optional[datetime.datetime]: + def revocation_time(self) -> datetime.datetime | None: """ The date of when the certificate was revoked or None if not revoked. @@ -332,7 +332,7 @@ def revocation_time(self) -> typing.Optional[datetime.datetime]: @property @abc.abstractmethod - def revocation_reason(self) -> typing.Optional[x509.ReasonFlags]: + def revocation_reason(self) -> x509.ReasonFlags | None: """ The reason the certificate was revoked or None if not specified or not revoked. @@ -348,7 +348,7 @@ def this_update(self) -> datetime.datetime: @property @abc.abstractmethod - def next_update(self) -> typing.Optional[datetime.datetime]: + def next_update(self) -> datetime.datetime | None: """ The time when newer information will be available """ @@ -405,15 +405,13 @@ def public_bytes(self, encoding: serialization.Encoding) -> bytes: class OCSPRequestBuilder: def __init__( self, - request: typing.Optional[ - typing.Tuple[ - x509.Certificate, x509.Certificate, hashes.HashAlgorithm - ] - ] = None, - request_hash: typing.Optional[ - typing.Tuple[bytes, bytes, int, hashes.HashAlgorithm] - ] = None, - extensions: typing.List[x509.Extension[x509.ExtensionType]] = [], + request: tuple[ + x509.Certificate, x509.Certificate, hashes.HashAlgorithm + ] + | None = None, + request_hash: tuple[bytes, bytes, int, hashes.HashAlgorithm] + | None = None, + extensions: list[x509.Extension[x509.ExtensionType]] = [], ) -> None: self._request = request self._request_hash = request_hash @@ -478,7 +476,7 @@ def add_extension( _reject_duplicate_extension(extension, self._extensions) return OCSPRequestBuilder( - self._request, self._request_hash, self._extensions + [extension] + self._request, self._request_hash, [*self._extensions, extension] ) def build(self) -> OCSPRequest: @@ -491,12 +489,11 @@ def build(self) -> OCSPRequest: class OCSPResponseBuilder: def __init__( self, - response: typing.Optional[_SingleResponse] = None, - responder_id: typing.Optional[ - typing.Tuple[x509.Certificate, OCSPResponderEncoding] - ] = None, - certs: typing.Optional[typing.List[x509.Certificate]] = None, - extensions: typing.List[x509.Extension[x509.ExtensionType]] = [], + response: _SingleResponse | None = None, + responder_id: tuple[x509.Certificate, OCSPResponderEncoding] + | None = None, + certs: list[x509.Certificate] | None = None, + extensions: list[x509.Extension[x509.ExtensionType]] = [], ): self._response = response self._responder_id = responder_id @@ -510,9 +507,9 @@ def add_response( algorithm: hashes.HashAlgorithm, cert_status: OCSPCertStatus, this_update: datetime.datetime, - next_update: typing.Optional[datetime.datetime], - revocation_time: typing.Optional[datetime.datetime], - revocation_reason: typing.Optional[x509.ReasonFlags], + next_update: datetime.datetime | None, + revocation_time: datetime.datetime | None, + revocation_reason: x509.ReasonFlags | None, ) -> OCSPResponseBuilder: if self._response is not None: raise ValueError("Only one response per OCSPResponse.") @@ -583,13 +580,13 @@ def add_extension( self._response, self._responder_id, self._certs, - self._extensions + [extension], + [*self._extensions, extension], ) def sign( self, private_key: CertificateIssuerPrivateKeyTypes, - algorithm: typing.Optional[hashes.HashAlgorithm], + algorithm: hashes.HashAlgorithm | None, ) -> OCSPResponse: if self._response is None: raise ValueError("You must add a response before signing") @@ -614,9 +611,5 @@ def build_unsuccessful( return ocsp.create_ocsp_response(response_status, None, None, None) -def load_der_ocsp_request(data: bytes) -> OCSPRequest: - return ocsp.load_der_ocsp_request(data) - - -def load_der_ocsp_response(data: bytes) -> OCSPResponse: - return ocsp.load_der_ocsp_response(data) +load_der_ocsp_request = ocsp.load_der_ocsp_request +load_der_ocsp_response = ocsp.load_der_ocsp_response diff --git a/dist/ba_data/python-site-packages/cryptography/x509/verification.py b/dist/ba_data/python-site-packages/cryptography/x509/verification.py new file mode 100644 index 00000000..ab1a37ae --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/verification.py @@ -0,0 +1,24 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.bindings._rust import x509 as rust_x509 +from cryptography.x509.general_name import DNSName, IPAddress + +__all__ = [ + "Store", + "Subject", + "ServerVerifier", + "PolicyBuilder", + "VerificationError", +] + +Store = rust_x509.Store +Subject = typing.Union[DNSName, IPAddress] +ServerVerifier = rust_x509.ServerVerifier +PolicyBuilder = rust_x509.PolicyBuilder +VerificationError = rust_x509.VerificationError diff --git a/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/INSTALLER b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/METADATA b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/METADATA new file mode 100644 index 00000000..1f564b82 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/METADATA @@ -0,0 +1,16 @@ +Metadata-Version: 2.1 +Name: discord +Version: 2.3.2 +Summary: A mirror package for discord.py. Please install that instead. +Home-page: https://github.com/Rapptz/discord.py +Author: Rapptz +License: UNKNOWN +Platform: UNKNOWN +Description-Content-Type: text/markdown +Requires-Dist: discord.py (>=2.3.2) + +### This is a mirror package! + +It is recommended to install `discord.py` instead. + + diff --git a/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/RECORD b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/RECORD new file mode 100644 index 00000000..eb952177 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/RECORD @@ -0,0 +1,6 @@ +discord-2.3.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +discord-2.3.2.dist-info/METADATA,sha256=14Tyt3XWdWbE24XwYnLNkvB872elf4jLieMZf-MXlU8,381 +discord-2.3.2.dist-info/RECORD,, +discord-2.3.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +discord-2.3.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +discord-2.3.2.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 diff --git a/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/REQUESTED b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/WHEEL b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/WHEEL new file mode 100644 index 00000000..becc9a66 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dist/ba_data/python-site-packages/chardet/cli/__init__.py b/dist/ba_data/python-site-packages/discord-2.3.2.dist-info/top_level.txt similarity index 100% rename from dist/ba_data/python-site-packages/chardet/cli/__init__.py rename to dist/ba_data/python-site-packages/discord-2.3.2.dist-info/top_level.txt diff --git a/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/INSTALLER b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/LICENSE b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/LICENSE new file mode 100644 index 00000000..700c21b6 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. diff --git a/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/METADATA b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/METADATA new file mode 100644 index 00000000..acbc57a9 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/METADATA @@ -0,0 +1,166 @@ +Metadata-Version: 2.1 +Name: discord.py +Version: 2.3.2 +Summary: A Python wrapper for the Discord API +Home-page: https://github.com/Rapptz/discord.py +Author: Rapptz +License: MIT +Project-URL: Documentation, https://discordpy.readthedocs.io/en/latest/ +Project-URL: Issue tracker, https://github.com/Rapptz/discord.py/issues +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Topic :: Internet +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Classifier: Typing :: Typed +Requires-Python: >=3.8.0 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: aiohttp (<4,>=3.7.4) +Provides-Extra: docs +Requires-Dist: sphinx (==4.4.0) ; extra == 'docs' +Requires-Dist: sphinxcontrib-trio (==1.1.2) ; extra == 'docs' +Requires-Dist: sphinxcontrib-websupport ; extra == 'docs' +Requires-Dist: typing-extensions (<5,>=4.3) ; extra == 'docs' +Provides-Extra: speed +Requires-Dist: orjson (>=3.5.4) ; extra == 'speed' +Requires-Dist: aiodns (>=1.1) ; extra == 'speed' +Requires-Dist: Brotli ; extra == 'speed' +Requires-Dist: cchardet (==2.1.7) ; (python_version < "3.10") and extra == 'speed' +Provides-Extra: test +Requires-Dist: coverage[toml] ; extra == 'test' +Requires-Dist: pytest ; extra == 'test' +Requires-Dist: pytest-asyncio ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' +Requires-Dist: pytest-mock ; extra == 'test' +Requires-Dist: typing-extensions (<5,>=4.3) ; extra == 'test' +Provides-Extra: voice +Requires-Dist: PyNaCl (<1.6,>=1.3.0) ; extra == 'voice' + +discord.py +========== + +.. image:: https://discord.com/api/guilds/336642139381301249/embed.png + :target: https://discord.gg/r3sSKJJ + :alt: Discord server invite +.. image:: https://img.shields.io/pypi/v/discord.py.svg + :target: https://pypi.python.org/pypi/discord.py + :alt: PyPI version info +.. image:: https://img.shields.io/pypi/pyversions/discord.py.svg + :target: https://pypi.python.org/pypi/discord.py + :alt: PyPI supported Python versions + +A modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python. + +Key Features +------------- + +- Modern Pythonic API using ``async`` and ``await``. +- Proper rate limit handling. +- Optimised in both speed and memory. + +Installing +---------- + +**Python 3.8 or higher is required** + +To install the library without full voice support, you can just run the following command: + +.. code:: sh + + # Linux/macOS + python3 -m pip install -U discord.py + + # Windows + py -3 -m pip install -U discord.py + +Otherwise to get voice support you should run the following command: + +.. code:: sh + + # Linux/macOS + python3 -m pip install -U "discord.py[voice]" + + # Windows + py -3 -m pip install -U discord.py[voice] + + +To install the development version, do the following: + +.. code:: sh + + $ git clone https://github.com/Rapptz/discord.py + $ cd discord.py + $ python3 -m pip install -U .[voice] + + +Optional Packages +~~~~~~~~~~~~~~~~~~ + +* `PyNaCl `__ (for voice support) + +Please note that when installing voice support on Linux, you must install the following packages via your favourite package manager (e.g. ``apt``, ``dnf``, etc) before running the above commands: + +* libffi-dev (or ``libffi-devel`` on some systems) +* python-dev (e.g. ``python3.8-dev`` for Python 3.8) + +Quick Example +-------------- + +.. code:: py + + import discord + + class MyClient(discord.Client): + async def on_ready(self): + print('Logged on as', self.user) + + async def on_message(self, message): + # don't respond to ourselves + if message.author == self.user: + return + + if message.content == 'ping': + await message.channel.send('pong') + + intents = discord.Intents.default() + intents.message_content = True + client = MyClient(intents=intents) + client.run('token') + +Bot Example +~~~~~~~~~~~~~ + +.. code:: py + + import discord + from discord.ext import commands + + intents = discord.Intents.default() + intents.message_content = True + bot = commands.Bot(command_prefix='>', intents=intents) + + @bot.command() + async def ping(ctx): + await ctx.send('pong') + + bot.run('token') + +You can find more examples in the examples directory. + +Links +------ + +- `Documentation `_ +- `Official Discord Server `_ +- `Discord API `_ + + diff --git a/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/RECORD b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/RECORD new file mode 100644 index 00000000..31555374 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/RECORD @@ -0,0 +1,243 @@ +discord.py-2.3.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +discord.py-2.3.2.dist-info/LICENSE,sha256=IRr8eHptwl13Oez9dujx-pRmN028VYOGiW2Yzf7lEn0,1081 +discord.py-2.3.2.dist-info/METADATA,sha256=3Kuv_E0jlGPe7jltcyg5MicDBvmrdNYF3OONjUgw3N8,4897 +discord.py-2.3.2.dist-info/RECORD,, +discord.py-2.3.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +discord.py-2.3.2.dist-info/top_level.txt,sha256=fJkrNbR-_8ubMBUcDEJBcfkpECrvSEmMrNKgvLlQFoM,8 +discord/__init__.py,sha256=75ePASY8wcoRPB8TxKbIfi9HBdv5INqHw37UvfQJ2ZY,1886 +discord/__main__.py,sha256=DEe4CqYJGe53oxJsZAQVXNRQUEUILXpo1r5iwp5wIW8,11051 +discord/__pycache__/__init__.cpython-312.pyc,, +discord/__pycache__/__main__.cpython-312.pyc,, +discord/__pycache__/_types.cpython-312.pyc,, +discord/__pycache__/abc.cpython-312.pyc,, +discord/__pycache__/activity.cpython-312.pyc,, +discord/__pycache__/appinfo.cpython-312.pyc,, +discord/__pycache__/asset.cpython-312.pyc,, +discord/__pycache__/audit_logs.cpython-312.pyc,, +discord/__pycache__/automod.cpython-312.pyc,, +discord/__pycache__/backoff.cpython-312.pyc,, +discord/__pycache__/channel.cpython-312.pyc,, +discord/__pycache__/client.cpython-312.pyc,, +discord/__pycache__/colour.cpython-312.pyc,, +discord/__pycache__/components.cpython-312.pyc,, +discord/__pycache__/context_managers.cpython-312.pyc,, +discord/__pycache__/embeds.cpython-312.pyc,, +discord/__pycache__/emoji.cpython-312.pyc,, +discord/__pycache__/enums.cpython-312.pyc,, +discord/__pycache__/errors.cpython-312.pyc,, +discord/__pycache__/file.cpython-312.pyc,, +discord/__pycache__/flags.cpython-312.pyc,, +discord/__pycache__/gateway.cpython-312.pyc,, +discord/__pycache__/guild.cpython-312.pyc,, +discord/__pycache__/http.cpython-312.pyc,, +discord/__pycache__/integrations.cpython-312.pyc,, +discord/__pycache__/interactions.cpython-312.pyc,, +discord/__pycache__/invite.cpython-312.pyc,, +discord/__pycache__/member.cpython-312.pyc,, +discord/__pycache__/mentions.cpython-312.pyc,, +discord/__pycache__/message.cpython-312.pyc,, +discord/__pycache__/mixins.cpython-312.pyc,, +discord/__pycache__/object.cpython-312.pyc,, +discord/__pycache__/oggparse.cpython-312.pyc,, +discord/__pycache__/opus.cpython-312.pyc,, +discord/__pycache__/partial_emoji.cpython-312.pyc,, +discord/__pycache__/permissions.cpython-312.pyc,, +discord/__pycache__/player.cpython-312.pyc,, +discord/__pycache__/raw_models.cpython-312.pyc,, +discord/__pycache__/reaction.cpython-312.pyc,, +discord/__pycache__/role.cpython-312.pyc,, +discord/__pycache__/scheduled_event.cpython-312.pyc,, +discord/__pycache__/shard.cpython-312.pyc,, +discord/__pycache__/stage_instance.cpython-312.pyc,, +discord/__pycache__/state.cpython-312.pyc,, +discord/__pycache__/sticker.cpython-312.pyc,, +discord/__pycache__/team.cpython-312.pyc,, +discord/__pycache__/template.cpython-312.pyc,, +discord/__pycache__/threads.cpython-312.pyc,, +discord/__pycache__/user.cpython-312.pyc,, +discord/__pycache__/utils.cpython-312.pyc,, +discord/__pycache__/voice_client.cpython-312.pyc,, +discord/__pycache__/welcome_screen.cpython-312.pyc,, +discord/__pycache__/widget.cpython-312.pyc,, +discord/_types.py,sha256=b6Ij97rnyo9WGs3qVFyRQ210LsIApH7Jr3-ZfmxU268,1410 +discord/abc.py,sha256=zhtYcxn2JfG72MT_d0kdVQiWQe_8UxXnO5uSJy4H1U0,65822 +discord/activity.py,sha256=2q-Kah0_BMOrwQ3q4_8OxACu_1gPh719T9g4eKEaCPs,26864 +discord/app_commands/__init__.py,sha256=xaANFF28sifxXO__x6eSd7r5r7UjpO-tMQirjaKiNSc,424 +discord/app_commands/__pycache__/__init__.cpython-312.pyc,, +discord/app_commands/__pycache__/checks.cpython-312.pyc,, +discord/app_commands/__pycache__/commands.cpython-312.pyc,, +discord/app_commands/__pycache__/errors.cpython-312.pyc,, +discord/app_commands/__pycache__/models.cpython-312.pyc,, +discord/app_commands/__pycache__/namespace.cpython-312.pyc,, +discord/app_commands/__pycache__/transformers.cpython-312.pyc,, +discord/app_commands/__pycache__/translator.cpython-312.pyc,, +discord/app_commands/__pycache__/tree.cpython-312.pyc,, +discord/app_commands/checks.py,sha256=Z0OIrHuoYHu3eE2q05luQ_MQGrqSC5XhA0rourJ9tFs,18077 +discord/app_commands/commands.py,sha256=NR0z9bKQUvyGr55jNGWoCJhqTJweXmK3iNlNoJ7YW_A,94536 +discord/app_commands/errors.py,sha256=yU3Rb77UoKjQTInnTtPlq6osBnoJLK3L_FrcnAD3nR4,19006 +discord/app_commands/models.py,sha256=blPfJeLmez-1Le_maQ1SiGd79KfNMF0ooRPAW1zsfFQ,38502 +discord/app_commands/namespace.py,sha256=oNfmQPNDbfW3uTGadOOw8F_X872rX4-qNFYR8ZhDAKw,13123 +discord/app_commands/transformers.py,sha256=8iP3ApdisRXfiwAhEwS0kwygeFn-sVrtgA-VgEwS_7U,32512 +discord/app_commands/translator.py,sha256=m9ENDO7GGCJXiSuhCCvXi1jW4ccHOBEM0Hk9qomS6I0,10686 +discord/app_commands/tree.py,sha256=vhwRreDEPqr7otd_NVz06c0cidW15_RXkBlI-zkCisg,47965 +discord/appinfo.py,sha256=4Y-XqFxOuB_roDceQcUNRs0f3BogaHyOuOtmmlB2MTg,12713 +discord/asset.py,sha256=SuZBQ9mgz092zUpXem2gco0WOOAOiW9pJpWpbfJtsUI,15837 +discord/audit_logs.py,sha256=pFGUg9oKneMHBZ1CJY6cewWRKXpgZ72WcmMTyk1oGgs,35367 +discord/automod.py,sha256=bMK9tloCA0iU0CSKpPwVikoi00erIyxBcQJnZLyq_r0,23833 +discord/backoff.py,sha256=3yQ0uJbQ3ij7Tmdzv7GdhqfHjbNVO4eTB3Eu0VCxuvM,3751 +discord/bin/libopus-0.x64.dll,sha256=yE2oNujZJCGsMFhCz-WnJImO0J00DUaxKeIQvclEgTE,441856 +discord/bin/libopus-0.x86.dll,sha256=O1v-EpUPNQQ-110rb6kCyTbWelBxYL92NY1nx2wdveg,366080 +discord/channel.py,sha256=xmb1oJ4i6AwIiiT1HmEfAkNq0LagyUK8pRgeMkgcLpA,116803 +discord/client.py,sha256=hhT8HCdxmM7EkJOIjsdNs_5gsf7A0HPw2AEt9bDHDK4,85400 +discord/colour.py,sha256=l8-TuIYTNwaDGdIRLwjHNHsMjqjNl_pJ-RscHkXJcDM,14403 +discord/components.py,sha256=1koyIHyOVLKdsd3trSYyPAQ37zOn7IMCbFBsbOu4mz4,16850 +discord/context_managers.py,sha256=hloaEAAhLcDB-QfyoCPEpH_vsc3y4WLs1Ujs352tLbQ,3032 +discord/embeds.py,sha256=sijnFNm84KCoo_IUPUUC1bzX1IWyMfPcBPFXFocq50g,22722 +discord/emoji.py,sha256=ucJuzNIfAbvDBf8QxFrD4RyVwxDGCRyl7Zr_QWI5ZRo,8574 +discord/enums.py,sha256=gErFkTYnvfwE-EaOFQfMT9kAZhCLY4-Hj3Ut-geNpfQ,22242 +discord/errors.py,sha256=h0BHhp-UjoWTvoxqlLjtOziM9nxVFR8qMHZmEt8m5oc,8952 +discord/ext/commands/__init__.py,sha256=ZQPvApylgqC07qrj80DDkT4Dbd7j_OVy5Xw4RiYZJRc,437 +discord/ext/commands/__pycache__/__init__.cpython-312.pyc,, +discord/ext/commands/__pycache__/_types.cpython-312.pyc,, +discord/ext/commands/__pycache__/bot.cpython-312.pyc,, +discord/ext/commands/__pycache__/cog.cpython-312.pyc,, +discord/ext/commands/__pycache__/context.cpython-312.pyc,, +discord/ext/commands/__pycache__/converter.cpython-312.pyc,, +discord/ext/commands/__pycache__/cooldowns.cpython-312.pyc,, +discord/ext/commands/__pycache__/core.cpython-312.pyc,, +discord/ext/commands/__pycache__/errors.cpython-312.pyc,, +discord/ext/commands/__pycache__/flags.cpython-312.pyc,, +discord/ext/commands/__pycache__/help.cpython-312.pyc,, +discord/ext/commands/__pycache__/hybrid.cpython-312.pyc,, +discord/ext/commands/__pycache__/parameters.cpython-312.pyc,, +discord/ext/commands/__pycache__/view.cpython-312.pyc,, +discord/ext/commands/_types.py,sha256=ULLyGU6nLcITfnS-yTrlRU0N3e0zXETo2w8dBWKMrf4,2638 +discord/ext/commands/bot.py,sha256=3u57VTED60mwKrRmd8eH5GogWZLMfNA90qKh6oPhtHA,51719 +discord/ext/commands/cog.py,sha256=54f5j_I-fU30zFY-cxin_x3sHfsSjntm_w_arbhsiXI,30245 +discord/ext/commands/context.py,sha256=2cJRDhyncu1NIURGumt0oo3GMN64EMoqf2JWE_j5FzA,40048 +discord/ext/commands/converter.py,sha256=lJIxLDXxnwVHdAQfuM3JROgxplytPGedW9LtFRGXlSc,46172 +discord/ext/commands/cooldowns.py,sha256=0TrIBTDYLz2PhVx7yE9RDNoCENFRlLDEw1e8nvabm1k,9716 +discord/ext/commands/core.py,sha256=KMPSoicVLfCoX9771BbHgYqOVzaSUKQMk9gUfQBobPY,89619 +discord/ext/commands/errors.py,sha256=ZQJ2slp3HVUH3aWvOU1iLLVxpxA1LsjQOjKTj9mdmEQ,36450 +discord/ext/commands/flags.py,sha256=1LaqI9z_lnxl380W1THHg-tk7ta0ht0_gPWPFmdFDjY,22966 +discord/ext/commands/help.py,sha256=Qnfby8ZQ6RFKP31KgP4gk2eq0e8sSbNwd548sAdQPHI,57873 +discord/ext/commands/hybrid.py,sha256=0FmvT7xovJJt5tEknVelZ5Dxi3iu9A3CqDMftBCNV30,36595 +discord/ext/commands/parameters.py,sha256=3OUpzbljB6GLazvW51Rq1XlVbEGiWC-Bsfjk3_RW4-4,9295 +discord/ext/commands/view.py,sha256=lwRVmdXEkTIyzLLacr7Wz6jFY0s7KEbzuFgzx8Wgjog,6247 +discord/ext/tasks/__init__.py,sha256=R33gptpvC616c9c8L52fKDTl73w4_2YNWQvMolyPCcM,29180 +discord/ext/tasks/__pycache__/__init__.cpython-312.pyc,, +discord/file.py,sha256=YeNS1cUZlcnMnx6QmPjpT7wT7h8hXOa11T1hz8cpr0Y,5378 +discord/flags.py,sha256=rRefO1GRBhvW0_lDwxwlSjfe9VwpYq8j_z9mjk8EKRE,54264 +discord/gateway.py,sha256=G_ngUX5CiWU5JBPDElRf4yLHxKgmzKNHghbasvK0L3Q,35191 +discord/guild.py,sha256=bBGGP64iI_aw0_EP61VkLQcsNsoJqIUNXQJGl50LL30,150337 +discord/http.py,sha256=PI68vFC3ez3p8b_hJjShJWejLjQ8-OTPF5nOqdlalU8,90056 +discord/integrations.py,sha256=P2s9NjyWhlcdQs3IcRrVdr6wHmCVszwXSlhXNnU_CEk,13334 +discord/interactions.py,sha256=OIRG_5XceVKl52OtiICzI0StWmkUT_pvdQLEvVoNTFs,45246 +discord/invite.py,sha256=fRK2UbCwAoLY8mTCCThZOfsaCbMC6yM3of2dswXG9w0,20595 +discord/member.py,sha256=xqdEgNuaaTTWPBO9e7YARxKMxleVNvhLtyRMKnwKGE0,41018 +discord/mentions.py,sha256=2DZE_Uh2sDIoext6-bAXkdyWAjRVSAV3GrMYxKFIL14,5592 +discord/message.py,sha256=LZv2wc_XjrYQuD7wThnffnvLlrYmPBTSl4JXRwm-QBg,85375 +discord/mixins.py,sha256=_mKBOfdhQKNwlVx2m4jbJmOvtWxkuWSBEbnhxNDd4qo,1485 +discord/object.py,sha256=KHaw4UBOgcw74m-uXI9uU3mba2wAIgEKeaP5n2uuKsQ,3702 +discord/oggparse.py,sha256=F_wjGRC2TWeq0tMltNukivWSP-YUdP8WAIOy-oVqNmU,3646 +discord/opus.py,sha256=zfeQfMAvH7zRu6Msu42Thy9PMtLm8IdIqQk3ygTAtJg,15233 +discord/partial_emoji.py,sha256=OtsS-zYNyk2bv-ZepZ4z4RSAxZ40d8eQDsiob6_-Om0,7954 +discord/permissions.py,sha256=9LMdh0u5t-j1FWLMf1BcZmBndkZHwY2rnZqNmH8jBrc,30153 +discord/player.py,sha256=RNDcaWGl0_4rQvTCQSSQmnMwdTjQMfFBQ2kfD4Pief0,26498 +discord/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +discord/raw_models.py,sha256=9aCXMFEbBiEXUeJ5u1Gkrk2WH0MFn3DI-NE2mKHqmSM,16826 +discord/reaction.py,sha256=5LEcjk3i33sdBCF6l54wF90473OyjuNU7SBBzJA2tE0,8207 +discord/role.py,sha256=xyzYK1VJIrP_LAcem68XqOylfp8ZaCsrsZOBbKEO_eI,17906 +discord/scheduled_event.py,sha256=rCduKyK3HaEGxGXM6VJYvig52VQsy6ReWqIFuOe8Ej8,23629 +discord/shard.py,sha256=LV60FOxFm6-_EN0fLDgjGZPBpavO6c8YN2PyPrGtfVI,20399 +discord/stage_instance.py,sha256=TBiXfIoaMKemDZLj_Fy7glDo4mnrtJu735O5catVM7c,6498 +discord/state.py,sha256=9UDn_zIXMycsvBMKLfhPJkmn66mZ0e_1QnMlLaBVwnE,73376 +discord/sticker.py,sha256=RiqwVAU5cfEAk87_zJozoWJlE1_SJU1cl9mQKexr8jE,16039 +discord/team.py,sha256=Gj6mL0d1jIuO3dX3JMQjyyPzelPuMgbYP7wvCOkVx3E,4792 +discord/template.py,sha256=hlxSwq35_wZ8anANs4aStCzDdQNMl0QE0qZA4bhr6YU,9574 +discord/threads.py,sha256=-SA_j8g0P4tRDq3Z15HX2-sjSeVlXKGzLD3SOv_4k8Q,32456 +discord/types/__init__.py,sha256=7kT6hLaDiMVwuJvp4Os08kxqu9bxX3Yr9FFcOGYd6YQ,149 +discord/types/__pycache__/__init__.cpython-312.pyc,, +discord/types/__pycache__/activity.cpython-312.pyc,, +discord/types/__pycache__/appinfo.cpython-312.pyc,, +discord/types/__pycache__/audit_log.cpython-312.pyc,, +discord/types/__pycache__/automod.cpython-312.pyc,, +discord/types/__pycache__/channel.cpython-312.pyc,, +discord/types/__pycache__/command.cpython-312.pyc,, +discord/types/__pycache__/components.cpython-312.pyc,, +discord/types/__pycache__/embed.cpython-312.pyc,, +discord/types/__pycache__/emoji.cpython-312.pyc,, +discord/types/__pycache__/gateway.cpython-312.pyc,, +discord/types/__pycache__/guild.cpython-312.pyc,, +discord/types/__pycache__/integration.cpython-312.pyc,, +discord/types/__pycache__/interactions.cpython-312.pyc,, +discord/types/__pycache__/invite.cpython-312.pyc,, +discord/types/__pycache__/member.cpython-312.pyc,, +discord/types/__pycache__/message.cpython-312.pyc,, +discord/types/__pycache__/role.cpython-312.pyc,, +discord/types/__pycache__/scheduled_event.cpython-312.pyc,, +discord/types/__pycache__/snowflake.cpython-312.pyc,, +discord/types/__pycache__/sticker.cpython-312.pyc,, +discord/types/__pycache__/team.cpython-312.pyc,, +discord/types/__pycache__/template.cpython-312.pyc,, +discord/types/__pycache__/threads.cpython-312.pyc,, +discord/types/__pycache__/user.cpython-312.pyc,, +discord/types/__pycache__/voice.cpython-312.pyc,, +discord/types/__pycache__/webhook.cpython-312.pyc,, +discord/types/__pycache__/welcome_screen.cpython-312.pyc,, +discord/types/__pycache__/widget.cpython-312.pyc,, +discord/types/activity.py,sha256=k7tqp11m_t77Lu9D5T8pAMw1dnQcs7CtLJ5NV-4CgzQ,2707 +discord/types/appinfo.py,sha256=e0jA4OUxkjK439-tShxZWzqr1Ihx8Nz6ULhGYYEcb6k,2487 +discord/types/audit_log.py,sha256=cD8CEbC7bwBYJdrBSU6JuHo6_9sW6l7FQ4ZnGdraZLg,8192 +discord/types/automod.py,sha256=JxdWKf2evnFOuObcxnIi0QKzGpPOWsmKEx1nRJOwvQs,4009 +discord/types/channel.py,sha256=LHHLGBQpDju1043xDFjxhS5shBdnLnyQhNhxZk9PiVs,4804 +discord/types/command.py,sha256=1hcNoTUcJmpQy29ILcevQSxT8X2nxCngwubshVdgtyI,6266 +discord/types/components.py,sha256=b27cICDVSxXxHzadK7r8sipDn4fI5UCln2jPs33XKe0,3057 +discord/types/embed.py,sha256=VnYSZqjPIYXAGA87P-JhjXs_mGhswaMpOd81mzF5iPc,2329 +discord/types/emoji.py,sha256=JfwRzhcs7KRLKVtl8bCrvbgBTl9Ww8MboNoUcEf2EkM,1528 +discord/types/gateway.py,sha256=So8DWqEqVkqrlhbTSHrYTOcyfUNjRx3CiLVn2sR9yZ4,8453 +discord/types/guild.py,sha256=KikAryWEXz_cqhw1ZcmM-Hg7UytI1VgPswPRLEpQSB0,5279 +discord/types/integration.py,sha256=8HU48LNhr4eqXBzOkib3a5zEfxg1rvOTWp1IeERNpnw,2288 +discord/types/interactions.py,sha256=0VvwucoupXmCD0QGU1tBAT1xzlXcaMSt38h5_HG3gnQ,7046 +discord/types/invite.py,sha256=sLmvX0Imw5qtV-h78BYVf928Q0YIfGWVuz9XxY8Ctqg,2704 +discord/types/member.py,sha256=vOttPlR_PRpVKlQNnilcWjNEIAJBymVC6N0w08WZ248,1898 +discord/types/message.py,sha256=gCd0Hf9z-mWaxzzVJTn3ZITq2p3KKwgYRE9FYUbC9fY,4251 +discord/types/role.py,sha256=m1ZNSq4n-SNSWLELmBV2hE70Bo5YWuaovfLLhXBhL6U,1746 +discord/types/scheduled_event.py,sha256=WwSiBISWsOD81CVxBc2dwfnLSCaRPsZUdYFWyW8ouJI,3294 +discord/types/snowflake.py,sha256=x_L3OXauewQagDr6jPzj7uCw1MNqijsy-Uo9vvkwvF0,1182 +discord/types/sticker.py,sha256=WXQH2KaEAe0dK1tn0p0ZwxXV0OfWuxDGBEMQdBu0kr4,2257 +discord/types/team.py,sha256=rOgj3_h4UGMTSx9dgyBrYTX-1MQZdvPqpJgZKtnOOF4,1499 +discord/types/template.py,sha256=EO4tA2WypntCGQ9sWud5VS_uI8n12iVVHVPcNgCtZvM,1609 +discord/types/threads.py,sha256=p2VuQCd8NbAfIV3FUsG4IwHsd1uXk-rWQCfP22RQqNo,2454 +discord/types/user.py,sha256=eGW7Au7gGBbsQwod9ADXUdePArfZOgCM7kTTBf6rrkE,1572 +discord/types/voice.py,sha256=wFQLiPZaQuXBKE1dM_bdWNpkglpGFC7kEtghwCHBDQM,2268 +discord/types/webhook.py,sha256=iqBUgbz38o0_mWp-gcVI0_urpgZ_dq2EfOOXACg47u8,1978 +discord/types/welcome_screen.py,sha256=ukQMefZLHpgyg0_5IoAzN0UX40VayhF2vnJzNJNMZzA,1460 +discord/types/widget.py,sha256=YRkhDoBHbCEtkmYTVOSoHM8Y3mH9GIdowthoz8ISJYU,1883 +discord/ui/__init__.py,sha256=zsTlMLSiy6RzXzNVl1i5WDiM5piE_bgzCTLYU93axYM,285 +discord/ui/__pycache__/__init__.cpython-312.pyc,, +discord/ui/__pycache__/button.cpython-312.pyc,, +discord/ui/__pycache__/dynamic.cpython-312.pyc,, +discord/ui/__pycache__/item.cpython-312.pyc,, +discord/ui/__pycache__/modal.cpython-312.pyc,, +discord/ui/__pycache__/select.cpython-312.pyc,, +discord/ui/__pycache__/text_input.cpython-312.pyc,, +discord/ui/__pycache__/view.cpython-312.pyc,, +discord/ui/button.py,sha256=_5F4oEYfFwLcXeY056nZ_gp68zyPRDWgWh17klpos_E,10620 +discord/ui/dynamic.py,sha256=iWQ9-6JVT8HBdBY7utlJqK8fzC2BPzlgo_mE0TEA4VI,5899 +discord/ui/item.py,sha256=4Y-XTeYWsWrwriU1ihpVxVUOiCGTIgcnPP8wkjLdqCs,4372 +discord/ui/modal.py,sha256=VeziCgKCQTg8mei5cFlpv_5yoDyozKR2Cb4OoSZqzF4,7035 +discord/ui/select.py,sha256=yrjB41sDFXQEotsyXwqM1vASf7KF8qs7RIEYuDc0_d8,34030 +discord/ui/text_input.py,sha256=6vqvxCdDfMWoDNre-F69LeeoSugdL72x8jtOF8hW3Vc,8092 +discord/ui/view.py,sha256=KxJHGKb76_7mgfIfLhysPfQkRWSb_mUnAckXI3E-mFE,22878 +discord/user.py,sha256=ZZfKq97mG_w0Hf8Sli2E9zoUGawKdi32GC2aLhvxAbo,16504 +discord/utils.py,sha256=mWXsJSN3itR80f2BFtpwzgl_CuU2lG40CHrK89Ci5sI,41506 +discord/voice_client.py,sha256=dYywhW7CAztq0dnnUS3bG3OebUwLVTbndWEggnAUTLo,25089 +discord/webhook/__init__.py,sha256=5lx7IcCFf9DAjdX7CVen3-8DjHAfGvS1rSDY3DyVnqM,182 +discord/webhook/__pycache__/__init__.cpython-312.pyc,, +discord/webhook/__pycache__/async_.cpython-312.pyc,, +discord/webhook/__pycache__/sync.cpython-312.pyc,, +discord/webhook/async_.py,sha256=9NaW7OY2poMGZAja0CnQCdYlQEKagW0zraEPDTi7vH0,69729 +discord/webhook/sync.py,sha256=1sfj1QRohdA1NFBE7hMvfN0b38i0YXijzUHeNdfuQoE,42586 +discord/welcome_screen.py,sha256=CP5i3eujqzt_yVs0IBrTH_MOzTlEG0iid9xBvMvDQYk,7539 +discord/widget.py,sha256=FLqKcOyPRE6qbqgFEbhz0RJvl4DG7Ui7zzDnlp5SapI,10426 diff --git a/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/WHEEL b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/WHEEL new file mode 100644 index 00000000..becc9a66 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/top_level.txt b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/top_level.txt new file mode 100644 index 00000000..e46fba20 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord.py-2.3.2.dist-info/top_level.txt @@ -0,0 +1 @@ +discord diff --git a/dist/ba_data/python-site-packages/discord/__init__.py b/dist/ba_data/python-site-packages/discord/__init__.py index e2c8101b..7e927f43 100644 --- a/dist/ba_data/python-site-packages/discord/__init__.py +++ b/dist/ba_data/python-site-packages/discord/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ Discord API Wrapper ~~~~~~~~~~~~~~~~~~~ @@ -15,53 +13,73 @@ __author__ = 'Rapptz' __license__ = 'MIT' __copyright__ = 'Copyright 2015-present Rapptz' -__version__ = '1.7.3' +__version__ = '2.3.2' __path__ = __import__('pkgutil').extend_path(__path__, __name__) -from collections import namedtuple import logging +from typing import NamedTuple, Literal -from .client import Client -from .appinfo import AppInfo -from .user import User, ClientUser, Profile -from .emoji import Emoji -from .partial_emoji import PartialEmoji +from .client import * +from .appinfo import * +from .user import * +from .emoji import * +from .partial_emoji import * from .activity import * from .channel import * -from .guild import Guild +from .guild import * from .flags import * -from .relationship import Relationship -from .member import Member, VoiceState +from .member import * from .message import * -from .asset import Asset +from .asset import * from .errors import * -from .calls import CallMessage, GroupCall -from .permissions import Permissions, PermissionOverwrite -from .role import Role, RoleTags -from .file import File -from .colour import Color, Colour -from .integrations import Integration, IntegrationAccount -from .invite import Invite, PartialInviteChannel, PartialInviteGuild -from .template import Template -from .widget import Widget, WidgetMember, WidgetChannel -from .object import Object -from .reaction import Reaction -from . import utils, opus, abc +from .permissions import * +from .role import * +from .file import * +from .colour import * +from .integrations import * +from .invite import * +from .template import * +from .welcome_screen import * +from .widget import * +from .object import * +from .reaction import * +from . import ( + utils as utils, + opus as opus, + abc as abc, + ui as ui, + app_commands as app_commands, +) from .enums import * -from .embeds import Embed -from .mentions import AllowedMentions -from .shard import AutoShardedClient, ShardInfo +from .embeds import * +from .mentions import * +from .shard import * from .player import * from .webhook import * -from .voice_client import VoiceClient, VoiceProtocol -from .audit_logs import AuditLogChanges, AuditLogEntry, AuditLogDiff +from .voice_client import * +from .audit_logs import * from .raw_models import * from .team import * -from .sticker import Sticker +from .sticker import * +from .stage_instance import * +from .scheduled_event import * +from .interactions import * +from .components import * +from .threads import * +from .automod import * + -VersionInfo = namedtuple('VersionInfo', 'major minor micro releaselevel serial') +class VersionInfo(NamedTuple): + major: int + minor: int + micro: int + releaselevel: Literal["alpha", "beta", "candidate", "final"] + serial: int -version_info = VersionInfo(major=1, minor=7, micro=3, releaselevel='final', serial=0) + +version_info: VersionInfo = VersionInfo(major=2, minor=3, micro=2, releaselevel='final', serial=0) logging.getLogger(__name__).addHandler(logging.NullHandler()) + +del logging, NamedTuple, Literal, VersionInfo diff --git a/dist/ba_data/python-site-packages/discord/__main__.py b/dist/ba_data/python-site-packages/discord/__main__.py index 92528354..6e34be54 100644 --- a/dist/ba_data/python-site-packages/discord/__main__.py +++ b/dist/ba_data/python-site-packages/discord/__main__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,63 +22,75 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + +from typing import Optional, Tuple, Dict + import argparse import sys from pathlib import Path import discord -import pkg_resources +import importlib.metadata import aiohttp import platform -def show_version(): + +def show_version() -> None: entries = [] entries.append('- Python v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(sys.version_info)) version_info = discord.version_info entries.append('- discord.py v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(version_info)) if version_info.releaselevel != 'final': - pkg = pkg_resources.get_distribution('discord.py') - if pkg: - entries.append(' - discord.py pkg_resources: v{0}'.format(pkg.version)) + version = importlib.metadata.version('discord.py') + if version: + entries.append(f' - discord.py metadata: v{version}') - entries.append('- aiohttp v{0.__version__}'.format(aiohttp)) + entries.append(f'- aiohttp v{aiohttp.__version__}') uname = platform.uname() entries.append('- system info: {0.system} {0.release} {0.version}'.format(uname)) print('\n'.join(entries)) -def core(parser, args): + +def core(parser: argparse.ArgumentParser, args: argparse.Namespace) -> None: if args.version: show_version() + else: + parser.print_help() -bot_template = """#!/usr/bin/env python3 -# -*- coding: utf-8 -*- + +_bot_template = """#!/usr/bin/env python3 from discord.ext import commands import discord import config class Bot(commands.{base}): - def __init__(self, **kwargs): - super().__init__(command_prefix=commands.when_mentioned_or('{prefix}'), **kwargs) + def __init__(self, intents: discord.Intents, **kwargs): + super().__init__(command_prefix=commands.when_mentioned_or('{prefix}'), intents=intents, **kwargs) + + async def setup_hook(self): for cog in config.cogs: try: - self.load_extension(cog) + await self.load_extension(cog) except Exception as exc: - print('Could not load extension {{0}} due to {{1.__class__.__name__}}: {{1}}'.format(cog, exc)) + print(f'Could not load extension {{cog}} due to {{exc.__class__.__name__}}: {{exc}}') async def on_ready(self): - print('Logged on as {{0}} (ID: {{0.id}})'.format(self.user)) + print(f'Logged on as {{self.user}} (ID: {{self.user.id}})') -bot = Bot() +intents = discord.Intents.default() +intents.message_content = True +bot = Bot(intents=intents) # write general commands here bot.run(config.token) """ -gitignore_template = """# Byte-compiled / optimized / DLL files +_gitignore_template = """# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class @@ -110,9 +120,7 @@ async def on_ready(self): config.py """ -cog_template = '''# -*- coding: utf-8 -*- - -from discord.ext import commands +_cog_template = '''from discord.ext import commands import discord class {name}(commands.Cog{attrs}): @@ -121,12 +129,16 @@ class {name}(commands.Cog{attrs}): def __init__(self, bot): self.bot = bot {extra} -def setup(bot): - bot.add_cog({name}(bot)) +async def setup(bot): + await bot.add_cog({name}(bot)) ''' -cog_extras = ''' - def cog_unload(self): +_cog_extras = ''' + async def cog_load(self): + # loading logic goes here + pass + + async def cog_unload(self): # clean up logic goes here pass @@ -145,6 +157,10 @@ async def bot_check_once(self, ctx): async def cog_command_error(self, ctx, error): # error handling to every command in here pass + + async def cog_app_command_error(self, interaction, error): + # error handling to every application command in here + pass async def cog_before_invoke(self, ctx): # called before a command is called here @@ -160,7 +176,7 @@ async def cog_after_invoke(self, ctx): # certain file names and directory names are forbidden # see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx # although some of this doesn't apply to Linux, we might as well be consistent -_base_table = { +_base_table: Dict[str, Optional[str]] = { '<': '-', '>': '-', ':': '-', @@ -175,24 +191,48 @@ async def cog_after_invoke(self, ctx): # NUL (0) and 1-31 are disallowed _base_table.update((chr(i), None) for i in range(32)) -translation_table = str.maketrans(_base_table) +_translation_table = str.maketrans(_base_table) + -def to_path(parser, name, *, replace_spaces=False): +def to_path(parser: argparse.ArgumentParser, name: str, *, replace_spaces: bool = False) -> Path: if isinstance(name, Path): return name if sys.platform == 'win32': - forbidden = ('CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', \ - 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9') + forbidden = ( + 'CON', + 'PRN', + 'AUX', + 'NUL', + 'COM1', + 'COM2', + 'COM3', + 'COM4', + 'COM5', + 'COM6', + 'COM7', + 'COM8', + 'COM9', + 'LPT1', + 'LPT2', + 'LPT3', + 'LPT4', + 'LPT5', + 'LPT6', + 'LPT7', + 'LPT8', + 'LPT9', + ) if len(name) <= 4 and name.upper() in forbidden: parser.error('invalid directory name given, use a different one') - name = name.translate(translation_table) + name = name.translate(_translation_table) if replace_spaces: name = name.replace(' ', '-') return Path(name) -def newbot(parser, args): + +def newbot(parser: argparse.ArgumentParser, args: argparse.Namespace) -> None: new_directory = to_path(parser, args.directory) / to_path(parser, args.name) # as a note exist_ok for Path is a 3.5+ only feature @@ -200,7 +240,7 @@ def newbot(parser, args): try: new_directory.mkdir(exist_ok=True, parents=True) except OSError as exc: - parser.error('could not create our bot directory ({})'.format(exc)) + parser.error(f'could not create our bot directory ({exc})') cogs = new_directory / 'cogs' @@ -209,43 +249,44 @@ def newbot(parser, args): init = cogs / '__init__.py' init.touch() except OSError as exc: - print('warning: could not create cogs directory ({})'.format(exc)) + print(f'warning: could not create cogs directory ({exc})') try: with open(str(new_directory / 'config.py'), 'w', encoding='utf-8') as fp: fp.write('token = "place your token here"\ncogs = []\n') except OSError as exc: - parser.error('could not create config file ({})'.format(exc)) + parser.error(f'could not create config file ({exc})') try: with open(str(new_directory / 'bot.py'), 'w', encoding='utf-8') as fp: base = 'Bot' if not args.sharded else 'AutoShardedBot' - fp.write(bot_template.format(base=base, prefix=args.prefix)) + fp.write(_bot_template.format(base=base, prefix=args.prefix)) except OSError as exc: - parser.error('could not create bot file ({})'.format(exc)) + parser.error(f'could not create bot file ({exc})') if not args.no_git: try: with open(str(new_directory / '.gitignore'), 'w', encoding='utf-8') as fp: - fp.write(gitignore_template) + fp.write(_gitignore_template) except OSError as exc: - print('warning: could not create .gitignore file ({})'.format(exc)) + print(f'warning: could not create .gitignore file ({exc})') print('successfully made bot at', new_directory) -def newcog(parser, args): + +def newcog(parser: argparse.ArgumentParser, args: argparse.Namespace) -> None: cog_dir = to_path(parser, args.directory) try: cog_dir.mkdir(exist_ok=True) except OSError as exc: - print('warning: could not create cogs directory ({})'.format(exc)) + print(f'warning: could not create cogs directory ({exc})') directory = cog_dir / to_path(parser, args.name) directory = directory.with_suffix('.py') try: with open(str(directory), 'w', encoding='utf-8') as fp: attrs = '' - extra = cog_extras if args.full else '' + extra = _cog_extras if args.full else '' if args.class_name: name = args.class_name else: @@ -257,16 +298,17 @@ def newcog(parser, args): name = name.title() if args.display_name: - attrs += ', name="{}"'.format(args.display_name) + attrs += f', name="{args.display_name}"' if args.hide_commands: attrs += ', command_attrs=dict(hidden=True)' - fp.write(cog_template.format(name=name, extra=extra, attrs=attrs)) + fp.write(_cog_template.format(name=name, extra=extra, attrs=attrs)) except OSError as exc: - parser.error('could not create cog file ({})'.format(exc)) + parser.error(f'could not create cog file ({exc})') else: print('successfully made cog at', directory) -def add_newbot_args(subparser): + +def add_newbot_args(subparser: argparse._SubParsersAction[argparse.ArgumentParser]) -> None: parser = subparser.add_parser('newbot', help='creates a command bot project quickly') parser.set_defaults(func=newbot) @@ -276,7 +318,8 @@ def add_newbot_args(subparser): parser.add_argument('--sharded', help='whether to use AutoShardedBot', action='store_true') parser.add_argument('--no-git', help='do not create a .gitignore file', action='store_true', dest='no_git') -def add_newcog_args(subparser): + +def add_newcog_args(subparser: argparse._SubParsersAction[argparse.ArgumentParser]) -> None: parser = subparser.add_parser('newcog', help='creates a new cog template quickly') parser.set_defaults(func=newcog) @@ -287,7 +330,8 @@ def add_newcog_args(subparser): parser.add_argument('--hide-commands', help='whether to hide all commands in the cog', action='store_true') parser.add_argument('--full', help='add all special methods as well', action='store_true') -def parse_args(): + +def parse_args() -> Tuple[argparse.ArgumentParser, argparse.Namespace]: parser = argparse.ArgumentParser(prog='discord', description='Tools for helping with discord.py') parser.add_argument('-v', '--version', action='store_true', help='shows the library version') parser.set_defaults(func=core) @@ -297,9 +341,11 @@ def parse_args(): add_newcog_args(subparser) return parser, parser.parse_args() -def main(): + +def main() -> None: parser, args = parse_args() args.func(parser, args) + if __name__ == '__main__': main() diff --git a/dist/ba_data/python-site-packages/discord/_types.py b/dist/ba_data/python-site-packages/discord/_types.py new file mode 100644 index 00000000..33106354 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/_types.py @@ -0,0 +1,34 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +from typing import TypeVar, TYPE_CHECKING + +if TYPE_CHECKING: + from typing_extensions import TypeVar + from .client import Client + + ClientT = TypeVar('ClientT', bound=Client, covariant=True, default=Client) +else: + ClientT = TypeVar('ClientT', bound='Client', covariant=True) diff --git a/dist/ba_data/python-site-packages/discord/abc.py b/dist/ba_data/python-site-packages/discord/abc.py index 0e48a2f4..f4091887 100644 --- a/dist/ba_data/python-site-packages/discord/abc.py +++ b/dist/ba_data/python-site-packages/discord/abc.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,30 +22,168 @@ DEALINGS IN THE SOFTWARE. """ -import abc -import sys +from __future__ import annotations + import copy +import time import asyncio - -from .iterators import HistoryIterator +from datetime import datetime +from typing import ( + Any, + AsyncIterator, + Callable, + Dict, + Iterable, + List, + Optional, + TYPE_CHECKING, + Protocol, + Sequence, + Tuple, + TypeVar, + Union, + overload, + runtime_checkable, +) + +from .object import OLDEST_OBJECT, Object from .context_managers import Typing -from .enums import ChannelType -from .errors import InvalidArgument, ClientException +from .enums import ChannelType, InviteTarget +from .errors import ClientException from .mentions import AllowedMentions from .permissions import PermissionOverwrite, Permissions from .role import Role from .invite import Invite from .file import File +from .http import handle_message_parameters from .voice_client import VoiceClient, VoiceProtocol +from .sticker import GuildSticker, StickerItem from . import utils +__all__ = ( + 'Snowflake', + 'User', + 'PrivateChannel', + 'GuildChannel', + 'Messageable', + 'Connectable', +) + +T = TypeVar('T', bound=VoiceProtocol) + +if TYPE_CHECKING: + from typing_extensions import Self + + from .client import Client + from .user import ClientUser + from .asset import Asset + from .state import ConnectionState + from .guild import Guild + from .member import Member + from .channel import CategoryChannel + from .embeds import Embed + from .message import Message, MessageReference, PartialMessage + from .channel import ( + TextChannel, + DMChannel, + GroupChannel, + PartialMessageable, + VocalGuildChannel, + VoiceChannel, + StageChannel, + ) + from .threads import Thread + from .ui.view import View + from .types.channel import ( + PermissionOverwrite as PermissionOverwritePayload, + Channel as ChannelPayload, + GuildChannel as GuildChannelPayload, + OverwriteType, + ) + from .types.snowflake import ( + SnowflakeList, + ) + + PartialMessageableChannel = Union[TextChannel, VoiceChannel, StageChannel, Thread, DMChannel, PartialMessageable] + MessageableChannel = Union[PartialMessageableChannel, GroupChannel] + SnowflakeTime = Union["Snowflake", datetime] + +MISSING = utils.MISSING + + class _Undefined: - def __repr__(self): + def __repr__(self) -> str: return 'see-below' -_undefined = _Undefined() -class Snowflake(metaclass=abc.ABCMeta): +_undefined: Any = _Undefined() + + +async def _single_delete_strategy(messages: Iterable[Message], *, reason: Optional[str] = None): + for m in messages: + await m.delete() + + +async def _purge_helper( + channel: Union[Thread, TextChannel, VocalGuildChannel], + *, + limit: Optional[int] = 100, + check: Callable[[Message], bool] = MISSING, + before: Optional[SnowflakeTime] = None, + after: Optional[SnowflakeTime] = None, + around: Optional[SnowflakeTime] = None, + oldest_first: Optional[bool] = None, + bulk: bool = True, + reason: Optional[str] = None, +) -> List[Message]: + if check is MISSING: + check = lambda m: True + + iterator = channel.history(limit=limit, before=before, after=after, oldest_first=oldest_first, around=around) + ret: List[Message] = [] + count = 0 + + minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22 + strategy = channel.delete_messages if bulk else _single_delete_strategy + + async for message in iterator: + if count == 100: + to_delete = ret[-100:] + await strategy(to_delete, reason=reason) + count = 0 + await asyncio.sleep(1) + + if not check(message): + continue + + if message.id < minimum_time: + # older than 14 days old + if count == 1: + await ret[-1].delete() + elif count >= 2: + to_delete = ret[-count:] + await strategy(to_delete, reason=reason) + + count = 0 + strategy = _single_delete_strategy + + count += 1 + ret.append(message) + + # Some messages remaining to poll + if count >= 2: + # more than 2 messages -> bulk delete + to_delete = ret[-count:] + await strategy(to_delete, reason=reason) + elif count == 1: + # delete a single message + await ret[-1].delete() + + return ret + + +@runtime_checkable +class Snowflake(Protocol): """An ABC that details the common operations on a Discord model. Almost all :ref:`Discord models ` meet this @@ -61,28 +197,12 @@ class Snowflake(metaclass=abc.ABCMeta): id: :class:`int` The model's unique ID. """ - __slots__ = () - @property - @abc.abstractmethod - def created_at(self): - """:class:`datetime.datetime`: Returns the model's creation time as a naive datetime in UTC.""" - raise NotImplementedError + id: int - @classmethod - def __subclasshook__(cls, C): - if cls is Snowflake: - mro = C.__mro__ - for attr in ('created_at', 'id'): - for base in mro: - if attr in base.__dict__: - break - else: - return NotImplemented - return True - return NotImplemented -class User(metaclass=abc.ABCMeta): +@runtime_checkable +class User(Snowflake, Protocol): """An ABC that details the common operations on a Discord user. The following implement this ABC: @@ -98,43 +218,68 @@ class User(metaclass=abc.ABCMeta): name: :class:`str` The user's username. discriminator: :class:`str` - The user's discriminator. - avatar: Optional[:class:`str`] - The avatar hash the user has. + The user's discriminator. This is a legacy concept that is no longer used. + global_name: Optional[:class:`str`] + The user's global nickname. bot: :class:`bool` If the user is a bot account. + system: :class:`bool` + If the user is a system account. """ - __slots__ = () + + name: str + discriminator: str + global_name: Optional[str] + bot: bool + system: bool @property - @abc.abstractmethod - def display_name(self): + def display_name(self) -> str: """:class:`str`: Returns the user's display name.""" raise NotImplementedError @property - @abc.abstractmethod - def mention(self): + def mention(self) -> str: """:class:`str`: Returns a string that allows you to mention the given user.""" raise NotImplementedError - @classmethod - def __subclasshook__(cls, C): - if cls is User: - if Snowflake.__subclasshook__(C) is NotImplemented: - return NotImplemented - - mro = C.__mro__ - for attr in ('display_name', 'mention', 'name', 'avatar', 'discriminator', 'bot'): - for base in mro: - if attr in base.__dict__: - break - else: - return NotImplemented - return True - return NotImplemented + @property + def avatar(self) -> Optional[Asset]: + """Optional[:class:`~discord.Asset`]: Returns an Asset that represents the user's avatar, if present.""" + raise NotImplementedError + + @property + def default_avatar(self) -> Asset: + """:class:`~discord.Asset`: Returns the default avatar for a given user.""" + raise NotImplementedError + + @property + def display_avatar(self) -> Asset: + """:class:`~discord.Asset`: Returns the user's display avatar. + + For regular users this is just their default avatar or uploaded avatar. + + .. versionadded:: 2.0 + """ + raise NotImplementedError + + def mentioned_in(self, message: Message) -> bool: + """Checks if the user is mentioned in the specified message. + + Parameters + ----------- + message: :class:`~discord.Message` + The message to check if you're mentioned in. + + Returns + ------- + :class:`bool` + Indicates if the user is mentioned in the message. + """ + raise NotImplementedError + -class PrivateChannel(metaclass=abc.ABCMeta): +class PrivateChannel: """An ABC that details the common operations on a private Discord channel. The following implement this ABC: @@ -149,31 +294,26 @@ class PrivateChannel(metaclass=abc.ABCMeta): me: :class:`~discord.ClientUser` The user presenting yourself. """ + __slots__ = () - @classmethod - def __subclasshook__(cls, C): - if cls is PrivateChannel: - if Snowflake.__subclasshook__(C) is NotImplemented: - return NotImplemented + id: int + me: ClientUser - mro = C.__mro__ - for base in mro: - if 'me' in base.__dict__: - return True - return NotImplemented - return NotImplemented class _Overwrites: __slots__ = ('id', 'allow', 'deny', 'type') - def __init__(self, **kwargs): - self.id = kwargs.pop('id') - self.allow = int(kwargs.pop('allow_new', 0)) - self.deny = int(kwargs.pop('deny_new', 0)) - self.type = sys.intern(kwargs.pop('type')) + ROLE = 0 + MEMBER = 1 + + def __init__(self, data: PermissionOverwritePayload) -> None: + self.id: int = int(data['id']) + self.allow: int = int(data.get('allow', 0)) + self.deny: int = int(data.get('deny', 0)) + self.type: OverwriteType = data['type'] - def _asdict(self): + def _asdict(self) -> PermissionOverwritePayload: return { 'id': self.id, 'allow': str(self.allow), @@ -181,6 +321,13 @@ def _asdict(self): 'type': self.type, } + def is_role(self) -> bool: + return self.type == 0 + + def is_member(self) -> bool: + return self.type == 1 + + class GuildChannel: """An ABC that details the common operations on a Discord guild channel. @@ -190,6 +337,7 @@ class GuildChannel: - :class:`~discord.VoiceChannel` - :class:`~discord.CategoryChannel` - :class:`~discord.StageChannel` + - :class:`~discord.ForumChannel` This ABC must also implement :class:`~discord.abc.Snowflake`. @@ -203,22 +351,47 @@ class GuildChannel: The position in the channel list. This is a number that starts at 0. e.g. the top channel is position 0. """ + __slots__ = () - def __str__(self): + id: int + name: str + guild: Guild + type: ChannelType + position: int + category_id: Optional[int] + _state: ConnectionState + _overwrites: List[_Overwrites] + + if TYPE_CHECKING: + + def __init__(self, *, state: ConnectionState, guild: Guild, data: GuildChannelPayload): + ... + + def __str__(self) -> str: return self.name @property - def _sorting_bucket(self): + def _sorting_bucket(self) -> int: raise NotImplementedError - async def _move(self, position, parent_id=None, lock_permissions=False, *, reason): + def _update(self, guild: Guild, data: Dict[str, Any]) -> None: + raise NotImplementedError + + async def _move( + self, + position: int, + parent_id: Optional[Any] = None, + lock_permissions: bool = False, + *, + reason: Optional[str], + ) -> None: if position < 0: - raise InvalidArgument('Channel position cannot be less than 0.') + raise ValueError('Channel position cannot be less than 0.') http = self._state.http bucket = self._sorting_bucket - channels = [c for c in self.guild.channels if c._sorting_bucket == bucket] + channels: List[GuildChannel] = [c for c in self.guild.channels if c._sorting_bucket == bucket] channels.sort(key=lambda c: c.position) @@ -235,17 +408,14 @@ async def _move(self, position, parent_id=None, lock_permissions=False, *, reaso payload = [] for index, c in enumerate(channels): - d = {'id': c.id, 'position': index} + d: Dict[str, Any] = {'id': c.id, 'position': index} if parent_id is not _undefined and c.id == self.id: d.update(parent_id=parent_id, lock_permissions=lock_permissions) payload.append(d) await http.bulk_channel_update(self.guild.id, payload, reason=reason) - self.position = position - if parent_id is not _undefined: - self.category_id = int(parent_id) if parent_id else None - async def _edit(self, options, reason): + async def _edit(self, options: Dict[str, Any], reason: Optional[str]) -> Optional[ChannelPayload]: try: parent = options.pop('category') except KeyError: @@ -258,6 +428,11 @@ async def _edit(self, options, reason): except KeyError: pass + try: + options['default_thread_rate_limit_per_user'] = options.pop('default_thread_slowmode_delay') + except KeyError: + pass + try: rtc_region = options.pop('rtc_region') except KeyError: @@ -265,6 +440,13 @@ async def _edit(self, options, reason): else: options['rtc_region'] = None if rtc_region is None else str(rtc_region) + try: + video_quality_mode = options.pop('video_quality_mode') + except KeyError: + pass + else: + options['video_quality_mode'] = int(video_quality_mode) + lock_permissions = options.pop('sync_permissions', False) try: @@ -273,13 +455,15 @@ async def _edit(self, options, reason): if parent_id is not _undefined: if lock_permissions: category = self.guild.get_channel(parent_id) - options['permission_overwrites'] = [c._asdict() for c in category._overwrites] + if category: + options['permission_overwrites'] = [c._asdict() for c in category._overwrites] options['parent_id'] = parent_id elif lock_permissions and self.category_id is not None: # if we're syncing permissions on a pre-existing channel category without changing it # we need to update the permissions to point to the pre-existing category category = self.guild.get_channel(self.category_id) - options['permission_overwrites'] = [c._asdict() for c in category._overwrites] + if category: + options['permission_overwrites'] = [c._asdict() for c in category._overwrites] else: await self._move(position, parent_id=parent_id, lock_permissions=lock_permissions, reason=reason) @@ -288,19 +472,21 @@ async def _edit(self, options, reason): perms = [] for target, perm in overwrites.items(): if not isinstance(perm, PermissionOverwrite): - raise InvalidArgument('Expected PermissionOverwrite received {0.__name__}'.format(type(perm))) + raise TypeError(f'Expected PermissionOverwrite received {perm.__class__.__name__}') allow, deny = perm.pair() payload = { 'allow': allow.value, 'deny': deny.value, - 'id': target.id + 'id': target.id, } if isinstance(target, Role): - payload['type'] = 'role' + payload['type'] = _Overwrites.ROLE + elif isinstance(target, Object): + payload['type'] = _Overwrites.ROLE if target.type is Role else _Overwrites.MEMBER else: - payload['type'] = 'member' + payload['type'] = _Overwrites.MEMBER perms.append(payload) options['permission_overwrites'] = perms @@ -311,26 +497,25 @@ async def _edit(self, options, reason): pass else: if not isinstance(ch_type, ChannelType): - raise InvalidArgument('type field must be of type ChannelType') + raise TypeError('type field must be of type ChannelType') options['type'] = ch_type.value if options: - data = await self._state.http.edit_channel(self.id, reason=reason, **options) - self._update(self.guild, data) + return await self._state.http.edit_channel(self.id, reason=reason, **options) - def _fill_overwrites(self, data): + def _fill_overwrites(self, data: GuildChannelPayload) -> None: self._overwrites = [] everyone_index = 0 everyone_id = self.guild.id for index, overridden in enumerate(data.get('permission_overwrites', [])): - overridden_id = int(overridden.pop('id')) - self._overwrites.append(_Overwrites(id=overridden_id, **overridden)) + overwrite = _Overwrites(overridden) + self._overwrites.append(overwrite) - if overridden['type'] == 'member': + if overwrite.type == _Overwrites.MEMBER: continue - if overridden_id == everyone_id: + if overwrite.id == everyone_id: # the @everyone role is not guaranteed to be the first one # in the list of permission overwrites, however the permission # resolution code kind of requires that it is the first one in @@ -344,12 +529,12 @@ def _fill_overwrites(self, data): tmp[everyone_index], tmp[0] = tmp[0], tmp[everyone_index] @property - def changed_roles(self): + def changed_roles(self) -> List[Role]: """List[:class:`~discord.Role`]: Returns a list of roles that have been overridden from their default values in the :attr:`~discord.Guild.roles` attribute.""" ret = [] g = self.guild - for overwrite in filter(lambda o: o.type == 'role', self._overwrites): + for overwrite in filter(lambda o: o.is_role(), self._overwrites): role = g.get_role(overwrite.id) if role is None: continue @@ -360,23 +545,30 @@ def changed_roles(self): return ret @property - def mention(self): + def mention(self) -> str: """:class:`str`: The string that allows you to mention the channel.""" - return '<#%s>' % self.id + return f'<#{self.id}>' + + @property + def jump_url(self) -> str: + """:class:`str`: Returns a URL that allows the client to jump to the channel. + + .. versionadded:: 2.0 + """ + return f'https://discord.com/channels/{self.guild.id}/{self.id}' @property - def created_at(self): + def created_at(self) -> datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return utils.snowflake_time(self.id) - def overwrites_for(self, obj): + def overwrites_for(self, obj: Union[Role, User, Object]) -> PermissionOverwrite: """Returns the channel-specific overwrites for a member or a role. Parameters ----------- - obj: Union[:class:`~discord.Role`, :class:`~discord.abc.User`] - The role or user denoting - whose overwrite to get. + obj: Union[:class:`~discord.Role`, :class:`~discord.abc.User`, :class:`~discord.Object`] + The role or user denoting whose overwrite to get. Returns --------- @@ -385,9 +577,9 @@ def overwrites_for(self, obj): """ if isinstance(obj, User): - predicate = lambda p: p.type == 'member' + predicate = lambda p: p.is_member() elif isinstance(obj, Role): - predicate = lambda p: p.type == 'role' + predicate = lambda p: p.is_role() else: predicate = lambda p: True @@ -400,16 +592,19 @@ def overwrites_for(self, obj): return PermissionOverwrite() @property - def overwrites(self): + def overwrites(self) -> Dict[Union[Role, Member, Object], PermissionOverwrite]: """Returns all of the channel's overwrites. This is returned as a dictionary where the key contains the target which can be either a :class:`~discord.Role` or a :class:`~discord.Member` and the value is the overwrite as a :class:`~discord.PermissionOverwrite`. + .. versionchanged:: 2.0 + Overwrites can now be type-aware :class:`~discord.Object` in case of cache lookup failure + Returns -------- - Mapping[Union[:class:`~discord.Role`, :class:`~discord.Member`], :class:`~discord.PermissionOverwrite`] + Dict[Union[:class:`~discord.Role`, :class:`~discord.Member`, :class:`~discord.Object`], :class:`~discord.PermissionOverwrite`] The channel's permission overwrites. """ ret = {} @@ -417,31 +612,30 @@ def overwrites(self): allow = Permissions(ow.allow) deny = Permissions(ow.deny) overwrite = PermissionOverwrite.from_pair(allow, deny) + target = None - if ow.type == 'role': + if ow.is_role(): target = self.guild.get_role(ow.id) - elif ow.type == 'member': + elif ow.is_member(): target = self.guild.get_member(ow.id) - # TODO: There is potential data loss here in the non-chunked - # case, i.e. target is None because get_member returned nothing. - # This can be fixed with a slight breaking change to the return type, - # i.e. adding discord.Object to the list of it - # However, for now this is an acceptable compromise. - if target is not None: - ret[target] = overwrite + if target is None: + target_type = Role if ow.is_role() else User + target = Object(id=ow.id, type=target_type) # type: ignore + + ret[target] = overwrite return ret @property - def category(self): + def category(self) -> Optional[CategoryChannel]: """Optional[:class:`~discord.CategoryChannel`]: The category this channel belongs to. If there is no category then this is ``None``. """ - return self.guild.get_channel(self.category_id) + return self.guild.get_channel(self.category_id) # type: ignore # These are coerced into CategoryChannel @property - def permissions_synced(self): + def permissions_synced(self) -> bool: """:class:`bool`: Whether or not the permissions for this channel are synced with the category it belongs to. @@ -449,11 +643,29 @@ def permissions_synced(self): .. versionadded:: 1.3 """ + if self.category_id is None: + return False + category = self.guild.get_channel(self.category_id) return bool(category and category.overwrites == self.overwrites) - def permissions_for(self, member): - """Handles permission resolution for the current :class:`~discord.Member`. + def _apply_implicit_permissions(self, base: Permissions) -> None: + # if you can't send a message in a channel then you can't have certain + # permissions as well + if not base.send_messages: + base.send_tts_messages = False + base.mention_everyone = False + base.embed_links = False + base.attach_files = False + + # if you can't read a channel then you have no permissions there + if not base.read_messages: + denied = Permissions.all_channel() + base.value &= ~denied.value + + def permissions_for(self, obj: Union[Member, Role], /) -> Permissions: + """Handles permission resolution for the :class:`~discord.Member` + or :class:`~discord.Role`. This function takes into consideration the following cases: @@ -461,16 +673,34 @@ def permissions_for(self, member): - Guild roles - Channel overrides - Member overrides + - Implicit permissions + - Member timeout + + If a :class:`~discord.Role` is passed, then it checks the permissions + someone with that role would have, which is essentially: + + - The default role permissions + - The permissions of the role used as a parameter + - The default role permission overwrites + - The permission overwrites of the role used as a parameter + + .. versionchanged:: 2.0 + The object passed in can now be a role object. + + .. versionchanged:: 2.0 + ``obj`` parameter is now positional-only. Parameters ---------- - member: :class:`~discord.Member` - The member to resolve permissions for. + obj: Union[:class:`~discord.Member`, :class:`~discord.Role`] + The object to resolve permissions for. This could be either + a member or a role. If it's a role then member overwrites + are not computed. Returns ------- :class:`~discord.Permissions` - The resolved permissions for the member. + The resolved permissions for the member or role. """ # The current cases can be explained as: @@ -487,12 +717,37 @@ def permissions_for(self, member): # The operation first takes into consideration the denied # and then the allowed. - if self.guild.owner_id == member.id: + if self.guild.owner_id == obj.id: return Permissions.all() default = self.guild.default_role base = Permissions(default.permissions.value) - roles = member._roles + + # Handle the role case first + if isinstance(obj, Role): + base.value |= obj._permissions + + if base.administrator: + return Permissions.all() + + # Apply @everyone allow/deny first since it's special + try: + maybe_everyone = self._overwrites[0] + if maybe_everyone.id == self.guild.id: + base.handle_overwrite(allow=maybe_everyone.allow, deny=maybe_everyone.deny) + except IndexError: + pass + + if obj.is_default(): + return base + + overwrite = utils.get(self._overwrites, type=_Overwrites.ROLE, id=obj.id) + if overwrite is not None: + base.handle_overwrite(overwrite.allow, overwrite.deny) + + return base + + roles = obj._roles get_role = self.guild.get_role # Apply guild roles that the member has. @@ -522,7 +777,7 @@ def permissions_for(self, member): # Apply channel specific role permission overwrites for overwrite in remaining_overwrites: - if overwrite.type == 'role' and roles.has(overwrite.id): + if overwrite.is_role() and roles.has(overwrite.id): denies |= overwrite.deny allows |= overwrite.allow @@ -530,31 +785,24 @@ def permissions_for(self, member): # Apply member specific permission overwrites for overwrite in remaining_overwrites: - if overwrite.type == 'member' and overwrite.id == member.id: + if overwrite.is_member() and overwrite.id == obj.id: base.handle_overwrite(allow=overwrite.allow, deny=overwrite.deny) break - # if you can't send a message in a channel then you can't have certain - # permissions as well - if not base.send_messages: - base.send_tts_messages = False - base.mention_everyone = False - base.embed_links = False - base.attach_files = False - - # if you can't read a channel then you have no permissions there - if not base.read_messages: - denied = Permissions.all_channel() - base.value &= ~denied.value + if obj.is_timed_out(): + # Timeout leads to every permission except VIEW_CHANNEL and READ_MESSAGE_HISTORY + # being explicitly denied + # N.B.: This *must* come last, because it's a conclusive mask + base.value &= Permissions._timeout_mask() return base - async def delete(self, *, reason=None): + async def delete(self, *, reason: Optional[str] = None) -> None: """|coro| Deletes the channel. - You must have :attr:`~Permissions.manage_channels` permission to use this. + You must have :attr:`~discord.Permissions.manage_channels` to do this. Parameters ----------- @@ -573,7 +821,34 @@ async def delete(self, *, reason=None): """ await self._state.http.delete_channel(self.id, reason=reason) - async def set_permissions(self, target, *, overwrite=_undefined, reason=None, **permissions): + @overload + async def set_permissions( + self, + target: Union[Member, Role], + *, + overwrite: Optional[Union[PermissionOverwrite, _Undefined]] = ..., + reason: Optional[str] = ..., + ) -> None: + ... + + @overload + async def set_permissions( + self, + target: Union[Member, Role], + *, + reason: Optional[str] = ..., + **permissions: Optional[bool], + ) -> None: + ... + + async def set_permissions( + self, + target: Union[Member, Role], + *, + overwrite: Any = _undefined, + reason: Optional[str] = None, + **permissions: Optional[bool], + ) -> None: r"""|coro| Sets the channel specific permission overwrites for a target in the @@ -591,7 +866,11 @@ async def set_permissions(self, target, *, overwrite=_undefined, reason=None, ** If the ``overwrite`` parameter is ``None``, then the permission overwrites are deleted. - You must have the :attr:`~Permissions.manage_roles` permission to use this. + You must have :attr:`~discord.Permissions.manage_roles` to do this. + + .. note:: + + This method *replaces* the old overwrites with the ones given. Examples ---------- @@ -612,6 +891,11 @@ async def set_permissions(self, target, *, overwrite=_undefined, reason=None, ** overwrite.read_messages = True await channel.set_permissions(member, overwrite=overwrite) + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` instead of + ``InvalidArgument``. + + Parameters ----------- target: Union[:class:`~discord.Member`, :class:`~discord.Role`] @@ -633,45 +917,52 @@ async def set_permissions(self, target, *, overwrite=_undefined, reason=None, ** Editing channel specific permissions failed. ~discord.NotFound The role or member being edited is not part of the guild. - ~discord.InvalidArgument - The overwrite parameter invalid or the target type was not + TypeError + The ``overwrite`` parameter was invalid or the target type was not :class:`~discord.Role` or :class:`~discord.Member`. + ValueError + The ``overwrite`` parameter and ``positions`` parameters were both + unset. """ http = self._state.http if isinstance(target, User): - perm_type = 'member' + perm_type = _Overwrites.MEMBER elif isinstance(target, Role): - perm_type = 'role' + perm_type = _Overwrites.ROLE else: - raise InvalidArgument('target parameter must be either Member or Role') + raise ValueError('target parameter must be either Member or Role') - if isinstance(overwrite, _Undefined): + if overwrite is _undefined: if len(permissions) == 0: - raise InvalidArgument('No overwrite provided.') + raise ValueError('No overwrite provided.') try: overwrite = PermissionOverwrite(**permissions) except (ValueError, TypeError): - raise InvalidArgument('Invalid permissions given to keyword arguments.') + raise TypeError('Invalid permissions given to keyword arguments.') else: if len(permissions) > 0: - raise InvalidArgument('Cannot mix overwrite and keyword arguments.') - - # TODO: wait for event + raise TypeError('Cannot mix overwrite and keyword arguments.') if overwrite is None: await http.delete_channel_permissions(self.id, target.id, reason=reason) elif isinstance(overwrite, PermissionOverwrite): (allow, deny) = overwrite.pair() - await http.edit_channel_permissions(self.id, target.id, allow.value, deny.value, perm_type, reason=reason) + await http.edit_channel_permissions( + self.id, target.id, str(allow.value), str(deny.value), perm_type, reason=reason + ) else: - raise InvalidArgument('Invalid overwrite type provided.') - - async def _clone_impl(self, base_attrs, *, name=None, reason=None): - base_attrs['permission_overwrites'] = [ - x._asdict() for x in self._overwrites - ] + raise TypeError('Invalid overwrite type provided.') + + async def _clone_impl( + self, + base_attrs: Dict[str, Any], + *, + name: Optional[str] = None, + reason: Optional[str] = None, + ) -> Self: + base_attrs['permission_overwrites'] = [x._asdict() for x in self._overwrites] base_attrs['parent_id'] = self.category_id base_attrs['name'] = name or self.name guild_id = self.guild.id @@ -680,17 +971,16 @@ async def _clone_impl(self, base_attrs, *, name=None, reason=None): obj = cls(state=self._state, guild=self.guild, data=data) # temporarily add it to the cache - self.guild._channels[obj.id] = obj + self.guild._channels[obj.id] = obj # type: ignore # obj is a GuildChannel return obj - async def clone(self, *, name=None, reason=None): + async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> Self: """|coro| Clones this channel. This creates a channel with the same properties as this channel. - You must have the :attr:`~discord.Permissions.manage_channels` permission to - do this. + You must have :attr:`~discord.Permissions.manage_channels` to do this. .. versionadded:: 1.1 @@ -716,15 +1006,62 @@ async def clone(self, *, name=None, reason=None): """ raise NotImplementedError - async def move(self, **kwargs): + @overload + async def move( + self, + *, + beginning: bool, + offset: int = MISSING, + category: Optional[Snowflake] = MISSING, + sync_permissions: bool = MISSING, + reason: Optional[str] = MISSING, + ) -> None: + ... + + @overload + async def move( + self, + *, + end: bool, + offset: int = MISSING, + category: Optional[Snowflake] = MISSING, + sync_permissions: bool = MISSING, + reason: str = MISSING, + ) -> None: + ... + + @overload + async def move( + self, + *, + before: Snowflake, + offset: int = MISSING, + category: Optional[Snowflake] = MISSING, + sync_permissions: bool = MISSING, + reason: str = MISSING, + ) -> None: + ... + + @overload + async def move( + self, + *, + after: Snowflake, + offset: int = MISSING, + category: Optional[Snowflake] = MISSING, + sync_permissions: bool = MISSING, + reason: str = MISSING, + ) -> None: + ... + + async def move(self, **kwargs: Any) -> None: """|coro| A rich interface to help move a channel relative to other channels. - If exact position movement is required, :meth:`edit` should be used instead. + If exact position movement is required, ``edit`` should be used instead. - You must have the :attr:`~discord.Permissions.manage_channels` permission to - do this. + You must have :attr:`~discord.Permissions.manage_channels` to do this. .. note:: @@ -733,6 +1070,10 @@ async def move(self, **kwargs): .. versionadded:: 1.7 + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` or + :exc:`ValueError` instead of ``InvalidArgument``. + Parameters ------------ beginning: :class:`bool` @@ -767,8 +1108,10 @@ async def move(self, **kwargs): Raises ------- - InvalidArgument - An invalid position was given or a bad mix of arguments were passed. + ValueError + An invalid position was given. + TypeError + A bad mix of arguments were passed. Forbidden You do not have permissions to move the channel. HTTPException @@ -782,11 +1125,13 @@ async def move(self, **kwargs): before, after = kwargs.get('before'), kwargs.get('after') offset = kwargs.get('offset', 0) if sum(bool(a) for a in (beginning, end, before, after)) > 1: - raise InvalidArgument('Only one of [before, after, end, beginning] can be used.') + raise TypeError('Only one of [before, after, end, beginning] can be used.') bucket = self._sorting_bucket - parent_id = kwargs.get('category', ...) - if parent_id not in (..., None): + parent_id = kwargs.get('category', MISSING) + # fmt: off + channels: List[GuildChannel] + if parent_id not in (MISSING, None): parent_id = parent_id.id channels = [ ch @@ -801,6 +1146,7 @@ async def move(self, **kwargs): if ch._sorting_bucket == bucket and ch.category_id == self.category_id ] + # fmt: on channels.sort(key=lambda c: (c.position, c.id)) @@ -822,28 +1168,37 @@ async def move(self, **kwargs): index = next((i + 1 for i, c in enumerate(channels) if c.id == after.id), None) if index is None: - raise InvalidArgument('Could not resolve appropriate move position') + raise ValueError('Could not resolve appropriate move position') channels.insert(max((index + offset), 0), self) payload = [] lock_permissions = kwargs.get('sync_permissions', False) reason = kwargs.get('reason') for index, channel in enumerate(channels): - d = { 'id': channel.id, 'position': index } - if parent_id is not ... and channel.id == self.id: + d = {'id': channel.id, 'position': index} + if parent_id is not MISSING and channel.id == self.id: d.update(parent_id=parent_id, lock_permissions=lock_permissions) payload.append(d) await self._state.http.bulk_channel_update(self.guild.id, payload, reason=reason) - - async def create_invite(self, *, reason=None, **fields): + async def create_invite( + self, + *, + reason: Optional[str] = None, + max_age: int = 0, + max_uses: int = 0, + temporary: bool = False, + unique: bool = True, + target_type: Optional[InviteTarget] = None, + target_user: Optional[User] = None, + target_application_id: Optional[int] = None, + ) -> Invite: """|coro| Creates an instant invite from a text or voice channel. - You must have the :attr:`~Permissions.create_instant_invite` permission to - do this. + You must have :attr:`~discord.Permissions.create_instant_invite` to do this. Parameters ------------ @@ -862,6 +1217,20 @@ async def create_invite(self, *, reason=None, **fields): invite. reason: Optional[:class:`str`] The reason for creating this invite. Shows up on the audit log. + target_type: Optional[:class:`.InviteTarget`] + The type of target for the voice channel invite, if any. + + .. versionadded:: 2.0 + + target_user: Optional[:class:`User`] + The user whose stream to display for this invite, required if ``target_type`` is :attr:`.InviteTarget.stream`. The user must be streaming in the channel. + + .. versionadded:: 2.0 + + target_application_id:: Optional[:class:`int`] + The id of the embedded application for the invite, required if ``target_type`` is :attr:`.InviteTarget.embedded_application`. + + .. versionadded:: 2.0 Raises ------- @@ -877,15 +1246,25 @@ async def create_invite(self, *, reason=None, **fields): The invite that was created. """ - data = await self._state.http.create_invite(self.id, reason=reason, **fields) + data = await self._state.http.create_invite( + self.id, + reason=reason, + max_age=max_age, + max_uses=max_uses, + temporary=temporary, + unique=unique, + target_type=target_type.value if target_type else None, + target_user_id=target_user.id if target_user else None, + target_application_id=target_application_id, + ) return Invite.from_incomplete(data=data, state=self._state) - async def invites(self): + async def invites(self) -> List[Invite]: """|coro| Returns a list of all active instant invites from this channel. - You must have :attr:`~Permissions.manage_channels` to get this information. + You must have :attr:`~discord.Permissions.manage_channels` to get this information. Raises ------- @@ -902,38 +1281,132 @@ async def invites(self): state = self._state data = await state.http.invites_from_channel(self.id) - result = [] + guild = self.guild + return [Invite(state=state, data=invite, channel=self, guild=guild) for invite in data] - for invite in data: - invite['channel'] = self - invite['guild'] = self.guild - result.append(Invite(state=state, data=invite)) - return result - -class Messageable(metaclass=abc.ABCMeta): +class Messageable: """An ABC that details the common operations on a model that can send messages. - The following implement this ABC: + The following classes implement this ABC: - :class:`~discord.TextChannel` + - :class:`~discord.VoiceChannel` + - :class:`~discord.StageChannel` - :class:`~discord.DMChannel` - :class:`~discord.GroupChannel` + - :class:`~discord.PartialMessageable` - :class:`~discord.User` - :class:`~discord.Member` - :class:`~discord.ext.commands.Context` + - :class:`~discord.Thread` """ __slots__ = () + _state: ConnectionState - @abc.abstractmethod - async def _get_channel(self): + async def _get_channel(self) -> MessageableChannel: raise NotImplementedError - async def send(self, content=None, *, tts=False, embed=None, file=None, - files=None, delete_after=None, nonce=None, - allowed_mentions=None, reference=None, - mention_author=None): + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embed: Embed = ..., + file: File = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embed: Embed = ..., + files: Sequence[File] = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embeds: Sequence[Embed] = ..., + file: File = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embeds: Sequence[Embed] = ..., + files: Sequence[File] = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + async def send( + self, + content: Optional[str] = None, + *, + tts: bool = False, + embed: Optional[Embed] = None, + embeds: Optional[Sequence[Embed]] = None, + file: Optional[File] = None, + files: Optional[Sequence[File]] = None, + stickers: Optional[Sequence[Union[GuildSticker, StickerItem]]] = None, + delete_after: Optional[float] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[AllowedMentions] = None, + reference: Optional[Union[Message, MessageReference, PartialMessage]] = None, + mention_author: Optional[bool] = None, + view: Optional[View] = None, + suppress_embeds: bool = False, + silent: bool = False, + ) -> Message: """|coro| Sends a message to the destination with the content given. @@ -947,17 +1420,27 @@ async def send(self, content=None, *, tts=False, embed=None, file=None, parameter should be used with a :class:`list` of :class:`~discord.File` objects. **Specifying both parameters will lead to an exception**. - If the ``embed`` parameter is provided, it must be of type :class:`~discord.Embed` and - it must be a rich embed type. + To upload a single embed, the ``embed`` parameter should be used with a + single :class:`~discord.Embed` object. To upload multiple embeds, the ``embeds`` + parameter should be used with a :class:`list` of :class:`~discord.Embed` objects. + **Specifying both parameters will lead to an exception**. + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` or + :exc:`ValueError` instead of ``InvalidArgument``. Parameters ------------ - content: :class:`str` + content: Optional[:class:`str`] The content of the message to send. tts: :class:`bool` Indicates if the message should be sent using text-to-speech. embed: :class:`~discord.Embed` The rich embed for the content. + embeds: List[:class:`~discord.Embed`] + A list of embeds to upload. Must be a maximum of 10. + + .. versionadded:: 2.0 file: :class:`~discord.File` The file to upload. files: List[:class:`~discord.File`] @@ -979,7 +1462,7 @@ async def send(self, content=None, *, tts=False, embed=None, file=None, .. versionadded:: 1.4 - reference: Union[:class:`~discord.Message`, :class:`~discord.MessageReference`] + reference: Union[:class:`~discord.Message`, :class:`~discord.MessageReference`, :class:`~discord.PartialMessage`] A reference to the :class:`~discord.Message` to which you are replying, this can be created using :meth:`~discord.Message.to_reference` or passed directly as a :class:`~discord.Message`. You can control whether this mentions the author of the referenced message using the :attr:`~discord.AllowedMentions.replied_user` @@ -991,6 +1474,23 @@ async def send(self, content=None, *, tts=False, embed=None, file=None, If set, overrides the :attr:`~discord.AllowedMentions.replied_user` attribute of ``allowed_mentions``. .. versionadded:: 1.6 + view: :class:`discord.ui.View` + A Discord UI View to add to the message. + + .. versionadded:: 2.0 + stickers: Sequence[Union[:class:`~discord.GuildSticker`, :class:`~discord.StickerItem`]] + A list of stickers to upload. Must be a maximum of 3. + + .. versionadded:: 2.0 + suppress_embeds: :class:`bool` + Whether to suppress embeds for the message. This sends the message without any embeds if set to ``True``. + + .. versionadded:: 2.0 + silent: :class:`bool` + Whether to suppress push and desktop notifications for the message. This will increment the mention counter + in the UI, but will not actually send a notification. + + .. versionadded:: 2.2 Raises -------- @@ -998,11 +1498,13 @@ async def send(self, content=None, *, tts=False, embed=None, file=None, Sending the message failed. ~discord.Forbidden You do not have the proper permissions to send the message. - ~discord.InvalidArgument - The ``files`` list is not of the appropriate size, - you specified both ``file`` and ``files``, - or the ``reference`` object is not a :class:`~discord.Message` - or :class:`~discord.MessageReference`. + ValueError + The ``files`` or ``embeds`` list is not of the appropriate size. + TypeError + You specified both ``file`` and ``files``, + or you specified both ``embed`` and ``embeds``, + or the ``reference`` object is not a :class:`~discord.Message`, + :class:`~discord.MessageReference` or :class:`~discord.PartialMessage`. Returns --------- @@ -1013,101 +1515,91 @@ async def send(self, content=None, *, tts=False, embed=None, file=None, channel = await self._get_channel() state = self._state content = str(content) if content is not None else None - if embed is not None: - embed = embed.to_dict() + previous_allowed_mention = state.allowed_mentions - if allowed_mentions is not None: - if state.allowed_mentions is not None: - allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict() - else: - allowed_mentions = allowed_mentions.to_dict() + if stickers is not None: + sticker_ids: SnowflakeList = [sticker.id for sticker in stickers] else: - allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict() - - if mention_author is not None: - allowed_mentions = allowed_mentions or AllowedMentions().to_dict() - allowed_mentions['replied_user'] = bool(mention_author) + sticker_ids = MISSING if reference is not None: try: - reference = reference.to_message_reference_dict() + reference_dict = reference.to_message_reference_dict() except AttributeError: - raise InvalidArgument('reference parameter must be Message or MessageReference') from None + raise TypeError('reference parameter must be Message, MessageReference, or PartialMessage') from None + else: + reference_dict = MISSING - if file is not None and files is not None: - raise InvalidArgument('cannot pass both file and files parameter to send()') + if view and not hasattr(view, '__discord_ui_view__'): + raise TypeError(f'view parameter must be View not {view.__class__.__name__}') - if file is not None: - if not isinstance(file, File): - raise InvalidArgument('file parameter must be File') + if suppress_embeds or silent: + from .message import MessageFlags # circular import - try: - data = await state.http.send_files(channel.id, files=[file], allowed_mentions=allowed_mentions, - content=content, tts=tts, embed=embed, nonce=nonce, - message_reference=reference) - finally: - file.close() - - elif files is not None: - if len(files) > 10: - raise InvalidArgument('files parameter must be a list of up to 10 elements') - elif not all(isinstance(file, File) for file in files): - raise InvalidArgument('files parameter must be a list of File') - - try: - data = await state.http.send_files(channel.id, files=files, content=content, tts=tts, - embed=embed, nonce=nonce, allowed_mentions=allowed_mentions, - message_reference=reference) - finally: - for f in files: - f.close() + flags = MessageFlags._from_value(0) + flags.suppress_embeds = suppress_embeds + flags.suppress_notifications = silent else: - data = await state.http.send_message(channel.id, content, tts=tts, embed=embed, - nonce=nonce, allowed_mentions=allowed_mentions, - message_reference=reference) + flags = MISSING + + with handle_message_parameters( + content=content, + tts=tts, + file=file if file is not None else MISSING, + files=files if files is not None else MISSING, + embed=embed if embed is not None else MISSING, + embeds=embeds if embeds is not None else MISSING, + nonce=nonce, + allowed_mentions=allowed_mentions, + message_reference=reference_dict, + previous_allowed_mentions=previous_allowed_mention, + mention_author=mention_author, + stickers=sticker_ids, + view=view, + flags=flags, + ) as params: + data = await state.http.send_message(channel.id, params=params) ret = state.create_message(channel=channel, data=data) + if view and not view.is_finished(): + state.store_view(view, ret.id) + if delete_after is not None: await ret.delete(delay=delete_after) return ret - async def trigger_typing(self): - """|coro| - - Triggers a *typing* indicator to the destination. - - *Typing* indicator will go away after 10 seconds, or after a message is sent. - """ - - channel = await self._get_channel() - await self._state.http.send_typing(channel.id) + def typing(self) -> Typing: + """Returns an asynchronous context manager that allows you to send a typing indicator to + the destination for an indefinite period of time, or 10 seconds if the context manager + is called using ``await``. - def typing(self): - """Returns a context manager that allows you to type for an indefinite period of time. - - This is useful for denoting long computations in your bot. + Example Usage: :: - .. note:: + async with channel.typing(): + # simulate something heavy + await asyncio.sleep(20) - This is both a regular context manager and an async context manager. - This means that both ``with`` and ``async with`` work with this. + await channel.send('Done!') Example Usage: :: - async with channel.typing(): - # do expensive stuff here - await channel.send('done!') + await channel.typing() + # Do some computational magic for about 10 seconds + await channel.send('Done!') + + .. versionchanged:: 2.0 + This no longer works with the ``with`` syntax, ``async with`` must be used instead. + .. versionchanged:: 2.0 + Added functionality to ``await`` the context manager to send a typing indicator for 10 seconds. """ return Typing(self) - async def fetch_message(self, id): + async def fetch_message(self, id: int, /) -> Message: """|coro| Retrieves a single :class:`~discord.Message` from the destination. - This can only be used by bot accounts. - Parameters ------------ id: :class:`int` @@ -1132,7 +1624,7 @@ async def fetch_message(self, id): data = await self._state.http.get_message(channel.id, id) return self._state.create_message(channel=channel, data=data) - async def pins(self): + async def pins(self) -> List[Message]: """|coro| Retrieves all messages that are currently pinned in the channel. @@ -1145,6 +1637,8 @@ async def pins(self): Raises ------- + ~discord.Forbidden + You do not have the permission to retrieve pinned messages. ~discord.HTTPException Retrieving the pinned messages failed. @@ -1159,10 +1653,18 @@ async def pins(self): data = await state.http.pins_from(channel.id) return [state.create_message(channel=channel, data=m) for m in data] - def history(self, *, limit=100, before=None, after=None, around=None, oldest_first=None): - """Returns an :class:`~discord.AsyncIterator` that enables receiving the destination's message history. + async def history( + self, + *, + limit: Optional[int] = 100, + before: Optional[SnowflakeTime] = None, + after: Optional[SnowflakeTime] = None, + around: Optional[SnowflakeTime] = None, + oldest_first: Optional[bool] = None, + ) -> AsyncIterator[Message]: + """Returns an :term:`asynchronous iterator` that enables receiving the destination's message history. - You must have :attr:`~Permissions.read_message_history` permissions to use this. + You must have :attr:`~discord.Permissions.read_message_history` to do this. Examples --------- @@ -1176,7 +1678,7 @@ def history(self, *, limit=100, before=None, after=None, around=None, oldest_fir Flattening into a list: :: - messages = await channel.history(limit=123).flatten() + messages = [message async for message in channel.history(limit=123)] # messages is now a list of Message... All parameters are optional. @@ -1189,13 +1691,16 @@ def history(self, *, limit=100, before=None, after=None, around=None, oldest_fir that this would make it a slow operation. before: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]] Retrieve messages before this date or message. - If a date is provided it must be a timezone-naive datetime representing UTC time. + If a datetime is provided, it is recommended to use a UTC aware datetime. + If the datetime is naive, it is assumed to be local time. after: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]] Retrieve messages after this date or message. - If a date is provided it must be a timezone-naive datetime representing UTC time. + If a datetime is provided, it is recommended to use a UTC aware datetime. + If the datetime is naive, it is assumed to be local time. around: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]] Retrieve messages around this date or message. - If a date is provided it must be a timezone-naive datetime representing UTC time. + If a datetime is provided, it is recommended to use a UTC aware datetime. + If the datetime is naive, it is assumed to be local time. When using this argument, the maximum limit is 101. Note that if the limit is an even number then this will return at most limit + 1 messages. oldest_first: Optional[:class:`bool`] @@ -1214,32 +1719,140 @@ def history(self, *, limit=100, before=None, after=None, around=None, oldest_fir :class:`~discord.Message` The message with the message data parsed. """ - return HistoryIterator(self, limit=limit, before=before, after=after, around=around, oldest_first=oldest_first) -class Connectable(metaclass=abc.ABCMeta): + async def _around_strategy(retrieve: int, around: Optional[Snowflake], limit: Optional[int]): + if not around: + return [], None, 0 + + around_id = around.id if around else None + data = await self._state.http.logs_from(channel.id, retrieve, around=around_id) + + return data, None, 0 + + async def _after_strategy(retrieve: int, after: Optional[Snowflake], limit: Optional[int]): + after_id = after.id if after else None + data = await self._state.http.logs_from(channel.id, retrieve, after=after_id) + + if data: + if limit is not None: + limit -= len(data) + + after = Object(id=int(data[0]['id'])) + + return data, after, limit + + async def _before_strategy(retrieve: int, before: Optional[Snowflake], limit: Optional[int]): + before_id = before.id if before else None + data = await self._state.http.logs_from(channel.id, retrieve, before=before_id) + + if data: + if limit is not None: + limit -= len(data) + + before = Object(id=int(data[-1]['id'])) + + return data, before, limit + + if isinstance(before, datetime): + before = Object(id=utils.time_snowflake(before, high=False)) + if isinstance(after, datetime): + after = Object(id=utils.time_snowflake(after, high=True)) + if isinstance(around, datetime): + around = Object(id=utils.time_snowflake(around)) + + if oldest_first is None: + reverse = after is not None + else: + reverse = oldest_first + + after = after or OLDEST_OBJECT + predicate = None + + if around: + if limit is None: + raise ValueError('history does not support around with limit=None') + if limit > 101: + raise ValueError("history max limit 101 when specifying around parameter") + + # Strange Discord quirk + limit = 100 if limit == 101 else limit + + strategy, state = _around_strategy, around + + if before and after: + predicate = lambda m: after.id < int(m['id']) < before.id + elif before: + predicate = lambda m: int(m['id']) < before.id + elif after: + predicate = lambda m: after.id < int(m['id']) + elif reverse: + strategy, state = _after_strategy, after + if before: + predicate = lambda m: int(m['id']) < before.id + else: + strategy, state = _before_strategy, before + if after and after != OLDEST_OBJECT: + predicate = lambda m: int(m['id']) > after.id + + channel = await self._get_channel() + + while True: + retrieve = 100 if limit is None else min(limit, 100) + if retrieve < 1: + return + + data, state, limit = await strategy(retrieve, state, limit) + + if reverse: + data = reversed(data) + if predicate: + data = filter(predicate, data) + + count = 0 + + for count, raw_message in enumerate(data, 1): + yield self._state.create_message(channel=channel, data=raw_message) + + if count < 100: + # There's no data left after this + break + + +class Connectable(Protocol): """An ABC that details the common operations on a channel that can connect to a voice server. The following implement this ABC: - :class:`~discord.VoiceChannel` + - :class:`~discord.StageChannel` """ + __slots__ = () + _state: ConnectionState - @abc.abstractmethod - def _get_voice_client_key(self): + def _get_voice_client_key(self) -> Tuple[int, str]: raise NotImplementedError - @abc.abstractmethod - def _get_voice_state_pair(self): + def _get_voice_state_pair(self) -> Tuple[int, int]: raise NotImplementedError - async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient): + async def connect( + self, + *, + timeout: float = 60.0, + reconnect: bool = True, + cls: Callable[[Client, Connectable], T] = VoiceClient, + self_deaf: bool = False, + self_mute: bool = False, + ) -> T: """|coro| - Connects to voice and creates a :class:`VoiceClient` to establish + Connects to voice and creates a :class:`~discord.VoiceClient` to establish your connection to the voice server. + This requires :attr:`~discord.Intents.voice_states`. + Parameters ----------- timeout: :class:`float` @@ -1248,9 +1861,17 @@ async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient): Whether the bot should automatically attempt a reconnect if a part of the handshake fails or the gateway goes down. - cls: Type[:class:`VoiceProtocol`] + cls: Type[:class:`~discord.VoiceProtocol`] A type that subclasses :class:`~discord.VoiceProtocol` to connect with. Defaults to :class:`~discord.VoiceClient`. + self_mute: :class:`bool` + Indicates if the client should be self-muted. + + .. versionadded:: 2.0 + self_deaf: :class:`bool` + Indicates if the client should be self-deafened. + + .. versionadded:: 2.0 Raises ------- @@ -1274,7 +1895,7 @@ async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient): raise ClientException('Already connected to a voice channel.') client = state._get_client() - voice = cls(client, self) + voice: T = cls(client, self) if not isinstance(voice, VoiceProtocol): raise TypeError('Type must meet VoiceProtocol abstract base class.') @@ -1282,13 +1903,13 @@ async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient): state._add_voice_client(key_id, voice) try: - await voice.connect(timeout=timeout, reconnect=reconnect) + await voice.connect(timeout=timeout, reconnect=reconnect, self_deaf=self_deaf, self_mute=self_mute) except asyncio.TimeoutError: try: await voice.disconnect(force=True) except Exception: # we don't care if disconnect failed because connection failed pass - raise # re-raise + raise # re-raise return voice diff --git a/dist/ba_data/python-site-packages/discord/activity.py b/dist/ba_data/python-site-packages/discord/activity.py index cf5192ad..534d12a2 100644 --- a/dist/ba_data/python-site-packages/discord/activity.py +++ b/dist/ba_data/python-site-packages/discord/activity.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,7 +22,10 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + import datetime +from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union, overload from .asset import Asset from .enums import ActivityType, try_enum @@ -73,6 +74,7 @@ sync_id: str session_id: str flags: int +buttons: list[str (max: 32)] There are also activity flags which are mostly uninteresting for the library atm. @@ -86,6 +88,17 @@ } """ +if TYPE_CHECKING: + from .types.activity import ( + Activity as ActivityPayload, + ActivityTimestamps, + ActivityParty, + ActivityAssets, + ) + + from .state import ConnectionState + + class BaseActivity: """The base activity that all user-settable activities inherit from. A user-settable activity is one that can be used in :meth:`Client.change_presence`. @@ -104,19 +117,24 @@ class BaseActivity: .. versionadded:: 1.3 """ + __slots__ = ('_created_at',) - def __init__(self, **kwargs): - self._created_at = kwargs.pop('created_at', None) + def __init__(self, **kwargs: Any) -> None: + self._created_at: Optional[float] = kwargs.pop('created_at', None) @property - def created_at(self): + def created_at(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC. .. versionadded:: 1.3 """ if self._created_at is not None: - return datetime.datetime.utcfromtimestamp(self._created_at / 1000) + return datetime.datetime.fromtimestamp(self._created_at / 1000, tz=datetime.timezone.utc) + + def to_dict(self) -> ActivityPayload: + raise NotImplementedError + class Activity(BaseActivity): """Represents an activity in Discord. @@ -132,17 +150,17 @@ class Activity(BaseActivity): Attributes ------------ - application_id: :class:`int` + application_id: Optional[:class:`int`] The application ID of the game. - name: :class:`str` + name: Optional[:class:`str`] The name of the activity. - url: :class:`str` + url: Optional[:class:`str`] A stream URL that the activity could be doing. type: :class:`ActivityType` The type of activity currently being done. - state: :class:`str` + state: Optional[:class:`str`] The user's current state. For example, "In Game". - details: :class:`str` + details: Optional[:class:`str`] The detail of the user's current activity. timestamps: :class:`dict` A dictionary of timestamps. It contains the following optional keys: @@ -166,49 +184,70 @@ class Activity(BaseActivity): - ``id``: A string representing the party ID. - ``size``: A list of up to two integer elements denoting (current_size, maximum_size). + buttons: List[:class:`str`] + A list of strings representing the labels of custom buttons shown in a rich presence. + + .. versionadded:: 2.0 + emoji: Optional[:class:`PartialEmoji`] The emoji that belongs to this activity. """ - __slots__ = ('state', 'details', '_created_at', 'timestamps', 'assets', 'party', - 'flags', 'sync_id', 'session_id', 'type', 'name', 'url', - 'application_id', 'emoji') - - def __init__(self, **kwargs): + __slots__ = ( + 'state', + 'details', + 'timestamps', + 'assets', + 'party', + 'flags', + 'sync_id', + 'session_id', + 'type', + 'name', + 'url', + 'application_id', + 'emoji', + 'buttons', + ) + + def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) - self.state = kwargs.pop('state', None) - self.details = kwargs.pop('details', None) - self.timestamps = kwargs.pop('timestamps', {}) - self.assets = kwargs.pop('assets', {}) - self.party = kwargs.pop('party', {}) - self.application_id = _get_as_snowflake(kwargs, 'application_id') - self.name = kwargs.pop('name', None) - self.url = kwargs.pop('url', None) - self.flags = kwargs.pop('flags', 0) - self.sync_id = kwargs.pop('sync_id', None) - self.session_id = kwargs.pop('session_id', None) - self.type = try_enum(ActivityType, kwargs.pop('type', -1)) + self.state: Optional[str] = kwargs.pop('state', None) + self.details: Optional[str] = kwargs.pop('details', None) + self.timestamps: ActivityTimestamps = kwargs.pop('timestamps', {}) + self.assets: ActivityAssets = kwargs.pop('assets', {}) + self.party: ActivityParty = kwargs.pop('party', {}) + self.application_id: Optional[int] = _get_as_snowflake(kwargs, 'application_id') + self.name: Optional[str] = kwargs.pop('name', None) + self.url: Optional[str] = kwargs.pop('url', None) + self.flags: int = kwargs.pop('flags', 0) + self.sync_id: Optional[str] = kwargs.pop('sync_id', None) + self.session_id: Optional[str] = kwargs.pop('session_id', None) + self.buttons: List[str] = kwargs.pop('buttons', []) + + activity_type = kwargs.pop('type', -1) + self.type: ActivityType = ( + activity_type if isinstance(activity_type, ActivityType) else try_enum(ActivityType, activity_type) + ) + emoji = kwargs.pop('emoji', None) - if emoji is not None: - self.emoji = PartialEmoji.from_dict(emoji) - else: - self.emoji = None + self.emoji: Optional[PartialEmoji] = PartialEmoji.from_dict(emoji) if emoji is not None else None - def __repr__(self): + def __repr__(self) -> str: attrs = ( - 'type', - 'name', - 'url', - 'details', - 'application_id', - 'session_id', - 'emoji', + ('type', self.type), + ('name', self.name), + ('url', self.url), + ('details', self.details), + ('application_id', self.application_id), + ('session_id', self.session_id), + ('emoji', self.emoji), ) - mapped = ' '.join('%s=%r' % (attr, getattr(self, attr)) for attr in attrs) - return '' % mapped + inner = ' '.join('%s=%r' % t for t in attrs) + return f'' - def to_dict(self): - ret = {} + def to_dict(self) -> Dict[str, Any]: + ret: Dict[str, Any] = {} for attr in self.__slots__: value = getattr(self, attr, None) if value is None: @@ -224,54 +263,59 @@ def to_dict(self): return ret @property - def start(self): + def start(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC, if applicable.""" try: - return datetime.datetime.utcfromtimestamp(self.timestamps['start'] / 1000) + timestamp = self.timestamps['start'] / 1000 except KeyError: return None + else: + return datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) @property - def end(self): + def end(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: When the user will stop doing this activity in UTC, if applicable.""" try: - return datetime.datetime.utcfromtimestamp(self.timestamps['end'] / 1000) + timestamp = self.timestamps['end'] / 1000 except KeyError: return None + else: + return datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) @property - def large_image_url(self): - """Optional[:class:`str`]: Returns a URL pointing to the large image asset of this activity if applicable.""" - if self.application_id is None: - return None - + def large_image_url(self) -> Optional[str]: + """Optional[:class:`str`]: Returns a URL pointing to the large image asset of this activity, if applicable.""" try: large_image = self.assets['large_image'] except KeyError: return None else: - return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, large_image) + return self._image_url(large_image) @property - def small_image_url(self): - """Optional[:class:`str`]: Returns a URL pointing to the small image asset of this activity if applicable.""" - if self.application_id is None: - return None - + def small_image_url(self) -> Optional[str]: + """Optional[:class:`str`]: Returns a URL pointing to the small image asset of this activity, if applicable.""" try: small_image = self.assets['small_image'] except KeyError: return None else: - return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, small_image) + return self._image_url(small_image) + + def _image_url(self, image: str) -> Optional[str]: + if image.startswith('mp:'): + return f'https://media.discordapp.net/{image[3:]}' + elif self.application_id is not None: + return Asset.BASE + f'/app-assets/{self.application_id}/{image}.png' + @property - def large_image_text(self): - """Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable.""" + def large_image_text(self) -> Optional[str]: + """Optional[:class:`str`]: Returns the large image asset hover text of this activity, if applicable.""" return self.assets.get('large_text', None) @property - def small_image_text(self): - """Optional[:class:`str`]: Returns the small image asset hover text of this activity if applicable.""" + def small_image_text(self) -> Optional[str]: + """Optional[:class:`str`]: Returns the small image asset hover text of this activity, if applicable.""" return self.assets.get('small_text', None) @@ -302,10 +346,6 @@ class Game(BaseActivity): ----------- name: :class:`str` The game's name. - start: Optional[:class:`datetime.datetime`] - A naive UTC timestamp representing when the game started. Keyword-only parameter. Ignored for bots. - end: Optional[:class:`datetime.datetime`] - A naive UTC timestamp representing when the game ends. Keyword-only parameter. Ignored for bots. Attributes ----------- @@ -315,29 +355,21 @@ class Game(BaseActivity): __slots__ = ('name', '_end', '_start') - def __init__(self, name, **extra): + def __init__(self, name: str, **extra: Any) -> None: super().__init__(**extra) - self.name = name + self.name: str = name try: - timestamps = extra['timestamps'] + timestamps: ActivityTimestamps = extra['timestamps'] except KeyError: - self._extract_timestamp(extra, 'start') - self._extract_timestamp(extra, 'end') + self._start = 0 + self._end = 0 else: self._start = timestamps.get('start', 0) self._end = timestamps.get('end', 0) - def _extract_timestamp(self, data, key): - try: - dt = data[key] - except KeyError: - setattr(self, '_' + key, 0) - else: - setattr(self, '_' + key, dt.timestamp() * 1000.0) - @property - def type(self): + def type(self) -> ActivityType: """:class:`ActivityType`: Returns the game's type. This is for compatibility with :class:`Activity`. It always returns :attr:`ActivityType.playing`. @@ -345,27 +377,27 @@ def type(self): return ActivityType.playing @property - def start(self): + def start(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: When the user started playing this game in UTC, if applicable.""" if self._start: - return datetime.datetime.utcfromtimestamp(self._start / 1000) + return datetime.datetime.fromtimestamp(self._start / 1000, tz=datetime.timezone.utc) return None @property - def end(self): + def end(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: When the user will stop playing this game in UTC, if applicable.""" if self._end: - return datetime.datetime.utcfromtimestamp(self._end / 1000) + return datetime.datetime.fromtimestamp(self._end / 1000, tz=datetime.timezone.utc) return None - def __str__(self): + def __str__(self) -> str: return str(self.name) - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' - def to_dict(self): - timestamps = {} + def to_dict(self) -> Dict[str, Any]: + timestamps: Dict[str, Any] = {} if self._start: timestamps['start'] = self._start @@ -375,18 +407,19 @@ def to_dict(self): return { 'type': ActivityType.playing.value, 'name': str(self.name), - 'timestamps': timestamps + 'timestamps': timestamps, } - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return isinstance(other, Game) and other.name == self.name - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: return hash(self.name) + class Streaming(BaseActivity): """A slimmed down version of :class:`Activity` that represents a Discord streaming status. @@ -412,7 +445,7 @@ class Streaming(BaseActivity): Attributes ----------- - platform: :class:`str` + platform: Optional[:class:`str`] Where the user is streaming from (ie. YouTube, Twitch). .. versionadded:: 1.3 @@ -434,31 +467,31 @@ class Streaming(BaseActivity): __slots__ = ('platform', 'name', 'game', 'url', 'details', 'assets') - def __init__(self, *, name, url, **extra): + def __init__(self, *, name: Optional[str], url: str, **extra: Any) -> None: super().__init__(**extra) - self.platform = name - self.name = extra.pop('details', name) - self.game = extra.pop('state', None) - self.url = url - self.details = extra.pop('details', self.name) # compatibility - self.assets = extra.pop('assets', {}) + self.platform: Optional[str] = name + self.name: Optional[str] = extra.pop('details', name) + self.game: Optional[str] = extra.pop('state', None) + self.url: str = url + self.details: Optional[str] = extra.pop('details', self.name) # compatibility + self.assets: ActivityAssets = extra.pop('assets', {}) @property - def type(self): + def type(self) -> ActivityType: """:class:`ActivityType`: Returns the game's type. This is for compatibility with :class:`Activity`. It always returns :attr:`ActivityType.streaming`. """ return ActivityType.streaming - def __str__(self): + def __str__(self) -> str: return str(self.name) - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' @property - def twitch_name(self): + def twitch_name(self) -> Optional[str]: """Optional[:class:`str`]: If provided, the twitch name of the user streaming. This corresponds to the ``large_image`` key of the :attr:`Streaming.assets` @@ -472,26 +505,27 @@ def twitch_name(self): else: return name[7:] if name[:7] == 'twitch:' else None - def to_dict(self): - ret = { + def to_dict(self) -> Dict[str, Any]: + ret: Dict[str, Any] = { 'type': ActivityType.streaming.value, 'name': str(self.name), 'url': str(self.url), - 'assets': self.assets + 'assets': self.assets, } if self.details: ret['details'] = self.details return ret - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return isinstance(other, Streaming) and other.name == self.name and other.url == self.url - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: return hash(self.name) + class Spotify: """Represents a Spotify listening activity from Discord. This is a special case of :class:`Activity` that makes it easier to work with the Spotify integration. @@ -515,21 +549,20 @@ class Spotify: Returns the string 'Spotify'. """ - __slots__ = ('_state', '_details', '_timestamps', '_assets', '_party', '_sync_id', '_session_id', - '_created_at') + __slots__ = ('_state', '_details', '_timestamps', '_assets', '_party', '_sync_id', '_session_id', '_created_at') - def __init__(self, **data): - self._state = data.pop('state', None) - self._details = data.pop('details', None) - self._timestamps = data.pop('timestamps', {}) - self._assets = data.pop('assets', {}) - self._party = data.pop('party', {}) - self._sync_id = data.pop('sync_id') - self._session_id = data.pop('session_id') - self._created_at = data.pop('created_at', None) + def __init__(self, **data: Any) -> None: + self._state: str = data.pop('state', '') + self._details: str = data.pop('details', '') + self._timestamps: ActivityTimestamps = data.pop('timestamps', {}) + self._assets: ActivityAssets = data.pop('assets', {}) + self._party: ActivityParty = data.pop('party', {}) + self._sync_id: str = data.pop('sync_id', '') + self._session_id: Optional[str] = data.pop('session_id') + self._created_at: Optional[float] = data.pop('created_at', None) @property - def type(self): + def type(self) -> ActivityType: """:class:`ActivityType`: Returns the activity's type. This is for compatibility with :class:`Activity`. It always returns :attr:`ActivityType.listening`. @@ -537,31 +570,31 @@ def type(self): return ActivityType.listening @property - def created_at(self): + def created_at(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: When the user started listening in UTC. .. versionadded:: 1.3 """ if self._created_at is not None: - return datetime.datetime.utcfromtimestamp(self._created_at / 1000) + return datetime.datetime.fromtimestamp(self._created_at / 1000, tz=datetime.timezone.utc) @property - def colour(self): + def colour(self) -> Colour: """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`. There is an alias for this named :attr:`color`""" - return Colour(0x1db954) + return Colour(0x1DB954) @property - def color(self): + def color(self) -> Colour: """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`. There is an alias for this named :attr:`colour`""" return self.colour - def to_dict(self): + def to_dict(self) -> Dict[str, Any]: return { - 'flags': 48, # SYNC | PLAY + 'flags': 48, # SYNC | PLAY 'name': 'Spotify', 'assets': self._assets, 'party': self._party, @@ -569,42 +602,46 @@ def to_dict(self): 'session_id': self._session_id, 'timestamps': self._timestamps, 'details': self._details, - 'state': self._state + 'state': self._state, } @property - def name(self): + def name(self) -> str: """:class:`str`: The activity's name. This will always return "Spotify".""" return 'Spotify' - def __eq__(self, other): - return (isinstance(other, Spotify) and other._session_id == self._session_id - and other._sync_id == self._sync_id and other.start == self.start) + def __eq__(self, other: object) -> bool: + return ( + isinstance(other, Spotify) + and other._session_id == self._session_id + and other._sync_id == self._sync_id + and other.start == self.start + ) - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: return hash(self._session_id) - def __str__(self): + def __str__(self) -> str: return 'Spotify' - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' @property - def title(self): + def title(self) -> str: """:class:`str`: The title of the song being played.""" return self._details @property - def artists(self): + def artists(self) -> List[str]: """List[:class:`str`]: The artists of the song being played.""" return self._state.split('; ') @property - def artist(self): + def artist(self) -> str: """:class:`str`: The artist of the song being played. This does not attempt to split the artist information into @@ -613,12 +650,12 @@ def artist(self): return self._state @property - def album(self): + def album(self) -> str: """:class:`str`: The album that the song being played belongs to.""" return self._assets.get('large_text', '') @property - def album_cover_url(self): + def album_cover_url(self) -> str: """:class:`str`: The album cover image URL from Spotify's CDN.""" large_image = self._assets.get('large_image', '') if large_image[:8] != 'spotify:': @@ -627,32 +664,43 @@ def album_cover_url(self): return 'https://i.scdn.co/image/' + album_image_id @property - def track_id(self): + def track_id(self) -> str: """:class:`str`: The track ID used by Spotify to identify this song.""" return self._sync_id @property - def start(self): + def track_url(self) -> str: + """:class:`str`: The track URL to listen on Spotify. + + .. versionadded:: 2.0 + """ + return f'https://open.spotify.com/track/{self.track_id}' + + @property + def start(self) -> datetime.datetime: """:class:`datetime.datetime`: When the user started playing this song in UTC.""" - return datetime.datetime.utcfromtimestamp(self._timestamps['start'] / 1000) + # the start key will be present here + return datetime.datetime.fromtimestamp(self._timestamps['start'] / 1000, tz=datetime.timezone.utc) # type: ignore @property - def end(self): + def end(self) -> datetime.datetime: """:class:`datetime.datetime`: When the user will stop playing this song in UTC.""" - return datetime.datetime.utcfromtimestamp(self._timestamps['end'] / 1000) + # the end key will be present here + return datetime.datetime.fromtimestamp(self._timestamps['end'] / 1000, tz=datetime.timezone.utc) # type: ignore @property - def duration(self): + def duration(self) -> datetime.timedelta: """:class:`datetime.timedelta`: The duration of the song being played.""" return self.end - self.start @property - def party_id(self): + def party_id(self) -> str: """:class:`str`: The party ID of the listening party.""" return self._party.get('id', '') + class CustomActivity(BaseActivity): - """Represents a Custom activity from Discord. + """Represents a custom activity from Discord. .. container:: operations @@ -684,13 +732,14 @@ class CustomActivity(BaseActivity): __slots__ = ('name', 'emoji', 'state') - def __init__(self, name, *, emoji=None, **extra): + def __init__(self, name: Optional[str], *, emoji: Optional[PartialEmoji] = None, **extra: Any) -> None: super().__init__(**extra) - self.name = name - self.state = extra.pop('state', None) + self.name: Optional[str] = name + self.state: Optional[str] = extra.pop('state', name) if self.name == 'Custom Status': self.name = self.state + self.emoji: Optional[PartialEmoji] if emoji is None: self.emoji = emoji elif isinstance(emoji, dict): @@ -700,17 +749,17 @@ def __init__(self, name, *, emoji=None, **extra): elif isinstance(emoji, PartialEmoji): self.emoji = emoji else: - raise TypeError('Expected str, PartialEmoji, or None, received {0!r} instead.'.format(type(emoji))) + raise TypeError(f'Expected str, PartialEmoji, or None, received {type(emoji)!r} instead.') @property - def type(self): + def type(self) -> ActivityType: """:class:`ActivityType`: Returns the activity's type. This is for compatibility with :class:`Activity`. It always returns :attr:`ActivityType.custom`. """ return ActivityType.custom - def to_dict(self): + def to_dict(self) -> Dict[str, Any]: if self.name == self.state: o = { 'type': ActivityType.custom.value, @@ -727,28 +776,41 @@ def to_dict(self): o['emoji'] = self.emoji.to_dict() return o - def __eq__(self, other): - return (isinstance(other, CustomActivity) and other.name == self.name and other.emoji == self.emoji) + def __eq__(self, other: object) -> bool: + return isinstance(other, CustomActivity) and other.name == self.name and other.emoji == self.emoji - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: return hash((self.name, str(self.emoji))) - def __str__(self): + def __str__(self) -> str: if self.emoji: if self.name: - return '%s %s' % (self.emoji, self.name) + return f'{self.emoji} {self.name}' return str(self.emoji) else: return str(self.name) - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' + + +ActivityTypes = Union[Activity, Game, CustomActivity, Streaming, Spotify] + +@overload +def create_activity(data: ActivityPayload, state: ConnectionState) -> ActivityTypes: + ... -def create_activity(data): + +@overload +def create_activity(data: None, state: ConnectionState) -> None: + ... + + +def create_activity(data: Optional[ActivityPayload], state: ConnectionState) -> Optional[ActivityTypes]: if not data: return None @@ -759,15 +821,22 @@ def create_activity(data): return Game(**data) elif game_type is ActivityType.custom: try: - name = data.pop('name') + name = data.pop('name') # type: ignore except KeyError: - return Activity(**data) + ret = Activity(**data) else: - return CustomActivity(name=name, **data) + # we removed the name key from data already + ret = CustomActivity(name=name, **data) # type: ignore elif game_type is ActivityType.streaming: if 'url' in data: - return Streaming(**data) + # the url won't be None here + return Streaming(**data) # type: ignore return Activity(**data) elif game_type is ActivityType.listening and 'sync_id' in data and 'session_id' in data: return Spotify(**data) - return Activity(**data) + else: + ret = Activity(**data) + + if isinstance(ret.emoji, PartialEmoji): + ret.emoji._state = state + return ret diff --git a/dist/ba_data/python-site-packages/discord/app_commands/__init__.py b/dist/ba_data/python-site-packages/discord/app_commands/__init__.py new file mode 100644 index 00000000..97146171 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/__init__.py @@ -0,0 +1,20 @@ +""" +discord.app_commands +~~~~~~~~~~~~~~~~~~~~~ + +Application commands support for the Discord API + +:copyright: (c) 2015-present Rapptz +:license: MIT, see LICENSE for more details. + +""" + +from .commands import * +from .errors import * +from .models import * +from .tree import * +from .namespace import * +from .transformers import * +from .translator import * +from . import checks as checks +from .checks import Cooldown as Cooldown diff --git a/dist/ba_data/python-site-packages/discord/app_commands/checks.py b/dist/ba_data/python-site-packages/discord/app_commands/checks.py new file mode 100644 index 00000000..f6c09481 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/checks.py @@ -0,0 +1,537 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations + +from typing import ( + Any, + Coroutine, + Dict, + Hashable, + Union, + Callable, + TypeVar, + Optional, + TYPE_CHECKING, +) + +import time + +from .commands import check +from .errors import ( + NoPrivateMessage, + MissingRole, + MissingAnyRole, + MissingPermissions, + BotMissingPermissions, + CommandOnCooldown, +) + +from ..user import User +from ..permissions import Permissions +from ..utils import get as utils_get, MISSING, maybe_coroutine + +T = TypeVar('T') + +if TYPE_CHECKING: + from typing_extensions import Self + from ..interactions import Interaction + + CooldownFunction = Union[ + Callable[[Interaction[Any]], Coroutine[Any, Any, T]], + Callable[[Interaction[Any]], T], + ] + +__all__ = ( + 'has_role', + 'has_any_role', + 'has_permissions', + 'bot_has_permissions', + 'cooldown', + 'dynamic_cooldown', +) + + +class Cooldown: + """Represents a cooldown for a command. + + .. versionadded:: 2.0 + + Attributes + ----------- + rate: :class:`float` + The total number of tokens available per :attr:`per` seconds. + per: :class:`float` + The length of the cooldown period in seconds. + """ + + __slots__ = ('rate', 'per', '_window', '_tokens', '_last') + + def __init__(self, rate: float, per: float) -> None: + self.rate: int = int(rate) + self.per: float = float(per) + self._window: float = 0.0 + self._tokens: int = self.rate + self._last: float = 0.0 + + def get_tokens(self, current: Optional[float] = None) -> int: + """Returns the number of available tokens before rate limiting is applied. + + Parameters + ------------ + current: Optional[:class:`float`] + The time in seconds since Unix epoch to calculate tokens at. + If not supplied then :func:`time.time()` is used. + + Returns + -------- + :class:`int` + The number of tokens available before the cooldown is to be applied. + """ + if not current: + current = time.time() + + # the calculated tokens should be non-negative + tokens = max(self._tokens, 0) + + if current > self._window + self.per: + tokens = self.rate + return tokens + + def get_retry_after(self, current: Optional[float] = None) -> float: + """Returns the time in seconds until the cooldown will be reset. + + Parameters + ------------- + current: Optional[:class:`float`] + The current time in seconds since Unix epoch. + If not supplied, then :func:`time.time()` is used. + + Returns + ------- + :class:`float` + The number of seconds to wait before this cooldown will be reset. + """ + current = current or time.time() + tokens = self.get_tokens(current) + + if tokens == 0: + return self.per - (current - self._window) + + return 0.0 + + def update_rate_limit(self, current: Optional[float] = None, *, tokens: int = 1) -> Optional[float]: + """Updates the cooldown rate limit. + + Parameters + ------------- + current: Optional[:class:`float`] + The time in seconds since Unix epoch to update the rate limit at. + If not supplied, then :func:`time.time()` is used. + tokens: :class:`int` + The amount of tokens to deduct from the rate limit. + + Returns + ------- + Optional[:class:`float`] + The retry-after time in seconds if rate limited. + """ + current = current or time.time() + self._last = current + + self._tokens = self.get_tokens(current) + + # first token used means that we start a new rate limit window + if self._tokens == self.rate: + self._window = current + + # decrement tokens by specified number + self._tokens -= tokens + + # check if we are rate limited and return retry-after + if self._tokens < 0: + return self.per - (current - self._window) + + def reset(self) -> None: + """Reset the cooldown to its initial state.""" + self._tokens = self.rate + self._last = 0.0 + + def copy(self) -> Self: + """Creates a copy of this cooldown. + + Returns + -------- + :class:`Cooldown` + A new instance of this cooldown. + """ + return Cooldown(self.rate, self.per) + + def __repr__(self) -> str: + return f'' + + +def has_role(item: Union[int, str], /) -> Callable[[T], T]: + """A :func:`~discord.app_commands.check` that is added that checks if the member invoking the + command has the role specified via the name or ID specified. + + If a string is specified, you must give the exact name of the role, including + caps and spelling. + + If an integer is specified, you must give the exact snowflake ID of the role. + + This check raises one of two special exceptions, :exc:`~discord.app_commands.MissingRole` + if the user is missing a role, or :exc:`~discord.app_commands.NoPrivateMessage` if + it is used in a private message. Both inherit from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + .. note:: + + This is different from the permission system that Discord provides for application + commands. This is done entirely locally in the program rather than being handled + by Discord. + + Parameters + ----------- + item: Union[:class:`int`, :class:`str`] + The name or ID of the role to check. + """ + + def predicate(interaction: Interaction) -> bool: + if isinstance(interaction.user, User): + raise NoPrivateMessage() + + if isinstance(item, int): + role = interaction.user.get_role(item) + else: + role = utils_get(interaction.user.roles, name=item) + + if role is None: + raise MissingRole(item) + return True + + return check(predicate) + + +def has_any_role(*items: Union[int, str]) -> Callable[[T], T]: + r"""A :func:`~discord.app_commands.check` that is added that checks if the member + invoking the command has **any** of the roles specified. This means that if they have + one out of the three roles specified, then this check will return ``True``. + + Similar to :func:`has_role`\, the names or IDs passed in must be exact. + + This check raises one of two special exceptions, :exc:`~discord.app_commands.MissingAnyRole` + if the user is missing all roles, or :exc:`~discord.app_commands.NoPrivateMessage` if + it is used in a private message. Both inherit from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + .. note:: + + This is different from the permission system that Discord provides for application + commands. This is done entirely locally in the program rather than being handled + by Discord. + + Parameters + ----------- + items: List[Union[:class:`str`, :class:`int`]] + An argument list of names or IDs to check that the member has roles wise. + + Example + -------- + + .. code-block:: python3 + + @tree.command() + @app_commands.checks.has_any_role('Library Devs', 'Moderators', 492212595072434186) + async def cool(interaction: discord.Interaction): + await interaction.response.send_message('You are cool indeed') + """ + + def predicate(interaction: Interaction) -> bool: + if isinstance(interaction.user, User): + raise NoPrivateMessage() + + if any( + interaction.user.get_role(item) is not None + if isinstance(item, int) + else utils_get(interaction.user.roles, name=item) is not None + for item in items + ): + return True + raise MissingAnyRole(list(items)) + + return check(predicate) + + +def has_permissions(**perms: bool) -> Callable[[T], T]: + r"""A :func:`~discord.app_commands.check` that is added that checks if the member + has all of the permissions necessary. + + Note that this check operates on the permissions given by + :attr:`discord.Interaction.permissions`. + + The permissions passed in must be exactly like the properties shown under + :class:`discord.Permissions`. + + This check raises a special exception, :exc:`~discord.app_commands.MissingPermissions` + that is inherited from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + .. note:: + + This is different from the permission system that Discord provides for application + commands. This is done entirely locally in the program rather than being handled + by Discord. + + Parameters + ------------ + \*\*perms: :class:`bool` + Keyword arguments denoting the permissions to check for. + + Example + --------- + + .. code-block:: python3 + + @tree.command() + @app_commands.checks.has_permissions(manage_messages=True) + async def test(interaction: discord.Interaction): + await interaction.response.send_message('You can manage messages.') + + """ + + invalid = perms.keys() - Permissions.VALID_FLAGS.keys() + if invalid: + raise TypeError(f"Invalid permission(s): {', '.join(invalid)}") + + def predicate(interaction: Interaction) -> bool: + permissions = interaction.permissions + + missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] + + if not missing: + return True + + raise MissingPermissions(missing) + + return check(predicate) + + +def bot_has_permissions(**perms: bool) -> Callable[[T], T]: + """Similar to :func:`has_permissions` except checks if the bot itself has + the permissions listed. This relies on :attr:`discord.Interaction.app_permissions`. + + This check raises a special exception, :exc:`~discord.app_commands.BotMissingPermissions` + that is inherited from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + """ + + invalid = set(perms) - set(Permissions.VALID_FLAGS) + if invalid: + raise TypeError(f"Invalid permission(s): {', '.join(invalid)}") + + def predicate(interaction: Interaction) -> bool: + permissions = interaction.app_permissions + missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] + + if not missing: + return True + + raise BotMissingPermissions(missing) + + return check(predicate) + + +def _create_cooldown_decorator( + key: CooldownFunction[Hashable], factory: CooldownFunction[Optional[Cooldown]] +) -> Callable[[T], T]: + + mapping: Dict[Any, Cooldown] = {} + + async def get_bucket( + interaction: Interaction, + *, + mapping: Dict[Any, Cooldown] = mapping, + key: CooldownFunction[Hashable] = key, + factory: CooldownFunction[Optional[Cooldown]] = factory, + ) -> Optional[Cooldown]: + current = interaction.created_at.timestamp() + dead_keys = [k for k, v in mapping.items() if current > v._last + v.per] + for k in dead_keys: + del mapping[k] + + k = await maybe_coroutine(key, interaction) + if k not in mapping: + bucket: Optional[Cooldown] = await maybe_coroutine(factory, interaction) + if bucket is not None: + mapping[k] = bucket + else: + bucket = mapping[k] + + return bucket + + async def predicate(interaction: Interaction) -> bool: + bucket = await get_bucket(interaction) + if bucket is None: + return True + + retry_after = bucket.update_rate_limit(interaction.created_at.timestamp()) + if retry_after is None: + return True + + raise CommandOnCooldown(bucket, retry_after) + + return check(predicate) + + +def cooldown( + rate: float, + per: float, + *, + key: Optional[CooldownFunction[Hashable]] = MISSING, +) -> Callable[[T], T]: + """A decorator that adds a cooldown to a command. + + A cooldown allows a command to only be used a specific amount + of times in a specific time frame. These cooldowns are based off + of the ``key`` function provided. If a ``key`` is not provided + then it defaults to a user-level cooldown. The ``key`` function + must take a single parameter, the :class:`discord.Interaction` and + return a value that is used as a key to the internal cooldown mapping. + + The ``key`` function can optionally be a coroutine. + + If a cooldown is triggered, then :exc:`~discord.app_commands.CommandOnCooldown` is + raised to the error handlers. + + Examples + --------- + + Setting a one per 5 seconds per member cooldown on a command: + + .. code-block:: python3 + + @tree.command() + @app_commands.checks.cooldown(1, 5.0, key=lambda i: (i.guild_id, i.user.id)) + async def test(interaction: discord.Interaction): + await interaction.response.send_message('Hello') + + @test.error + async def on_test_error(interaction: discord.Interaction, error: app_commands.AppCommandError): + if isinstance(error, app_commands.CommandOnCooldown): + await interaction.response.send_message(str(error), ephemeral=True) + + Parameters + ------------ + rate: :class:`int` + The number of times a command can be used before triggering a cooldown. + per: :class:`float` + The amount of seconds to wait for a cooldown when it's been triggered. + key: Optional[Callable[[:class:`discord.Interaction`], :class:`collections.abc.Hashable`]] + A function that returns a key to the mapping denoting the type of cooldown. + Can optionally be a coroutine. If not given then defaults to a user-level + cooldown. If ``None`` is passed then it is interpreted as a "global" cooldown. + """ + + if key is MISSING: + key_func = lambda interaction: interaction.user.id + elif key is None: + key_func = lambda i: None + else: + key_func = key + + factory = lambda interaction: Cooldown(rate, per) + + return _create_cooldown_decorator(key_func, factory) + + +def dynamic_cooldown( + factory: CooldownFunction[Optional[Cooldown]], + *, + key: Optional[CooldownFunction[Hashable]] = MISSING, +) -> Callable[[T], T]: + """A decorator that adds a dynamic cooldown to a command. + + A cooldown allows a command to only be used a specific amount + of times in a specific time frame. These cooldowns are based off + of the ``key`` function provided. If a ``key`` is not provided + then it defaults to a user-level cooldown. The ``key`` function + must take a single parameter, the :class:`discord.Interaction` and + return a value that is used as a key to the internal cooldown mapping. + + If a ``factory`` function is given, it must be a function that + accepts a single parameter of type :class:`discord.Interaction` and must + return a :class:`~discord.app_commands.Cooldown` or ``None``. + If ``None`` is returned then that cooldown is effectively bypassed. + + Both ``key`` and ``factory`` can optionally be coroutines. + + If a cooldown is triggered, then :exc:`~discord.app_commands.CommandOnCooldown` is + raised to the error handlers. + + Examples + --------- + + Setting a cooldown for everyone but the owner. + + .. code-block:: python3 + + def cooldown_for_everyone_but_me(interaction: discord.Interaction) -> Optional[app_commands.Cooldown]: + if interaction.user.id == 80088516616269824: + return None + return app_commands.Cooldown(1, 10.0) + + @tree.command() + @app_commands.checks.dynamic_cooldown(cooldown_for_everyone_but_me) + async def test(interaction: discord.Interaction): + await interaction.response.send_message('Hello') + + @test.error + async def on_test_error(interaction: discord.Interaction, error: app_commands.AppCommandError): + if isinstance(error, app_commands.CommandOnCooldown): + await interaction.response.send_message(str(error), ephemeral=True) + + Parameters + ------------ + factory: Optional[Callable[[:class:`discord.Interaction`], Optional[:class:`~discord.app_commands.Cooldown`]]] + A function that takes an interaction and returns a cooldown that will apply to that interaction + or ``None`` if the interaction should not have a cooldown. + key: Optional[Callable[[:class:`discord.Interaction`], :class:`collections.abc.Hashable`]] + A function that returns a key to the mapping denoting the type of cooldown. + Can optionally be a coroutine. If not given then defaults to a user-level + cooldown. If ``None`` is passed then it is interpreted as a "global" cooldown. + """ + + if key is MISSING: + key_func = lambda interaction: interaction.user.id + elif key is None: + key_func = lambda i: None + else: + key_func = key + + return _create_cooldown_decorator(key_func, factory) diff --git a/dist/ba_data/python-site-packages/discord/app_commands/commands.py b/dist/ba_data/python-site-packages/discord/app_commands/commands.py new file mode 100644 index 00000000..8e669340 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/commands.py @@ -0,0 +1,2479 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +import inspect + +from typing import ( + Any, + Callable, + ClassVar, + Coroutine, + Dict, + Generator, + Generic, + List, + MutableMapping, + Optional, + Set, + TYPE_CHECKING, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +import re +from copy import copy as shallow_copy + +from ..enums import AppCommandOptionType, AppCommandType, ChannelType, Locale +from .models import Choice +from .transformers import annotation_to_parameter, CommandParameter, NoneType +from .errors import AppCommandError, CheckFailure, CommandInvokeError, CommandSignatureMismatch, CommandAlreadyRegistered +from .translator import TranslationContextLocation, TranslationContext, Translator, locale_str +from ..message import Message +from ..user import User +from ..member import Member +from ..permissions import Permissions +from ..utils import resolve_annotation, MISSING, is_inside_class, maybe_coroutine, async_all, _shorten, _to_kebab_case + +if TYPE_CHECKING: + from typing_extensions import ParamSpec, Concatenate + from ..interactions import Interaction + from ..abc import Snowflake + from .namespace import Namespace + from .models import ChoiceT + + # Generally, these two libraries are supposed to be separate from each other. + # However, for type hinting purposes it's unfortunately necessary for one to + # reference the other to prevent type checking errors in callbacks + from discord.ext import commands + + ErrorFunc = Callable[[Interaction, AppCommandError], Coroutine[Any, Any, None]] + +__all__ = ( + 'Command', + 'ContextMenu', + 'Group', + 'Parameter', + 'context_menu', + 'command', + 'describe', + 'check', + 'rename', + 'choices', + 'autocomplete', + 'guilds', + 'guild_only', + 'default_permissions', +) + +if TYPE_CHECKING: + P = ParamSpec('P') +else: + P = TypeVar('P') + +T = TypeVar('T') +F = TypeVar('F', bound=Callable[..., Any]) +GroupT = TypeVar('GroupT', bound='Binding') +Coro = Coroutine[Any, Any, T] +UnboundError = Callable[['Interaction[Any]', AppCommandError], Coro[Any]] +Error = Union[ + Callable[[GroupT, 'Interaction[Any]', AppCommandError], Coro[Any]], + UnboundError, +] +Check = Callable[['Interaction[Any]'], Union[bool, Coro[bool]]] +Binding = Union['Group', 'commands.Cog'] + + +if TYPE_CHECKING: + CommandCallback = Union[ + Callable[Concatenate[GroupT, 'Interaction[Any]', P], Coro[T]], + Callable[Concatenate['Interaction[Any]', P], Coro[T]], + ] + + ContextMenuCallback = Union[ + # If groups end up support context menus these would be uncommented + # Callable[[GroupT, 'Interaction', Member], Coro[Any]], + # Callable[[GroupT, 'Interaction', User], Coro[Any]], + # Callable[[GroupT, 'Interaction', Message], Coro[Any]], + # Callable[[GroupT, 'Interaction', Union[Member, User]], Coro[Any]], + Callable[['Interaction[Any]', Member], Coro[Any]], + Callable[['Interaction[Any]', User], Coro[Any]], + Callable[['Interaction[Any]', Message], Coro[Any]], + Callable[['Interaction[Any]', Union[Member, User]], Coro[Any]], + ] + + AutocompleteCallback = Union[ + Callable[[GroupT, 'Interaction[Any]', str], Coro[List[Choice[ChoiceT]]]], + Callable[['Interaction[Any]', str], Coro[List[Choice[ChoiceT]]]], + ] +else: + CommandCallback = Callable[..., Coro[T]] + ContextMenuCallback = Callable[..., Coro[T]] + AutocompleteCallback = Callable[..., Coro[T]] + + +CheckInputParameter = Union['Command[Any, ..., Any]', 'ContextMenu', 'CommandCallback[Any, ..., Any]', ContextMenuCallback] + +# The re module doesn't support \p{} so we have to list characters from Thai and Devanagari manually. +THAI_COMBINING = r'\u0e31-\u0e3a\u0e47-\u0e4e' +DEVANAGARI_COMBINING = r'\u0900-\u0903\u093a\u093b\u093c\u093e\u093f\u0940-\u094f\u0955\u0956\u0957\u0962\u0963' +VALID_SLASH_COMMAND_NAME = re.compile(r'^[-_\w' + THAI_COMBINING + DEVANAGARI_COMBINING + r']{1,32}$') + +ARG_NAME_SUBREGEX = r'(?:\\?\*){0,2}(?P\w+)' + +ARG_DESCRIPTION_SUBREGEX = r'(?P(?:.|\n)+?(?:\Z|\r?\n(?=[\S\r\n])))' + +ARG_TYPE_SUBREGEX = r'(?:.+)' + +GOOGLE_DOCSTRING_ARG_REGEX = re.compile( + rf'^{ARG_NAME_SUBREGEX}[ \t]*(?:\({ARG_TYPE_SUBREGEX}\))?[ \t]*:[ \t]*{ARG_DESCRIPTION_SUBREGEX}', + re.MULTILINE, +) + +SPHINX_DOCSTRING_ARG_REGEX = re.compile( + rf'^:param {ARG_NAME_SUBREGEX}:[ \t]+{ARG_DESCRIPTION_SUBREGEX}', + re.MULTILINE, +) + +NUMPY_DOCSTRING_ARG_REGEX = re.compile( + rf'^{ARG_NAME_SUBREGEX}(?:[ \t]*:)?(?:[ \t]+{ARG_TYPE_SUBREGEX})?[ \t]*\r?\n[ \t]+{ARG_DESCRIPTION_SUBREGEX}', + re.MULTILINE, +) + + +def _parse_args_from_docstring(func: Callable[..., Any], params: Dict[str, CommandParameter]) -> Dict[str, str]: + docstring = inspect.getdoc(func) + + if docstring is None: + return {} + + # Extract the arguments + # Note: These are loose regexes, but they are good enough for our purposes + # For Google-style, look only at the lines that are indented + section_lines = inspect.cleandoc('\n'.join(line for line in docstring.splitlines() if line.startswith(' '))) + docstring_styles = ( + GOOGLE_DOCSTRING_ARG_REGEX.finditer(section_lines), + SPHINX_DOCSTRING_ARG_REGEX.finditer(docstring), + NUMPY_DOCSTRING_ARG_REGEX.finditer(docstring), + ) + + return { + m.group('name'): m.group('description') for matches in docstring_styles for m in matches if m.group('name') in params + } + + +def validate_name(name: str) -> str: + match = VALID_SLASH_COMMAND_NAME.match(name) + if match is None: + raise ValueError( + f'{name!r} must be between 1-32 characters and contain only lower-case letters, numbers, hyphens, or underscores.' + ) + + # Ideally, name.islower() would work instead but since certain characters + # are Lo (e.g. CJK) those don't pass the test. I'd use `casefold` instead as + # well, but chances are the server-side check is probably something similar to + # this code anyway. + if name.lower() != name: + raise ValueError(f'{name!r} must be all lower-case') + return name + + +def validate_context_menu_name(name: str) -> str: + if not name or len(name) > 32: + raise ValueError('context menu names must be between 1-32 characters') + return name + + +def validate_auto_complete_callback( + callback: AutocompleteCallback[GroupT, ChoiceT] +) -> AutocompleteCallback[GroupT, ChoiceT]: + # This function needs to ensure the following is true: + # If self.foo is passed then don't pass command.binding to the callback + # If Class.foo is passed then it is assumed command.binding has to be passed + # If free_function_foo is passed then no binding should be passed at all + # Passing command.binding is mandated by pass_command_binding + + binding = getattr(callback, '__self__', None) + pass_command_binding = binding is None and is_inside_class(callback) + + # 'method' objects can't have dynamic attributes + if binding is None: + callback.pass_command_binding = pass_command_binding + + required_parameters = 2 + pass_command_binding + params = inspect.signature(callback).parameters + if len(params) != required_parameters: + raise TypeError(f'autocomplete callback {callback.__qualname__!r} requires either 2 or 3 parameters to be passed') + + return callback + + +def _context_menu_annotation(annotation: Any, *, _none: type = NoneType) -> AppCommandType: + if annotation is Message: + return AppCommandType.message + + supported_types: Set[Any] = {Member, User} + if annotation in supported_types: + return AppCommandType.user + + # Check if there's an origin + origin = getattr(annotation, '__origin__', None) + if origin is not Union: + # Only Union is supported so bail early + msg = ( + f'unsupported type annotation {annotation!r}, must be either discord.Member, ' + 'discord.User, discord.Message, or a typing.Union of discord.Member and discord.User' + ) + raise TypeError(msg) + + # Only Union[Member, User] is supported + if not all(arg in supported_types for arg in annotation.__args__): + raise TypeError(f'unsupported types given inside {annotation!r}') + + return AppCommandType.user + + +def _populate_descriptions(params: Dict[str, CommandParameter], descriptions: Dict[str, Any]) -> None: + for name, param in params.items(): + description = descriptions.pop(name, MISSING) + if description is MISSING: + param.description = '…' + continue + + if not isinstance(description, (str, locale_str)): + raise TypeError('description must be a string') + + if isinstance(description, str): + param.description = _shorten(description) + else: + param.description = description + + if descriptions: + first = next(iter(descriptions)) + raise TypeError(f'unknown parameter given: {first}') + + +def _populate_renames(params: Dict[str, CommandParameter], renames: Dict[str, Union[str, locale_str]]) -> None: + rename_map: Dict[str, Union[str, locale_str]] = {} + + # original name to renamed name + + for name in params.keys(): + new_name = renames.pop(name, MISSING) + + if new_name is MISSING: + rename_map[name] = name + continue + + if name in rename_map: + raise ValueError(f'{new_name} is already used') + + if isinstance(new_name, str): + new_name = validate_name(new_name) + else: + validate_name(new_name.message) + + rename_map[name] = new_name + params[name]._rename = new_name + + if renames: + first = next(iter(renames)) + raise ValueError(f'unknown parameter given: {first}') + + +def _populate_choices(params: Dict[str, CommandParameter], all_choices: Dict[str, List[Choice]]) -> None: + for name, param in params.items(): + choices = all_choices.pop(name, MISSING) + if choices is MISSING: + continue + + if not isinstance(choices, list): + raise TypeError('choices must be a list of Choice') + + if not all(isinstance(choice, Choice) for choice in choices): + raise TypeError('choices must be a list of Choice') + + if param.type not in (AppCommandOptionType.string, AppCommandOptionType.number, AppCommandOptionType.integer): + raise TypeError('choices are only supported for integer, string, or number option types') + + if not all(param.type == choice._option_type for choice in choices): + raise TypeError('choices must all have the same inner option type as the parameter choice type') + + param.choices = choices + + if all_choices: + first = next(iter(all_choices)) + raise TypeError(f'unknown parameter given: {first}') + + +def _populate_autocomplete(params: Dict[str, CommandParameter], autocomplete: Dict[str, Any]) -> None: + for name, param in params.items(): + callback = autocomplete.pop(name, MISSING) + if callback is MISSING: + continue + + if not inspect.iscoroutinefunction(callback): + raise TypeError('autocomplete callback must be a coroutine function') + + if param.type not in (AppCommandOptionType.string, AppCommandOptionType.number, AppCommandOptionType.integer): + raise TypeError('autocomplete is only supported for integer, string, or number option types') + + if param.is_choice_annotation(): + raise TypeError( + 'Choice annotation unsupported for autocomplete parameters, consider using a regular annotation instead' + ) + + param.autocomplete = validate_auto_complete_callback(callback) + + if autocomplete: + first = next(iter(autocomplete)) + raise TypeError(f'unknown parameter given: {first}') + + +def _extract_parameters_from_callback(func: Callable[..., Any], globalns: Dict[str, Any]) -> Dict[str, CommandParameter]: + params = inspect.signature(func).parameters + cache = {} + required_params = is_inside_class(func) + 1 + if len(params) < required_params: + raise TypeError(f'callback {func.__qualname__!r} must have more than {required_params - 1} parameter(s)') + + iterator = iter(params.values()) + for _ in range(0, required_params): + next(iterator) + + parameters: List[CommandParameter] = [] + for parameter in iterator: + if parameter.annotation is parameter.empty: + raise TypeError(f'parameter {parameter.name!r} is missing a type annotation in callback {func.__qualname__!r}') + + resolved = resolve_annotation(parameter.annotation, globalns, globalns, cache) + param = annotation_to_parameter(resolved, parameter) + parameters.append(param) + + values = sorted(parameters, key=lambda a: a.required, reverse=True) + result = {v.name: v for v in values} + + descriptions = _parse_args_from_docstring(func, result) + + try: + descriptions.update(func.__discord_app_commands_param_description__) + except AttributeError: + for param in values: + if param.description is MISSING: + param.description = '…' + if descriptions: + _populate_descriptions(result, descriptions) + + try: + renames = func.__discord_app_commands_param_rename__ + except AttributeError: + pass + else: + _populate_renames(result, renames.copy()) + + try: + choices = func.__discord_app_commands_param_choices__ + except AttributeError: + pass + else: + _populate_choices(result, choices.copy()) + + try: + autocomplete = func.__discord_app_commands_param_autocomplete__ + except AttributeError: + pass + else: + _populate_autocomplete(result, autocomplete.copy()) + + return result + + +def _get_context_menu_parameter(func: ContextMenuCallback) -> Tuple[str, Any, AppCommandType]: + params = inspect.signature(func).parameters + if is_inside_class(func) and not hasattr(func, '__self__'): + raise TypeError('context menus cannot be defined inside a class') + + if len(params) != 2: + msg = ( + f'context menu callback {func.__qualname__!r} requires 2 parameters, ' + 'the first one being the interaction and the other one explicitly ' + 'annotated with either discord.Message, discord.User, discord.Member, ' + 'or a typing.Union of discord.Member and discord.User' + ) + raise TypeError(msg) + + iterator = iter(params.values()) + next(iterator) # skip interaction + parameter = next(iterator) + if parameter.annotation is parameter.empty: + msg = ( + f'second parameter of context menu callback {func.__qualname__!r} must be explicitly ' + 'annotated with either discord.Message, discord.User, discord.Member, or ' + 'a typing.Union of discord.Member and discord.User' + ) + raise TypeError(msg) + + resolved = resolve_annotation(parameter.annotation, func.__globals__, func.__globals__, {}) + type = _context_menu_annotation(resolved) + return (parameter.name, resolved, type) + + +def mark_overrideable(func: F) -> F: + func.__discord_app_commands_base_function__ = None + return func + + +class Parameter: + """A class that contains the parameter information of a :class:`Command` callback. + + .. versionadded:: 2.0 + + Attributes + ----------- + name: :class:`str` + The name of the parameter. This is the Python identifier for the parameter. + display_name: :class:`str` + The displayed name of the parameter on Discord. + description: :class:`str` + The description of the parameter. + autocomplete: :class:`bool` + Whether the parameter has an autocomplete handler. + locale_name: Optional[:class:`locale_str`] + The display name's locale string, if available. + locale_description: Optional[:class:`locale_str`] + The description's locale string, if available. + required: :class:`bool` + Whether the parameter is required + choices: List[:class:`~discord.app_commands.Choice`] + A list of choices this parameter takes, if any. + type: :class:`~discord.AppCommandOptionType` + The underlying type of this parameter. + channel_types: List[:class:`~discord.ChannelType`] + The channel types that are allowed for this parameter. + min_value: Optional[Union[:class:`int`, :class:`float`]] + The minimum supported value for this parameter. + max_value: Optional[Union[:class:`int`, :class:`float`]] + The maximum supported value for this parameter. + default: Any + The default value of the parameter, if given. + If not given then this is :data:`~discord.utils.MISSING`. + command: :class:`Command` + The command this parameter is attached to. + """ + + def __init__(self, parent: CommandParameter, command: Command[Any, ..., Any]) -> None: + self.__parent: CommandParameter = parent + self.__command: Command[Any, ..., Any] = command + + @property + def command(self) -> Command[Any, ..., Any]: + return self.__command + + @property + def name(self) -> str: + return self.__parent.name + + @property + def display_name(self) -> str: + return self.__parent.display_name + + @property + def required(self) -> bool: + return self.__parent.required + + @property + def description(self) -> str: + return str(self.__parent.description) + + @property + def locale_name(self) -> Optional[locale_str]: + if isinstance(self.__parent._rename, locale_str): + return self.__parent._rename + return None + + @property + def locale_description(self) -> Optional[locale_str]: + if isinstance(self.__parent.description, locale_str): + return self.__parent.description + return None + + @property + def autocomplete(self) -> bool: + return self.__parent.autocomplete is not None + + @property + def default(self) -> Any: + return self.__parent.default + + @property + def type(self) -> AppCommandOptionType: + return self.__parent.type + + @property + def choices(self) -> List[Choice[Union[int, float, str]]]: + choices = self.__parent.choices + if choices is MISSING: + return [] + return choices.copy() + + @property + def channel_types(self) -> List[ChannelType]: + channel_types = self.__parent.channel_types + if channel_types is MISSING: + return [] + return channel_types.copy() + + @property + def min_value(self) -> Optional[Union[int, float]]: + return self.__parent.min_value + + @property + def max_value(self) -> Optional[Union[int, float]]: + return self.__parent.max_value + + +class Command(Generic[GroupT, P, T]): + """A class that implements an application command. + + These are usually not created manually, instead they are created using + one of the following decorators: + + - :func:`~discord.app_commands.command` + - :meth:`Group.command ` + - :meth:`CommandTree.command ` + + .. versionadded:: 2.0 + + Parameters + ----------- + name: Union[:class:`str`, :class:`locale_str`] + The name of the application command. + description: Union[:class:`str`, :class:`locale_str`] + The description of the application command. This shows up in the UI to describe + the application command. + callback: :ref:`coroutine ` + The coroutine that is executed when the command is called. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + parent: Optional[:class:`Group`] + The parent application command. ``None`` if there isn't one. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + + Attributes + ------------ + name: :class:`str` + The name of the application command. + description: :class:`str` + The description of the application command. This shows up in the UI to describe + the application command. + checks + A list of predicates that take a :class:`~discord.Interaction` parameter + to indicate whether the command callback should be executed. If an exception + is necessary to be thrown to signal failure, then one inherited from + :exc:`AppCommandError` should be used. If all the checks fail without + propagating an exception, :exc:`CheckFailure` is raised. + default_permissions: Optional[:class:`~discord.Permissions`] + The default permissions that can execute this command on Discord. Note + that server administrators can override this value in the client. + Setting an empty permissions field will disallow anyone except server + administrators from using the command in a guild. + + Due to a Discord limitation, this does not work on subcommands. + guild_only: :class:`bool` + Whether the command should only be usable in guild contexts. + + Due to a Discord limitation, this does not work on subcommands. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + + Due to a Discord limitation, this does not work on subcommands. + parent: Optional[:class:`Group`] + The parent application command. ``None`` if there isn't one. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def __init__( + self, + *, + name: Union[str, locale_str], + description: Union[str, locale_str], + callback: CommandCallback[GroupT, P, T], + nsfw: bool = False, + parent: Optional[Group] = None, + guild_ids: Optional[List[int]] = None, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, + ): + name, locale = (name.message, name) if isinstance(name, locale_str) else (name, None) + self.name: str = validate_name(name) + self._locale_name: Optional[locale_str] = locale + description, locale = ( + (description.message, description) if isinstance(description, locale_str) else (description, None) + ) + self.description: str = description + self._locale_description: Optional[locale_str] = locale + self._attr: Optional[str] = None + self._callback: CommandCallback[GroupT, P, T] = callback + self.parent: Optional[Group] = parent + self.binding: Optional[GroupT] = None + self.on_error: Optional[Error[GroupT]] = None + self.module: Optional[str] = callback.__module__ + + # Unwrap __self__ for bound methods + try: + self.binding = callback.__self__ + self._callback = callback = callback.__func__ + except AttributeError: + pass + + self._params: Dict[str, CommandParameter] = _extract_parameters_from_callback(callback, callback.__globals__) + self.checks: List[Check] = getattr(callback, '__discord_app_commands_checks__', []) + self._guild_ids: Optional[List[int]] = guild_ids or getattr( + callback, '__discord_app_commands_default_guilds__', None + ) + self.default_permissions: Optional[Permissions] = getattr( + callback, '__discord_app_commands_default_permissions__', None + ) + self.guild_only: bool = getattr(callback, '__discord_app_commands_guild_only__', False) + self.nsfw: bool = nsfw + self.extras: Dict[Any, Any] = extras or {} + + if self._guild_ids is not None and self.parent is not None: + raise ValueError('child commands cannot have default guilds set, consider setting them in the parent instead') + + if auto_locale_strings: + self._convert_to_locale_strings() + + def _convert_to_locale_strings(self) -> None: + if self._locale_name is None: + self._locale_name = locale_str(self.name) + if self._locale_description is None: + self._locale_description = locale_str(self.description) + + for param in self._params.values(): + param._convert_to_locale_strings() + + def __set_name__(self, owner: Type[Any], name: str) -> None: + self._attr = name + + @property + def callback(self) -> CommandCallback[GroupT, P, T]: + """:ref:`coroutine `: The coroutine that is executed when the command is called.""" + return self._callback + + def _copy_with( + self, + *, + parent: Optional[Group], + binding: GroupT, + bindings: MutableMapping[GroupT, GroupT] = MISSING, + set_on_binding: bool = True, + ) -> Command: + bindings = {} if bindings is MISSING else bindings + + copy = shallow_copy(self) + copy._params = self._params.copy() + copy.parent = parent + copy.binding = bindings.get(self.binding) if self.binding is not None else binding + + if copy._attr and set_on_binding: + setattr(copy.binding, copy._attr, copy) + + return copy + + async def get_translated_payload(self, translator: Translator) -> Dict[str, Any]: + base = self.to_dict() + name_localizations: Dict[str, str] = {} + description_localizations: Dict[str, str] = {} + + # Prevent creating these objects in a heavy loop + name_context = TranslationContext(location=TranslationContextLocation.command_name, data=self) + description_context = TranslationContext(location=TranslationContextLocation.command_description, data=self) + + for locale in Locale: + if self._locale_name: + translation = await translator._checked_translate(self._locale_name, locale, name_context) + if translation is not None: + name_localizations[locale.value] = translation + + if self._locale_description: + translation = await translator._checked_translate(self._locale_description, locale, description_context) + if translation is not None: + description_localizations[locale.value] = translation + + base['name_localizations'] = name_localizations + base['description_localizations'] = description_localizations + base['options'] = [ + await param.get_translated_payload(translator, Parameter(param, self)) for param in self._params.values() + ] + return base + + def to_dict(self) -> Dict[str, Any]: + # If we have a parent then our type is a subcommand + # Otherwise, the type falls back to the specific command type (e.g. slash command or context menu) + option_type = AppCommandType.chat_input.value if self.parent is None else AppCommandOptionType.subcommand.value + base: Dict[str, Any] = { + 'name': self.name, + 'description': self.description, + 'type': option_type, + 'options': [param.to_dict() for param in self._params.values()], + } + + if self.parent is None: + base['nsfw'] = self.nsfw + base['dm_permission'] = not self.guild_only + base['default_member_permissions'] = None if self.default_permissions is None else self.default_permissions.value + + return base + + async def _invoke_error_handlers(self, interaction: Interaction, error: AppCommandError) -> None: + # These type ignores are because the type checker can't narrow this type properly. + if self.on_error is not None: + if self.binding is not None: + await self.on_error(self.binding, interaction, error) # type: ignore + else: + await self.on_error(interaction, error) # type: ignore + + parent = self.parent + if parent is not None: + await parent.on_error(interaction, error) + + if parent.parent is not None: + await parent.parent.on_error(interaction, error) + + binding_error_handler = getattr(self.binding, '__discord_app_commands_error_handler__', None) + if binding_error_handler is not None: + await binding_error_handler(interaction, error) + + def _has_any_error_handlers(self) -> bool: + if self.on_error is not None: + return True + + parent = self.parent + if parent is not None: + # Check if the on_error is overridden + if not hasattr(parent.on_error, '__discord_app_commands_base_function__'): + return True + + if parent.parent is not None: + if not hasattr(parent.parent.on_error, '__discord_app_commands_base_function__'): + return True + + # Check if we have a bound error handler + if getattr(self.binding, '__discord_app_commands_error_handler__', None) is not None: + return True + + return False + + async def _transform_arguments(self, interaction: Interaction, namespace: Namespace) -> Dict[str, Any]: + values = namespace.__dict__ + transformed_values = {} + + for param in self._params.values(): + try: + value = values[param.display_name] + except KeyError: + if not param.required: + transformed_values[param.name] = param.default + else: + raise CommandSignatureMismatch(self) from None + else: + transformed_values[param.name] = await param.transform(interaction, value) + + return transformed_values + + async def _do_call(self, interaction: Interaction, params: Dict[str, Any]) -> T: + # These type ignores are because the type checker doesn't quite understand the narrowing here + # Likewise, it thinks we're missing positional arguments when there aren't any. + try: + if self.binding is not None: + return await self._callback(self.binding, interaction, **params) # type: ignore + return await self._callback(interaction, **params) # type: ignore + except TypeError as e: + # In order to detect mismatch from the provided signature and the Discord data, + # there are many ways it can go wrong yet all of them eventually lead to a TypeError + # from the Python compiler showcasing that the signature is incorrect. This lovely + # piece of code essentially checks the last frame of the caller and checks if the + # locals contains our `self` reference. + # + # This is because there is a possibility that a TypeError is raised within the body + # of the function, and in that case the locals wouldn't contain a reference to + # the command object under the name `self`. + frame = inspect.trace()[-1].frame + if frame.f_locals.get('self') is self: + raise CommandSignatureMismatch(self) from None + raise CommandInvokeError(self, e) from e + except AppCommandError: + raise + except Exception as e: + raise CommandInvokeError(self, e) from e + + async def _invoke_with_namespace(self, interaction: Interaction, namespace: Namespace) -> T: + if not await self._check_can_run(interaction): + raise CheckFailure(f'The check functions for command {self.name!r} failed.') + + transformed_values = await self._transform_arguments(interaction, namespace) + return await self._do_call(interaction, transformed_values) + + async def _invoke_autocomplete(self, interaction: Interaction, name: str, namespace: Namespace): + # The namespace contains the Discord provided names so this will be fine + # even if the name is renamed + value = namespace.__dict__[name] + + try: + param = self._params[name] + except KeyError: + # Slow case, it might be a rename + params = {param.display_name: param for param in self._params.values()} + try: + param = params[name] + except KeyError: + raise CommandSignatureMismatch(self) from None + + if param.autocomplete is None: + raise CommandSignatureMismatch(self) + + predicates = getattr(param.autocomplete, '__discord_app_commands_checks__', []) + if predicates: + try: + passed = await async_all(f(interaction) for f in predicates) + except Exception: + passed = False + + if not passed: + if not interaction.response.is_done(): + await interaction.response.autocomplete([]) + return + + if getattr(param.autocomplete, 'pass_command_binding', False): + binding = self.binding + if binding is not None: + choices = await param.autocomplete(binding, interaction, value) + else: + raise TypeError('autocomplete parameter expected a bound self parameter but one was not provided') + else: + choices = await param.autocomplete(interaction, value) + + if interaction.response.is_done(): + return + + await interaction.response.autocomplete(choices) + + def _get_internal_command(self, name: str) -> Optional[Union[Command, Group]]: + return None + + @property + def parameters(self) -> List[Parameter]: + """Returns a list of parameters for this command. + + This does not include the ``self`` or ``interaction`` parameters. + + Returns + -------- + List[:class:`Parameter`] + The parameters of this command. + """ + return [Parameter(p, self) for p in self._params.values()] + + def get_parameter(self, name: str) -> Optional[Parameter]: + """Retrieves a parameter by its name. + + The name must be the Python identifier rather than the renamed + one for display on Discord. + + Parameters + ----------- + name: :class:`str` + The parameter name in the callback function. + + Returns + -------- + Optional[:class:`Parameter`] + The parameter or ``None`` if not found. + """ + + parent = self._params.get(name) + if parent is not None: + return Parameter(parent, self) + return None + + @property + def root_parent(self) -> Optional[Group]: + """Optional[:class:`Group`]: The root parent of this command.""" + if self.parent is None: + return None + parent = self.parent + return parent.parent or parent + + @property + def qualified_name(self) -> str: + """:class:`str`: Returns the fully qualified command name. + + The qualified name includes the parent name as well. For example, + in a command like ``/foo bar`` the qualified name is ``foo bar``. + """ + # A B C + # ^ self + # ^ parent + # ^ grandparent + if self.parent is None: + return self.name + + names = [self.name, self.parent.name] + grandparent = self.parent.parent + if grandparent is not None: + names.append(grandparent.name) + + return ' '.join(reversed(names)) + + async def _check_can_run(self, interaction: Interaction) -> bool: + if self.parent is not None and self.parent is not self.binding: + # For commands with a parent which isn't the binding, i.e. + # + # + # + # The parent check needs to be called first + if not await maybe_coroutine(self.parent.interaction_check, interaction): + return False + + if self.binding is not None: + check: Optional[Check] = getattr(self.binding, 'interaction_check', None) + if check: + ret = await maybe_coroutine(check, interaction) # type: ignore # Probable pyright bug + if not ret: + return False + + predicates = self.checks + if not predicates: + return True + + return await async_all(f(interaction) for f in predicates) + + def error(self, coro: Error[GroupT]) -> Error[GroupT]: + """A decorator that registers a coroutine as a local error handler. + + The local error handler is called whenever an exception is raised in the body + of the command or during handling of the command. The error handler must take + 2 parameters, the interaction and the error. + + The error passed will be derived from :exc:`AppCommandError`. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the local error handler. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + + if not inspect.iscoroutinefunction(coro): + raise TypeError('The error handler must be a coroutine.') + + self.on_error = coro + return coro + + def autocomplete( + self, name: str + ) -> Callable[[AutocompleteCallback[GroupT, ChoiceT]], AutocompleteCallback[GroupT, ChoiceT]]: + """A decorator that registers a coroutine as an autocomplete prompt for a parameter. + + The coroutine callback must have 2 parameters, the :class:`~discord.Interaction`, + and the current value by the user (the string currently being typed by the user). + + To get the values from other parameters that may be filled in, accessing + :attr:`.Interaction.namespace` will give a :class:`Namespace` object with those + values. + + Parent :func:`checks ` are ignored within an autocomplete. However, checks can be added + to the autocomplete callback and the ones added will be called. If the checks fail for any reason + then an empty list is sent as the interaction response. + + The coroutine decorator **must** return a list of :class:`~discord.app_commands.Choice` objects. + Only up to 25 objects are supported. + + .. warning:: + The choices returned from this coroutine are suggestions. The user may ignore them and input their own value. + + Example: + + .. code-block:: python3 + + @app_commands.command() + async def fruits(interaction: discord.Interaction, fruit: str): + await interaction.response.send_message(f'Your favourite fruit seems to be {fruit}') + + @fruits.autocomplete('fruit') + async def fruits_autocomplete( + interaction: discord.Interaction, + current: str, + ) -> List[app_commands.Choice[str]]: + fruits = ['Banana', 'Pineapple', 'Apple', 'Watermelon', 'Melon', 'Cherry'] + return [ + app_commands.Choice(name=fruit, value=fruit) + for fruit in fruits if current.lower() in fruit.lower() + ] + + + Parameters + ----------- + name: :class:`str` + The parameter name to register as autocomplete. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine or + the parameter is not found or of an invalid type. + """ + + def decorator(coro: AutocompleteCallback[GroupT, ChoiceT]) -> AutocompleteCallback[GroupT, ChoiceT]: + if not inspect.iscoroutinefunction(coro): + raise TypeError('The error handler must be a coroutine.') + + try: + param = self._params[name] + except KeyError: + raise TypeError(f'unknown parameter: {name!r}') from None + + if param.type not in (AppCommandOptionType.string, AppCommandOptionType.number, AppCommandOptionType.integer): + raise TypeError('autocomplete is only supported for integer, string, or number option types') + + if param.is_choice_annotation(): + raise TypeError( + 'Choice annotation unsupported for autocomplete parameters, consider using a regular annotation instead' + ) + + param.autocomplete = validate_auto_complete_callback(coro) + return coro + + return decorator + + def add_check(self, func: Check, /) -> None: + """Adds a check to the command. + + This is the non-decorator interface to :func:`check`. + + Parameters + ----------- + func + The function that will be used as a check. + """ + + self.checks.append(func) + + def remove_check(self, func: Check, /) -> None: + """Removes a check from the command. + + This function is idempotent and will not raise an exception + if the function is not in the command's checks. + + Parameters + ----------- + func + The function to remove from the checks. + """ + + try: + self.checks.remove(func) + except ValueError: + pass + + +class ContextMenu: + """A class that implements a context menu application command. + + These are usually not created manually, instead they are created using + one of the following decorators: + + - :func:`~discord.app_commands.context_menu` + - :meth:`CommandTree.context_menu ` + + .. versionadded:: 2.0 + + Parameters + ----------- + name: Union[:class:`str`, :class:`locale_str`] + The name of the context menu. + callback: :ref:`coroutine ` + The coroutine that is executed when the command is called. + type: :class:`.AppCommandType` + The type of context menu application command. By default, this is inferred + by the parameter of the callback. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + Defaults to ``False``. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + + Attributes + ------------ + name: :class:`str` + The name of the context menu. + type: :class:`.AppCommandType` + The type of context menu application command. By default, this is inferred + by the parameter of the callback. + default_permissions: Optional[:class:`~discord.Permissions`] + The default permissions that can execute this command on Discord. Note + that server administrators can override this value in the client. + Setting an empty permissions field will disallow anyone except server + administrators from using the command in a guild. + guild_only: :class:`bool` + Whether the command should only be usable in guild contexts. + Defaults to ``False``. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + Defaults to ``False``. + checks + A list of predicates that take a :class:`~discord.Interaction` parameter + to indicate whether the command callback should be executed. If an exception + is necessary to be thrown to signal failure, then one inherited from + :exc:`AppCommandError` should be used. If all the checks fail without + propagating an exception, :exc:`CheckFailure` is raised. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def __init__( + self, + *, + name: Union[str, locale_str], + callback: ContextMenuCallback, + type: AppCommandType = MISSING, + nsfw: bool = False, + guild_ids: Optional[List[int]] = None, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, + ): + name, locale = (name.message, name) if isinstance(name, locale_str) else (name, None) + self.name: str = validate_context_menu_name(name) + self._locale_name: Optional[locale_str] = locale + self._callback: ContextMenuCallback = callback + (param, annotation, actual_type) = _get_context_menu_parameter(callback) + if type is MISSING: + type = actual_type + + if actual_type != type: + raise ValueError(f'context menu callback implies a type of {actual_type} but {type} was passed.') + + self.type: AppCommandType = type + self._param_name = param + self._annotation = annotation + self.module: Optional[str] = callback.__module__ + self._guild_ids = guild_ids or getattr(callback, '__discord_app_commands_default_guilds__', None) + self.on_error: Optional[UnboundError] = None + self.default_permissions: Optional[Permissions] = getattr( + callback, '__discord_app_commands_default_permissions__', None + ) + self.nsfw: bool = nsfw + self.guild_only: bool = getattr(callback, '__discord_app_commands_guild_only__', False) + self.checks: List[Check] = getattr(callback, '__discord_app_commands_checks__', []) + self.extras: Dict[Any, Any] = extras or {} + + if auto_locale_strings: + if self._locale_name is None: + self._locale_name = locale_str(self.name) + + @property + def callback(self) -> ContextMenuCallback: + """:ref:`coroutine `: The coroutine that is executed when the context menu is called.""" + return self._callback + + @property + def qualified_name(self) -> str: + """:class:`str`: Returns the fully qualified command name.""" + return self.name + + async def get_translated_payload(self, translator: Translator) -> Dict[str, Any]: + base = self.to_dict() + context = TranslationContext(location=TranslationContextLocation.command_name, data=self) + if self._locale_name: + name_localizations: Dict[str, str] = {} + for locale in Locale: + translation = await translator._checked_translate(self._locale_name, locale, context) + if translation is not None: + name_localizations[locale.value] = translation + + base['name_localizations'] = name_localizations + return base + + def to_dict(self) -> Dict[str, Any]: + return { + 'name': self.name, + 'type': self.type.value, + 'dm_permission': not self.guild_only, + 'default_member_permissions': None if self.default_permissions is None else self.default_permissions.value, + 'nsfw': self.nsfw, + } + + async def _check_can_run(self, interaction: Interaction) -> bool: + predicates = self.checks + if not predicates: + return True + + return await async_all(f(interaction) for f in predicates) + + def _has_any_error_handlers(self) -> bool: + return self.on_error is not None + + async def _invoke(self, interaction: Interaction, arg: Any): + try: + if not await self._check_can_run(interaction): + raise CheckFailure(f'The check functions for context menu {self.name!r} failed.') + + await self._callback(interaction, arg) + except AppCommandError: + raise + except Exception as e: + raise CommandInvokeError(self, e) from e + + def error(self, coro: UnboundError) -> UnboundError: + """A decorator that registers a coroutine as a local error handler. + + The local error handler is called whenever an exception is raised in the body + of the command or during handling of the command. The error handler must take + 2 parameters, the interaction and the error. + + The error passed will be derived from :exc:`AppCommandError`. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the local error handler. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + + if not inspect.iscoroutinefunction(coro): + raise TypeError('The error handler must be a coroutine.') + + self.on_error = coro + return coro + + def add_check(self, func: Check, /) -> None: + """Adds a check to the command. + + This is the non-decorator interface to :func:`check`. + + Parameters + ----------- + func + The function that will be used as a check. + """ + + self.checks.append(func) + + def remove_check(self, func: Check, /) -> None: + """Removes a check from the command. + + This function is idempotent and will not raise an exception + if the function is not in the command's checks. + + Parameters + ----------- + func + The function to remove from the checks. + """ + + try: + self.checks.remove(func) + except ValueError: + pass + + +class Group: + """A class that implements an application command group. + + These are usually inherited rather than created manually. + + Decorators such as :func:`guild_only`, :func:`guilds`, and :func:`default_permissions` + will apply to the group if used on top of a subclass. For example: + + .. code-block:: python3 + + from discord import app_commands + + @app_commands.guild_only() + class MyGroup(app_commands.Group): + pass + + .. versionadded:: 2.0 + + Parameters + ----------- + name: Union[:class:`str`, :class:`locale_str`] + The name of the group. If not given, it defaults to a lower-case + kebab-case version of the class name. + description: Union[:class:`str`, :class:`locale_str`] + The description of the group. This shows up in the UI to describe + the group. If not given, it defaults to the docstring of the + class shortened to 100 characters. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + default_permissions: Optional[:class:`~discord.Permissions`] + The default permissions that can execute this group on Discord. Note + that server administrators can override this value in the client. + Setting an empty permissions field will disallow anyone except server + administrators from using the command in a guild. + + Due to a Discord limitation, this does not work on subcommands. + guild_only: :class:`bool` + Whether the group should only be usable in guild contexts. + Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + parent: Optional[:class:`Group`] + The parent application command. ``None`` if there isn't one. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + + Attributes + ------------ + name: :class:`str` + The name of the group. + description: :class:`str` + The description of the group. This shows up in the UI to describe + the group. + default_permissions: Optional[:class:`~discord.Permissions`] + The default permissions that can execute this group on Discord. Note + that server administrators can override this value in the client. + Setting an empty permissions field will disallow anyone except server + administrators from using the command in a guild. + + Due to a Discord limitation, this does not work on subcommands. + guild_only: :class:`bool` + Whether the group should only be usable in guild contexts. + + Due to a Discord limitation, this does not work on subcommands. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + + Due to a Discord limitation, this does not work on subcommands. + parent: Optional[:class:`Group`] + The parent group. ``None`` if there isn't one. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + __discord_app_commands_group_children__: ClassVar[List[Union[Command[Any, ..., Any], Group]]] = [] + __discord_app_commands_skip_init_binding__: bool = False + __discord_app_commands_group_name__: str = MISSING + __discord_app_commands_group_description__: str = MISSING + __discord_app_commands_group_locale_name__: Optional[locale_str] = None + __discord_app_commands_group_locale_description__: Optional[locale_str] = None + __discord_app_commands_group_nsfw__: bool = False + __discord_app_commands_guild_only__: bool = MISSING + __discord_app_commands_default_permissions__: Optional[Permissions] = MISSING + __discord_app_commands_has_module__: bool = False + __discord_app_commands_error_handler__: Optional[ + Callable[[Interaction, AppCommandError], Coroutine[Any, Any, None]] + ] = None + + def __init_subclass__( + cls, + *, + name: Union[str, locale_str] = MISSING, + description: Union[str, locale_str] = MISSING, + guild_only: bool = MISSING, + nsfw: bool = False, + default_permissions: Optional[Permissions] = MISSING, + ) -> None: + if not cls.__discord_app_commands_group_children__: + children: List[Union[Command[Any, ..., Any], Group]] = [ + member for member in cls.__dict__.values() if isinstance(member, (Group, Command)) and member.parent is None + ] + + cls.__discord_app_commands_group_children__ = children + + found = set() + for child in children: + if child.name in found: + raise TypeError(f'Command {child.name!r} is a duplicate') + found.add(child.name) + + if len(children) > 25: + raise TypeError('groups cannot have more than 25 commands') + + if name is MISSING: + cls.__discord_app_commands_group_name__ = validate_name(_to_kebab_case(cls.__name__)) + elif isinstance(name, str): + cls.__discord_app_commands_group_name__ = validate_name(name) + else: + cls.__discord_app_commands_group_name__ = validate_name(name.message) + cls.__discord_app_commands_group_locale_name__ = name + + if description is MISSING: + if cls.__doc__ is None: + cls.__discord_app_commands_group_description__ = '…' + else: + cls.__discord_app_commands_group_description__ = _shorten(cls.__doc__) + elif isinstance(description, str): + cls.__discord_app_commands_group_description__ = description + else: + cls.__discord_app_commands_group_description__ = description.message + cls.__discord_app_commands_group_locale_description__ = description + + if guild_only is not MISSING: + cls.__discord_app_commands_guild_only__ = guild_only + + if default_permissions is not MISSING: + cls.__discord_app_commands_default_permissions__ = default_permissions + + if cls.__module__ != __name__: + cls.__discord_app_commands_has_module__ = True + cls.__discord_app_commands_group_nsfw__ = nsfw + + def __init__( + self, + *, + name: Union[str, locale_str] = MISSING, + description: Union[str, locale_str] = MISSING, + parent: Optional[Group] = None, + guild_ids: Optional[List[int]] = None, + guild_only: bool = MISSING, + nsfw: bool = MISSING, + auto_locale_strings: bool = True, + default_permissions: Optional[Permissions] = MISSING, + extras: Dict[Any, Any] = MISSING, + ): + cls = self.__class__ + + if name is MISSING: + name, locale = cls.__discord_app_commands_group_name__, cls.__discord_app_commands_group_locale_name__ + elif isinstance(name, str): + name, locale = validate_name(name), None + else: + name, locale = validate_name(name.message), name + self.name: str = name + self._locale_name: Optional[locale_str] = locale + + if description is MISSING: + description, locale = ( + cls.__discord_app_commands_group_description__, + cls.__discord_app_commands_group_locale_description__, + ) + elif isinstance(description, str): + description, locale = description, None + else: + description, locale = description.message, description + self.description: str = description + self._locale_description: Optional[locale_str] = locale + + self._attr: Optional[str] = None + self._owner_cls: Optional[Type[Any]] = None + self._guild_ids: Optional[List[int]] = guild_ids or getattr(cls, '__discord_app_commands_default_guilds__', None) + + if default_permissions is MISSING: + if cls.__discord_app_commands_default_permissions__ is MISSING: + default_permissions = None + else: + default_permissions = cls.__discord_app_commands_default_permissions__ + + self.default_permissions: Optional[Permissions] = default_permissions + + if guild_only is MISSING: + if cls.__discord_app_commands_guild_only__ is MISSING: + guild_only = False + else: + guild_only = cls.__discord_app_commands_guild_only__ + + self.guild_only: bool = guild_only + + if nsfw is MISSING: + nsfw = cls.__discord_app_commands_group_nsfw__ + + self.nsfw: bool = nsfw + + if not self.description: + raise TypeError('groups must have a description') + + self.parent: Optional[Group] = parent + self.module: Optional[str] + if cls.__discord_app_commands_has_module__: + self.module = cls.__module__ + else: + try: + # This is pretty hacky + # It allows the module to be fetched if someone just constructs a bare Group object though. + self.module = inspect.currentframe().f_back.f_globals['__name__'] # type: ignore + except (AttributeError, IndexError, KeyError): + self.module = None + + self._children: Dict[str, Union[Command, Group]] = {} + self.extras: Dict[Any, Any] = extras or {} + + bindings: Dict[Group, Group] = {} + + for child in self.__discord_app_commands_group_children__: + # commands and groups created directly in this class (no parent) + copy = ( + child._copy_with(parent=self, binding=self, bindings=bindings, set_on_binding=False) + if not cls.__discord_app_commands_skip_init_binding__ + else child + ) + + self._children[copy.name] = copy + if copy._attr and not cls.__discord_app_commands_skip_init_binding__: + setattr(self, copy._attr, copy) + + if parent is not None: + if parent.parent is not None: + raise ValueError('groups can only be nested at most one level') + parent.add_command(self) + + if auto_locale_strings: + self._convert_to_locale_strings() + + def _convert_to_locale_strings(self) -> None: + if self._locale_name is None: + self._locale_name = locale_str(self.name) + if self._locale_description is None: + self._locale_description = locale_str(self.description) + + # I don't know if propagating to the children is the right behaviour here. + + def __set_name__(self, owner: Type[Any], name: str) -> None: + self._attr = name + self.module = owner.__module__ + self._owner_cls = owner + + def _copy_with( + self, + *, + parent: Optional[Group], + binding: Binding, + bindings: MutableMapping[Group, Group] = MISSING, + set_on_binding: bool = True, + ) -> Group: + bindings = {} if bindings is MISSING else bindings + + copy = shallow_copy(self) + copy.parent = parent + copy._children = {} + + bindings[self] = copy + + for child in self._children.values(): + child_copy = child._copy_with(parent=copy, binding=binding, bindings=bindings) + child_copy.parent = copy + copy._children[child_copy.name] = child_copy + + if isinstance(child_copy, Group) and child_copy._attr and set_on_binding: + if binding.__class__ is child_copy._owner_cls: + setattr(binding, child_copy._attr, child_copy) + elif child_copy._owner_cls is copy.__class__: + setattr(copy, child_copy._attr, child_copy) + + if copy._attr and set_on_binding: + setattr(parent or binding, copy._attr, copy) + + return copy + + async def get_translated_payload(self, translator: Translator) -> Dict[str, Any]: + base = self.to_dict() + name_localizations: Dict[str, str] = {} + description_localizations: Dict[str, str] = {} + + # Prevent creating these objects in a heavy loop + name_context = TranslationContext(location=TranslationContextLocation.group_name, data=self) + description_context = TranslationContext(location=TranslationContextLocation.group_description, data=self) + for locale in Locale: + if self._locale_name: + translation = await translator._checked_translate(self._locale_name, locale, name_context) + if translation is not None: + name_localizations[locale.value] = translation + + if self._locale_description: + translation = await translator._checked_translate(self._locale_description, locale, description_context) + if translation is not None: + description_localizations[locale.value] = translation + + base['name_localizations'] = name_localizations + base['description_localizations'] = description_localizations + base['options'] = [await child.get_translated_payload(translator) for child in self._children.values()] + return base + + def to_dict(self) -> Dict[str, Any]: + # If this has a parent command then it's part of a subcommand group + # Otherwise, it's just a regular command + option_type = 1 if self.parent is None else AppCommandOptionType.subcommand_group.value + base: Dict[str, Any] = { + 'name': self.name, + 'description': self.description, + 'type': option_type, + 'options': [child.to_dict() for child in self._children.values()], + } + + if self.parent is None: + base['nsfw'] = self.nsfw + base['dm_permission'] = not self.guild_only + base['default_member_permissions'] = None if self.default_permissions is None else self.default_permissions.value + + return base + + @property + def root_parent(self) -> Optional[Group]: + """Optional[:class:`Group`]: The parent of this group.""" + return self.parent + + @property + def qualified_name(self) -> str: + """:class:`str`: Returns the fully qualified group name. + + The qualified name includes the parent name as well. For example, + in a group like ``/foo bar`` the qualified name is ``foo bar``. + """ + + if self.parent is None: + return self.name + return f'{self.parent.name} {self.name}' + + def _get_internal_command(self, name: str) -> Optional[Union[Command[Any, ..., Any], Group]]: + return self._children.get(name) + + @property + def commands(self) -> List[Union[Command[Any, ..., Any], Group]]: + """List[Union[:class:`Command`, :class:`Group`]]: The commands that this group contains.""" + return list(self._children.values()) + + def walk_commands(self) -> Generator[Union[Command[Any, ..., Any], Group], None, None]: + """An iterator that recursively walks through all commands that this group contains. + + Yields + --------- + Union[:class:`Command`, :class:`Group`] + The commands in this group. + """ + + for command in self._children.values(): + yield command + if isinstance(command, Group): + yield from command.walk_commands() + + @mark_overrideable + async def on_error(self, interaction: Interaction, error: AppCommandError, /) -> None: + """|coro| + + A callback that is called when a child's command raises an :exc:`AppCommandError`. + + To get the command that failed, :attr:`discord.Interaction.command` should be used. + + The default implementation does nothing. + + Parameters + ----------- + interaction: :class:`~discord.Interaction` + The interaction that is being handled. + error: :exc:`AppCommandError` + The exception that was raised. + """ + + pass + + def error(self, coro: ErrorFunc) -> ErrorFunc: + """A decorator that registers a coroutine as a local error handler. + + The local error handler is called whenever an exception is raised in a child command. + The error handler must take 2 parameters, the interaction and the error. + + The error passed will be derived from :exc:`AppCommandError`. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the local error handler. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine, or is an invalid coroutine. + """ + + if not inspect.iscoroutinefunction(coro): + raise TypeError('The error handler must be a coroutine.') + + params = inspect.signature(coro).parameters + if len(params) != 2: + raise TypeError('The error handler must have 2 parameters.') + + self.on_error = coro + return coro + + async def interaction_check(self, interaction: Interaction, /) -> bool: + """|coro| + + A callback that is called when an interaction happens within the group + that checks whether a command inside the group should be executed. + + This is useful to override if, for example, you want to ensure that the + interaction author is a given user. + + The default implementation of this returns ``True``. + + .. note:: + + If an exception occurs within the body then the check + is considered a failure and error handlers such as + :meth:`on_error` is called. See :exc:`AppCommandError` + for more information. + + Parameters + ----------- + interaction: :class:`~discord.Interaction` + The interaction that occurred. + + Returns + --------- + :class:`bool` + Whether the view children's callbacks should be called. + """ + + return True + + def add_command(self, command: Union[Command[Any, ..., Any], Group], /, *, override: bool = False) -> None: + """Adds a command or group to this group's internal list of commands. + + Parameters + ----------- + command: Union[:class:`Command`, :class:`Group`] + The command or group to add. + override: :class:`bool` + Whether to override a pre-existing command or group with the same name. + If ``False`` then an exception is raised. + + Raises + ------- + CommandAlreadyRegistered + The command or group is already registered. Note that the :attr:`CommandAlreadyRegistered.guild_id` + attribute will always be ``None`` in this case. + ValueError + There are too many commands already registered or the group is too + deeply nested. + TypeError + The wrong command type was passed. + """ + + if not isinstance(command, (Command, Group)): + raise TypeError(f'expected Command or Group not {command.__class__.__name__}') + + if isinstance(command, Group) and self.parent is not None: + # In a tree like so: + # + # + # + # this needs to be forbidden + raise ValueError(f'{command.name!r} is too nested, groups can only be nested at most one level') + + if not override and command.name in self._children: + raise CommandAlreadyRegistered(command.name, guild_id=None) + + self._children[command.name] = command + command.parent = self + if len(self._children) > 25: + raise ValueError('maximum number of child commands exceeded') + + def remove_command(self, name: str, /) -> Optional[Union[Command[Any, ..., Any], Group]]: + """Removes a command or group from the internal list of commands. + + Parameters + ----------- + name: :class:`str` + The name of the command or group to remove. + + Returns + -------- + Optional[Union[:class:`~discord.app_commands.Command`, :class:`~discord.app_commands.Group`]] + The command that was removed. If nothing was removed + then ``None`` is returned instead. + """ + + self._children.pop(name, None) + + def get_command(self, name: str, /) -> Optional[Union[Command[Any, ..., Any], Group]]: + """Retrieves a command or group from its name. + + Parameters + ----------- + name: :class:`str` + The name of the command or group to retrieve. + + Returns + -------- + Optional[Union[:class:`~discord.app_commands.Command`, :class:`~discord.app_commands.Group`]] + The command or group that was retrieved. If nothing was found + then ``None`` is returned instead. + """ + return self._children.get(name) + + def command( + self, + *, + name: Union[str, locale_str] = MISSING, + description: Union[str, locale_str] = MISSING, + nsfw: bool = False, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, + ) -> Callable[[CommandCallback[GroupT, P, T]], Command[GroupT, P, T]]: + """A decorator that creates an application command from a regular function under this group. + + Parameters + ------------ + name: Union[:class:`str`, :class:`locale_str`] + The name of the application command. If not given, it defaults to a lower-case + version of the callback name. + description: Union[:class:`str`, :class:`locale_str`] + The description of the application command. This shows up in the UI to describe + the application command. If not given, it defaults to the first line of the docstring + of the callback shortened to 100 characters. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def decorator(func: CommandCallback[GroupT, P, T]) -> Command[GroupT, P, T]: + if not inspect.iscoroutinefunction(func): + raise TypeError('command function must be a coroutine function') + + if description is MISSING: + if func.__doc__ is None: + desc = '…' + else: + desc = _shorten(func.__doc__) + else: + desc = description + + command = Command( + name=name if name is not MISSING else func.__name__, + description=desc, + callback=func, + nsfw=nsfw, + parent=self, + auto_locale_strings=auto_locale_strings, + extras=extras, + ) + self.add_command(command) + return command + + return decorator + + +def command( + *, + name: Union[str, locale_str] = MISSING, + description: Union[str, locale_str] = MISSING, + nsfw: bool = False, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, +) -> Callable[[CommandCallback[GroupT, P, T]], Command[GroupT, P, T]]: + """Creates an application command from a regular function. + + Parameters + ------------ + name: :class:`str` + The name of the application command. If not given, it defaults to a lower-case + version of the callback name. + description: :class:`str` + The description of the application command. This shows up in the UI to describe + the application command. If not given, it defaults to the first line of the docstring + of the callback shortened to 100 characters. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def decorator(func: CommandCallback[GroupT, P, T]) -> Command[GroupT, P, T]: + if not inspect.iscoroutinefunction(func): + raise TypeError('command function must be a coroutine function') + + if description is MISSING: + if func.__doc__ is None: + desc = '…' + else: + desc = _shorten(func.__doc__) + else: + desc = description + + return Command( + name=name if name is not MISSING else func.__name__, + description=desc, + callback=func, + parent=None, + nsfw=nsfw, + auto_locale_strings=auto_locale_strings, + extras=extras, + ) + + return decorator + + +def context_menu( + *, + name: Union[str, locale_str] = MISSING, + nsfw: bool = False, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, +) -> Callable[[ContextMenuCallback], ContextMenu]: + """Creates an application command context menu from a regular function. + + This function must have a signature of :class:`~discord.Interaction` as its first parameter + and taking either a :class:`~discord.Member`, :class:`~discord.User`, or :class:`~discord.Message`, + or a :obj:`typing.Union` of ``Member`` and ``User`` as its second parameter. + + Examples + --------- + + .. code-block:: python3 + + @app_commands.context_menu() + async def react(interaction: discord.Interaction, message: discord.Message): + await interaction.response.send_message('Very cool message!', ephemeral=True) + + @app_commands.context_menu() + async def ban(interaction: discord.Interaction, user: discord.Member): + await interaction.response.send_message(f'Should I actually ban {user}...', ephemeral=True) + + Parameters + ------------ + name: Union[:class:`str`, :class:`locale_str`] + The name of the context menu command. If not given, it defaults to a title-case + version of the callback name. Note that unlike regular slash commands this can + have spaces and upper case characters in the name. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def decorator(func: ContextMenuCallback) -> ContextMenu: + if not inspect.iscoroutinefunction(func): + raise TypeError('context menu function must be a coroutine function') + + actual_name = func.__name__.title() if name is MISSING else name + return ContextMenu( + name=actual_name, + nsfw=nsfw, + callback=func, + auto_locale_strings=auto_locale_strings, + extras=extras, + ) + + return decorator + + +def describe(**parameters: Union[str, locale_str]) -> Callable[[T], T]: + r'''Describes the given parameters by their name using the key of the keyword argument + as the name. + + Example: + + .. code-block:: python3 + + @app_commands.command(description='Bans a member') + @app_commands.describe(member='the member to ban') + async def ban(interaction: discord.Interaction, member: discord.Member): + await interaction.response.send_message(f'Banned {member}') + + Alternatively, you can describe parameters using Google, Sphinx, or Numpy style docstrings. + + Example: + + .. code-block:: python3 + + @app_commands.command() + async def ban(interaction: discord.Interaction, member: discord.Member): + """Bans a member + + Parameters + ----------- + member: discord.Member + the member to ban + """ + await interaction.response.send_message(f'Banned {member}') + + Parameters + ----------- + \*\*parameters: Union[:class:`str`, :class:`locale_str`] + The description of the parameters. + + Raises + -------- + TypeError + The parameter name is not found. + ''' + + def decorator(inner: T) -> T: + if isinstance(inner, Command): + _populate_descriptions(inner._params, parameters) + else: + try: + inner.__discord_app_commands_param_description__.update(parameters) # type: ignore # Runtime attribute access + except AttributeError: + inner.__discord_app_commands_param_description__ = parameters # type: ignore # Runtime attribute assignment + + return inner + + return decorator + + +def rename(**parameters: Union[str, locale_str]) -> Callable[[T], T]: + r"""Renames the given parameters by their name using the key of the keyword argument + as the name. + + This renames the parameter within the Discord UI. When referring to the parameter in other + decorators, the parameter name used in the function is used instead of the renamed one. + + Example: + + .. code-block:: python3 + + @app_commands.command() + @app_commands.rename(the_member_to_ban='member') + async def ban(interaction: discord.Interaction, the_member_to_ban: discord.Member): + await interaction.response.send_message(f'Banned {the_member_to_ban}') + + Parameters + ----------- + \*\*parameters: Union[:class:`str`, :class:`locale_str`] + The name of the parameters. + + Raises + -------- + ValueError + The parameter name is already used by another parameter. + TypeError + The parameter name is not found. + """ + + def decorator(inner: T) -> T: + if isinstance(inner, Command): + _populate_renames(inner._params, parameters) + else: + try: + inner.__discord_app_commands_param_rename__.update(parameters) # type: ignore # Runtime attribute access + except AttributeError: + inner.__discord_app_commands_param_rename__ = parameters # type: ignore # Runtime attribute assignment + + return inner + + return decorator + + +def choices(**parameters: List[Choice[ChoiceT]]) -> Callable[[T], T]: + r"""Instructs the given parameters by their name to use the given choices for their choices. + + Example: + + .. code-block:: python3 + + @app_commands.command() + @app_commands.describe(fruits='fruits to choose from') + @app_commands.choices(fruits=[ + Choice(name='apple', value=1), + Choice(name='banana', value=2), + Choice(name='cherry', value=3), + ]) + async def fruit(interaction: discord.Interaction, fruits: Choice[int]): + await interaction.response.send_message(f'Your favourite fruit is {fruits.name}.') + + .. note:: + + This is not the only way to provide choices to a command. There are two more ergonomic ways + of doing this. The first one is to use a :obj:`typing.Literal` annotation: + + .. code-block:: python3 + + @app_commands.command() + @app_commands.describe(fruits='fruits to choose from') + async def fruit(interaction: discord.Interaction, fruits: Literal['apple', 'banana', 'cherry']): + await interaction.response.send_message(f'Your favourite fruit is {fruits}.') + + The second way is to use an :class:`enum.Enum`: + + .. code-block:: python3 + + class Fruits(enum.Enum): + apple = 1 + banana = 2 + cherry = 3 + + @app_commands.command() + @app_commands.describe(fruits='fruits to choose from') + async def fruit(interaction: discord.Interaction, fruits: Fruits): + await interaction.response.send_message(f'Your favourite fruit is {fruits}.') + + + Parameters + ----------- + \*\*parameters + The choices of the parameters. + + Raises + -------- + TypeError + The parameter name is not found or the parameter type was incorrect. + """ + + def decorator(inner: T) -> T: + if isinstance(inner, Command): + _populate_choices(inner._params, parameters) + else: + try: + inner.__discord_app_commands_param_choices__.update(parameters) # type: ignore # Runtime attribute access + except AttributeError: + inner.__discord_app_commands_param_choices__ = parameters # type: ignore # Runtime attribute assignment + + return inner + + return decorator + + +def autocomplete(**parameters: AutocompleteCallback[GroupT, ChoiceT]) -> Callable[[T], T]: + r"""Associates the given parameters with the given autocomplete callback. + + Autocomplete is only supported on types that have :class:`str`, :class:`int`, or :class:`float` + values. + + :func:`Checks ` are supported, however they must be attached to the autocomplete + callback in order to work. Checks attached to the command are ignored when invoking the autocomplete + callback. + + For more information, see the :meth:`Command.autocomplete` documentation. + + .. warning:: + The choices returned from this coroutine are suggestions. The user may ignore them and input their own value. + + Example: + + .. code-block:: python3 + + async def fruit_autocomplete( + interaction: discord.Interaction, + current: str, + ) -> List[app_commands.Choice[str]]: + fruits = ['Banana', 'Pineapple', 'Apple', 'Watermelon', 'Melon', 'Cherry'] + return [ + app_commands.Choice(name=fruit, value=fruit) + for fruit in fruits if current.lower() in fruit.lower() + ] + + @app_commands.command() + @app_commands.autocomplete(fruit=fruit_autocomplete) + async def fruits(interaction: discord.Interaction, fruit: str): + await interaction.response.send_message(f'Your favourite fruit seems to be {fruit}') + + Parameters + ----------- + \*\*parameters + The parameters to mark as autocomplete. + + Raises + -------- + TypeError + The parameter name is not found or the parameter type was incorrect. + """ + + def decorator(inner: T) -> T: + if isinstance(inner, Command): + _populate_autocomplete(inner._params, parameters) + else: + try: + inner.__discord_app_commands_param_autocomplete__.update(parameters) # type: ignore # Runtime attribute access + except AttributeError: + inner.__discord_app_commands_param_autocomplete__ = parameters # type: ignore # Runtime attribute assignment + + return inner + + return decorator + + +def guilds(*guild_ids: Union[Snowflake, int]) -> Callable[[T], T]: + r"""Associates the given guilds with the command. + + When the command instance is added to a :class:`CommandTree`, the guilds that are + specified by this decorator become the default guilds that it's added to rather + than being a global command. + + .. note:: + + Due to an implementation quirk and Python limitation, if this is used in conjunction + with the :meth:`CommandTree.command` or :meth:`CommandTree.context_menu` decorator + then this must go below that decorator. + + Example: + + .. code-block:: python3 + + MY_GUILD_ID = discord.Object(...) # Guild ID here + + @app_commands.command() + @app_commands.guilds(MY_GUILD_ID) + async def bonk(interaction: discord.Interaction): + await interaction.response.send_message('Bonk', ephemeral=True) + + Parameters + ----------- + \*guild_ids: Union[:class:`int`, :class:`~discord.abc.Snowflake`] + The guilds to associate this command with. The command tree will + use this as the default when added rather than adding it as a global + command. + """ + + defaults: List[int] = [g if isinstance(g, int) else g.id for g in guild_ids] + + def decorator(inner: T) -> T: + if isinstance(inner, (Group, ContextMenu)): + inner._guild_ids = defaults + elif isinstance(inner, Command): + if inner.parent is not None: + raise ValueError('child commands of a group cannot have default guilds set') + + inner._guild_ids = defaults + else: + # Runtime attribute assignment + inner.__discord_app_commands_default_guilds__ = defaults # type: ignore + + return inner + + return decorator + + +def check(predicate: Check) -> Callable[[T], T]: + r"""A decorator that adds a check to an application command. + + These checks should be predicates that take in a single parameter taking + a :class:`~discord.Interaction`. If the check returns a ``False``\-like value then + during invocation a :exc:`CheckFailure` exception is raised and sent to + the appropriate error handlers. + + These checks can be either a coroutine or not. + + Examples + --------- + + Creating a basic check to see if the command invoker is you. + + .. code-block:: python3 + + def check_if_it_is_me(interaction: discord.Interaction) -> bool: + return interaction.user.id == 85309593344815104 + + @tree.command() + @app_commands.check(check_if_it_is_me) + async def only_for_me(interaction: discord.Interaction): + await interaction.response.send_message('I know you!', ephemeral=True) + + Transforming common checks into its own decorator: + + .. code-block:: python3 + + def is_me(): + def predicate(interaction: discord.Interaction) -> bool: + return interaction.user.id == 85309593344815104 + return app_commands.check(predicate) + + @tree.command() + @is_me() + async def only_me(interaction: discord.Interaction): + await interaction.response.send_message('Only you!') + + Parameters + ----------- + predicate: Callable[[:class:`~discord.Interaction`], :class:`bool`] + The predicate to check if the command should be invoked. + """ + + def decorator(func: CheckInputParameter) -> CheckInputParameter: + if isinstance(func, (Command, ContextMenu)): + func.checks.append(predicate) + else: + if not hasattr(func, '__discord_app_commands_checks__'): + func.__discord_app_commands_checks__ = [] + + func.__discord_app_commands_checks__.append(predicate) + + return func + + return decorator # type: ignore + + +@overload +def guild_only(func: None = ...) -> Callable[[T], T]: + ... + + +@overload +def guild_only(func: T) -> T: + ... + + +def guild_only(func: Optional[T] = None) -> Union[T, Callable[[T], T]]: + """A decorator that indicates this command can only be used in a guild context. + + This is **not** implemented as a :func:`check`, and is instead verified by Discord server side. + Therefore, there is no error handler called when a command is used within a private message. + + This decorator can be called with or without parentheses. + + Due to a Discord limitation, this decorator does nothing in subcommands and is ignored. + + Examples + --------- + + .. code-block:: python3 + + @app_commands.command() + @app_commands.guild_only() + async def my_guild_only_command(interaction: discord.Interaction) -> None: + await interaction.response.send_message('I am only available in guilds!') + """ + + def inner(f: T) -> T: + if isinstance(f, (Command, Group, ContextMenu)): + f.guild_only = True + else: + f.__discord_app_commands_guild_only__ = True # type: ignore # Runtime attribute assignment + return f + + # Check if called with parentheses or not + if func is None: + # Called with parentheses + return inner + else: + return inner(func) + + +def default_permissions(**perms: bool) -> Callable[[T], T]: + r"""A decorator that sets the default permissions needed to execute this command. + + When this decorator is used, by default users must have these permissions to execute the command. + However, an administrator can change the permissions needed to execute this command using the official + client. Therefore, this only serves as a hint. + + Setting an empty permissions field, including via calling this with no arguments, will disallow anyone + except server administrators from using the command in a guild. + + This is sent to Discord server side, and is not a :func:`check`. Therefore, error handlers are not called. + + Due to a Discord limitation, this decorator does nothing in subcommands and is ignored. + + .. warning:: + + This serves as a *hint* and members are *not* required to have the permissions given to actually + execute this command. If you want to ensure that members have the permissions needed, consider using + :func:`~discord.app_commands.checks.has_permissions` instead. + + Parameters + ----------- + \*\*perms: :class:`bool` + Keyword arguments denoting the permissions to set as the default. + + Example + --------- + + .. code-block:: python3 + + @app_commands.command() + @app_commands.default_permissions(manage_messages=True) + async def test(interaction: discord.Interaction): + await interaction.response.send_message('You may or may not have manage messages.') + """ + + permissions = Permissions(**perms) + + def decorator(func: T) -> T: + if isinstance(func, (Command, Group, ContextMenu)): + func.default_permissions = permissions + else: + func.__discord_app_commands_default_permissions__ = permissions # type: ignore # Runtime attribute assignment + + return func + + return decorator diff --git a/dist/ba_data/python-site-packages/discord/app_commands/errors.py b/dist/ba_data/python-site-packages/discord/app_commands/errors.py new file mode 100644 index 00000000..3cc12c72 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/errors.py @@ -0,0 +1,537 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations + +from typing import Any, TYPE_CHECKING, List, Optional, Sequence, Union + +from ..enums import AppCommandOptionType, AppCommandType, Locale +from ..errors import DiscordException, HTTPException, _flatten_error_dict + +__all__ = ( + 'AppCommandError', + 'CommandInvokeError', + 'TransformerError', + 'TranslationError', + 'CheckFailure', + 'CommandAlreadyRegistered', + 'CommandSignatureMismatch', + 'CommandNotFound', + 'CommandLimitReached', + 'NoPrivateMessage', + 'MissingRole', + 'MissingAnyRole', + 'MissingPermissions', + 'BotMissingPermissions', + 'CommandOnCooldown', + 'MissingApplicationID', + 'CommandSyncFailure', +) + +if TYPE_CHECKING: + from .commands import Command, Group, ContextMenu, Parameter + from .transformers import Transformer + from .translator import TranslationContextTypes, locale_str + from ..types.snowflake import Snowflake, SnowflakeList + from .checks import Cooldown + + CommandTypes = Union[Command[Any, ..., Any], Group, ContextMenu] + +APP_ID_NOT_FOUND = ( + 'Client does not have an application_id set. Either the function was called before on_ready ' + 'was called or application_id was not passed to the Client constructor.' +) + + +class AppCommandError(DiscordException): + """The base exception type for all application command related errors. + + This inherits from :exc:`discord.DiscordException`. + + This exception and exceptions inherited from it are handled + in a special way as they are caught and passed into various error handlers + in this order: + + - :meth:`Command.error ` + - :meth:`Group.on_error ` + - :meth:`CommandTree.on_error ` + + .. versionadded:: 2.0 + """ + + pass + + +class CommandInvokeError(AppCommandError): + """An exception raised when the command being invoked raised an exception. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + + Attributes + ----------- + original: :exc:`Exception` + The original exception that was raised. You can also get this via + the ``__cause__`` attribute. + command: Union[:class:`Command`, :class:`ContextMenu`] + The command that failed. + """ + + def __init__(self, command: Union[Command[Any, ..., Any], ContextMenu], e: Exception) -> None: + self.original: Exception = e + self.command: Union[Command[Any, ..., Any], ContextMenu] = command + super().__init__(f'Command {command.name!r} raised an exception: {e.__class__.__name__}: {e}') + + +class TransformerError(AppCommandError): + """An exception raised when a :class:`Transformer` or type annotation fails to + convert to its target type. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + If an exception occurs while converting that does not subclass + :exc:`AppCommandError` then the exception is wrapped into this exception. + The original exception can be retrieved using the ``__cause__`` attribute. + Otherwise if the exception derives from :exc:`AppCommandError` then it will + be propagated as-is. + + .. versionadded:: 2.0 + + Attributes + ----------- + value: Any + The value that failed to convert. + type: :class:`~discord.AppCommandOptionType` + The type of argument that failed to convert. + transformer: :class:`Transformer` + The transformer that failed the conversion. + """ + + def __init__(self, value: Any, opt_type: AppCommandOptionType, transformer: Transformer): + self.value: Any = value + self.type: AppCommandOptionType = opt_type + self.transformer: Transformer = transformer + + super().__init__(f'Failed to convert {value} to {transformer._error_display_name!s}') + + +class TranslationError(AppCommandError): + """An exception raised when the library fails to translate a string. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + If an exception occurs while calling :meth:`Translator.translate` that does + not subclass this then the exception is wrapped into this exception. + The original exception can be retrieved using the ``__cause__`` attribute. + Otherwise it will be propagated as-is. + + .. versionadded:: 2.0 + + Attributes + ----------- + string: Optional[Union[:class:`str`, :class:`locale_str`]] + The string that caused the error, if any. + locale: Optional[:class:`~discord.Locale`] + The locale that caused the error, if any. + context: :class:`~discord.app_commands.TranslationContext` + The context of the translation that triggered the error. + """ + + def __init__( + self, + *msg: str, + string: Optional[Union[str, locale_str]] = None, + locale: Optional[Locale] = None, + context: TranslationContextTypes, + ) -> None: + self.string: Optional[Union[str, locale_str]] = string + self.locale: Optional[Locale] = locale + self.context: TranslationContextTypes = context + + if msg: + super().__init__(*msg) + else: + ctx = context.location.name.replace('_', ' ') + fmt = f'Failed to translate {self.string!r} in a {ctx}' + if self.locale is not None: + fmt = f'{fmt} in the {self.locale.value} locale' + + super().__init__(fmt) + + +class CheckFailure(AppCommandError): + """An exception raised when check predicates in a command have failed. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + """ + + pass + + +class NoPrivateMessage(CheckFailure): + """An exception raised when a command does not work in a direct message. + + This inherits from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + """ + + def __init__(self, message: Optional[str] = None) -> None: + super().__init__(message or 'This command cannot be used in direct messages.') + + +class MissingRole(CheckFailure): + """An exception raised when the command invoker lacks a role to run a command. + + This inherits from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + Attributes + ----------- + missing_role: Union[:class:`str`, :class:`int`] + The required role that is missing. + This is the parameter passed to :func:`~discord.app_commands.checks.has_role`. + """ + + def __init__(self, missing_role: Snowflake) -> None: + self.missing_role: Snowflake = missing_role + message = f'Role {missing_role!r} is required to run this command.' + super().__init__(message) + + +class MissingAnyRole(CheckFailure): + """An exception raised when the command invoker lacks any of the roles + specified to run a command. + + This inherits from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + Attributes + ----------- + missing_roles: List[Union[:class:`str`, :class:`int`]] + The roles that the invoker is missing. + These are the parameters passed to :func:`~discord.app_commands.checks.has_any_role`. + """ + + def __init__(self, missing_roles: SnowflakeList) -> None: + self.missing_roles: SnowflakeList = missing_roles + + missing = [f"'{role}'" for role in missing_roles] + + if len(missing) > 2: + fmt = '{}, or {}'.format(', '.join(missing[:-1]), missing[-1]) + else: + fmt = ' or '.join(missing) + + message = f'You are missing at least one of the required roles: {fmt}' + super().__init__(message) + + +class MissingPermissions(CheckFailure): + """An exception raised when the command invoker lacks permissions to run a + command. + + This inherits from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + Attributes + ----------- + missing_permissions: List[:class:`str`] + The required permissions that are missing. + """ + + def __init__(self, missing_permissions: List[str], *args: Any) -> None: + self.missing_permissions: List[str] = missing_permissions + + missing = [perm.replace('_', ' ').replace('guild', 'server').title() for perm in missing_permissions] + + if len(missing) > 2: + fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1]) + else: + fmt = ' and '.join(missing) + message = f'You are missing {fmt} permission(s) to run this command.' + super().__init__(message, *args) + + +class BotMissingPermissions(CheckFailure): + """An exception raised when the bot's member lacks permissions to run a + command. + + This inherits from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + Attributes + ----------- + missing_permissions: List[:class:`str`] + The required permissions that are missing. + """ + + def __init__(self, missing_permissions: List[str], *args: Any) -> None: + self.missing_permissions: List[str] = missing_permissions + + missing = [perm.replace('_', ' ').replace('guild', 'server').title() for perm in missing_permissions] + + if len(missing) > 2: + fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1]) + else: + fmt = ' and '.join(missing) + message = f'Bot requires {fmt} permission(s) to run this command.' + super().__init__(message, *args) + + +class CommandOnCooldown(CheckFailure): + """An exception raised when the command being invoked is on cooldown. + + This inherits from :exc:`~discord.app_commands.CheckFailure`. + + .. versionadded:: 2.0 + + Attributes + ----------- + cooldown: :class:`~discord.app_commands.Cooldown` + The cooldown that was triggered. + retry_after: :class:`float` + The amount of seconds to wait before you can retry again. + """ + + def __init__(self, cooldown: Cooldown, retry_after: float) -> None: + self.cooldown: Cooldown = cooldown + self.retry_after: float = retry_after + super().__init__(f'You are on cooldown. Try again in {retry_after:.2f}s') + + +class CommandAlreadyRegistered(AppCommandError): + """An exception raised when a command is already registered. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + + Attributes + ----------- + name: :class:`str` + The name of the command already registered. + guild_id: Optional[:class:`int`] + The guild ID this command was already registered at. + If ``None`` then it was a global command. + """ + + def __init__(self, name: str, guild_id: Optional[int]): + self.name: str = name + self.guild_id: Optional[int] = guild_id + super().__init__(f'Command {name!r} already registered.') + + +class CommandNotFound(AppCommandError): + """An exception raised when an application command could not be found. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + + Attributes + ------------ + name: :class:`str` + The name of the application command not found. + parents: List[:class:`str`] + A list of parent command names that were previously found + prior to the application command not being found. + type: :class:`~discord.AppCommandType` + The type of command that was not found. + """ + + def __init__(self, name: str, parents: List[str], type: AppCommandType = AppCommandType.chat_input): + self.name: str = name + self.parents: List[str] = parents + self.type: AppCommandType = type + super().__init__(f'Application command {name!r} not found') + + +class CommandLimitReached(AppCommandError): + """An exception raised when the maximum number of application commands was reached + either globally or in a guild. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + + Attributes + ------------ + type: :class:`~discord.AppCommandType` + The type of command that reached the limit. + guild_id: Optional[:class:`int`] + The guild ID that reached the limit or ``None`` if it was global. + limit: :class:`int` + The limit that was hit. + """ + + def __init__(self, guild_id: Optional[int], limit: int, type: AppCommandType = AppCommandType.chat_input): + self.guild_id: Optional[int] = guild_id + self.limit: int = limit + self.type: AppCommandType = type + + lookup = { + AppCommandType.chat_input: 'slash commands', + AppCommandType.message: 'message context menu commands', + AppCommandType.user: 'user context menu commands', + } + desc = lookup.get(type, 'application commands') + ns = 'globally' if self.guild_id is None else f'for guild ID {self.guild_id}' + super().__init__(f'maximum number of {desc} exceeded {limit} {ns}') + + +class CommandSignatureMismatch(AppCommandError): + """An exception raised when an application command from Discord has a different signature + from the one provided in the code. This happens because your command definition differs + from the command definition you provided Discord. Either your code is out of date or the + data from Discord is out of sync. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + + Attributes + ------------ + command: Union[:class:`~.app_commands.Command`, :class:`~.app_commands.ContextMenu`, :class:`~.app_commands.Group`] + The command that had the signature mismatch. + """ + + def __init__(self, command: Union[Command[Any, ..., Any], ContextMenu, Group]): + self.command: Union[Command[Any, ..., Any], ContextMenu, Group] = command + msg = ( + f'The signature for command {command.name!r} is different from the one provided by Discord. ' + 'This can happen because either your code is out of date or you have not synced the ' + 'commands with Discord, causing the mismatch in data. It is recommended to sync the ' + 'command tree to fix this issue.' + ) + super().__init__(msg) + + +class MissingApplicationID(AppCommandError): + """An exception raised when the client does not have an application ID set. + An application ID is required for syncing application commands. + + This inherits from :exc:`~discord.app_commands.AppCommandError`. + + .. versionadded:: 2.0 + """ + + def __init__(self, message: Optional[str] = None): + super().__init__(message or APP_ID_NOT_FOUND) + + +def _get_command_error( + index: str, + inner: Any, + objects: Sequence[Union[Parameter, CommandTypes]], + messages: List[str], + indent: int = 0, +) -> None: + # Import these here to avoid circular imports + from .commands import Command, Group, ContextMenu + + indentation = ' ' * indent + + # Top level errors are: + # : { : } + # The dicts could be nested, e.g. + # : { : { : } } + # Luckily, this is already handled by the flatten_error_dict utility + if not index.isdigit(): + errors = _flatten_error_dict(inner, index) + messages.extend(f'In {k}: {v}' for k, v in errors.items()) + return + + idx = int(index) + try: + obj = objects[idx] + except IndexError: + dedent_one_level = ' ' * (indent - 2) + errors = _flatten_error_dict(inner, index) + messages.extend(f'{dedent_one_level}In {k}: {v}' for k, v in errors.items()) + return + + children: Sequence[Union[Parameter, CommandTypes]] = [] + if isinstance(obj, Command): + messages.append(f'{indentation}In command {obj.qualified_name!r} defined in function {obj.callback.__qualname__!r}') + children = obj.parameters + elif isinstance(obj, Group): + messages.append(f'{indentation}In group {obj.qualified_name!r} defined in module {obj.module!r}') + children = obj.commands + elif isinstance(obj, ContextMenu): + messages.append( + f'{indentation}In context menu {obj.qualified_name!r} defined in function {obj.callback.__qualname__!r}' + ) + else: + messages.append(f'{indentation}In parameter {obj.name!r}') + + for key, remaining in inner.items(): + # Special case the 'options' key since they have well defined meanings + if key == 'options': + for index, d in remaining.items(): + _get_command_error(index, d, children, messages, indent=indent + 2) + else: + if isinstance(remaining, dict): + try: + inner_errors = remaining['_errors'] + except KeyError: + errors = _flatten_error_dict(remaining, key=key) + else: + errors = {key: ' '.join(x.get('message', '') for x in inner_errors)} + else: + errors = _flatten_error_dict(remaining, key=key) + + messages.extend(f'{indentation} {k}: {v}' for k, v in errors.items()) + + +class CommandSyncFailure(AppCommandError, HTTPException): + """An exception raised when :meth:`CommandTree.sync` failed. + + This provides syncing failures in a slightly more readable format. + + This inherits from :exc:`~discord.app_commands.AppCommandError` + and :exc:`~discord.HTTPException`. + + .. versionadded:: 2.0 + """ + + def __init__(self, child: HTTPException, commands: List[CommandTypes]) -> None: + # Consume the child exception and make it seem as if we are that exception + self.__dict__.update(child.__dict__) + + messages = [f'Failed to upload commands to Discord (HTTP status {self.status}, error code {self.code})'] + + if self._errors: + for index, inner in self._errors.items(): + _get_command_error(index, inner, commands, messages) + + # Equivalent to super().__init__(...) but skips other constructors + self.args = ('\n'.join(messages),) diff --git a/dist/ba_data/python-site-packages/discord/app_commands/models.py b/dist/ba_data/python-site-packages/discord/app_commands/models.py new file mode 100644 index 00000000..3e9d250b --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/models.py @@ -0,0 +1,1091 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +from datetime import datetime + +from .errors import MissingApplicationID +from .translator import TranslationContextLocation, TranslationContext, locale_str, Translator +from ..permissions import Permissions +from ..enums import AppCommandOptionType, AppCommandType, AppCommandPermissionType, ChannelType, Locale, try_enum +from ..mixins import Hashable +from ..utils import _get_as_snowflake, parse_time, snowflake_time, MISSING +from ..object import Object +from ..role import Role +from ..member import Member + +from typing import Any, Dict, Generic, List, TYPE_CHECKING, Optional, TypeVar, Union + +__all__ = ( + 'AppCommand', + 'AppCommandGroup', + 'AppCommandChannel', + 'AppCommandThread', + 'AppCommandPermissions', + 'GuildAppCommandPermissions', + 'Argument', + 'Choice', + 'AllChannels', +) + +ChoiceT = TypeVar('ChoiceT', str, int, float, Union[str, int, float]) + + +def is_app_command_argument_type(value: int) -> bool: + return 11 >= value >= 3 + + +if TYPE_CHECKING: + from ..types.command import ( + ApplicationCommand as ApplicationCommandPayload, + ApplicationCommandOption, + ApplicationCommandOptionChoice, + ApplicationCommandPermissions, + GuildApplicationCommandPermissions, + ) + from ..types.interactions import ( + PartialChannel, + PartialThread, + ) + from ..types.threads import ( + ThreadMetadata, + ThreadArchiveDuration, + ) + + from ..abc import Snowflake + from ..state import ConnectionState + from ..guild import GuildChannel, Guild + from ..channel import TextChannel + from ..threads import Thread + from ..user import User + + ApplicationCommandParent = Union['AppCommand', 'AppCommandGroup'] + + +class AllChannels: + """Represents all channels for application command permissions. + + .. versionadded:: 2.0 + + Attributes + ----------- + guild: :class:`~discord.Guild` + The guild the application command permission is for. + """ + + __slots__ = ('guild',) + + def __init__(self, guild: Guild): + self.guild: Guild = guild + + @property + def id(self) -> int: + """:class:`int`: The ID sentinel used to represent all channels. Equivalent to the guild's ID minus 1.""" + return self.guild.id - 1 + + def __repr__(self) -> str: + return f'' + + +def _to_locale_dict(data: Dict[str, str]) -> Dict[Locale, str]: + return {try_enum(Locale, key): value for key, value in data.items()} + + +class AppCommand(Hashable): + """Represents an application command. + + In common parlance this is referred to as a "Slash Command" or a + "Context Menu Command". + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two application commands are equal. + + .. describe:: x != y + + Checks if two application commands are not equal. + + .. describe:: hash(x) + + Returns the application command's hash. + + .. describe:: str(x) + + Returns the application command's name. + + Attributes + ----------- + id: :class:`int` + The application command's ID. + application_id: :class:`int` + The application command's application's ID. + type: :class:`~discord.AppCommandType` + The application command's type. + name: :class:`str` + The application command's name. + description: :class:`str` + The application command's description. + name_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised names of the application command. Used for display purposes. + description_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised descriptions of the application command. Used for display purposes. + options: List[Union[:class:`Argument`, :class:`AppCommandGroup`]] + A list of options. + default_member_permissions: Optional[:class:`~discord.Permissions`] + The default member permissions that can run this command. + dm_permission: :class:`bool` + A boolean that indicates whether this command can be run in direct messages. + guild_id: Optional[:class:`int`] + The ID of the guild this command is registered in. A value of ``None`` + denotes that it is a global command. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. + """ + + __slots__ = ( + 'id', + 'type', + 'application_id', + 'name', + 'description', + 'name_localizations', + 'description_localizations', + 'guild_id', + 'options', + 'default_member_permissions', + 'dm_permission', + 'nsfw', + '_state', + ) + + def __init__(self, *, data: ApplicationCommandPayload, state: ConnectionState) -> None: + self._state: ConnectionState = state + self._from_data(data) + + def _from_data(self, data: ApplicationCommandPayload) -> None: + self.id: int = int(data['id']) + self.application_id: int = int(data['application_id']) + self.name: str = data['name'] + self.description: str = data['description'] + self.guild_id: Optional[int] = _get_as_snowflake(data, 'guild_id') + self.type: AppCommandType = try_enum(AppCommandType, data.get('type', 1)) + self.options: List[Union[Argument, AppCommandGroup]] = [ + app_command_option_factory(data=d, parent=self, state=self._state) for d in data.get('options', []) + ] + self.default_member_permissions: Optional[Permissions] + permissions = data.get('default_member_permissions') + if permissions is None: + self.default_member_permissions = None + else: + self.default_member_permissions = Permissions(int(permissions)) + + dm_permission = data.get('dm_permission') + # For some reason this field can be explicit null and mean True + if dm_permission is None: + dm_permission = True + + self.dm_permission: bool = dm_permission + self.nsfw: bool = data.get('nsfw', False) + self.name_localizations: Dict[Locale, str] = _to_locale_dict(data.get('name_localizations') or {}) + self.description_localizations: Dict[Locale, str] = _to_locale_dict(data.get('description_localizations') or {}) + + def to_dict(self) -> ApplicationCommandPayload: + return { + 'id': self.id, + 'type': self.type.value, + 'application_id': self.application_id, + 'name': self.name, + 'description': self.description, + 'name_localizations': {str(k): v for k, v in self.name_localizations.items()}, + 'description_localizations': {str(k): v for k, v in self.description_localizations.items()}, + 'options': [opt.to_dict() for opt in self.options], + } # type: ignore # Type checker does not understand this literal. + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id={self.id!r} name={self.name!r} type={self.type!r}>' + + @property + def mention(self) -> str: + """:class:`str`: Returns a string that allows you to mention the given AppCommand.""" + return f'' + + @property + def guild(self) -> Optional[Guild]: + """Optional[:class:`~discord.Guild`]: Returns the guild this command is registered to + if it exists. + """ + return self._state._get_guild(self.guild_id) + + async def delete(self) -> None: + """|coro| + + Deletes the application command. + + Raises + ------- + NotFound + The application command was not found. + Forbidden + You do not have permission to delete this application command. + HTTPException + Deleting the application command failed. + MissingApplicationID + The client does not have an application ID. + """ + state = self._state + if not state.application_id: + raise MissingApplicationID + + if self.guild_id: + await state.http.delete_guild_command( + state.application_id, + self.guild_id, + self.id, + ) + else: + await state.http.delete_global_command( + state.application_id, + self.id, + ) + + async def edit( + self, + *, + name: str = MISSING, + description: str = MISSING, + default_member_permissions: Optional[Permissions] = MISSING, + dm_permission: bool = MISSING, + options: List[Union[Argument, AppCommandGroup]] = MISSING, + ) -> AppCommand: + """|coro| + + Edits the application command. + + Parameters + ----------- + name: :class:`str` + The new name for the application command. + description: :class:`str` + The new description for the application command. + default_member_permissions: Optional[:class:`~discord.Permissions`] + The new default permissions needed to use this application command. + Pass value of ``None`` to remove any permission requirements. + dm_permission: :class:`bool` + Indicates if the application command can be used in DMs. + options: List[Union[:class:`Argument`, :class:`AppCommandGroup`]] + List of new options for this application command. + + Raises + ------- + NotFound + The application command was not found. + Forbidden + You do not have permission to edit this application command. + HTTPException + Editing the application command failed. + MissingApplicationID + The client does not have an application ID. + + Returns + -------- + :class:`AppCommand` + The newly edited application command. + """ + state = self._state + if not state.application_id: + raise MissingApplicationID + + payload = {} + + if name is not MISSING: + payload['name'] = name + + if description is not MISSING: + payload['description'] = description + + if default_member_permissions is not MISSING: + if default_member_permissions is not None: + payload['default_member_permissions'] = default_member_permissions.value + else: + payload['default_member_permissions'] = None + + if self.guild_id is None and dm_permission is not MISSING: + payload['dm_permission'] = dm_permission + + if options is not MISSING: + payload['options'] = [option.to_dict() for option in options] + + if not payload: + return self + + if self.guild_id: + data = await state.http.edit_guild_command( + state.application_id, + self.guild_id, + self.id, + payload, + ) + else: + data = await state.http.edit_global_command( + state.application_id, + self.id, + payload, + ) + return AppCommand(data=data, state=state) + + async def fetch_permissions(self, guild: Snowflake) -> GuildAppCommandPermissions: + """|coro| + + Retrieves this command's permission in the guild. + + Parameters + ----------- + guild: :class:`~discord.abc.Snowflake` + The guild to retrieve the permissions from. + + Raises + ------- + Forbidden + You do not have permission to fetch the application command's permissions. + HTTPException + Fetching the application command's permissions failed. + MissingApplicationID + The client does not have an application ID. + NotFound + The application command's permissions could not be found. + This can also indicate that the permissions are synced with the guild + (i.e. they are unchanged from the default). + + Returns + -------- + :class:`GuildAppCommandPermissions` + An object representing the application command's permissions in the guild. + """ + state = self._state + if not state.application_id: + raise MissingApplicationID + + data = await state.http.get_application_command_permissions( + state.application_id, + guild.id, + self.id, + ) + return GuildAppCommandPermissions(data=data, state=state, command=self) + + +class Choice(Generic[ChoiceT]): + """Represents an application command argument choice. + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two choices are equal. + + .. describe:: x != y + + Checks if two choices are not equal. + + .. describe:: hash(x) + + Returns the choice's hash. + + Parameters + ----------- + name: Union[:class:`str`, :class:`locale_str`] + The name of the choice. Used for display purposes. + Can only be up to 100 characters. + name_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised names of the choice. Used for display purposes. + value: Union[:class:`int`, :class:`str`, :class:`float`] + The value of the choice. If it's a string, it can only be + up to 100 characters long. + """ + + __slots__ = ('name', 'value', '_locale_name', 'name_localizations') + + def __init__(self, *, name: Union[str, locale_str], value: ChoiceT): + name, locale = (name.message, name) if isinstance(name, locale_str) else (name, None) + self.name: str = name + self._locale_name: Optional[locale_str] = locale + self.value: ChoiceT = value + self.name_localizations: Dict[Locale, str] = {} + + @classmethod + def from_dict(cls, data: ApplicationCommandOptionChoice) -> Choice[ChoiceT]: + self = cls.__new__(cls) + self.name = data['name'] + self.value = data['value'] # type: ignore # This seems to break every other pyright release + self.name_localizations = _to_locale_dict(data.get('name_localizations') or {}) + return self + + def __eq__(self, o: object) -> bool: + return isinstance(o, Choice) and self.name == o.name and self.value == o.value + + def __hash__(self) -> int: + return hash((self.name, self.value)) + + def __repr__(self) -> str: + return f'{self.__class__.__name__}(name={self.name!r}, value={self.value!r})' + + @property + def _option_type(self) -> AppCommandOptionType: + if isinstance(self.value, int): + return AppCommandOptionType.integer + elif isinstance(self.value, float): + return AppCommandOptionType.number + elif isinstance(self.value, str): + return AppCommandOptionType.string + else: + raise TypeError( + f'invalid Choice value type given, expected int, str, or float but received {self.value.__class__.__name__}' + ) + + async def get_translated_payload(self, translator: Translator) -> Dict[str, Any]: + base = self.to_dict() + name_localizations: Dict[str, str] = {} + context = TranslationContext(location=TranslationContextLocation.choice_name, data=self) + if self._locale_name: + for locale in Locale: + translation = await translator._checked_translate(self._locale_name, locale, context) + if translation is not None: + name_localizations[locale.value] = translation + + if name_localizations: + base['name_localizations'] = name_localizations + + return base + + async def get_translated_payload_for_locale(self, translator: Translator, locale: Locale) -> Dict[str, Any]: + base = self.to_dict() + if self._locale_name: + context = TranslationContext(location=TranslationContextLocation.choice_name, data=self) + translation = await translator._checked_translate(self._locale_name, locale, context) + if translation is not None: + base['name'] = translation + + return base + + def to_dict(self) -> Dict[str, Any]: + base = { + 'name': self.name, + 'value': self.value, + } + if self.name_localizations: + base['name_localizations'] = {str(k): v for k, v in self.name_localizations.items()} + return base + + +class AppCommandChannel(Hashable): + """Represents an application command partially resolved channel object. + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns the channel's name. + + Attributes + ----------- + id: :class:`int` + The ID of the channel. + type: :class:`~discord.ChannelType` + The type of channel. + name: :class:`str` + The name of the channel. + permissions: :class:`~discord.Permissions` + The resolved permissions of the user who invoked + the application command in that channel. + guild_id: :class:`int` + The guild ID this channel belongs to. + """ + + __slots__ = ( + 'id', + 'type', + 'name', + 'permissions', + 'guild_id', + '_state', + ) + + def __init__( + self, + *, + state: ConnectionState, + data: PartialChannel, + guild_id: int, + ): + self._state: ConnectionState = state + self.guild_id: int = guild_id + self.id: int = int(data['id']) + self.type: ChannelType = try_enum(ChannelType, data['type']) + self.name: str = data['name'] + self.permissions: Permissions = Permissions(int(data['permissions'])) + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id={self.id!r} name={self.name!r} type={self.type!r}>' + + @property + def guild(self) -> Optional[Guild]: + """Optional[:class:`~discord.Guild`]: The channel's guild, from cache, if found.""" + return self._state._get_guild(self.guild_id) + + def resolve(self) -> Optional[GuildChannel]: + """Resolves the application command channel to the appropriate channel + from cache if found. + + Returns + -------- + Optional[:class:`.abc.GuildChannel`] + The resolved guild channel or ``None`` if not found in cache. + """ + guild = self._state._get_guild(self.guild_id) + if guild is not None: + return guild.get_channel(self.id) + return None + + async def fetch(self) -> GuildChannel: + """|coro| + + Fetches the partial channel to a full :class:`.abc.GuildChannel`. + + Raises + -------- + NotFound + The channel was not found. + Forbidden + You do not have the permissions required to get a channel. + HTTPException + Retrieving the channel failed. + + Returns + -------- + :class:`.abc.GuildChannel` + The full channel. + """ + client = self._state._get_client() + return await client.fetch_channel(self.id) # type: ignore # This is explicit narrowing + + @property + def mention(self) -> str: + """:class:`str`: The string that allows you to mention the channel.""" + return f'<#{self.id}>' + + @property + def created_at(self) -> datetime: + """:class:`datetime.datetime`: An aware timestamp of when this channel was created in UTC.""" + return snowflake_time(self.id) + + +class AppCommandThread(Hashable): + """Represents an application command partially resolved thread object. + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two thread are equal. + + .. describe:: x != y + + Checks if two thread are not equal. + + .. describe:: hash(x) + + Returns the thread's hash. + + .. describe:: str(x) + + Returns the thread's name. + + Attributes + ----------- + id: :class:`int` + The ID of the thread. + type: :class:`~discord.ChannelType` + The type of thread. + name: :class:`str` + The name of the thread. + parent_id: :class:`int` + The parent text channel ID this thread belongs to. + permissions: :class:`~discord.Permissions` + The resolved permissions of the user who invoked + the application command in that thread. + guild_id: :class:`int` + The guild ID this thread belongs to. + archived: :class:`bool` + Whether the thread is archived. + locked: :class:`bool` + Whether the thread is locked. + invitable: :class:`bool` + Whether non-moderators can add other non-moderators to this thread. + This is always ``True`` for public threads. + archiver_id: Optional[:class:`int`] + The user's ID that archived this thread. + auto_archive_duration: :class:`int` + The duration in minutes until the thread is automatically hidden from the channel list. + Usually a value of 60, 1440, 4320 and 10080. + archive_timestamp: :class:`datetime.datetime` + An aware timestamp of when the thread's archived status was last updated in UTC. + """ + + __slots__ = ( + 'id', + 'type', + 'name', + 'permissions', + 'guild_id', + 'parent_id', + 'archived', + 'archiver_id', + 'auto_archive_duration', + 'archive_timestamp', + 'locked', + 'invitable', + '_created_at', + '_state', + ) + + def __init__( + self, + *, + state: ConnectionState, + data: PartialThread, + guild_id: int, + ): + self._state: ConnectionState = state + self.guild_id: int = guild_id + self.id: int = int(data['id']) + self.parent_id: int = int(data['parent_id']) + self.type: ChannelType = try_enum(ChannelType, data['type']) + self.name: str = data['name'] + self.permissions: Permissions = Permissions(int(data['permissions'])) + self._unroll_metadata(data['thread_metadata']) + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id={self.id!r} name={self.name!r} archived={self.archived} type={self.type!r}>' + + @property + def guild(self) -> Optional[Guild]: + """Optional[:class:`~discord.Guild`]: The channel's guild, from cache, if found.""" + return self._state._get_guild(self.guild_id) + + def _unroll_metadata(self, data: ThreadMetadata) -> None: + self.archived: bool = data['archived'] + self.archiver_id: Optional[int] = _get_as_snowflake(data, 'archiver_id') + self.auto_archive_duration: ThreadArchiveDuration = data['auto_archive_duration'] + self.archive_timestamp: datetime = parse_time(data['archive_timestamp']) + self.locked: bool = data.get('locked', False) + self.invitable: bool = data.get('invitable', True) + self._created_at: Optional[datetime] = parse_time(data.get('create_timestamp')) + + @property + def parent(self) -> Optional[TextChannel]: + """Optional[:class:`~discord.TextChannel`]: The parent channel this thread belongs to.""" + return self.guild.get_channel(self.parent_id) # type: ignore + + @property + def mention(self) -> str: + """:class:`str`: The string that allows you to mention the thread.""" + return f'<#{self.id}>' + + @property + def created_at(self) -> Optional[datetime]: + """An aware timestamp of when the thread was created in UTC. + + .. note:: + + This timestamp only exists for threads created after 9 January 2022, otherwise returns ``None``. + """ + return self._created_at + + def resolve(self) -> Optional[Thread]: + """Resolves the application command channel to the appropriate channel + from cache if found. + + Returns + -------- + Optional[:class:`.abc.GuildChannel`] + The resolved guild channel or ``None`` if not found in cache. + """ + guild = self._state._get_guild(self.guild_id) + if guild is not None: + return guild.get_thread(self.id) + return None + + async def fetch(self) -> Thread: + """|coro| + + Fetches the partial channel to a full :class:`~discord.Thread`. + + Raises + -------- + NotFound + The thread was not found. + Forbidden + You do not have the permissions required to get a thread. + HTTPException + Retrieving the thread failed. + + Returns + -------- + :class:`~discord.Thread` + The full thread. + """ + client = self._state._get_client() + return await client.fetch_channel(self.id) # type: ignore # This is explicit narrowing + + +class Argument: + """Represents an application command argument. + + .. versionadded:: 2.0 + + Attributes + ------------ + type: :class:`~discord.AppCommandOptionType` + The type of argument. + name: :class:`str` + The name of the argument. + description: :class:`str` + The description of the argument. + name_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised names of the argument. Used for display purposes. + description_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised descriptions of the argument. Used for display purposes. + required: :class:`bool` + Whether the argument is required. + choices: List[:class:`Choice`] + A list of choices for the command to choose from for this argument. + parent: Union[:class:`AppCommand`, :class:`AppCommandGroup`] + The parent application command that has this argument. + channel_types: List[:class:`~discord.ChannelType`] + The channel types that are allowed for this parameter. + min_value: Optional[Union[:class:`int`, :class:`float`]] + The minimum supported value for this parameter. + max_value: Optional[Union[:class:`int`, :class:`float`]] + The maximum supported value for this parameter. + min_length: Optional[:class:`int`] + The minimum allowed length for this parameter. + max_length: Optional[:class:`int`] + The maximum allowed length for this parameter. + autocomplete: :class:`bool` + Whether the argument has autocomplete. + """ + + __slots__ = ( + 'type', + 'name', + 'description', + 'name_localizations', + 'description_localizations', + 'required', + 'choices', + 'channel_types', + 'min_value', + 'max_value', + 'min_length', + 'max_length', + 'autocomplete', + 'parent', + '_state', + ) + + def __init__( + self, *, parent: ApplicationCommandParent, data: ApplicationCommandOption, state: Optional[ConnectionState] = None + ) -> None: + self._state: Optional[ConnectionState] = state + self.parent: ApplicationCommandParent = parent + self._from_data(data) + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} name={self.name!r} type={self.type!r} required={self.required}>' + + def _from_data(self, data: ApplicationCommandOption) -> None: + self.type: AppCommandOptionType = try_enum(AppCommandOptionType, data['type']) + self.name: str = data['name'] + self.description: str = data['description'] + self.required: bool = data.get('required', False) + self.min_value: Optional[Union[int, float]] = data.get('min_value') + self.max_value: Optional[Union[int, float]] = data.get('max_value') + self.min_length: Optional[int] = data.get('min_length') + self.max_length: Optional[int] = data.get('max_length') + self.autocomplete: bool = data.get('autocomplete', False) + self.channel_types: List[ChannelType] = [try_enum(ChannelType, d) for d in data.get('channel_types', [])] + self.choices: List[Choice[Union[int, float, str]]] = [Choice.from_dict(d) for d in data.get('choices', [])] + self.name_localizations: Dict[Locale, str] = _to_locale_dict(data.get('name_localizations') or {}) + self.description_localizations: Dict[Locale, str] = _to_locale_dict(data.get('description_localizations') or {}) + + def to_dict(self) -> ApplicationCommandOption: + return { + 'name': self.name, + 'type': self.type.value, + 'description': self.description, + 'required': self.required, + 'choices': [choice.to_dict() for choice in self.choices], + 'channel_types': [channel_type.value for channel_type in self.channel_types], + 'min_value': self.min_value, + 'max_value': self.max_value, + 'min_length': self.min_length, + 'max_length': self.max_length, + 'autocomplete': self.autocomplete, + 'options': [], + 'name_localizations': {str(k): v for k, v in self.name_localizations.items()}, + 'description_localizations': {str(k): v for k, v in self.description_localizations.items()}, + } # type: ignore # Type checker does not understand this literal. + + +class AppCommandGroup: + """Represents an application command subcommand. + + .. versionadded:: 2.0 + + Attributes + ------------ + type: :class:`~discord.AppCommandOptionType` + The type of subcommand. + name: :class:`str` + The name of the subcommand. + description: :class:`str` + The description of the subcommand. + name_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised names of the subcommand. Used for display purposes. + description_localizations: Dict[:class:`~discord.Locale`, :class:`str`] + The localised descriptions of the subcommand. Used for display purposes. + options: List[Union[:class:`Argument`, :class:`AppCommandGroup`]] + A list of options. + parent: Union[:class:`AppCommand`, :class:`AppCommandGroup`] + The parent application command. + """ + + __slots__ = ( + 'type', + 'name', + 'description', + 'name_localizations', + 'description_localizations', + 'options', + 'parent', + '_state', + ) + + def __init__( + self, *, parent: ApplicationCommandParent, data: ApplicationCommandOption, state: Optional[ConnectionState] = None + ) -> None: + self.parent: ApplicationCommandParent = parent + self._state: Optional[ConnectionState] = state + self._from_data(data) + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} name={self.name!r} type={self.type!r}>' + + @property + def qualified_name(self) -> str: + """:class:`str`: Returns the fully qualified command name. + + The qualified name includes the parent name as well. For example, + in a command like ``/foo bar`` the qualified name is ``foo bar``. + """ + # A B C + # ^ self + # ^ parent + # ^ grandparent + names = [self.name, self.parent.name] + if isinstance(self.parent, AppCommandGroup): + names.append(self.parent.parent.name) + + return ' '.join(reversed(names)) + + @property + def mention(self) -> str: + """:class:`str`: Returns a string that allows you to mention the given AppCommandGroup.""" + if isinstance(self.parent, AppCommand): + base_command = self.parent + else: + base_command = self.parent.parent + return f'' # type: ignore + + def _from_data(self, data: ApplicationCommandOption) -> None: + self.type: AppCommandOptionType = try_enum(AppCommandOptionType, data['type']) + self.name: str = data['name'] + self.description: str = data['description'] + self.options: List[Union[Argument, AppCommandGroup]] = [ + app_command_option_factory(data=d, parent=self, state=self._state) for d in data.get('options', []) + ] + self.name_localizations: Dict[Locale, str] = _to_locale_dict(data.get('name_localizations') or {}) + self.description_localizations: Dict[Locale, str] = _to_locale_dict(data.get('description_localizations') or {}) + + def to_dict(self) -> 'ApplicationCommandOption': + return { + 'name': self.name, + 'type': self.type.value, + 'description': self.description, + 'options': [arg.to_dict() for arg in self.options], + 'name_localizations': {str(k): v for k, v in self.name_localizations.items()}, + 'description_localizations': {str(k): v for k, v in self.description_localizations.items()}, + } # type: ignore # Type checker does not understand this literal. + + +class AppCommandPermissions: + """Represents the permissions for an application command. + + .. versionadded:: 2.0 + + Attributes + ----------- + guild: :class:`~discord.Guild` + The guild associated with this permission. + id: :class:`int` + The ID of the permission target, such as a role, channel, or guild. + The special ``guild_id - 1`` sentinel is used to represent "all channels". + target: Any + The role, user, or channel associated with this permission. This could also be the :class:`AllChannels` sentinel type. + Falls back to :class:`~discord.Object` if the target could not be found in the cache. + type: :class:`.AppCommandPermissionType` + The type of permission. + permission: :class:`bool` + The permission value. ``True`` for allow, ``False`` for deny. + """ + + __slots__ = ('id', 'type', 'permission', 'target', 'guild', '_state') + + def __init__(self, *, data: ApplicationCommandPermissions, guild: Guild, state: ConnectionState) -> None: + self._state: ConnectionState = state + self.guild: Guild = guild + + self.id: int = int(data['id']) + self.type: AppCommandPermissionType = try_enum(AppCommandPermissionType, data['type']) + self.permission: bool = data['permission'] + + _object = None + _type = MISSING + + if self.type is AppCommandPermissionType.user: + _object = guild.get_member(self.id) or self._state.get_user(self.id) + _type = Member + elif self.type is AppCommandPermissionType.channel: + if self.id == (guild.id - 1): + _object = AllChannels(guild) + else: + _object = guild.get_channel(self.id) + elif self.type is AppCommandPermissionType.role: + _object = guild.get_role(self.id) + _type = Role + + if _object is None: + _object = Object(id=self.id, type=_type) + + self.target: Union[Object, User, Member, Role, AllChannels, GuildChannel] = _object + + def to_dict(self) -> ApplicationCommandPermissions: + return { + 'id': self.target.id, + 'type': self.type.value, + 'permission': self.permission, + } + + +class GuildAppCommandPermissions: + """Represents the permissions for an application command in a guild. + + .. versionadded:: 2.0 + + Attributes + ----------- + application_id: :class:`int` + The application ID. + command: :class:`.AppCommand` + The application command associated with the permissions. + id: :class:`int` + ID of the command or the application ID. + When this is the application ID instead of a command ID, + the permissions apply to all commands that do not contain explicit overwrites. + guild_id: :class:`int` + The guild ID associated with the permissions. + permissions: List[:class:`AppCommandPermissions`] + The permissions, this is a max of 100. + """ + + __slots__ = ('id', 'application_id', 'command', 'guild_id', 'permissions', '_state') + + def __init__(self, *, data: GuildApplicationCommandPermissions, state: ConnectionState, command: AppCommand) -> None: + self._state: ConnectionState = state + self.command: AppCommand = command + + self.id: int = int(data['id']) + self.application_id: int = int(data['application_id']) + self.guild_id: int = int(data['guild_id']) + guild = self.guild + self.permissions: List[AppCommandPermissions] = [ + AppCommandPermissions(data=value, guild=guild, state=self._state) for value in data['permissions'] + ] + + def to_dict(self) -> Dict[str, Any]: + return {'permissions': [p.to_dict() for p in self.permissions]} + + @property + def guild(self) -> Guild: + """:class:`~discord.Guild`: The guild associated with the permissions.""" + return self._state._get_or_create_unavailable_guild(self.guild_id) + + +def app_command_option_factory( + parent: ApplicationCommandParent, data: ApplicationCommandOption, *, state: Optional[ConnectionState] = None +) -> Union[Argument, AppCommandGroup]: + if is_app_command_argument_type(data['type']): + return Argument(parent=parent, data=data, state=state) + else: + return AppCommandGroup(parent=parent, data=data, state=state) diff --git a/dist/ba_data/python-site-packages/discord/app_commands/namespace.py b/dist/ba_data/python-site-packages/discord/app_commands/namespace.py new file mode 100644 index 00000000..7fad617c --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/namespace.py @@ -0,0 +1,263 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, NamedTuple, Tuple +from ..member import Member +from ..object import Object +from ..role import Role +from ..message import Message, Attachment +from ..channel import PartialMessageable +from ..enums import AppCommandOptionType +from .models import AppCommandChannel, AppCommandThread + +if TYPE_CHECKING: + from ..interactions import Interaction + from ..types.interactions import ResolvedData, ApplicationCommandInteractionDataOption + +__all__ = ('Namespace',) + + +class ResolveKey(NamedTuple): + id: str + # CommandOptionType does not use 0 or negative numbers so those can be safe for library + # internal use, if necessary. Likewise, only 6, 7, 8, and 11 are actually in use. + type: int + + @classmethod + def any_with(cls, id: str) -> ResolveKey: + return ResolveKey(id=id, type=-1) + + def __eq__(self, o: object) -> bool: + if not isinstance(o, ResolveKey): + return NotImplemented + if self.type == -1 or o.type == -1: + return self.id == o.id + return (self.id, self.type) == (o.id, o.type) + + def __hash__(self) -> int: + # Most of the time an ID lookup is all that is necessary + # In case of collision then we look up both the ID and the type. + return hash(self.id) + + +class Namespace: + """An object that holds the parameters being passed to a command in a mostly raw state. + + This class is deliberately simple and just holds the option name and resolved value as a simple + key-pair mapping. These attributes can be accessed using dot notation. For example, an option + with the name of ``example`` can be accessed using ``ns.example``. If an attribute is not found, + then ``None`` is returned rather than an attribute error. + + .. warning:: + + The key names come from the raw Discord data, which means that if a parameter was renamed then the + renamed key is used instead of the function parameter name. + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two namespaces are equal by checking if all attributes are equal. + .. describe:: x != y + + Checks if two namespaces are not equal. + .. describe:: x[key] + + Returns an attribute if it is found, otherwise raises + a :exc:`KeyError`. + .. describe:: key in x + + Checks if the attribute is in the namespace. + .. describe:: iter(x) + + Returns an iterator of ``(name, value)`` pairs. This allows it + to be, for example, constructed as a dict or a list of pairs. + + This namespace object converts resolved objects into their appropriate form depending on their + type. Consult the table below for conversion information. + + +-------------------------------------------+-------------------------------------------------------------------------------+ + | Option Type | Resolved Type | + +===========================================+===============================================================================+ + | :attr:`.AppCommandOptionType.string` | :class:`str` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.integer` | :class:`int` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.boolean` | :class:`bool` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.number` | :class:`float` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.user` | :class:`~discord.User` or :class:`~discord.Member` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.channel` | :class:`.AppCommandChannel` or :class:`.AppCommandThread` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.role` | :class:`~discord.Role` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.mentionable` | :class:`~discord.User` or :class:`~discord.Member`, or :class:`~discord.Role` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + | :attr:`.AppCommandOptionType.attachment` | :class:`~discord.Attachment` | + +-------------------------------------------+-------------------------------------------------------------------------------+ + + .. note:: + + In autocomplete interactions, the namespace might not be validated or filled in. Discord does not + send the resolved data as well, so this means that certain fields end up just as IDs rather than + the resolved data. In these cases, a :class:`discord.Object` is returned instead. + + This is a Discord limitation. + """ + + def __init__( + self, + interaction: Interaction, + resolved: ResolvedData, + options: List[ApplicationCommandInteractionDataOption], + ): + completed = self._get_resolved_items(interaction, resolved) + for option in options: + opt_type = option['type'] + name = option['name'] + focused = option.get('focused', False) + if opt_type in (3, 4, 5): # string, integer, boolean + value = option['value'] # type: ignore # Key is there + self.__dict__[name] = value + elif opt_type == 10: # number + value = option['value'] # type: ignore # Key is there + # This condition is written this way because 0 can be a valid float + if value is None or value == '': + self.__dict__[name] = float('nan') + else: + if not focused: + self.__dict__[name] = float(value) + else: + # Autocomplete focused values tend to be garbage in + self.__dict__[name] = value + elif opt_type in (6, 7, 8, 9, 11): + # Remaining ones should be snowflake based ones with resolved data + snowflake: str = option['value'] # type: ignore # Key is there + if opt_type == 9: # Mentionable + # Mentionable is User | Role, these do not cause any conflict + key = ResolveKey.any_with(snowflake) + else: + # The remaining keys can conflict, for example, a role and a channel + # could end up with the same ID in very old guilds since they used to default + # to sharing the guild ID. Old general channels no longer exist, but some old + # servers will still have them so this needs to be handled. + key = ResolveKey(id=snowflake, type=opt_type) + + value = completed.get(key) or Object(id=int(snowflake)) + self.__dict__[name] = value + + @classmethod + def _get_resolved_items(cls, interaction: Interaction, resolved: ResolvedData) -> Dict[ResolveKey, Any]: + completed: Dict[ResolveKey, Any] = {} + state = interaction._state + members = resolved.get('members', {}) + guild_id = interaction.guild_id + guild = state._get_or_create_unavailable_guild(guild_id) if guild_id is not None else None + type = AppCommandOptionType.user.value + for (user_id, user_data) in resolved.get('users', {}).items(): + try: + member_data = members[user_id] + except KeyError: + completed[ResolveKey(id=user_id, type=type)] = state.create_user(user_data) + else: + member_data['user'] = user_data + # Guild ID can't be None in this case. + # There's a type mismatch here that I don't actually care about + member = Member(state=state, guild=guild, data=member_data) # type: ignore + completed[ResolveKey(id=user_id, type=type)] = member + + type = AppCommandOptionType.role.value + completed.update( + { + # The guild ID can't be None in this case. + ResolveKey(id=role_id, type=type): Role(guild=guild, state=state, data=role_data) # type: ignore + for role_id, role_data in resolved.get('roles', {}).items() + } + ) + + type = AppCommandOptionType.channel.value + for (channel_id, channel_data) in resolved.get('channels', {}).items(): + key = ResolveKey(id=channel_id, type=type) + if channel_data['type'] in (10, 11, 12): + # The guild ID can't be none in this case + completed[key] = AppCommandThread(state=state, data=channel_data, guild_id=guild_id) # type: ignore + else: + # The guild ID can't be none in this case + completed[key] = AppCommandChannel(state=state, data=channel_data, guild_id=guild_id) # type: ignore + + type = AppCommandOptionType.attachment.value + completed.update( + { + ResolveKey(id=attachment_id, type=type): Attachment(data=attachment_data, state=state) + for attachment_id, attachment_data in resolved.get('attachments', {}).items() + } + ) + + guild = state._get_guild(guild_id) + for (message_id, message_data) in resolved.get('messages', {}).items(): + channel_id = int(message_data['channel_id']) + if guild is None: + channel = PartialMessageable(state=state, guild_id=guild_id, id=channel_id) + else: + channel = guild.get_channel_or_thread(channel_id) or PartialMessageable( + state=state, guild_id=guild_id, id=channel_id + ) + + # Type checker doesn't understand this due to failure to narrow + message = Message(state=state, channel=channel, data=message_data) # type: ignore + key = ResolveKey(id=message_id, type=-1) + completed[key] = message + + return completed + + def __repr__(self) -> str: + items = (f'{k}={v!r}' for k, v in self.__dict__.items()) + return '<{} {}>'.format(self.__class__.__name__, ' '.join(items)) + + def __eq__(self, other: object) -> bool: + if isinstance(self, Namespace) and isinstance(other, Namespace): + return self.__dict__ == other.__dict__ + return NotImplemented + + def __getitem__(self, key: str) -> Any: + return self.__dict__[key] + + def __contains__(self, key: str) -> Any: + return key in self.__dict__ + + def __getattr__(self, attr: str) -> Any: + return None + + def __iter__(self) -> Iterator[Tuple[str, Any]]: + yield from self.__dict__.items() + + def _update_with_defaults(self, defaults: Iterable[Tuple[str, Any]]) -> None: + for key, value in defaults: + self.__dict__.setdefault(key, value) diff --git a/dist/ba_data/python-site-packages/discord/app_commands/transformers.py b/dist/ba_data/python-site-packages/discord/app_commands/transformers.py new file mode 100644 index 00000000..8f009181 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/transformers.py @@ -0,0 +1,877 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +import inspect + +from dataclasses import dataclass +from enum import Enum +from typing import ( + TYPE_CHECKING, + Any, + Callable, + ClassVar, + Coroutine, + Dict, + List, + Literal, + Optional, + Set, + Tuple, + Type, + TypeVar, + Union, +) + +from .errors import AppCommandError, TransformerError +from .models import AppCommandChannel, AppCommandThread, Choice +from .translator import TranslationContextLocation, TranslationContext, Translator, locale_str +from ..channel import StageChannel, VoiceChannel, TextChannel, CategoryChannel, ForumChannel +from ..abc import GuildChannel +from ..threads import Thread +from ..enums import Enum as InternalEnum, AppCommandOptionType, ChannelType, Locale +from ..utils import MISSING, maybe_coroutine +from ..user import User +from ..role import Role +from ..member import Member +from ..message import Attachment + +__all__ = ( + 'Transformer', + 'Transform', + 'Range', +) + +T = TypeVar('T') +FuncT = TypeVar('FuncT', bound=Callable[..., Any]) +ChoiceT = TypeVar('ChoiceT', str, int, float, Union[str, int, float]) +NoneType = type(None) + +if TYPE_CHECKING: + from ..interactions import Interaction + from .commands import Parameter + + +@dataclass +class CommandParameter: + # The name of the parameter is *always* the parameter name in the code + # Therefore, it can't be Union[str, locale_str] + name: str = MISSING + description: Union[str, locale_str] = MISSING + required: bool = MISSING + default: Any = MISSING + choices: List[Choice[Union[str, int, float]]] = MISSING + type: AppCommandOptionType = MISSING + channel_types: List[ChannelType] = MISSING + min_value: Optional[Union[int, float]] = None + max_value: Optional[Union[int, float]] = None + autocomplete: Optional[Callable[..., Coroutine[Any, Any, Any]]] = None + _rename: Union[str, locale_str] = MISSING + _annotation: Any = MISSING + + async def get_translated_payload(self, translator: Translator, data: Parameter) -> Dict[str, Any]: + base = self.to_dict() + + rename = self._rename + description = self.description + needs_name_translations = isinstance(rename, locale_str) + needs_description_translations = isinstance(description, locale_str) + name_localizations: Dict[str, str] = {} + description_localizations: Dict[str, str] = {} + + # Prevent creating these objects in a heavy loop + name_context = TranslationContext(location=TranslationContextLocation.parameter_name, data=data) + description_context = TranslationContext(location=TranslationContextLocation.parameter_description, data=data) + for locale in Locale: + if needs_name_translations: + translation = await translator._checked_translate(rename, locale, name_context) + if translation is not None: + name_localizations[locale.value] = translation + + if needs_description_translations: + translation = await translator._checked_translate(description, locale, description_context) + if translation is not None: + description_localizations[locale.value] = translation + + if self.choices: + base['choices'] = [await choice.get_translated_payload(translator) for choice in self.choices] + + if name_localizations: + base['name_localizations'] = name_localizations + + if description_localizations: + base['description_localizations'] = description_localizations + + return base + + def to_dict(self) -> Dict[str, Any]: + base = { + 'type': self.type.value, + 'name': self.display_name, + 'description': str(self.description), + 'required': self.required, + } + + if self.choices: + base['choices'] = [choice.to_dict() for choice in self.choices] + if self.channel_types: + base['channel_types'] = [t.value for t in self.channel_types] + if self.autocomplete: + base['autocomplete'] = True + + min_key, max_key = ( + ('min_value', 'max_value') if self.type is not AppCommandOptionType.string else ('min_length', 'max_length') + ) + if self.min_value is not None: + base[min_key] = self.min_value + if self.max_value is not None: + base[max_key] = self.max_value + + return base + + def _convert_to_locale_strings(self) -> None: + if self._rename is MISSING: + self._rename = locale_str(self.name) + elif isinstance(self._rename, str): + self._rename = locale_str(self._rename) + + if isinstance(self.description, str): + self.description = locale_str(self.description) + + if self.choices: + for choice in self.choices: + if choice._locale_name is None: + choice._locale_name = locale_str(choice.name) + + def is_choice_annotation(self) -> bool: + return getattr(self._annotation, '__discord_app_commands_is_choice__', False) + + async def transform(self, interaction: Interaction, value: Any, /) -> Any: + if hasattr(self._annotation, '__discord_app_commands_transformer__'): + # This one needs special handling for type safety reasons + if self._annotation.__discord_app_commands_is_choice__: + choice = next((c for c in self.choices if c.value == value), None) + if choice is None: + raise TransformerError(value, self.type, self._annotation) + return choice + + try: + # ParamSpec doesn't understand that transform is a callable since it's unbound + return await maybe_coroutine(self._annotation.transform, interaction, value) # type: ignore + except AppCommandError: + raise + except Exception as e: + raise TransformerError(value, self.type, self._annotation) from e + + return value + + @property + def display_name(self) -> str: + """:class:`str`: The name of the parameter as it should be displayed to the user.""" + return self.name if self._rename is MISSING else str(self._rename) + + +class Transformer: + """The base class that allows a type annotation in an application command parameter + to map into a :class:`~discord.AppCommandOptionType` and transform the raw value into one + from this type. + + This class is customisable through the overriding of methods and properties in the class + and by using it as the second type parameter of the :class:`~discord.app_commands.Transform` + class. For example, to convert a string into a custom pair type: + + .. code-block:: python3 + + class Point(typing.NamedTuple): + x: int + y: int + + class PointTransformer(app_commands.Transformer): + async def transform(self, interaction: discord.Interaction, value: str) -> Point: + (x, _, y) = value.partition(',') + return Point(x=int(x.strip()), y=int(y.strip())) + + @app_commands.command() + async def graph( + interaction: discord.Interaction, + point: app_commands.Transform[Point, PointTransformer], + ): + await interaction.response.send_message(str(point)) + + If a class is passed instead of an instance to the second type parameter, then it is + constructed with no arguments passed to the ``__init__`` method. + + .. versionadded:: 2.0 + """ + + __discord_app_commands_transformer__: ClassVar[bool] = True + __discord_app_commands_is_choice__: ClassVar[bool] = False + + # This is needed to pass typing's type checks. + # e.g. Optional[MyTransformer] + def __call__(self) -> None: + pass + + def __or__(self, rhs: Any) -> Any: + return Union[self, rhs] # type: ignore + + @property + def type(self) -> AppCommandOptionType: + """:class:`~discord.AppCommandOptionType`: The option type associated with this transformer. + + This must be a :obj:`property`. + + Defaults to :attr:`~discord.AppCommandOptionType.string`. + """ + return AppCommandOptionType.string + + @property + def channel_types(self) -> List[ChannelType]: + """List[:class:`~discord.ChannelType`]: A list of channel types that are allowed to this parameter. + + Only valid if the :meth:`type` returns :attr:`~discord.AppCommandOptionType.channel`. + + This must be a :obj:`property`. + + Defaults to an empty list. + """ + return [] + + @property + def min_value(self) -> Optional[Union[int, float]]: + """Optional[:class:`int`]: The minimum supported value for this parameter. + + Only valid if the :meth:`type` returns :attr:`~discord.AppCommandOptionType.number` + :attr:`~discord.AppCommandOptionType.integer`, or :attr:`~discord.AppCommandOptionType.string`. + + This must be a :obj:`property`. + + Defaults to ``None``. + """ + return None + + @property + def max_value(self) -> Optional[Union[int, float]]: + """Optional[:class:`int`]: The maximum supported value for this parameter. + + Only valid if the :meth:`type` returns :attr:`~discord.AppCommandOptionType.number` + :attr:`~discord.AppCommandOptionType.integer`, or :attr:`~discord.AppCommandOptionType.string`. + + This must be a :obj:`property`. + + Defaults to ``None``. + """ + return None + + @property + def choices(self) -> Optional[List[Choice[Union[int, float, str]]]]: + """Optional[List[:class:`~discord.app_commands.Choice`]]: A list of up to 25 choices that are allowed to this parameter. + + Only valid if the :meth:`type` returns :attr:`~discord.AppCommandOptionType.number` + :attr:`~discord.AppCommandOptionType.integer`, or :attr:`~discord.AppCommandOptionType.string`. + + This must be a :obj:`property`. + + Defaults to ``None``. + """ + return None + + @property + def _error_display_name(self) -> str: + name = self.__class__.__name__ + if name.endswith('Transformer'): + return name[:-11] + else: + return name + + async def transform(self, interaction: Interaction, value: Any, /) -> Any: + """|maybecoro| + + Transforms the converted option value into another value. + + The value passed into this transform function is the same as the + one in the :class:`conversion table `. + + Parameters + ----------- + interaction: :class:`~discord.Interaction` + The interaction being handled. + value: Any + The value of the given argument after being resolved. + See the :class:`conversion table ` + for how certain option types correspond to certain values. + """ + raise NotImplementedError('Derived classes need to implement this.') + + async def autocomplete( + self, interaction: Interaction, value: Union[int, float, str], / + ) -> List[Choice[Union[int, float, str]]]: + """|coro| + + An autocomplete prompt handler to be automatically used by options using this transformer. + + .. note:: + + Autocomplete is only supported for options with a :meth:`~discord.app_commands.Transformer.type` + of :attr:`~discord.AppCommandOptionType.string`, :attr:`~discord.AppCommandOptionType.integer`, + or :attr:`~discord.AppCommandOptionType.number`. + + Parameters + ----------- + interaction: :class:`~discord.Interaction` + The autocomplete interaction being handled. + value: Union[:class:`str`, :class:`int`, :class:`float`] + The current value entered by the user. + + Returns + -------- + List[:class:`~discord.app_commands.Choice`] + A list of choices to be displayed to the user, a maximum of 25. + + """ + raise NotImplementedError('Derived classes can implement this.') + + +class IdentityTransformer(Transformer): + def __init__(self, type: AppCommandOptionType) -> None: + self._type = type + + @property + def type(self) -> AppCommandOptionType: + return self._type + + async def transform(self, interaction: Interaction, value: Any, /) -> Any: + return value + + +class RangeTransformer(IdentityTransformer): + def __init__( + self, + opt_type: AppCommandOptionType, + *, + min: Optional[Union[int, float]] = None, + max: Optional[Union[int, float]] = None, + ) -> None: + if min and max and min > max: + raise TypeError('minimum cannot be larger than maximum') + + self._min: Optional[Union[int, float]] = min + self._max: Optional[Union[int, float]] = max + super().__init__(opt_type) + + @property + def min_value(self) -> Optional[Union[int, float]]: + return self._min + + @property + def max_value(self) -> Optional[Union[int, float]]: + return self._max + + +class LiteralTransformer(IdentityTransformer): + def __init__(self, values: Tuple[Any, ...]) -> None: + first = type(values[0]) + if first is int: + opt_type = AppCommandOptionType.integer + elif first is float: + opt_type = AppCommandOptionType.number + elif first is str: + opt_type = AppCommandOptionType.string + else: + raise TypeError(f'expected int, str, or float values not {first!r}') + + self._choices = [Choice(name=str(v), value=v) for v in values] + super().__init__(opt_type) + + @property + def choices(self): + return self._choices + + +class ChoiceTransformer(IdentityTransformer): + __discord_app_commands_is_choice__: ClassVar[bool] = True + + def __init__(self, inner_type: Any) -> None: + if inner_type is int: + opt_type = AppCommandOptionType.integer + elif inner_type is float: + opt_type = AppCommandOptionType.number + elif inner_type is str: + opt_type = AppCommandOptionType.string + else: + raise TypeError(f'expected int, str, or float values not {inner_type!r}') + + super().__init__(opt_type) + + +class EnumValueTransformer(Transformer): + def __init__(self, enum: Any) -> None: + super().__init__() + + values = list(enum) + if len(values) < 2: + raise TypeError('enum.Enum requires at least two values.') + + first = type(values[0].value) + if first is int: + opt_type = AppCommandOptionType.integer + elif first is float: + opt_type = AppCommandOptionType.number + elif first is str: + opt_type = AppCommandOptionType.string + else: + raise TypeError(f'expected int, str, or float values not {first!r}') + + self._type: AppCommandOptionType = opt_type + self._enum: Any = enum + self._choices = [Choice(name=v.name, value=v.value) for v in values] + + @property + def _error_display_name(self) -> str: + return self._enum.__name__ + + @property + def type(self) -> AppCommandOptionType: + return self._type + + @property + def choices(self): + return self._choices + + async def transform(self, interaction: Interaction, value: Any, /) -> Any: + return self._enum(value) + + +class EnumNameTransformer(Transformer): + def __init__(self, enum: Any) -> None: + super().__init__() + + values = list(enum) + if len(values) < 2: + raise TypeError('enum.Enum requires at least two values.') + + self._enum: Any = enum + self._choices = [Choice(name=v.name, value=v.name) for v in values] + + @property + def _error_display_name(self) -> str: + return self._enum.__name__ + + @property + def type(self) -> AppCommandOptionType: + return AppCommandOptionType.string + + @property + def choices(self): + return self._choices + + async def transform(self, interaction: Interaction, value: Any, /) -> Any: + return self._enum[value] + + +class InlineTransformer(Transformer): + def __init__(self, annotation: Any) -> None: + super().__init__() + self.annotation: Any = annotation + + @property + def _error_display_name(self) -> str: + return self.annotation.__name__ + + @property + def type(self) -> AppCommandOptionType: + return AppCommandOptionType.string + + async def transform(self, interaction: Interaction, value: Any, /) -> Any: + return await self.annotation.transform(interaction, value) + + +if TYPE_CHECKING: + from typing_extensions import Annotated as Transform + from typing_extensions import Annotated as Range +else: + + class Transform: + """A type annotation that can be applied to a parameter to customise the behaviour of + an option type by transforming with the given :class:`Transformer`. This requires + the usage of two generic parameters, the first one is the type you're converting to and the second + one is the type of the :class:`Transformer` actually doing the transformation. + + During type checking time this is equivalent to :obj:`typing.Annotated` so type checkers understand + the intent of the code. + + For example usage, check :class:`Transformer`. + + .. versionadded:: 2.0 + """ + + def __class_getitem__(cls, items) -> _TransformMetadata: + if not isinstance(items, tuple): + raise TypeError(f'expected tuple for arguments, received {items.__class__.__name__} instead') + + if len(items) != 2: + raise TypeError('Transform only accepts exactly two arguments') + + _, transformer = items + + if inspect.isclass(transformer): + if not issubclass(transformer, Transformer): + raise TypeError(f'second argument of Transform must be a Transformer class not {transformer!r}') + transformer = transformer() + elif not isinstance(transformer, Transformer): + raise TypeError(f'second argument of Transform must be a Transformer not {transformer.__class__.__name__}') + + return transformer + + class Range: + """A type annotation that can be applied to a parameter to require a numeric or string + type to fit within the range provided. + + During type checking time this is equivalent to :obj:`typing.Annotated` so type checkers understand + the intent of the code. + + Some example ranges: + + - ``Range[int, 10]`` means the minimum is 10 with no maximum. + - ``Range[int, None, 10]`` means the maximum is 10 with no minimum. + - ``Range[int, 1, 10]`` means the minimum is 1 and the maximum is 10. + - ``Range[float, 1.0, 5.0]`` means the minimum is 1.0 and the maximum is 5.0. + - ``Range[str, 1, 10]`` means the minimum length is 1 and the maximum length is 10. + + .. versionadded:: 2.0 + + Examples + ---------- + + .. code-block:: python3 + + @app_commands.command() + async def range(interaction: discord.Interaction, value: app_commands.Range[int, 10, 12]): + await interaction.response.send_message(f'Your value is {value}', ephemeral=True) + """ + + def __class_getitem__(cls, obj) -> _TransformMetadata: + if not isinstance(obj, tuple): + raise TypeError(f'expected tuple for arguments, received {obj.__class__.__name__} instead') + + if len(obj) == 2: + obj = (*obj, None) + elif len(obj) != 3: + raise TypeError('Range accepts either two or three arguments with the first being the type of range.') + + obj_type, min, max = obj + + if min is None and max is None: + raise TypeError('Range must not be empty') + + if min is not None and max is not None: + # At this point max and min are both not none + if type(min) != type(max): + raise TypeError('Both min and max in Range must be the same type') + + if obj_type is int: + opt_type = AppCommandOptionType.integer + elif obj_type is float: + opt_type = AppCommandOptionType.number + elif obj_type is str: + opt_type = AppCommandOptionType.string + else: + raise TypeError(f'expected int, float, or str as range type, received {obj_type!r} instead') + + if obj_type in (str, int): + cast = int + else: + cast = float + + transformer = RangeTransformer( + opt_type, + min=cast(min) if min is not None else None, + max=cast(max) if max is not None else None, + ) + return transformer + + +class MemberTransformer(Transformer): + @property + def type(self) -> AppCommandOptionType: + return AppCommandOptionType.user + + async def transform(self, interaction: Interaction, value: Any, /) -> Member: + if not isinstance(value, Member): + raise TransformerError(value, self.type, self) + return value + + +class BaseChannelTransformer(Transformer): + def __init__(self, *channel_types: Type[Any]) -> None: + super().__init__() + if len(channel_types) == 1: + display_name = channel_types[0].__name__ + types = CHANNEL_TO_TYPES[channel_types[0]] + else: + display_name = '{}, and {}'.format(', '.join(t.__name__ for t in channel_types[:-1]), channel_types[-1].__name__) + types = [] + + for t in channel_types: + try: + types.extend(CHANNEL_TO_TYPES[t]) + except KeyError: + raise TypeError('Union type of channels must be entirely made up of channels') from None + + self._types: Tuple[Type[Any]] = channel_types + self._channel_types: List[ChannelType] = types + self._display_name = display_name + + @property + def _error_display_name(self) -> str: + return self._display_name + + @property + def type(self) -> AppCommandOptionType: + return AppCommandOptionType.channel + + @property + def channel_types(self) -> List[ChannelType]: + return self._channel_types + + async def transform(self, interaction: Interaction, value: Any, /): + resolved = value.resolve() + if resolved is None or not isinstance(resolved, self._types): + raise TransformerError(value, AppCommandOptionType.channel, self) + return resolved + + +class RawChannelTransformer(BaseChannelTransformer): + async def transform(self, interaction: Interaction, value: Any, /): + if not isinstance(value, self._types): + raise TransformerError(value, AppCommandOptionType.channel, self) + return value + + +class UnionChannelTransformer(BaseChannelTransformer): + async def transform(self, interaction: Interaction, value: Any, /): + if isinstance(value, self._types): + return value + + resolved = value.resolve() + if resolved is None or not isinstance(resolved, self._types): + raise TransformerError(value, AppCommandOptionType.channel, self) + return resolved + + +CHANNEL_TO_TYPES: Dict[Any, List[ChannelType]] = { + AppCommandChannel: [ + ChannelType.stage_voice, + ChannelType.voice, + ChannelType.text, + ChannelType.news, + ChannelType.category, + ChannelType.forum, + ], + GuildChannel: [ + ChannelType.stage_voice, + ChannelType.voice, + ChannelType.text, + ChannelType.news, + ChannelType.category, + ChannelType.forum, + ], + AppCommandThread: [ChannelType.news_thread, ChannelType.private_thread, ChannelType.public_thread], + Thread: [ChannelType.news_thread, ChannelType.private_thread, ChannelType.public_thread], + StageChannel: [ChannelType.stage_voice], + VoiceChannel: [ChannelType.voice], + TextChannel: [ChannelType.text, ChannelType.news], + CategoryChannel: [ChannelType.category], + ForumChannel: [ChannelType.forum], +} + +BUILT_IN_TRANSFORMERS: Dict[Any, Transformer] = { + str: IdentityTransformer(AppCommandOptionType.string), + int: IdentityTransformer(AppCommandOptionType.integer), + float: IdentityTransformer(AppCommandOptionType.number), + bool: IdentityTransformer(AppCommandOptionType.boolean), + User: IdentityTransformer(AppCommandOptionType.user), + Member: MemberTransformer(), + Role: IdentityTransformer(AppCommandOptionType.role), + AppCommandChannel: RawChannelTransformer(AppCommandChannel), + AppCommandThread: RawChannelTransformer(AppCommandThread), + GuildChannel: BaseChannelTransformer(GuildChannel), + Thread: BaseChannelTransformer(Thread), + StageChannel: BaseChannelTransformer(StageChannel), + VoiceChannel: BaseChannelTransformer(VoiceChannel), + TextChannel: BaseChannelTransformer(TextChannel), + CategoryChannel: BaseChannelTransformer(CategoryChannel), + ForumChannel: BaseChannelTransformer(ForumChannel), + Attachment: IdentityTransformer(AppCommandOptionType.attachment), +} + +ALLOWED_DEFAULTS: Dict[AppCommandOptionType, Tuple[Type[Any], ...]] = { + AppCommandOptionType.string: (str, NoneType), + AppCommandOptionType.integer: (int, NoneType), + AppCommandOptionType.boolean: (bool, NoneType), + AppCommandOptionType.number: (float, NoneType), +} + + +def get_supported_annotation( + annotation: Any, + *, + _none: type = NoneType, + _mapping: Dict[Any, Transformer] = BUILT_IN_TRANSFORMERS, +) -> Tuple[Any, Any, bool]: + """Returns an appropriate, yet supported, annotation along with an optional default value. + + The third boolean element of the tuple indicates if default values should be validated. + + This differs from the built in mapping by supporting a few more things. + Likewise, this returns a "transformed" annotation that is ready to use with CommandParameter.transform. + """ + + try: + return (_mapping[annotation], MISSING, True) + except (KeyError, TypeError): + pass + + if isinstance(annotation, Transformer): + return (annotation, MISSING, False) + + if inspect.isclass(annotation): + if issubclass(annotation, Transformer): + return (annotation(), MISSING, False) + if issubclass(annotation, (Enum, InternalEnum)): + if all(isinstance(v.value, (str, int, float)) for v in annotation): + return (EnumValueTransformer(annotation), MISSING, False) + else: + return (EnumNameTransformer(annotation), MISSING, False) + if annotation is Choice: + raise TypeError('Choice requires a type argument of int, str, or float') + + # Check if a transform @classmethod is given to the class + # These flatten into simple "inline" transformers with implicit strings + transform_classmethod = annotation.__dict__.get('transform', None) + if isinstance(transform_classmethod, classmethod): + params = inspect.signature(transform_classmethod.__func__).parameters + if len(params) != 3: + raise TypeError('Inline transformer with transform classmethod requires 3 parameters') + if not inspect.iscoroutinefunction(transform_classmethod.__func__): + raise TypeError('Inline transformer with transform classmethod must be a coroutine') + return (InlineTransformer(annotation), MISSING, False) + + # Check if there's an origin + origin = getattr(annotation, '__origin__', None) + if origin is Literal: + args = annotation.__args__ # type: ignore + return (LiteralTransformer(args), MISSING, True) + + if origin is Choice: + arg = annotation.__args__[0] # type: ignore + return (ChoiceTransformer(arg), MISSING, True) + + if origin is not Union: + # Only Union/Optional is supported right now so bail early + raise TypeError(f'unsupported type annotation {annotation!r}') + + default = MISSING + args = annotation.__args__ # type: ignore + if args[-1] is _none: + if len(args) == 2: + underlying = args[0] + inner, _, validate_default = get_supported_annotation(underlying) + if inner is None: + raise TypeError(f'unsupported inner optional type {underlying!r}') + return (inner, None, validate_default) + else: + args = args[:-1] + default = None + + # Check for channel union types + if any(arg in CHANNEL_TO_TYPES for arg in args): + # If any channel type is given, then *all* must be channel types + return (UnionChannelTransformer(*args), default, True) + + # The only valid transformations here are: + # [Member, User] => user + # [Member, User, Role] => mentionable + # [Member | User, Role] => mentionable + supported_types: Set[Any] = {Role, Member, User} + if not all(arg in supported_types for arg in args): + raise TypeError(f'unsupported types given inside {annotation!r}') + if args == (User, Member) or args == (Member, User): + return (IdentityTransformer(AppCommandOptionType.user), default, True) + + return (IdentityTransformer(AppCommandOptionType.mentionable), default, True) + + +def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> CommandParameter: + """Returns the appropriate :class:`CommandParameter` for the given annotation. + + The resulting ``_annotation`` attribute might not match the one given here and might + be transformed in order to be easier to call from the ``transform`` asynchronous function + of a command parameter. + """ + + (inner, default, validate_default) = get_supported_annotation(annotation) + type = inner.type + + if default is MISSING or default is None: + param_default = parameter.default + if param_default is not parameter.empty: + default = param_default + + # Verify validity of the default parameter + if default is not MISSING and validate_default: + valid_types: Tuple[Any, ...] = ALLOWED_DEFAULTS.get(type, (NoneType,)) + if not isinstance(default, valid_types): + raise TypeError(f'invalid default parameter type given ({default.__class__}), expected {valid_types}') + + result = CommandParameter( + type=type, + _annotation=inner, + default=default, + required=default is MISSING, + name=parameter.name, + ) + + choices = inner.choices + if choices is not None: + result.choices = choices + + # These methods should be duck typed + if type in (AppCommandOptionType.number, AppCommandOptionType.string, AppCommandOptionType.integer): + result.min_value = inner.min_value + result.max_value = inner.max_value + + if type is AppCommandOptionType.channel: + result.channel_types = inner.channel_types + + if parameter.kind in (parameter.POSITIONAL_ONLY, parameter.VAR_KEYWORD, parameter.VAR_POSITIONAL): + raise TypeError(f'unsupported parameter kind in callback: {parameter.kind!s}') + + # Check if the method is overridden + if inner.autocomplete.__func__ is not Transformer.autocomplete: + from .commands import validate_auto_complete_callback + + result.autocomplete = validate_auto_complete_callback(inner.autocomplete) + + return result diff --git a/dist/ba_data/python-site-packages/discord/app_commands/translator.py b/dist/ba_data/python-site-packages/discord/app_commands/translator.py new file mode 100644 index 00000000..1741054e --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/translator.py @@ -0,0 +1,305 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +from typing import TYPE_CHECKING, Any, Generic, Literal, Optional, TypeVar, Union, overload +from .errors import TranslationError +from ..enums import Enum, Locale + + +if TYPE_CHECKING: + from .commands import Command, ContextMenu, Group, Parameter + from .models import Choice + + +__all__ = ( + 'TranslationContextLocation', + 'TranslationContextTypes', + 'TranslationContext', + 'Translator', + 'locale_str', +) + + +class TranslationContextLocation(Enum): + command_name = 0 + command_description = 1 + group_name = 2 + group_description = 3 + parameter_name = 4 + parameter_description = 5 + choice_name = 6 + other = 7 + + +_L = TypeVar('_L', bound=TranslationContextLocation) +_D = TypeVar('_D') + + +class TranslationContext(Generic[_L, _D]): + """A class that provides context for the :class:`locale_str` being translated. + + This is useful to determine where exactly the string is located and aid in looking + up the actual translation. + + Attributes + ----------- + location: :class:`TranslationContextLocation` + The location where this string is located. + data: Any + The extraneous data that is being translated. + """ + + __slots__ = ('location', 'data') + + @overload + def __init__( + self, location: Literal[TranslationContextLocation.command_name], data: Union[Command[Any, ..., Any], ContextMenu] + ) -> None: + ... + + @overload + def __init__( + self, location: Literal[TranslationContextLocation.command_description], data: Command[Any, ..., Any] + ) -> None: + ... + + @overload + def __init__( + self, + location: Literal[TranslationContextLocation.group_name, TranslationContextLocation.group_description], + data: Group, + ) -> None: + ... + + @overload + def __init__( + self, + location: Literal[TranslationContextLocation.parameter_name, TranslationContextLocation.parameter_description], + data: Parameter, + ) -> None: + ... + + @overload + def __init__(self, location: Literal[TranslationContextLocation.choice_name], data: Choice[Any]) -> None: + ... + + @overload + def __init__(self, location: Literal[TranslationContextLocation.other], data: Any) -> None: + ... + + def __init__(self, location: _L, data: _D) -> None: + self.location: _L = location + self.data: _D = data + + +# For type checking purposes, it makes sense to allow the user to leverage type narrowing +# So code like this works as expected: +# +# if context.type == TranslationContextLocation.command_name: +# reveal_type(context.data) # Revealed type is Command | ContextMenu +# +# This requires a union of types +CommandNameTranslationContext = TranslationContext[ + Literal[TranslationContextLocation.command_name], Union['Command[Any, ..., Any]', 'ContextMenu'] +] +CommandDescriptionTranslationContext = TranslationContext[ + Literal[TranslationContextLocation.command_description], 'Command[Any, ..., Any]' +] +GroupTranslationContext = TranslationContext[ + Literal[TranslationContextLocation.group_name, TranslationContextLocation.group_description], 'Group' +] +ParameterTranslationContext = TranslationContext[ + Literal[TranslationContextLocation.parameter_name, TranslationContextLocation.parameter_description], 'Parameter' +] +ChoiceTranslationContext = TranslationContext[Literal[TranslationContextLocation.choice_name], 'Choice[Any]'] +OtherTranslationContext = TranslationContext[Literal[TranslationContextLocation.other], Any] + +TranslationContextTypes = Union[ + CommandNameTranslationContext, + CommandDescriptionTranslationContext, + GroupTranslationContext, + ParameterTranslationContext, + ChoiceTranslationContext, + OtherTranslationContext, +] + + +class Translator: + """A class that handles translations for commands, parameters, and choices. + + Translations are done lazily in order to allow for async enabled translations as well + as supporting a wide array of translation systems such as :mod:`gettext` and + `Project Fluent `_. + + In order for a translator to be used, it must be set using the :meth:`CommandTree.set_translator` + method. The translation flow for a string is as follows: + + 1. Use :class:`locale_str` instead of :class:`str` in areas of a command you want to be translated. + - Currently, these are command names, command descriptions, parameter names, parameter descriptions, and choice names. + - This can also be used inside the :func:`~discord.app_commands.describe` decorator. + 2. Call :meth:`CommandTree.set_translator` to the translator instance that will handle the translations. + 3. Call :meth:`CommandTree.sync` + 4. The library will call :meth:`Translator.translate` on all the relevant strings being translated. + + .. versionadded:: 2.0 + """ + + async def load(self) -> None: + """|coro| + + An asynchronous setup function for loading the translation system. + + The default implementation does nothing. + + This is invoked when :meth:`CommandTree.set_translator` is called. + """ + pass + + async def unload(self) -> None: + """|coro| + + An asynchronous teardown function for unloading the translation system. + + The default implementation does nothing. + + This is invoked when :meth:`CommandTree.set_translator` is called + if a tree already has a translator or when :meth:`discord.Client.close` is called. + """ + pass + + async def _checked_translate( + self, string: locale_str, locale: Locale, context: TranslationContextTypes + ) -> Optional[str]: + try: + return await self.translate(string, locale, context) + except TranslationError: + raise + except Exception as e: + raise TranslationError(string=string, locale=locale, context=context) from e + + async def translate(self, string: locale_str, locale: Locale, context: TranslationContextTypes) -> Optional[str]: + """|coro| + + Translates the given string to the specified locale. + + If the string cannot be translated, ``None`` should be returned. + + The default implementation returns ``None``. + + If an exception is raised in this method, it should inherit from :exc:`TranslationError`. + If it doesn't, then when this is called the exception will be chained with it instead. + + Parameters + ------------ + string: :class:`locale_str` + The string being translated. + locale: :class:`~discord.Locale` + The locale being requested for translation. + context: :class:`TranslationContext` + The translation context where the string originated from. + For better type checking ergonomics, the ``TranslationContextTypes`` + type can be used instead to aid with type narrowing. It is functionally + equivalent to :class:`TranslationContext`. + """ + + return None + + +class locale_str: + """Marks a string as ready for translation. + + This is done lazily and is not actually translated until :meth:`CommandTree.sync` is called. + + The sync method then ultimately defers the responsibility of translating to the :class:`Translator` + instance used by the :class:`CommandTree`. For more information on the translation flow, see the + :class:`Translator` documentation. + + .. container:: operations + + .. describe:: str(x) + + Returns the message passed to the string. + + .. describe:: x == y + + Checks if the string is equal to another string. + + .. describe:: x != y + + Checks if the string is not equal to another string. + + .. describe:: hash(x) + + Returns the hash of the string. + + .. versionadded:: 2.0 + + Attributes + ------------ + message: :class:`str` + The message being translated. Once set, this cannot be changed. + + .. warning:: + + This must be the default "message" that you send to Discord. + Discord sends this message back to the library and the library + uses it to access the data in order to dispatch commands. + + For example, in a command name context, if the command + name is ``foo`` then the message *must* also be ``foo``. + For other translation systems that require a message ID such + as Fluent, consider using a keyword argument to pass it in. + extras: :class:`dict` + A dict of user provided extras to attach to the translated string. + This can be used to add more context, information, or any metadata necessary + to aid in actually translating the string. + + Since these are passed via keyword arguments, the keys are strings. + """ + + __slots__ = ('__message', 'extras') + + def __init__(self, message: str, /, **kwargs: Any) -> None: + self.__message: str = message + self.extras: dict[str, Any] = kwargs + + @property + def message(self) -> str: + return self.__message + + def __str__(self) -> str: + return self.__message + + def __repr__(self) -> str: + kwargs = ', '.join(f'{k}={v!r}' for k, v in self.extras.items()) + if kwargs: + return f'{self.__class__.__name__}({self.__message!r}, {kwargs})' + return f'{self.__class__.__name__}({self.__message!r})' + + def __eq__(self, obj: object) -> bool: + return isinstance(obj, locale_str) and self.message == obj.message + + def __hash__(self) -> int: + return hash(self.__message) diff --git a/dist/ba_data/python-site-packages/discord/app_commands/tree.py b/dist/ba_data/python-site-packages/discord/app_commands/tree.py new file mode 100644 index 00000000..5bdfbec5 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/app_commands/tree.py @@ -0,0 +1,1255 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +import logging +import inspect + +from typing import ( + Any, + TYPE_CHECKING, + Callable, + Coroutine, + Dict, + Generator, + Generic, + List, + Literal, + Optional, + Sequence, + Set, + Tuple, + Union, + overload, +) +from collections import Counter + + +from .namespace import Namespace, ResolveKey +from .models import AppCommand +from .commands import Command, ContextMenu, Group +from .errors import ( + AppCommandError, + CommandAlreadyRegistered, + CommandNotFound, + CommandSignatureMismatch, + CommandLimitReached, + CommandSyncFailure, + MissingApplicationID, +) +from .translator import Translator, locale_str +from ..errors import ClientException, HTTPException +from ..enums import AppCommandType, InteractionType +from ..utils import MISSING, _get_as_snowflake, _is_submodule, _shorten +from .._types import ClientT + + +if TYPE_CHECKING: + from ..types.interactions import ApplicationCommandInteractionData, ApplicationCommandInteractionDataOption + from ..interactions import Interaction + from ..abc import Snowflake + from .commands import ContextMenuCallback, CommandCallback, P, T + + ErrorFunc = Callable[ + [Interaction, AppCommandError], + Coroutine[Any, Any, Any], + ] + +__all__ = ('CommandTree',) + +_log = logging.getLogger(__name__) + + +def _retrieve_guild_ids( + command: Any, guild: Optional[Snowflake] = MISSING, guilds: Sequence[Snowflake] = MISSING +) -> Optional[Set[int]]: + if guild is not MISSING and guilds is not MISSING: + raise TypeError('cannot mix guild and guilds keyword arguments') + + # guilds=[] or guilds=[...] + if guild is MISSING: + # If no arguments are given then it should default to the ones + # given to the guilds(...) decorator or None for global. + if guilds is MISSING: + return getattr(command, '_guild_ids', None) + + # guilds=[] is the same as global + if len(guilds) == 0: + return None + + return {g.id for g in guilds} + + # At this point it should be... + # guild=None or guild=Object + if guild is None: + return None + return {guild.id} + + +class CommandTree(Generic[ClientT]): + """Represents a container that holds application command information. + + Parameters + ----------- + client: :class:`~discord.Client` + The client instance to get application command information from. + fallback_to_global: :class:`bool` + If a guild-specific command is not found when invoked, then try falling back into + a global command in the tree. For example, if the tree locally has a ``/ping`` command + under the global namespace but the guild has a guild-specific ``/ping``, instead of failing + to find the guild-specific ``/ping`` command it will fall back to the global ``/ping`` command. + This has the potential to raise more :exc:`~discord.app_commands.CommandSignatureMismatch` errors + than usual. Defaults to ``True``. + """ + + def __init__(self, client: ClientT, *, fallback_to_global: bool = True): + self.client: ClientT = client + self._http = client.http + self._state = client._connection + + if self._state._command_tree is not None: + raise ClientException('This client already has an associated command tree.') + + self._state._command_tree = self + self.fallback_to_global: bool = fallback_to_global + self._guild_commands: Dict[int, Dict[str, Union[Command, Group]]] = {} + self._global_commands: Dict[str, Union[Command, Group]] = {} + # (name, guild_id, command_type): Command + # The above two mappings can use this structure too but we need fast retrieval + # by name and guild_id in the above case while here it isn't as important since + # it's uncommon and N=5 anyway. + self._context_menus: Dict[Tuple[str, Optional[int], int], ContextMenu] = {} + + async def fetch_command(self, command_id: int, /, *, guild: Optional[Snowflake] = None) -> AppCommand: + """|coro| + + Fetches an application command from the application. + + Parameters + ----------- + command_id: :class:`int` + The ID of the command to fetch. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to fetch the command from. If not passed then the global command + is fetched instead. + + Raises + ------- + HTTPException + Fetching the command failed. + MissingApplicationID + The application ID could not be found. + NotFound + The application command was not found. + This could also be because the command is a guild command + and the guild was not specified and vice versa. + + Returns + -------- + :class:`~discord.app_commands.AppCommand` + The application command. + """ + if self.client.application_id is None: + raise MissingApplicationID + + if guild is None: + command = await self._http.get_global_command(self.client.application_id, command_id) + else: + command = await self._http.get_guild_command(self.client.application_id, guild.id, command_id) + + return AppCommand(data=command, state=self._state) + + async def fetch_commands(self, *, guild: Optional[Snowflake] = None) -> List[AppCommand]: + """|coro| + + Fetches the application's current commands. + + If no guild is passed then global commands are fetched, otherwise + the guild's commands are fetched instead. + + .. note:: + + This includes context menu commands. + + Parameters + ----------- + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to fetch the commands from. If not passed then global commands + are fetched instead. + + Raises + ------- + HTTPException + Fetching the commands failed. + MissingApplicationID + The application ID could not be found. + + Returns + -------- + List[:class:`~discord.app_commands.AppCommand`] + The application's commands. + """ + if self.client.application_id is None: + raise MissingApplicationID + + if guild is None: + commands = await self._http.get_global_commands(self.client.application_id) + else: + commands = await self._http.get_guild_commands(self.client.application_id, guild.id) + + return [AppCommand(data=data, state=self._state) for data in commands] + + def copy_global_to(self, *, guild: Snowflake) -> None: + """Copies all global commands to the specified guild. + + This method is mainly available for development purposes, as it allows you + to copy your global commands over to a testing guild easily. + + Note that this method will *override* pre-existing guild commands that would conflict. + + Parameters + ----------- + guild: :class:`~discord.abc.Snowflake` + The guild to copy the commands to. + + Raises + -------- + CommandLimitReached + The maximum number of commands was reached for that guild. + This is currently 100 for slash commands and 5 for context menu commands. + """ + + try: + mapping = self._guild_commands[guild.id].copy() + except KeyError: + mapping = {} + + mapping.update(self._global_commands) + if len(mapping) > 100: + raise CommandLimitReached(guild_id=guild.id, limit=100) + + ctx_menu: Dict[Tuple[str, Optional[int], int], ContextMenu] = { + (name, guild.id, cmd_type): cmd + for ((name, g, cmd_type), cmd) in self._context_menus.items() + if g is None or g == guild.id + } + + counter = Counter(cmd_type for _, _, cmd_type in ctx_menu) + for cmd_type, count in counter.items(): + if count > 5: + as_enum = AppCommandType(cmd_type) + raise CommandLimitReached(guild_id=guild.id, limit=5, type=as_enum) + + self._context_menus.update(ctx_menu) + self._guild_commands[guild.id] = mapping + + def add_command( + self, + command: Union[Command[Any, ..., Any], ContextMenu, Group], + /, + *, + guild: Optional[Snowflake] = MISSING, + guilds: Sequence[Snowflake] = MISSING, + override: bool = False, + ) -> None: + """Adds an application command to the tree. + + This only adds the command locally -- in order to sync the commands + and enable them in the client, :meth:`sync` must be called. + + The root parent of the command is added regardless of the type passed. + + Parameters + ----------- + command: Union[:class:`Command`, :class:`Group`] + The application command or group to add. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to add the command to. If not given or ``None`` then it + becomes a global command instead. + guilds: List[:class:`~discord.abc.Snowflake`] + The list of guilds to add the command to. This cannot be mixed + with the ``guild`` parameter. If no guilds are given at all + then it becomes a global command instead. + override: :class:`bool` + Whether to override a command with the same name. If ``False`` + an exception is raised. Default is ``False``. + + Raises + -------- + ~discord.app_commands.CommandAlreadyRegistered + The command was already registered and no override was specified. + TypeError + The application command passed is not a valid application command. + Or, ``guild`` and ``guilds`` were both given. + CommandLimitReached + The maximum number of commands was reached globally or for that guild. + This is currently 100 for slash commands and 5 for context menu commands. + """ + + guild_ids = _retrieve_guild_ids(command, guild, guilds) + if isinstance(command, ContextMenu): + type = command.type.value + name = command.name + + def _context_menu_add_helper( + guild_id: Optional[int], + data: Dict[Tuple[str, Optional[int], int], ContextMenu], + name: str = name, + type: int = type, + ) -> None: + key = (name, guild_id, type) + found = key in self._context_menus + if found and not override: + raise CommandAlreadyRegistered(name, guild_id) + + # If the key is found and overridden then it shouldn't count as an extra addition + # read as `0 if override and found else 1` if confusing + to_add = not (override and found) + total = sum(1 for _, g, t in self._context_menus if g == guild_id and t == type) + if total + to_add > 5: + raise CommandLimitReached(guild_id=guild_id, limit=5, type=AppCommandType(type)) + data[key] = command + + if guild_ids is None: + _context_menu_add_helper(None, self._context_menus) + else: + current: Dict[Tuple[str, Optional[int], int], ContextMenu] = {} + for guild_id in guild_ids: + _context_menu_add_helper(guild_id, current) + + # Update at the end in order to make sure the update is atomic. + # An error during addition could end up making the context menu mapping + # have a partial state + self._context_menus.update(current) + return + elif not isinstance(command, (Command, Group)): + raise TypeError(f'Expected an application command, received {command.__class__.__name__} instead') + + # todo: validate application command groups having children (required) + + root = command.root_parent or command + name = root.name + if guild_ids is not None: + # Validate that the command can be added first, before actually + # adding it into the mapping. This ensures atomicity. + for guild_id in guild_ids: + commands = self._guild_commands.get(guild_id, {}) + found = name in commands + if found and not override: + raise CommandAlreadyRegistered(name, guild_id) + + to_add = not (override and found) + if len(commands) + to_add > 100: + raise CommandLimitReached(guild_id=guild_id, limit=100) + + # Actually add the command now that it has been verified to be okay. + for guild_id in guild_ids: + commands = self._guild_commands.setdefault(guild_id, {}) + commands[name] = root + else: + found = name in self._global_commands + if found and not override: + raise CommandAlreadyRegistered(name, None) + + to_add = not (override and found) + if len(self._global_commands) + to_add > 100: + raise CommandLimitReached(guild_id=None, limit=100) + self._global_commands[name] = root + + @overload + def remove_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.message, AppCommandType.user], + ) -> Optional[ContextMenu]: + ... + + @overload + def remove_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.chat_input] = ..., + ) -> Optional[Union[Command[Any, ..., Any], Group]]: + ... + + @overload + def remove_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = ..., + type: AppCommandType, + ) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]: + ... + + def remove_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = None, + type: AppCommandType = AppCommandType.chat_input, + ) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]: + """Removes an application command from the tree. + + This only removes the command locally -- in order to sync the commands + and remove them in the client, :meth:`sync` must be called. + + Parameters + ----------- + command: :class:`str` + The name of the root command to remove. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to remove the command from. If not given or ``None`` then it + removes a global command instead. + type: :class:`~discord.AppCommandType` + The type of command to remove. Defaults to :attr:`~discord.AppCommandType.chat_input`, + i.e. slash commands. + + Returns + --------- + Optional[Union[:class:`Command`, :class:`ContextMenu`, :class:`Group`]] + The application command that got removed. + If nothing was removed then ``None`` is returned instead. + """ + + if type is AppCommandType.chat_input: + if guild is None: + return self._global_commands.pop(command, None) + else: + try: + commands = self._guild_commands[guild.id] + except KeyError: + return None + else: + return commands.pop(command, None) + elif type in (AppCommandType.user, AppCommandType.message): + guild_id = None if guild is None else guild.id + key = (command, guild_id, type.value) + return self._context_menus.pop(key, None) + + def clear_commands(self, *, guild: Optional[Snowflake], type: Optional[AppCommandType] = None) -> None: + """Clears all application commands from the tree. + + This only removes the commands locally -- in order to sync the commands + and remove them in the client, :meth:`sync` must be called. + + Parameters + ----------- + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to remove the commands from. If ``None`` then it + removes all global commands instead. + type: :class:`~discord.AppCommandType` + The type of command to clear. If not given or ``None`` then it removes all commands + regardless of the type. + """ + + if type is None or type is AppCommandType.chat_input: + if guild is None: + self._global_commands.clear() + else: + try: + commands = self._guild_commands[guild.id] + except KeyError: + pass + else: + commands.clear() + + guild_id = None if guild is None else guild.id + if type is None: + self._context_menus = { + (name, _guild_id, value): cmd + for (name, _guild_id, value), cmd in self._context_menus.items() + if _guild_id != guild_id + } + elif type in (AppCommandType.user, AppCommandType.message): + self._context_menus = { + (name, _guild_id, value): cmd + for (name, _guild_id, value), cmd in self._context_menus.items() + if _guild_id != guild_id or value != type.value + } + + @overload + def get_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.message, AppCommandType.user], + ) -> Optional[ContextMenu]: + ... + + @overload + def get_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.chat_input] = ..., + ) -> Optional[Union[Command[Any, ..., Any], Group]]: + ... + + @overload + def get_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = ..., + type: AppCommandType, + ) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]: + ... + + def get_command( + self, + command: str, + /, + *, + guild: Optional[Snowflake] = None, + type: AppCommandType = AppCommandType.chat_input, + ) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]: + """Gets an application command from the tree. + + Parameters + ----------- + command: :class:`str` + The name of the root command to get. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to get the command from. If not given or ``None`` then it + gets a global command instead. + type: :class:`~discord.AppCommandType` + The type of command to get. Defaults to :attr:`~discord.AppCommandType.chat_input`, + i.e. slash commands. + + Returns + --------- + Optional[Union[:class:`Command`, :class:`ContextMenu`, :class:`Group`]] + The application command that was found. + If nothing was found then ``None`` is returned instead. + """ + + if type is AppCommandType.chat_input: + if guild is None: + return self._global_commands.get(command) + else: + try: + commands = self._guild_commands[guild.id] + except KeyError: + return None + else: + return commands.get(command) + elif type in (AppCommandType.user, AppCommandType.message): + guild_id = None if guild is None else guild.id + key = (command, guild_id, type.value) + return self._context_menus.get(key) + + @overload + def get_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.message, AppCommandType.user], + ) -> List[ContextMenu]: + ... + + @overload + def get_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.chat_input], + ) -> List[Union[Command[Any, ..., Any], Group]]: + ... + + @overload + def get_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: AppCommandType, + ) -> Union[List[Union[Command[Any, ..., Any], Group]], List[ContextMenu]]: + ... + + @overload + def get_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: Optional[AppCommandType] = ..., + ) -> List[Union[Command[Any, ..., Any], Group, ContextMenu]]: + ... + + def get_commands( + self, + *, + guild: Optional[Snowflake] = None, + type: Optional[AppCommandType] = None, + ) -> Union[ + List[ContextMenu], + List[Union[Command[Any, ..., Any], Group]], + List[Union[Command[Any, ..., Any], Group, ContextMenu]], + ]: + """Gets all application commands from the tree. + + Parameters + ----------- + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to get the commands from, not including global commands. + If not given or ``None`` then only global commands are returned. + type: Optional[:class:`~discord.AppCommandType`] + The type of commands to get. When not given or ``None``, then all + command types are returned. + + Returns + --------- + List[Union[:class:`ContextMenu`, :class:`Command`, :class:`Group`]] + The application commands from the tree. + """ + if type is None: + return self._get_all_commands(guild=guild) + + if type is AppCommandType.chat_input: + if guild is None: + return list(self._global_commands.values()) + else: + try: + commands = self._guild_commands[guild.id] + except KeyError: + return [] + else: + return list(commands.values()) + else: + guild_id = None if guild is None else guild.id + value = type.value + return [command for ((_, g, t), command) in self._context_menus.items() if g == guild_id and t == value] + + @overload + def walk_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.message, AppCommandType.user], + ) -> Generator[ContextMenu, None, None]: + ... + + @overload + def walk_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: Literal[AppCommandType.chat_input] = ..., + ) -> Generator[Union[Command[Any, ..., Any], Group], None, None]: + ... + + @overload + def walk_commands( + self, + *, + guild: Optional[Snowflake] = ..., + type: AppCommandType, + ) -> Union[Generator[Union[Command[Any, ..., Any], Group], None, None], Generator[ContextMenu, None, None]]: + ... + + def walk_commands( + self, + *, + guild: Optional[Snowflake] = None, + type: AppCommandType = AppCommandType.chat_input, + ) -> Union[Generator[Union[Command[Any, ..., Any], Group], None, None], Generator[ContextMenu, None, None]]: + """An iterator that recursively walks through all application commands and child commands from the tree. + + Parameters + ----------- + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to iterate the commands from, not including global commands. + If not given or ``None`` then only global commands are iterated. + type: :class:`~discord.AppCommandType` + The type of commands to iterate over. Defaults to :attr:`~discord.AppCommandType.chat_input`, + i.e. slash commands. + + Yields + --------- + Union[:class:`ContextMenu`, :class:`Command`, :class:`Group`] + The application commands from the tree. + """ + + if type is AppCommandType.chat_input: + if guild is None: + for cmd in self._global_commands.values(): + yield cmd + if isinstance(cmd, Group): + yield from cmd.walk_commands() + else: + try: + commands = self._guild_commands[guild.id] + except KeyError: + return + else: + for cmd in commands.values(): + yield cmd + if isinstance(cmd, Group): + yield from cmd.walk_commands() + else: + guild_id = None if guild is None else guild.id + value = type.value + for ((_, g, t), command) in self._context_menus.items(): + if g == guild_id and t == value: + yield command + + def _get_all_commands( + self, *, guild: Optional[Snowflake] = None + ) -> List[Union[Command[Any, ..., Any], Group, ContextMenu]]: + if guild is None: + base: List[Union[Command[Any, ..., Any], Group, ContextMenu]] = list(self._global_commands.values()) + base.extend(cmd for ((_, g, _), cmd) in self._context_menus.items() if g is None) + return base + else: + try: + commands = self._guild_commands[guild.id] + except KeyError: + guild_id = guild.id + return [cmd for ((_, g, _), cmd) in self._context_menus.items() if g == guild_id] + else: + base: List[Union[Command[Any, ..., Any], Group, ContextMenu]] = list(commands.values()) + guild_id = guild.id + base.extend(cmd for ((_, g, _), cmd) in self._context_menus.items() if g == guild_id) + return base + + def _remove_with_module(self, name: str) -> None: + remove: List[Any] = [] + for key, cmd in self._context_menus.items(): + if cmd.module is not None and _is_submodule(name, cmd.module): + remove.append(key) + + for key in remove: + del self._context_menus[key] + + remove = [] + for key, cmd in self._global_commands.items(): + if cmd.module is not None and _is_submodule(name, cmd.module): + remove.append(key) + + for key in remove: + del self._global_commands[key] + + for mapping in self._guild_commands.values(): + remove = [] + for key, cmd in mapping.items(): + if cmd.module is not None and _is_submodule(name, cmd.module): + remove.append(key) + + for key in remove: + del mapping[key] + + async def on_error(self, interaction: Interaction[ClientT], error: AppCommandError, /) -> None: + """|coro| + + A callback that is called when any command raises an :exc:`AppCommandError`. + + The default implementation logs the exception using the library logger + if the command does not have any error handlers attached to it. + + To get the command that failed, :attr:`discord.Interaction.command` should + be used. + + Parameters + ----------- + interaction: :class:`~discord.Interaction` + The interaction that is being handled. + error: :exc:`AppCommandError` + The exception that was raised. + """ + + command = interaction.command + if command is not None: + if command._has_any_error_handlers(): + return + + _log.error('Ignoring exception in command %r', command.name, exc_info=error) + else: + _log.error('Ignoring exception in command tree', exc_info=error) + + def error(self, coro: ErrorFunc) -> ErrorFunc: + """A decorator that registers a coroutine as a local error handler. + + This must match the signature of the :meth:`on_error` callback. + + The error passed will be derived from :exc:`AppCommandError`. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the local error handler. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine or does + not match the signature. + """ + + if not inspect.iscoroutinefunction(coro): + raise TypeError('The error handler must be a coroutine.') + + params = inspect.signature(coro).parameters + if len(params) != 2: + raise TypeError('error handler must have 2 parameters') + + self.on_error = coro + return coro + + def command( + self, + *, + name: Union[str, locale_str] = MISSING, + description: Union[str, locale_str] = MISSING, + nsfw: bool = False, + guild: Optional[Snowflake] = MISSING, + guilds: Sequence[Snowflake] = MISSING, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, + ) -> Callable[[CommandCallback[Group, P, T]], Command[Group, P, T]]: + """A decorator that creates an application command from a regular function directly under this tree. + + Parameters + ------------ + name: Union[:class:`str`, :class:`locale_str`] + The name of the application command. If not given, it defaults to a lower-case + version of the callback name. + description: Union[:class:`str`, :class:`locale_str`] + The description of the application command. This shows up in the UI to describe + the application command. If not given, it defaults to the first line of the docstring + of the callback shortened to 100 characters. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to add the command to. If not given or ``None`` then it + becomes a global command instead. + guilds: List[:class:`~discord.abc.Snowflake`] + The list of guilds to add the command to. This cannot be mixed + with the ``guild`` parameter. If no guilds are given at all + then it becomes a global command instead. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def decorator(func: CommandCallback[Group, P, T]) -> Command[Group, P, T]: + if not inspect.iscoroutinefunction(func): + raise TypeError('command function must be a coroutine function') + + if description is MISSING: + if func.__doc__ is None: + desc = '…' + else: + desc = _shorten(func.__doc__) + else: + desc = description + + command = Command( + name=name if name is not MISSING else func.__name__, + description=desc, + callback=func, + nsfw=nsfw, + parent=None, + auto_locale_strings=auto_locale_strings, + extras=extras, + ) + self.add_command(command, guild=guild, guilds=guilds) + return command + + return decorator + + def context_menu( + self, + *, + name: Union[str, locale_str] = MISSING, + nsfw: bool = False, + guild: Optional[Snowflake] = MISSING, + guilds: Sequence[Snowflake] = MISSING, + auto_locale_strings: bool = True, + extras: Dict[Any, Any] = MISSING, + ) -> Callable[[ContextMenuCallback], ContextMenu]: + """A decorator that creates an application command context menu from a regular function directly under this tree. + + This function must have a signature of :class:`~discord.Interaction` as its first parameter + and taking either a :class:`~discord.Member`, :class:`~discord.User`, or :class:`~discord.Message`, + or a :obj:`typing.Union` of ``Member`` and ``User`` as its second parameter. + + Examples + --------- + + .. code-block:: python3 + + @app_commands.context_menu() + async def react(interaction: discord.Interaction, message: discord.Message): + await interaction.response.send_message('Very cool message!', ephemeral=True) + + @app_commands.context_menu() + async def ban(interaction: discord.Interaction, user: discord.Member): + await interaction.response.send_message(f'Should I actually ban {user}...', ephemeral=True) + + Parameters + ------------ + name: Union[:class:`str`, :class:`locale_str`] + The name of the context menu command. If not given, it defaults to a title-case + version of the callback name. Note that unlike regular slash commands this can + have spaces and upper case characters in the name. + nsfw: :class:`bool` + Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``. + + Due to a Discord limitation, this does not work on subcommands. + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to add the command to. If not given or ``None`` then it + becomes a global command instead. + guilds: List[:class:`~discord.abc.Snowflake`] + The list of guilds to add the command to. This cannot be mixed + with the ``guild`` parameter. If no guilds are given at all + then it becomes a global command instead. + auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`locale_str` rather than :class:`str`. This could + avoid some repetition and be more ergonomic for certain defaults such + as default command names, command descriptions, and parameter names. + Defaults to ``True``. + extras: :class:`dict` + A dictionary that can be used to store extraneous data. + The library will not touch any values or keys within this dictionary. + """ + + def decorator(func: ContextMenuCallback) -> ContextMenu: + if not inspect.iscoroutinefunction(func): + raise TypeError('context menu function must be a coroutine function') + + actual_name = func.__name__.title() if name is MISSING else name + context_menu = ContextMenu( + name=actual_name, + nsfw=nsfw, + callback=func, + auto_locale_strings=auto_locale_strings, + extras=extras, + ) + self.add_command(context_menu, guild=guild, guilds=guilds) + return context_menu + + return decorator + + @property + def translator(self) -> Optional[Translator]: + """Optional[:class:`Translator`]: The translator, if any, responsible for handling translation of commands. + + To change the translator, use :meth:`set_translator`. + """ + return self._state._translator + + async def set_translator(self, translator: Optional[Translator]) -> None: + """|coro| + + Sets the translator to use for translating commands. + + If a translator was previously set, it will be unloaded using its + :meth:`Translator.unload` method. + + When a translator is set, it will be loaded using its :meth:`Translator.load` method. + + Parameters + ------------ + translator: Optional[:class:`Translator`] + The translator to use. If ``None`` then the translator is just removed and unloaded. + + Raises + ------- + TypeError + The translator was not ``None`` or a :class:`Translator` instance. + """ + + if translator is not None and not isinstance(translator, Translator): + raise TypeError(f'expected None or Translator instance, received {translator.__class__.__name__} instead') + + old_translator = self._state._translator + if old_translator is not None: + await old_translator.unload() + + if translator is None: + self._state._translator = None + else: + await translator.load() + self._state._translator = translator + + async def sync(self, *, guild: Optional[Snowflake] = None) -> List[AppCommand]: + """|coro| + + Syncs the application commands to Discord. + + This also runs the translator to get the translated strings necessary for + feeding back into Discord. + + This must be called for the application commands to show up. + + Parameters + ----------- + guild: Optional[:class:`~discord.abc.Snowflake`] + The guild to sync the commands to. If ``None`` then it + syncs all global commands instead. + + Raises + ------- + HTTPException + Syncing the commands failed. + CommandSyncFailure + Syncing the commands failed due to a user related error, typically because + the command has invalid data. This is equivalent to an HTTP status code of + 400. + Forbidden + The client does not have the ``applications.commands`` scope in the guild. + MissingApplicationID + The client does not have an application ID. + TranslationError + An error occurred while translating the commands. + + Returns + -------- + List[:class:`AppCommand`] + The application's commands that got synced. + """ + + if self.client.application_id is None: + raise MissingApplicationID + + commands = self._get_all_commands(guild=guild) + + translator = self.translator + if translator: + payload = [await command.get_translated_payload(translator) for command in commands] + else: + payload = [command.to_dict() for command in commands] + + try: + if guild is None: + data = await self._http.bulk_upsert_global_commands(self.client.application_id, payload=payload) + else: + data = await self._http.bulk_upsert_guild_commands(self.client.application_id, guild.id, payload=payload) + except HTTPException as e: + if e.status == 400 and e.code == 50035: + raise CommandSyncFailure(e, commands) from None + raise + + return [AppCommand(data=d, state=self._state) for d in data] + + async def _dispatch_error(self, interaction: Interaction[ClientT], error: AppCommandError, /) -> None: + command = interaction.command + interaction.command_failed = True + try: + if isinstance(command, Command): + await command._invoke_error_handlers(interaction, error) + finally: + await self.on_error(interaction, error) + + def _from_interaction(self, interaction: Interaction[ClientT]) -> None: + async def wrapper(): + try: + await self._call(interaction) + except AppCommandError as e: + await self._dispatch_error(interaction, e) + + self.client.loop.create_task(wrapper(), name='CommandTree-invoker') + + def _get_context_menu(self, data: ApplicationCommandInteractionData) -> Optional[ContextMenu]: + name = data['name'] + guild_id = _get_as_snowflake(data, 'guild_id') + t = data.get('type', 1) + cmd = self._context_menus.get((name, guild_id, t)) + if cmd is None and self.fallback_to_global: + return self._context_menus.get((name, None, t)) + return cmd + + def _get_app_command_options( + self, data: ApplicationCommandInteractionData + ) -> Tuple[Command[Any, ..., Any], List[ApplicationCommandInteractionDataOption]]: + parents: List[str] = [] + name = data['name'] + + command_guild_id = _get_as_snowflake(data, 'guild_id') + if command_guild_id: + try: + guild_commands = self._guild_commands[command_guild_id] + except KeyError: + command = None if not self.fallback_to_global else self._global_commands.get(name) + else: + command = guild_commands.get(name) + if command is None and self.fallback_to_global: + command = self._global_commands.get(name) + else: + command = self._global_commands.get(name) + + # If it's not found at this point then it's not gonna be found at any point + if command is None: + raise CommandNotFound(name, parents) + + # This could be done recursively but it'd be a bother due to the state needed + # to be tracked above like the parents, the actual command type, and the + # resulting options we care about + searching = True + options: List[ApplicationCommandInteractionDataOption] = data.get('options', []) + while searching: + for option in options: + # Find subcommands + if option.get('type', 0) in (1, 2): + parents.append(name) + name = option['name'] + command = command._get_internal_command(name) + if command is None: + raise CommandNotFound(name, parents) + options = option.get('options', []) + break + else: + searching = False + break + else: + break + + if isinstance(command, Group): + # Right now, groups can't be invoked. This is a Discord limitation in how they + # do slash commands. So if we're here and we have a Group rather than a Command instance + # then something in the code is out of date from the data that Discord has. + raise CommandSignatureMismatch(command) + + return (command, options) + + async def _call_context_menu( + self, interaction: Interaction[ClientT], data: ApplicationCommandInteractionData, type: int + ) -> None: + name = data['name'] + guild_id = _get_as_snowflake(data, 'guild_id') + ctx_menu = self._context_menus.get((name, guild_id, type)) + if ctx_menu is None and self.fallback_to_global: + ctx_menu = self._context_menus.get((name, None, type)) + + # Pre-fill the cached slot to prevent re-computation + interaction._cs_command = ctx_menu + + if ctx_menu is None: + raise CommandNotFound(name, [], AppCommandType(type)) + + resolved = Namespace._get_resolved_items(interaction, data.get('resolved', {})) + + # This is annotated as str | int but realistically this will always be str + target_id: Optional[Union[str, int]] = data.get('target_id') + # Right now, the only types are message and user + # Therefore, there's no conflict with snowflakes + + # This will always work at runtime + key = ResolveKey.any_with(target_id) # type: ignore + value = resolved.get(key) + if ctx_menu.type.value != type: + raise CommandSignatureMismatch(ctx_menu) + + if value is None: + raise AppCommandError('This should not happen if Discord sent well-formed data.') + + # I assume I don't have to type check here. + try: + await ctx_menu._invoke(interaction, value) + except AppCommandError as e: + if ctx_menu.on_error is not None: + await ctx_menu.on_error(interaction, e) + await self.on_error(interaction, e) + else: + self.client.dispatch('app_command_completion', interaction, ctx_menu) + + async def interaction_check(self, interaction: Interaction[ClientT], /) -> bool: + """|coro| + + A global check to determine if an :class:`~discord.Interaction` should + be processed by the tree. + + The default implementation returns True (all interactions are processed), + but can be overridden if custom behaviour is desired. + """ + return True + + async def _call(self, interaction: Interaction[ClientT]) -> None: + if not await self.interaction_check(interaction): + interaction.command_failed = True + return + + data: ApplicationCommandInteractionData = interaction.data # type: ignore + type = data.get('type', 1) + if type != 1: + # Context menu command... + await self._call_context_menu(interaction, data, type) + return + + command, options = self._get_app_command_options(data) + + # Pre-fill the cached slot to prevent re-computation + interaction._cs_command = command + + # At this point options refers to the arguments of the command + # and command refers to the class type we care about + namespace = Namespace(interaction, data.get('resolved', {}), options) + + # Same pre-fill as above + interaction._cs_namespace = namespace + + # Auto complete handles the namespace differently... so at this point this is where we decide where that is. + if interaction.type is InteractionType.autocomplete: + focused = next((opt['name'] for opt in options if opt.get('focused')), None) + if focused is None: + raise AppCommandError('This should not happen, but there is no focused element. This is a Discord bug.') + + try: + await command._invoke_autocomplete(interaction, focused, namespace) + except Exception: + # Suppress exception since it can't be handled anyway. + pass + + return + + try: + await command._invoke_with_namespace(interaction, namespace) + except AppCommandError as e: + interaction.command_failed = True + await command._invoke_error_handlers(interaction, e) + await self.on_error(interaction, e) + else: + if not interaction.command_failed: + self.client.dispatch('app_command_completion', interaction, command) diff --git a/dist/ba_data/python-site-packages/discord/appinfo.py b/dist/ba_data/python-site-packages/discord/appinfo.py index cbc00566..129e543c 100644 --- a/dist/ba_data/python-site-packages/discord/appinfo.py +++ b/dist/ba_data/python-site-packages/discord/appinfo.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,10 +22,31 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + +from typing import List, TYPE_CHECKING, Optional + from . import utils -from .user import User from .asset import Asset -from .team import Team +from .flags import ApplicationFlags +from .permissions import Permissions + +if TYPE_CHECKING: + from .guild import Guild + from .types.appinfo import ( + AppInfo as AppInfoPayload, + PartialAppInfo as PartialAppInfoPayload, + Team as TeamPayload, + InstallParams as InstallParamsPayload, + ) + from .user import User + from .state import ConnectionState + +__all__ = ( + 'AppInfo', + 'PartialAppInfo', + 'AppInstallParams', +) class AppInfo: @@ -47,9 +66,7 @@ class AppInfo: .. versionadded:: 1.3 - icon: Optional[:class:`str`] - The icon hash, if it exists. - description: Optional[:class:`str`] + description: :class:`str` The application description. bot_public: :class:`bool` Whether the bot can be invited by anyone or if it is locked @@ -59,15 +76,10 @@ class AppInfo: grant flow to join. rpc_origins: Optional[List[:class:`str`]] A list of RPC origin URLs, if RPC is enabled. - summary: :class:`str` - If this application is a game sold on Discord, - this field will be the summary field for the store page of its primary SKU. - - .. versionadded:: 1.3 verify_key: :class:`str` The hex encoded key for verification in interactions and the - GameSDK's `GetTicket `_. + GameSDK's :ddocs:`GetTicket `. .. versionadded:: 1.3 @@ -90,128 +102,261 @@ class AppInfo: .. versionadded:: 1.3 - cover_image: Optional[:class:`str`] - If this application is a game sold on Discord, - this field will be the hash of the image on store embeds + terms_of_service_url: Optional[:class:`str`] + The application's terms of service URL, if set. - .. versionadded:: 1.3 - """ - __slots__ = ('_state', 'description', 'id', 'name', 'rpc_origins', - 'bot_public', 'bot_require_code_grant', 'owner', 'icon', - 'summary', 'verify_key', 'team', 'guild_id', 'primary_sku_id', - 'slug', 'cover_image') + .. versionadded:: 2.0 + + privacy_policy_url: Optional[:class:`str`] + The application's privacy policy URL, if set. + + .. versionadded:: 2.0 + + tags: List[:class:`str`] + The list of tags describing the functionality of the application. - def __init__(self, state, data): - self._state = state + .. versionadded:: 2.0 - self.id = int(data['id']) - self.name = data['name'] - self.description = data['description'] - self.icon = data['icon'] - self.rpc_origins = data['rpc_origins'] - self.bot_public = data['bot_public'] - self.bot_require_code_grant = data['bot_require_code_grant'] - self.owner = User(state=self._state, data=data['owner']) + custom_install_url: List[:class:`str`] + The custom authorization URL for the application, if enabled. - team = data.get('team') - self.team = Team(state, team) if team else None + .. versionadded:: 2.0 - self.summary = data['summary'] - self.verify_key = data['verify_key'] + install_params: Optional[:class:`AppInstallParams`] + The settings for custom authorization URL of application, if enabled. - self.guild_id = utils._get_as_snowflake(data, 'guild_id') + .. versionadded:: 2.0 + role_connections_verification_url: Optional[:class:`str`] + The application's connection verification URL which will render the application as + a verification method in the guild's role verification configuration. - self.primary_sku_id = utils._get_as_snowflake(data, 'primary_sku_id') - self.slug = data.get('slug') - self.cover_image = data.get('cover_image') + .. versionadded:: 2.2 + """ + + __slots__ = ( + '_state', + 'description', + 'id', + 'name', + 'rpc_origins', + 'bot_public', + 'bot_require_code_grant', + 'owner', + '_icon', + 'verify_key', + 'team', + 'guild_id', + 'primary_sku_id', + 'slug', + '_cover_image', + '_flags', + 'terms_of_service_url', + 'privacy_policy_url', + 'tags', + 'custom_install_url', + 'install_params', + 'role_connections_verification_url', + ) + + def __init__(self, state: ConnectionState, data: AppInfoPayload): + from .team import Team + + self._state: ConnectionState = state + self.id: int = int(data['id']) + self.name: str = data['name'] + self.description: str = data['description'] + self._icon: Optional[str] = data['icon'] + self.rpc_origins: Optional[List[str]] = data.get('rpc_origins') + self.bot_public: bool = data['bot_public'] + self.bot_require_code_grant: bool = data['bot_require_code_grant'] + self.owner: User = state.create_user(data['owner']) + + team: Optional[TeamPayload] = data.get('team') + self.team: Optional[Team] = Team(state, team) if team else None + + self.verify_key: str = data['verify_key'] + + self.guild_id: Optional[int] = utils._get_as_snowflake(data, 'guild_id') + + self.primary_sku_id: Optional[int] = utils._get_as_snowflake(data, 'primary_sku_id') + self.slug: Optional[str] = data.get('slug') + self._flags: int = data.get('flags', 0) + self._cover_image: Optional[str] = data.get('cover_image') + self.terms_of_service_url: Optional[str] = data.get('terms_of_service_url') + self.privacy_policy_url: Optional[str] = data.get('privacy_policy_url') + self.tags: List[str] = data.get('tags', []) + self.custom_install_url: Optional[str] = data.get('custom_install_url') + self.role_connections_verification_url: Optional[str] = data.get('role_connections_verification_url') + + params = data.get('install_params') + self.install_params: Optional[AppInstallParams] = AppInstallParams(params) if params else None + + def __repr__(self) -> str: + return ( + f'<{self.__class__.__name__} id={self.id} name={self.name!r} ' + f'description={self.description!r} public={self.bot_public} ' + f'owner={self.owner!r}>' + ) - def __repr__(self): - return '<{0.__class__.__name__} id={0.id} name={0.name!r} description={0.description!r} public={0.bot_public} ' \ - 'owner={0.owner!r}>'.format(self) + @property + def icon(self) -> Optional[Asset]: + """Optional[:class:`.Asset`]: Retrieves the application's icon asset, if any.""" + if self._icon is None: + return None + return Asset._from_icon(self._state, self.id, self._icon, path='app') @property - def icon_url(self): - """:class:`.Asset`: Retrieves the application's icon asset. + def cover_image(self) -> Optional[Asset]: + """Optional[:class:`.Asset`]: Retrieves the cover image on a store embed, if any. - This is equivalent to calling :meth:`icon_url_as` with - the default parameters ('webp' format and a size of 1024). + This is only available if the application is a game sold on Discord. + """ + if self._cover_image is None: + return None + return Asset._from_cover_image(self._state, self.id, self._cover_image) + + @property + def guild(self) -> Optional[Guild]: + """Optional[:class:`Guild`]: If this application is a game sold on Discord, + this field will be the guild to which it has been linked .. versionadded:: 1.3 """ - return self.icon_url_as() + return self._state._get_guild(self.guild_id) - def icon_url_as(self, *, format='webp', size=1024): - """Returns an :class:`Asset` for the icon the application has. + @property + def flags(self) -> ApplicationFlags: + """:class:`ApplicationFlags`: The application's flags. - The format must be one of 'webp', 'jpeg', 'jpg' or 'png'. - The size must be a power of 2 between 16 and 4096. + .. versionadded:: 2.0 + """ + return ApplicationFlags._from_value(self._flags) - .. versionadded:: 1.6 - Parameters - ----------- - format: :class:`str` - The format to attempt to convert the icon to. Defaults to 'webp'. - size: :class:`int` - The size of the image to display. +class PartialAppInfo: + """Represents a partial AppInfo given by :func:`~discord.abc.GuildChannel.create_invite` - Raises - ------ - InvalidArgument - Bad image format passed to ``format`` or invalid ``size``. + .. versionadded:: 2.0 - Returns - -------- - :class:`Asset` - The resulting CDN asset. - """ - return Asset._from_icon(self._state, self, 'app', format=format, size=size) + Attributes + ------------- + id: :class:`int` + The application ID. + name: :class:`str` + The application name. + description: :class:`str` + The application description. + rpc_origins: Optional[List[:class:`str`]] + A list of RPC origin URLs, if RPC is enabled. + verify_key: :class:`str` + The hex encoded key for verification in interactions and the + GameSDK's :ddocs:`GetTicket `. + terms_of_service_url: Optional[:class:`str`] + The application's terms of service URL, if set. + privacy_policy_url: Optional[:class:`str`] + The application's privacy policy URL, if set. + approximate_guild_count: :class:`int` + The approximate count of the guilds the bot was added to. + + .. versionadded:: 2.3 + redirect_uris: List[:class:`str`] + A list of authentication redirect URIs. + + .. versionadded:: 2.3 + interactions_endpoint_url: Optional[:class:`str`] + The interactions endpoint url of the application to receive interactions over this endpoint rather than + over the gateway, if configured. + + .. versionadded:: 2.3 + role_connections_verification_url: Optional[:class:`str`] + The application's connection verification URL which will render the application as + a verification method in the guild's role verification configuration. + + .. versionadded:: 2.3 + """ + + __slots__ = ( + '_state', + 'id', + 'name', + 'description', + 'rpc_origins', + 'verify_key', + 'terms_of_service_url', + 'privacy_policy_url', + '_icon', + '_flags', + '_cover_image', + 'approximate_guild_count', + 'redirect_uris', + 'interactions_endpoint_url', + 'role_connections_verification_url', + ) + + def __init__(self, *, state: ConnectionState, data: PartialAppInfoPayload): + self._state: ConnectionState = state + self.id: int = int(data['id']) + self.name: str = data['name'] + self._icon: Optional[str] = data.get('icon') + self._flags: int = data.get('flags', 0) + self._cover_image: Optional[str] = data.get('cover_image') + self.description: str = data['description'] + self.rpc_origins: Optional[List[str]] = data.get('rpc_origins') + self.verify_key: str = data['verify_key'] + self.terms_of_service_url: Optional[str] = data.get('terms_of_service_url') + self.privacy_policy_url: Optional[str] = data.get('privacy_policy_url') + self.approximate_guild_count: int = data.get('approximate_guild_count', 0) + self.redirect_uris: List[str] = data.get('redirect_uris', []) + self.interactions_endpoint_url: Optional[str] = data.get('interactions_endpoint_url') + self.role_connections_verification_url: Optional[str] = data.get('role_connections_verification_url') + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id={self.id} name={self.name!r} description={self.description!r}>' + @property + def icon(self) -> Optional[Asset]: + """Optional[:class:`.Asset`]: Retrieves the application's icon asset, if any.""" + if self._icon is None: + return None + return Asset._from_icon(self._state, self.id, self._icon, path='app') @property - def cover_image_url(self): - """:class:`.Asset`: Retrieves the cover image on a store embed. + def cover_image(self) -> Optional[Asset]: + """Optional[:class:`.Asset`]: Retrieves the cover image of the application's default rich presence. - This is equivalent to calling :meth:`cover_image_url_as` with - the default parameters ('webp' format and a size of 1024). + This is only available if the application is a game sold on Discord. - .. versionadded:: 1.3 + .. versionadded:: 2.3 """ - return self.cover_image_url_as() + if self._cover_image is None: + return None + return Asset._from_cover_image(self._state, self.id, self._cover_image) - def cover_image_url_as(self, *, format='webp', size=1024): - """Returns an :class:`Asset` for the image on store embeds - if this application is a game sold on Discord. + @property + def flags(self) -> ApplicationFlags: + """:class:`ApplicationFlags`: The application's flags. - The format must be one of 'webp', 'jpeg', 'jpg' or 'png'. - The size must be a power of 2 between 16 and 4096. + .. versionadded:: 2.0 + """ + return ApplicationFlags._from_value(self._flags) - .. versionadded:: 1.6 - Parameters - ----------- - format: :class:`str` - The format to attempt to convert the image to. Defaults to 'webp'. - size: :class:`int` - The size of the image to display. +class AppInstallParams: + """Represents the settings for custom authorization URL of an application. - Raises - ------ - InvalidArgument - Bad image format passed to ``format`` or invalid ``size``. + .. versionadded:: 2.0 - Returns - -------- - :class:`Asset` - The resulting CDN asset. - """ - return Asset._from_cover_image(self._state, self, format=format, size=size) + Attributes + ---------- + scopes: List[:class:`str`] + The list of :ddocs:`OAuth2 scopes ` + to add the application to a guild with. + permissions: :class:`Permissions` + The permissions to give to application in the guild. + """ - @property - def guild(self): - """Optional[:class:`Guild`]: If this application is a game sold on Discord, - this field will be the guild to which it has been linked + __slots__ = ('scopes', 'permissions') - .. versionadded:: 1.3 - """ - return self._state._get_guild(int(self.guild_id)) + def __init__(self, data: InstallParamsPayload) -> None: + self.scopes: List[str] = data.get('scopes', []) + self.permissions: Permissions = Permissions(int(data['permissions'])) diff --git a/dist/ba_data/python-site-packages/discord/asset.py b/dist/ba_data/python-site-packages/discord/asset.py index ea457297..d88ebb94 100644 --- a/dist/ba_data/python-site-packages/discord/asset.py +++ b/dist/ba_data/python-site-packages/discord/asset.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,15 +22,159 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + import io +import os +from typing import Any, Literal, Optional, TYPE_CHECKING, Tuple, Union from .errors import DiscordException -from .errors import InvalidArgument from . import utils +from .file import File + +import yarl + +# fmt: off +__all__ = ( + 'Asset', +) +# fmt: on + +if TYPE_CHECKING: + from typing_extensions import Self + + from .state import ConnectionState + from .webhook.async_ import _WebhookState + + _State = Union[ConnectionState, _WebhookState] + + ValidStaticFormatTypes = Literal['webp', 'jpeg', 'jpg', 'png'] + ValidAssetFormatTypes = Literal['webp', 'jpeg', 'jpg', 'png', 'gif'] VALID_STATIC_FORMATS = frozenset({"jpeg", "jpg", "webp", "png"}) -VALID_AVATAR_FORMATS = VALID_STATIC_FORMATS | {"gif"} +VALID_ASSET_FORMATS = VALID_STATIC_FORMATS | {"gif"} + + +MISSING = utils.MISSING + + +class AssetMixin: + __slots__ = () + url: str + _state: Optional[Any] + + async def read(self) -> bytes: + """|coro| + + Retrieves the content of this asset as a :class:`bytes` object. + + Raises + ------ + DiscordException + There was no internal connection state. + HTTPException + Downloading the asset failed. + NotFound + The asset was deleted. + + Returns + ------- + :class:`bytes` + The content of the asset. + """ + if self._state is None: + raise DiscordException('Invalid state (no ConnectionState provided)') + + return await self._state.http.get_from_cdn(self.url) + + async def save(self, fp: Union[str, bytes, os.PathLike[Any], io.BufferedIOBase], *, seek_begin: bool = True) -> int: + """|coro| + + Saves this asset into a file-like object. + + Parameters + ---------- + fp: Union[:class:`io.BufferedIOBase`, :class:`os.PathLike`] + The file-like object to save this asset to or the filename + to use. If a filename is passed then a file is created with that + filename and used instead. + seek_begin: :class:`bool` + Whether to seek to the beginning of the file after saving is + successfully done. + + Raises + ------ + DiscordException + There was no internal connection state. + HTTPException + Downloading the asset failed. + NotFound + The asset was deleted. + + Returns + -------- + :class:`int` + The number of bytes written. + """ + + data = await self.read() + if isinstance(fp, io.BufferedIOBase): + written = fp.write(data) + if seek_begin: + fp.seek(0) + return written + else: + with open(fp, 'wb') as f: + return f.write(data) + + async def to_file( + self, + *, + filename: Optional[str] = MISSING, + description: Optional[str] = None, + spoiler: bool = False, + ) -> File: + """|coro| + + Converts the asset into a :class:`File` suitable for sending via + :meth:`abc.Messageable.send`. + + .. versionadded:: 2.0 + + Parameters + ----------- + filename: Optional[:class:`str`] + The filename of the file. If not provided, then the filename from + the asset's URL is used. + description: Optional[:class:`str`] + The description for the file. + spoiler: :class:`bool` + Whether the file is a spoiler. + + Raises + ------ + DiscordException + The asset does not have an associated state. + ValueError + The asset is a unicode emoji. + TypeError + The asset is a sticker with lottie type. + HTTPException + Downloading the asset failed. + NotFound + The asset was deleted. + + Returns + ------- + :class:`File` + The asset as a file suitable for sending. + """ + + data = await self.read() + file_filename = filename if filename is not MISSING else yarl.URL(self.url).name + return File(io.BytesIO(data), filename=file_filename, description=description, spoiler=spoiler) -class Asset: + +class Asset(AssetMixin): """Represents a CDN asset on Discord. .. container:: operations @@ -45,10 +187,6 @@ class Asset: Returns the length of the CDN asset's URL. - .. describe:: bool(x) - - Checks if the Asset has a URL. - .. describe:: x == y Checks if the asset is equal to another asset. @@ -61,202 +199,318 @@ class Asset: Returns the hash of the asset. """ - __slots__ = ('_state', '_url') + + __slots__: Tuple[str, ...] = ( + '_state', + '_url', + '_animated', + '_key', + ) BASE = 'https://cdn.discordapp.com' - def __init__(self, state, url=None): - self._state = state - self._url = url + def __init__(self, state: _State, *, url: str, key: str, animated: bool = False) -> None: + self._state: _State = state + self._url: str = url + self._animated: bool = animated + self._key: str = key @classmethod - def _from_avatar(cls, state, user, *, format=None, static_format='webp', size=1024): - if not utils.valid_icon_size(size): - raise InvalidArgument("size must be a power of 2 between 16 and 4096") - if format is not None and format not in VALID_AVATAR_FORMATS: - raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS)) - if format == "gif" and not user.is_avatar_animated(): - raise InvalidArgument("non animated avatars do not support gif format") - if static_format not in VALID_STATIC_FORMATS: - raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) + def _from_default_avatar(cls, state: _State, index: int) -> Self: + return cls( + state, + url=f'{cls.BASE}/embed/avatars/{index}.png', + key=str(index), + animated=False, + ) - if user.avatar is None: - return user.default_avatar_url + @classmethod + def _from_avatar(cls, state: _State, user_id: int, avatar: str) -> Self: + animated = avatar.startswith('a_') + format = 'gif' if animated else 'png' + return cls( + state, + url=f'{cls.BASE}/avatars/{user_id}/{avatar}.{format}?size=1024', + key=avatar, + animated=animated, + ) - if format is None: - format = 'gif' if user.is_avatar_animated() else static_format + @classmethod + def _from_guild_avatar(cls, state: _State, guild_id: int, member_id: int, avatar: str) -> Self: + animated = avatar.startswith('a_') + format = 'gif' if animated else 'png' + return cls( + state, + url=f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.{format}?size=1024", + key=avatar, + animated=animated, + ) - return cls(state, '/avatars/{0.id}/{0.avatar}.{1}?size={2}'.format(user, format, size)) + @classmethod + def _from_icon(cls, state: _State, object_id: int, icon_hash: str, path: str) -> Self: + return cls( + state, + url=f'{cls.BASE}/{path}-icons/{object_id}/{icon_hash}.png?size=1024', + key=icon_hash, + animated=False, + ) @classmethod - def _from_icon(cls, state, object, path, *, format='webp', size=1024): - if object.icon is None: - return cls(state) + def _from_app_icon( + cls, state: _State, object_id: int, icon_hash: str, asset_type: Literal['icon', 'cover_image'] + ) -> Self: + return cls( + state, + url=f'{cls.BASE}/app-icons/{object_id}/{asset_type}.png?size=1024', + key=icon_hash, + animated=False, + ) - if not utils.valid_icon_size(size): - raise InvalidArgument("size must be a power of 2 between 16 and 4096") - if format not in VALID_STATIC_FORMATS: - raise InvalidArgument("format must be None or one of {}".format(VALID_STATIC_FORMATS)) + @classmethod + def _from_cover_image(cls, state: _State, object_id: int, cover_image_hash: str) -> Self: + return cls( + state, + url=f'{cls.BASE}/app-assets/{object_id}/store/{cover_image_hash}.png?size=1024', + key=cover_image_hash, + animated=False, + ) - url = '/{0}-icons/{1.id}/{1.icon}.{2}?size={3}'.format(path, object, format, size) - return cls(state, url) + @classmethod + def _from_scheduled_event_cover_image(cls, state: _State, scheduled_event_id: int, cover_image_hash: str) -> Self: + return cls( + state, + url=f'{cls.BASE}/guild-events/{scheduled_event_id}/{cover_image_hash}.png?size=1024', + key=cover_image_hash, + animated=False, + ) @classmethod - def _from_cover_image(cls, state, obj, *, format='webp', size=1024): - if obj.cover_image is None: - return cls(state) + def _from_guild_image(cls, state: _State, guild_id: int, image: str, path: str) -> Self: + animated = image.startswith('a_') + format = 'gif' if animated else 'png' + return cls( + state, + url=f'{cls.BASE}/{path}/{guild_id}/{image}.{format}?size=1024', + key=image, + animated=animated, + ) - if not utils.valid_icon_size(size): - raise InvalidArgument("size must be a power of 2 between 16 and 4096") - if format not in VALID_STATIC_FORMATS: - raise InvalidArgument("format must be None or one of {}".format(VALID_STATIC_FORMATS)) + @classmethod + def _from_guild_icon(cls, state: _State, guild_id: int, icon_hash: str) -> Self: + animated = icon_hash.startswith('a_') + format = 'gif' if animated else 'png' + return cls( + state, + url=f'{cls.BASE}/icons/{guild_id}/{icon_hash}.{format}?size=1024', + key=icon_hash, + animated=animated, + ) - url = '/app-assets/{0.id}/store/{0.cover_image}.{1}?size={2}'.format(obj, format, size) - return cls(state, url) + @classmethod + def _from_sticker_banner(cls, state: _State, banner: int) -> Self: + return cls( + state, + url=f'{cls.BASE}/app-assets/710982414301790216/store/{banner}.png', + key=str(banner), + animated=False, + ) @classmethod - def _from_guild_image(cls, state, id, hash, key, *, format='webp', size=1024): - if not utils.valid_icon_size(size): - raise InvalidArgument("size must be a power of 2 between 16 and 4096") - if format not in VALID_STATIC_FORMATS: - raise InvalidArgument("format must be one of {}".format(VALID_STATIC_FORMATS)) + def _from_user_banner(cls, state: _State, user_id: int, banner_hash: str) -> Self: + animated = banner_hash.startswith('a_') + format = 'gif' if animated else 'png' + return cls( + state, + url=f'{cls.BASE}/banners/{user_id}/{banner_hash}.{format}?size=512', + key=banner_hash, + animated=animated, + ) + + def __str__(self) -> str: + return self._url + + def __len__(self) -> int: + return len(self._url) + + def __repr__(self) -> str: + shorten = self._url.replace(self.BASE, '') + return f'' + + def __eq__(self, other: object) -> bool: + return isinstance(other, Asset) and self._url == other._url - if hash is None: - return cls(state) + def __hash__(self) -> int: + return hash(self._url) - url = '/{key}/{0}/{1}.{2}?size={3}' - return cls(state, url.format(id, hash, format, size, key=key)) + @property + def url(self) -> str: + """:class:`str`: Returns the underlying URL of the asset.""" + return self._url - @classmethod - def _from_guild_icon(cls, state, guild, *, format=None, static_format='webp', size=1024): - if not utils.valid_icon_size(size): - raise InvalidArgument("size must be a power of 2 between 16 and 4096") - if format is not None and format not in VALID_AVATAR_FORMATS: - raise InvalidArgument("format must be one of {}".format(VALID_AVATAR_FORMATS)) - if format == "gif" and not guild.is_icon_animated(): - raise InvalidArgument("non animated guild icons do not support gif format") - if static_format not in VALID_STATIC_FORMATS: - raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) + @property + def key(self) -> str: + """:class:`str`: Returns the identifying key of the asset.""" + return self._key - if guild.icon is None: - return cls(state) + def is_animated(self) -> bool: + """:class:`bool`: Returns whether the asset is animated.""" + return self._animated - if format is None: - format = 'gif' if guild.is_icon_animated() else static_format + def replace( + self, + *, + size: int = MISSING, + format: ValidAssetFormatTypes = MISSING, + static_format: ValidStaticFormatTypes = MISSING, + ) -> Self: + """Returns a new asset with the passed components replaced. - return cls(state, '/icons/{0.id}/{0.icon}.{1}?size={2}'.format(guild, format, size)) - @classmethod - def _from_sticker_url(cls, state, sticker, *, size=1024): - if not utils.valid_icon_size(size): - raise InvalidArgument("size must be a power of 2 between 16 and 4096") + .. versionchanged:: 2.0 + ``static_format`` is now preferred over ``format`` + if both are present and the asset is not animated. - return cls(state, '/stickers/{0.id}/{0.image}.png?size={2}'.format(sticker, format, size)) - - @classmethod - def _from_emoji(cls, state, emoji, *, format=None, static_format='png'): - if format is not None and format not in VALID_AVATAR_FORMATS: - raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS)) - if format == "gif" and not emoji.animated: - raise InvalidArgument("non animated emoji's do not support gif format") - if static_format not in VALID_STATIC_FORMATS: - raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) - if format is None: - format = 'gif' if emoji.animated else static_format + .. versionchanged:: 2.0 + This function will now raise :exc:`ValueError` instead of + ``InvalidArgument``. - return cls(state, '/emojis/{0.id}.{1}'.format(emoji, format)) + Parameters + ----------- + size: :class:`int` + The new size of the asset. + format: :class:`str` + The new format to change it to. Must be either + 'webp', 'jpeg', 'jpg', 'png', or 'gif' if it's animated. + static_format: :class:`str` + The new format to change it to if the asset isn't animated. + Must be either 'webp', 'jpeg', 'jpg', or 'png'. - def __str__(self): - return self.BASE + self._url if self._url is not None else '' + Raises + ------- + ValueError + An invalid size or format was passed. - def __len__(self): - if self._url: - return len(self.BASE + self._url) - return 0 + Returns + -------- + :class:`Asset` + The newly updated asset. + """ + url = yarl.URL(self._url) + path, _ = os.path.splitext(url.path) + + if format is not MISSING: + if self._animated: + if format not in VALID_ASSET_FORMATS: + raise ValueError(f'format must be one of {VALID_ASSET_FORMATS}') + else: + if static_format is MISSING and format not in VALID_STATIC_FORMATS: + raise ValueError(f'format must be one of {VALID_STATIC_FORMATS}') + url = url.with_path(f'{path}.{format}') + + if static_format is not MISSING and not self._animated: + if static_format not in VALID_STATIC_FORMATS: + raise ValueError(f'static_format must be one of {VALID_STATIC_FORMATS}') + url = url.with_path(f'{path}.{static_format}') + + if size is not MISSING: + if not utils.valid_icon_size(size): + raise ValueError('size must be a power of 2 between 16 and 4096') + url = url.with_query(size=size) + else: + url = url.with_query(url.raw_query_string) - def __bool__(self): - return self._url is not None + url = str(url) + return Asset(state=self._state, url=url, key=self._key, animated=self._animated) - def __repr__(self): - return ''.format(self) + def with_size(self, size: int, /) -> Self: + """Returns a new asset with the specified size. - def __eq__(self, other): - return isinstance(other, Asset) and self._url == other._url + .. versionchanged:: 2.0 + This function will now raise :exc:`ValueError` instead of + ``InvalidArgument``. - def __ne__(self, other): - return not self.__eq__(other) + Parameters + ------------ + size: :class:`int` + The new size of the asset. - def __hash__(self): - return hash(self._url) + Raises + ------- + ValueError + The asset had an invalid size. - async def read(self): - """|coro| + Returns + -------- + :class:`Asset` + The new updated asset. + """ + if not utils.valid_icon_size(size): + raise ValueError('size must be a power of 2 between 16 and 4096') - Retrieves the content of this asset as a :class:`bytes` object. + url = str(yarl.URL(self._url).with_query(size=size)) + return Asset(state=self._state, url=url, key=self._key, animated=self._animated) - .. warning:: + def with_format(self, format: ValidAssetFormatTypes, /) -> Self: + """Returns a new asset with the specified format. - :class:`PartialEmoji` won't have a connection state if user created, - and a URL won't be present if a custom image isn't associated with - the asset, e.g. a guild with no custom icon. + .. versionchanged:: 2.0 + This function will now raise :exc:`ValueError` instead of + ``InvalidArgument``. - .. versionadded:: 1.1 + Parameters + ------------ + format: :class:`str` + The new format of the asset. Raises - ------ - DiscordException - There was no valid URL or internal connection state. - HTTPException - Downloading the asset failed. - NotFound - The asset was deleted. + ------- + ValueError + The asset had an invalid format. Returns - ------- - :class:`bytes` - The content of the asset. + -------- + :class:`Asset` + The new updated asset. """ - if not self._url: - raise DiscordException('Invalid asset (no URL provided)') - if self._state is None: - raise DiscordException('Invalid state (no ConnectionState provided)') + if self._animated: + if format not in VALID_ASSET_FORMATS: + raise ValueError(f'format must be one of {VALID_ASSET_FORMATS}') + else: + if format not in VALID_STATIC_FORMATS: + raise ValueError(f'format must be one of {VALID_STATIC_FORMATS}') - return await self._state.http.get_from_cdn(self.BASE + self._url) + url = yarl.URL(self._url) + path, _ = os.path.splitext(url.path) + url = str(url.with_path(f'{path}.{format}').with_query(url.raw_query_string)) + return Asset(state=self._state, url=url, key=self._key, animated=self._animated) - async def save(self, fp, *, seek_begin=True): - """|coro| + def with_static_format(self, format: ValidStaticFormatTypes, /) -> Self: + """Returns a new asset with the specified static format. - Saves this asset into a file-like object. + This only changes the format if the underlying asset is + not animated. Otherwise, the asset is not changed. + + .. versionchanged:: 2.0 + This function will now raise :exc:`ValueError` instead of + ``InvalidArgument``. Parameters - ---------- - fp: Union[BinaryIO, :class:`os.PathLike`] - Same as in :meth:`Attachment.save`. - seek_begin: :class:`bool` - Same as in :meth:`Attachment.save`. + ------------ + format: :class:`str` + The new static format of the asset. Raises - ------ - DiscordException - There was no valid URL or internal connection state. - HTTPException - Downloading the asset failed. - NotFound - The asset was deleted. + ------- + ValueError + The asset had an invalid format. Returns -------- - :class:`int` - The number of bytes written. + :class:`Asset` + The new updated asset. """ - data = await self.read() - if isinstance(fp, io.IOBase) and fp.writable(): - written = fp.write(data) - if seek_begin: - fp.seek(0) - return written - else: - with open(fp, 'wb') as f: - return f.write(data) + if self._animated: + return self + return self.with_format(format) diff --git a/dist/ba_data/python-site-packages/discord/audit_logs.py b/dist/ba_data/python-site-packages/discord/audit_logs.py index 7d70a93b..eebcecfb 100644 --- a/dist/ba_data/python-site-packages/discord/audit_logs.py +++ b/dist/ba_data/python-site-packages/discord/audit_logs.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,122 +22,406 @@ DEALINGS IN THE SOFTWARE. """ -from . import utils, enums -from .object import Object -from .permissions import PermissionOverwrite, Permissions +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Callable, ClassVar, Mapping, Generator, List, Optional, Tuple, Type, TypeVar, Union + +from . import enums, flags, utils +from .asset import Asset from .colour import Colour from .invite import Invite from .mixins import Hashable +from .object import Object +from .permissions import PermissionOverwrite, Permissions +from .automod import AutoModTrigger, AutoModRuleAction, AutoModPresets, AutoModRule +from .role import Role +from .emoji import Emoji +from .partial_emoji import PartialEmoji +from .member import Member +from .scheduled_event import ScheduledEvent +from .stage_instance import StageInstance +from .sticker import GuildSticker +from .threads import Thread +from .integrations import PartialIntegration +from .channel import ForumChannel, StageChannel, ForumTag + +__all__ = ( + 'AuditLogDiff', + 'AuditLogChanges', + 'AuditLogEntry', +) + + +if TYPE_CHECKING: + import datetime + + from . import abc + from .guild import Guild + from .state import ConnectionState + from .types.audit_log import ( + AuditLogChange as AuditLogChangePayload, + AuditLogEntry as AuditLogEntryPayload, + ) + from .types.channel import ( + PermissionOverwrite as PermissionOverwritePayload, + ForumTag as ForumTagPayload, + DefaultReaction as DefaultReactionPayload, + ) + from .types.invite import Invite as InvitePayload + from .types.role import Role as RolePayload + from .types.snowflake import Snowflake + from .types.command import ApplicationCommandPermissions + from .types.automod import AutoModerationTriggerMetadata, AutoModerationAction + from .user import User + from .app_commands import AppCommand + from .webhook import Webhook + + TargetType = Union[ + Guild, + abc.GuildChannel, + Member, + User, + Role, + Invite, + Emoji, + StageInstance, + GuildSticker, + Thread, + Object, + PartialIntegration, + AutoModRule, + ScheduledEvent, + Webhook, + AppCommand, + None, + ] + + +def _transform_timestamp(entry: AuditLogEntry, data: Optional[str]) -> Optional[datetime.datetime]: + return utils.parse_time(data) + + +def _transform_color(entry: AuditLogEntry, data: int) -> Colour: + return Colour(data) -def _transform_verification_level(entry, data): - return enums.try_enum(enums.VerificationLevel, data) -def _transform_default_notifications(entry, data): - return enums.try_enum(enums.NotificationLevel, data) +def _transform_snowflake(entry: AuditLogEntry, data: Snowflake) -> int: + return int(data) + -def _transform_explicit_content_filter(entry, data): - return enums.try_enum(enums.ContentFilter, data) +def _transform_channel(entry: AuditLogEntry, data: Optional[Snowflake]) -> Optional[Union[abc.GuildChannel, Object]]: + if data is None: + return None + return entry.guild.get_channel(int(data)) or Object(id=data) -def _transform_permissions(entry, data): - return Permissions(data) -def _transform_color(entry, data): - return Colour(data) +def _transform_channels_or_threads( + entry: AuditLogEntry, data: List[Snowflake] +) -> List[Union[abc.GuildChannel, Thread, Object]]: + return [entry.guild.get_channel_or_thread(int(data)) or Object(id=data) for data in data] -def _transform_snowflake(entry, data): - return int(data) -def _transform_channel(entry, data): +def _transform_member_id(entry: AuditLogEntry, data: Optional[Snowflake]) -> Union[Member, User, None]: if data is None: return None - return entry.guild.get_channel(int(data)) or Object(id=data) + return entry._get_member(int(data)) + -def _transform_owner_id(entry, data): +def _transform_guild_id(entry: AuditLogEntry, data: Optional[Snowflake]) -> Optional[Guild]: if data is None: return None - return entry._get_member(int(data)) + return entry._state._get_guild(int(data)) + + +def _transform_roles(entry: AuditLogEntry, data: List[Snowflake]) -> List[Union[Role, Object]]: + return [entry.guild.get_role(int(role_id)) or Object(role_id, type=Role) for role_id in data] + + +def _transform_applied_forum_tags(entry: AuditLogEntry, data: List[Snowflake]) -> List[Union[ForumTag, Object]]: + thread = entry.target + if isinstance(thread, Thread) and isinstance(thread.parent, ForumChannel): + return [thread.parent.get_tag(tag_id) or Object(id=tag_id, type=ForumTag) for tag_id in map(int, data)] + return [Object(id=tag_id, type=ForumTag) for tag_id in data] + -def _transform_inviter_id(entry, data): +def _transform_overloaded_flags(entry: AuditLogEntry, data: int) -> Union[int, flags.ChannelFlags]: + # The `flags` key is definitely overloaded. Right now it's for channels and threads but + # I am aware of `member.flags` and `user.flags` existing. However, this does not impact audit logs + # at the moment but better safe than sorry. + channel_audit_log_types = ( + enums.AuditLogAction.channel_create, + enums.AuditLogAction.channel_update, + enums.AuditLogAction.channel_delete, + enums.AuditLogAction.thread_create, + enums.AuditLogAction.thread_update, + enums.AuditLogAction.thread_delete, + ) + + if entry.action in channel_audit_log_types: + return flags.ChannelFlags._from_value(data) + return data + + +def _transform_forum_tags(entry: AuditLogEntry, data: List[ForumTagPayload]) -> List[ForumTag]: + return [ForumTag.from_data(state=entry._state, data=d) for d in data] + + +def _transform_default_reaction(entry: AuditLogEntry, data: DefaultReactionPayload) -> Optional[PartialEmoji]: if data is None: return None - return entry._get_member(int(data)) -def _transform_overwrites(entry, data): + emoji_name = data.get('emoji_name') or '' + emoji_id = utils._get_as_snowflake(data, 'emoji_id') or None # Coerce 0 -> None + return PartialEmoji.with_state(state=entry._state, name=emoji_name, id=emoji_id) + + +def _transform_overwrites( + entry: AuditLogEntry, data: List[PermissionOverwritePayload] +) -> List[Tuple[Object, PermissionOverwrite]]: overwrites = [] for elem in data: - allow = Permissions(elem['allow']) - deny = Permissions(elem['deny']) + allow = Permissions(int(elem['allow'])) + deny = Permissions(int(elem['deny'])) ow = PermissionOverwrite.from_pair(allow, deny) ow_type = elem['type'] ow_id = int(elem['id']) - if ow_type == 'role': + target = None + if ow_type == '0': target = entry.guild.get_role(ow_id) - else: + elif ow_type == '1': target = entry._get_member(ow_id) if target is None: - target = Object(id=ow_id) + target = Object(id=ow_id, type=Role if ow_type == '0' else Member) overwrites.append((target, ow)) return overwrites + +def _transform_icon(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: + if data is None: + return None + if entry.action is enums.AuditLogAction.guild_update: + return Asset._from_guild_icon(entry._state, entry.guild.id, data) + else: + return Asset._from_icon(entry._state, entry._target_id, data, path='role') # type: ignore # target_id won't be None in this case + + +def _transform_avatar(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: + if data is None: + return None + return Asset._from_avatar(entry._state, entry._target_id, data) # type: ignore # target_id won't be None in this case + + +def _transform_cover_image(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: + if data is None: + return None + return Asset._from_scheduled_event_cover_image(entry._state, entry._target_id, data) # type: ignore # target_id won't be None in this case + + +def _guild_hash_transformer(path: str) -> Callable[[AuditLogEntry, Optional[str]], Optional[Asset]]: + def _transform(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: + if data is None: + return None + return Asset._from_guild_image(entry._state, entry.guild.id, data, path=path) + + return _transform + + +def _transform_automod_trigger_metadata( + entry: AuditLogEntry, data: AutoModerationTriggerMetadata +) -> Optional[AutoModTrigger]: + + if isinstance(entry.target, AutoModRule): + # Trigger type cannot be changed, so type should be the same before and after updates. + # Avoids checking which keys are in data to guess trigger type + # or returning None if data is empty. + try: + return AutoModTrigger.from_data(type=entry.target.trigger.type.value, data=data) + except Exception: + pass + + # Try to infer trigger type from available keys in data + if 'presets' in data: + return AutoModTrigger( + type=enums.AutoModRuleTriggerType.keyword_preset, + presets=AutoModPresets._from_value(data['presets']), # type: ignore + allow_list=data.get('allow_list'), + ) + elif 'keyword_filter' in data: + return AutoModTrigger( + type=enums.AutoModRuleTriggerType.keyword, + keyword_filter=data['keyword_filter'], # type: ignore + allow_list=data.get('allow_list'), + regex_patterns=data.get('regex_patterns'), + ) + elif 'mention_total_limit' in data: + return AutoModTrigger(type=enums.AutoModRuleTriggerType.mention_spam, mention_limit=data['mention_total_limit']) # type: ignore + else: + return AutoModTrigger(type=enums.AutoModRuleTriggerType.spam) + + +def _transform_automod_actions(entry: AuditLogEntry, data: List[AutoModerationAction]) -> List[AutoModRuleAction]: + return [AutoModRuleAction.from_data(action) for action in data] + + +E = TypeVar('E', bound=enums.Enum) + + +def _enum_transformer(enum: Type[E]) -> Callable[[AuditLogEntry, int], E]: + def _transform(entry: AuditLogEntry, data: int) -> E: + return enums.try_enum(enum, data) + + return _transform + + +F = TypeVar('F', bound=flags.BaseFlags) + + +def _flag_transformer(cls: Type[F]) -> Callable[[AuditLogEntry, Union[int, str]], F]: + def _transform(entry: AuditLogEntry, data: Union[int, str]) -> F: + return cls._from_value(int(data)) + + return _transform + + +def _transform_type( + entry: AuditLogEntry, data: Union[int, str] +) -> Union[enums.ChannelType, enums.StickerType, enums.WebhookType, str]: + if entry.action.name.startswith('sticker_'): + return enums.try_enum(enums.StickerType, data) + elif entry.action.name.startswith('integration_'): + return data # type: ignore # integration type is str + elif entry.action.name.startswith('webhook_'): + return enums.try_enum(enums.WebhookType, data) + else: + return enums.try_enum(enums.ChannelType, data) + + class AuditLogDiff: - def __len__(self): + def __len__(self) -> int: return len(self.__dict__) - def __iter__(self): - return iter(self.__dict__.items()) + def __iter__(self) -> Generator[Tuple[str, Any], None, None]: + yield from self.__dict__.items() - def __repr__(self): + def __repr__(self) -> str: values = ' '.join('%s=%r' % item for item in self.__dict__.items()) - return '' % values + return f'' + + if TYPE_CHECKING: + + def __getattr__(self, item: str) -> Any: + ... + + def __setattr__(self, key: str, value: Any) -> Any: + ... + + +Transformer = Callable[["AuditLogEntry", Any], Any] + class AuditLogChanges: - TRANSFORMERS = { - 'verification_level': (None, _transform_verification_level), - 'explicit_content_filter': (None, _transform_explicit_content_filter), - 'allow': (None, _transform_permissions), - 'deny': (None, _transform_permissions), - 'permissions': (None, _transform_permissions), - 'id': (None, _transform_snowflake), - 'color': ('colour', _transform_color), - 'owner_id': ('owner', _transform_owner_id), - 'inviter_id': ('inviter', _transform_inviter_id), - 'channel_id': ('channel', _transform_channel), - 'afk_channel_id': ('afk_channel', _transform_channel), - 'system_channel_id': ('system_channel', _transform_channel), - 'widget_channel_id': ('widget_channel', _transform_channel), - 'permission_overwrites': ('overwrites', _transform_overwrites), - 'splash_hash': ('splash', None), - 'icon_hash': ('icon', None), - 'avatar_hash': ('avatar', None), - 'rate_limit_per_user': ('slowmode_delay', None), - 'default_message_notifications': ('default_notifications', _transform_default_notifications), + # fmt: off + TRANSFORMERS: ClassVar[Mapping[str, Tuple[Optional[str], Optional[Transformer]]]] = { + 'verification_level': (None, _enum_transformer(enums.VerificationLevel)), + 'explicit_content_filter': (None, _enum_transformer(enums.ContentFilter)), + 'allow': (None, _flag_transformer(Permissions)), + 'deny': (None, _flag_transformer(Permissions)), + 'permissions': (None, _flag_transformer(Permissions)), + 'id': (None, _transform_snowflake), + 'color': ('colour', _transform_color), + 'owner_id': ('owner', _transform_member_id), + 'inviter_id': ('inviter', _transform_member_id), + 'channel_id': ('channel', _transform_channel), + 'afk_channel_id': ('afk_channel', _transform_channel), + 'system_channel_id': ('system_channel', _transform_channel), + 'system_channel_flags': (None, _flag_transformer(flags.SystemChannelFlags)), + 'widget_channel_id': ('widget_channel', _transform_channel), + 'rules_channel_id': ('rules_channel', _transform_channel), + 'public_updates_channel_id': ('public_updates_channel', _transform_channel), + 'permission_overwrites': ('overwrites', _transform_overwrites), + 'splash_hash': ('splash', _guild_hash_transformer('splashes')), + 'banner_hash': ('banner', _guild_hash_transformer('banners')), + 'discovery_splash_hash': ('discovery_splash', _guild_hash_transformer('discovery-splashes')), + 'icon_hash': ('icon', _transform_icon), + 'avatar_hash': ('avatar', _transform_avatar), + 'rate_limit_per_user': ('slowmode_delay', None), + 'default_thread_rate_limit_per_user': ('default_thread_slowmode_delay', None), + 'guild_id': ('guild', _transform_guild_id), + 'tags': ('emoji', None), + 'default_message_notifications': ('default_notifications', _enum_transformer(enums.NotificationLevel)), + 'video_quality_mode': (None, _enum_transformer(enums.VideoQualityMode)), + 'privacy_level': (None, _enum_transformer(enums.PrivacyLevel)), + 'format_type': (None, _enum_transformer(enums.StickerFormatType)), + 'type': (None, _transform_type), + 'communication_disabled_until': ('timed_out_until', _transform_timestamp), + 'expire_behavior': (None, _enum_transformer(enums.ExpireBehaviour)), + 'mfa_level': (None, _enum_transformer(enums.MFALevel)), + 'status': (None, _enum_transformer(enums.EventStatus)), + 'entity_type': (None, _enum_transformer(enums.EntityType)), + 'preferred_locale': (None, _enum_transformer(enums.Locale)), + 'image_hash': ('cover_image', _transform_cover_image), + 'trigger_type': (None, _enum_transformer(enums.AutoModRuleTriggerType)), + 'event_type': (None, _enum_transformer(enums.AutoModRuleEventType)), + 'trigger_metadata': ('trigger', _transform_automod_trigger_metadata), + 'actions': (None, _transform_automod_actions), + 'exempt_channels': (None, _transform_channels_or_threads), + 'exempt_roles': (None, _transform_roles), + 'applied_tags': (None, _transform_applied_forum_tags), + 'available_tags': (None, _transform_forum_tags), + 'flags': (None, _transform_overloaded_flags), + 'default_reaction_emoji': (None, _transform_default_reaction), } - - def __init__(self, entry, data): - self.before = AuditLogDiff() - self.after = AuditLogDiff() + # fmt: on + + def __init__(self, entry: AuditLogEntry, data: List[AuditLogChangePayload]): + self.before: AuditLogDiff = AuditLogDiff() + self.after: AuditLogDiff = AuditLogDiff() + # special case entire process since each + # element in data is a different target + # key is the target id + if entry.action is enums.AuditLogAction.app_command_permission_update: + self.before.app_command_permissions = [] + self.after.app_command_permissions = [] + + for elem in data: + self._handle_app_command_permissions( + self.before, + entry, + elem.get('old_value'), # type: ignore # value will be an ApplicationCommandPermissions if present + ) + + self._handle_app_command_permissions( + self.after, + entry, + elem.get('new_value'), # type: ignore # value will be an ApplicationCommandPermissions if present + ) + return for elem in data: attr = elem['key'] # special cases for role add/remove if attr == '$add': - self._handle_role(self.before, self.after, entry, elem['new_value']) + self._handle_role(self.before, self.after, entry, elem['new_value']) # type: ignore # new_value is a list of roles in this case continue elif attr == '$remove': - self._handle_role(self.after, self.before, entry, elem['new_value']) + self._handle_role(self.after, self.before, entry, elem['new_value']) # type: ignore # new_value is a list of roles in this case continue - transformer = self.TRANSFORMERS.get(attr) - if transformer: - key, transformer = transformer + try: + key, transformer = self.TRANSFORMERS[attr] + except (ValueError, KeyError): + transformer = None + else: if key: attr = key + transformer: Optional[Transformer] + try: before = elem['old_value'] except KeyError: @@ -164,29 +446,88 @@ def __init__(self, entry, data): if hasattr(self.after, 'colour'): self.after.color = self.after.colour self.before.color = self.before.colour + if hasattr(self.after, 'expire_behavior'): + self.after.expire_behaviour = self.after.expire_behavior + self.before.expire_behaviour = self.before.expire_behavior - def __repr__(self): - return '' % (self.before, self.after) + def __repr__(self) -> str: + return f'' - def _handle_role(self, first, second, entry, elem): + def _handle_role(self, first: AuditLogDiff, second: AuditLogDiff, entry: AuditLogEntry, elem: List[RolePayload]) -> None: if not hasattr(first, 'roles'): setattr(first, 'roles', []) data = [] - g = entry.guild + g: Guild = entry.guild for e in elem: role_id = int(e['id']) role = g.get_role(role_id) if role is None: - role = Object(id=role_id) - role.name = e['name'] + role = Object(id=role_id, type=Role) + role.name = e['name'] # type: ignore # Object doesn't usually have name data.append(role) setattr(second, 'roles', data) + def _handle_app_command_permissions( + self, + diff: AuditLogDiff, + entry: AuditLogEntry, + data: Optional[ApplicationCommandPermissions], + ): + if data is None: + return + + # avoid circular import + from discord.app_commands import AppCommandPermissions + + state = entry._state + guild = entry.guild + diff.app_command_permissions.append(AppCommandPermissions(data=data, guild=guild, state=state)) + + +class _AuditLogProxy: + def __init__(self, **kwargs: Any) -> None: + for k, v in kwargs.items(): + setattr(self, k, v) + + +class _AuditLogProxyMemberPrune(_AuditLogProxy): + delete_member_days: int + members_removed: int + + +class _AuditLogProxyMemberMoveOrMessageDelete(_AuditLogProxy): + channel: Union[abc.GuildChannel, Thread] + count: int + + +class _AuditLogProxyMemberDisconnect(_AuditLogProxy): + count: int + + +class _AuditLogProxyPinAction(_AuditLogProxy): + channel: Union[abc.GuildChannel, Thread] + message_id: int + + +class _AuditLogProxyStageInstanceAction(_AuditLogProxy): + channel: abc.GuildChannel + + +class _AuditLogProxyMessageBulkDelete(_AuditLogProxy): + count: int + + +class _AuditLogProxyAutoModAction(_AuditLogProxy): + automod_rule_name: str + automod_rule_trigger_type: str + channel: Optional[Union[abc.GuildChannel, Thread]] + + class AuditLogEntry(Hashable): r"""Represents an Audit Log entry. @@ -213,11 +554,17 @@ class AuditLogEntry(Hashable): ----------- action: :class:`AuditLogAction` The action that was done. - user: :class:`abc.User` + user: Optional[:class:`abc.User`] The user who initiated this action. Usually a :class:`Member`\, unless gone then it's a :class:`User`. + user_id: Optional[:class:`int`] + The user ID who initiated this action. + + .. versionadded:: 2.2 id: :class:`int` The entry ID. + guild: :class:`Guild` + The guild that this entry belongs to. target: Any The target that got changed. The exact type of this depends on the action being done. @@ -230,58 +577,114 @@ class AuditLogEntry(Hashable): which actions have this field filled out. """ - def __init__(self, *, users, data, guild): - self._state = guild._state - self.guild = guild - self._users = users + def __init__( + self, + *, + users: Mapping[int, User], + integrations: Mapping[int, PartialIntegration], + app_commands: Mapping[int, AppCommand], + automod_rules: Mapping[int, AutoModRule], + webhooks: Mapping[int, Webhook], + data: AuditLogEntryPayload, + guild: Guild, + ): + self._state: ConnectionState = guild._state + self.guild: Guild = guild + self._users: Mapping[int, User] = users + self._integrations: Mapping[int, PartialIntegration] = integrations + self._app_commands: Mapping[int, AppCommand] = app_commands + self._automod_rules: Mapping[int, AutoModRule] = automod_rules + self._webhooks: Mapping[int, Webhook] = webhooks self._from_data(data) - def _from_data(self, data): - self.action = enums.try_enum(enums.AuditLogAction, data['action_type']) - self.id = int(data['id']) + def _from_data(self, data: AuditLogEntryPayload) -> None: + self.action: enums.AuditLogAction = enums.try_enum(enums.AuditLogAction, data['action_type']) + self.id: int = int(data['id']) # this key is technically not usually present - self.reason = data.get('reason') - self.extra = data.get('options') - - if isinstance(self.action, enums.AuditLogAction) and self.extra: + self.reason: Optional[str] = data.get('reason') + extra = data.get('options') + + # fmt: off + self.extra: Union[ + _AuditLogProxyMemberPrune, + _AuditLogProxyMemberMoveOrMessageDelete, + _AuditLogProxyMemberDisconnect, + _AuditLogProxyPinAction, + _AuditLogProxyStageInstanceAction, + _AuditLogProxyMessageBulkDelete, + _AuditLogProxyAutoModAction, + Member, User, None, PartialIntegration, + Role, Object + ] = None + # fmt: on + + if isinstance(self.action, enums.AuditLogAction) and extra: if self.action is enums.AuditLogAction.member_prune: # member prune has two keys with useful information - self.extra = type('_AuditLogProxy', (), {k: int(v) for k, v in self.extra.items()})() + self.extra = _AuditLogProxyMemberPrune( + delete_member_days=int(extra['delete_member_days']), + members_removed=int(extra['members_removed']), + ) elif self.action is enums.AuditLogAction.member_move or self.action is enums.AuditLogAction.message_delete: - channel_id = int(self.extra['channel_id']) - elems = { - 'count': int(self.extra['count']), - 'channel': self.guild.get_channel(channel_id) or Object(id=channel_id) - } - self.extra = type('_AuditLogProxy', (), elems)() + channel_id = int(extra['channel_id']) + self.extra = _AuditLogProxyMemberMoveOrMessageDelete( + count=int(extra['count']), + channel=self.guild.get_channel_or_thread(channel_id) or Object(id=channel_id), + ) elif self.action is enums.AuditLogAction.member_disconnect: # The member disconnect action has a dict with some information - elems = { - 'count': int(self.extra['count']), - } - self.extra = type('_AuditLogProxy', (), elems)() + self.extra = _AuditLogProxyMemberDisconnect(count=int(extra['count'])) + elif self.action is enums.AuditLogAction.message_bulk_delete: + # The bulk message delete action has the number of messages deleted + self.extra = _AuditLogProxyMessageBulkDelete(count=int(extra['count'])) elif self.action.name.endswith('pin'): # the pin actions have a dict with some information - channel_id = int(self.extra['channel_id']) - message_id = int(self.extra['message_id']) - elems = { - 'channel': self.guild.get_channel(channel_id) or Object(id=channel_id), - 'message_id': message_id - } - self.extra = type('_AuditLogProxy', (), elems)() + channel_id = int(extra['channel_id']) + self.extra = _AuditLogProxyPinAction( + channel=self.guild.get_channel_or_thread(channel_id) or Object(id=channel_id), + message_id=int(extra['message_id']), + ) + elif ( + self.action is enums.AuditLogAction.automod_block_message + or self.action is enums.AuditLogAction.automod_flag_message + or self.action is enums.AuditLogAction.automod_timeout_member + ): + channel_id = utils._get_as_snowflake(extra, 'channel_id') + channel = None + + # May be an empty string instead of None due to a Discord issue + if channel_id: + channel = self.guild.get_channel_or_thread(channel_id) or Object(id=channel_id) + + self.extra = _AuditLogProxyAutoModAction( + automod_rule_name=extra['auto_moderation_rule_name'], + automod_rule_trigger_type=enums.try_enum( + enums.AutoModRuleTriggerType, extra['auto_moderation_rule_trigger_type'] + ), + channel=channel, + ) + elif self.action.name.startswith('overwrite_'): # the overwrite_ actions have a dict with some information - instance_id = int(self.extra['id']) - the_type = self.extra.get('type') - if the_type == 'member': + instance_id = int(extra['id']) + the_type = extra.get('type') + if the_type == '1': self.extra = self._get_member(instance_id) - else: + elif the_type == '0': role = self.guild.get_role(instance_id) if role is None: - role = Object(id=instance_id) - role.name = self.extra.get('role_name') + role = Object(id=instance_id, type=Role) + role.name = extra.get('role_name') # type: ignore # Object doesn't usually have name self.extra = role + elif self.action.name.startswith('stage_instance'): + channel_id = int(extra['channel_id']) + self.extra = _AuditLogProxyStageInstanceAction( + channel=self.guild.get_channel(channel_id) or Object(id=channel_id, type=StageChannel) + ) + elif self.action.name.startswith('app_command'): + app_id = int(extra['application_id']) + self.extra = self._get_integration_by_app_id(app_id) or Object(app_id, type=PartialIntegration) # this key is not present when the above is present, typically. # It's a list of { new_value: a, old_value: b, key: c } @@ -290,93 +693,173 @@ def _from_data(self, data): # into meaningful data when requested self._changes = data.get('changes', []) - self.user = self._get_member(utils._get_as_snowflake(data, 'user_id')) + self.user_id: Optional[int] = utils._get_as_snowflake(data, 'user_id') + self.user: Optional[Union[User, Member]] = self._get_member(self.user_id) self._target_id = utils._get_as_snowflake(data, 'target_id') - def _get_member(self, user_id): + def _get_member(self, user_id: Optional[int]) -> Union[Member, User, None]: + if user_id is None: + return None + return self.guild.get_member(user_id) or self._users.get(user_id) - def __repr__(self): - return ''.format(self) + def _get_integration(self, integration_id: Optional[int]) -> Optional[PartialIntegration]: + if integration_id is None: + return None + + return self._integrations.get(integration_id) + + def _get_integration_by_app_id(self, application_id: Optional[int]) -> Optional[PartialIntegration]: + if application_id is None: + return None + + # get PartialIntegration by application id + return utils.get(self._integrations.values(), application_id=application_id) + + def _get_app_command(self, app_command_id: Optional[int]) -> Optional[AppCommand]: + if app_command_id is None: + return None + + return self._app_commands.get(app_command_id) + + def __repr__(self) -> str: + return f'' @utils.cached_property - def created_at(self): + def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the entry's creation time in UTC.""" return utils.snowflake_time(self.id) @utils.cached_property - def target(self): + def target(self) -> TargetType: + if self.action.target_type is None: + return None + try: converter = getattr(self, '_convert_target_' + self.action.target_type) except AttributeError: + if self._target_id is None: + return None return Object(id=self._target_id) else: return converter(self._target_id) @utils.cached_property - def category(self): + def category(self) -> Optional[enums.AuditLogActionCategory]: """Optional[:class:`AuditLogActionCategory`]: The category of the action, if applicable.""" return self.action.category @utils.cached_property - def changes(self): + def changes(self) -> AuditLogChanges: """:class:`AuditLogChanges`: The list of changes this entry has.""" obj = AuditLogChanges(self, self._changes) del self._changes return obj @utils.cached_property - def before(self): + def before(self) -> AuditLogDiff: """:class:`AuditLogDiff`: The target's prior state.""" return self.changes.before @utils.cached_property - def after(self): + def after(self) -> AuditLogDiff: """:class:`AuditLogDiff`: The target's subsequent state.""" return self.changes.after - def _convert_target_guild(self, target_id): + def _convert_target_guild(self, target_id: int) -> Guild: return self.guild - def _convert_target_channel(self, target_id): - ch = self.guild.get_channel(target_id) - if ch is None: - return Object(id=target_id) - return ch + def _convert_target_channel(self, target_id: int) -> Union[abc.GuildChannel, Object]: + return self.guild.get_channel(target_id) or Object(id=target_id) + + def _convert_target_user(self, target_id: Optional[int]) -> Optional[Union[Member, User, Object]]: + # For some reason the member_disconnect and member_move action types + # do not have a non-null target_id so safeguard against that + if target_id is None: + return None - def _convert_target_user(self, target_id): - return self._get_member(target_id) + return self._get_member(target_id) or Object(id=target_id, type=Member) - def _convert_target_role(self, target_id): - role = self.guild.get_role(target_id) - if role is None: - return Object(id=target_id) - return role + def _convert_target_role(self, target_id: int) -> Union[Role, Object]: + return self.guild.get_role(target_id) or Object(id=target_id, type=Role) - def _convert_target_invite(self, target_id): + def _convert_target_invite(self, target_id: None) -> Invite: # invites have target_id set to null # so figure out which change has the full invite data changeset = self.before if self.action is enums.AuditLogAction.invite_delete else self.after - fake_payload = { + fake_payload: InvitePayload = { 'max_age': changeset.max_age, 'max_uses': changeset.max_uses, 'code': changeset.code, 'temporary': changeset.temporary, - 'channel': changeset.channel, 'uses': changeset.uses, - 'guild': self.guild, + 'channel': None, # type: ignore # the channel is passed to the Invite constructor directly } - obj = Invite(state=self._state, data=fake_payload) + obj = Invite(state=self._state, data=fake_payload, guild=self.guild, channel=changeset.channel) try: obj.inviter = changeset.inviter except AttributeError: pass return obj - def _convert_target_emoji(self, target_id): - return self._state.get_emoji(target_id) or Object(id=target_id) + def _convert_target_emoji(self, target_id: int) -> Union[Emoji, Object]: + return self._state.get_emoji(target_id) or Object(id=target_id, type=Emoji) + + def _convert_target_message(self, target_id: int) -> Union[Member, User, Object]: + return self._get_member(target_id) or Object(id=target_id, type=Member) + + def _convert_target_stage_instance(self, target_id: int) -> Union[StageInstance, Object]: + return self.guild.get_stage_instance(target_id) or Object(id=target_id, type=StageInstance) + + def _convert_target_sticker(self, target_id: int) -> Union[GuildSticker, Object]: + return self._state.get_sticker(target_id) or Object(id=target_id, type=GuildSticker) + + def _convert_target_thread(self, target_id: int) -> Union[Thread, Object]: + return self.guild.get_thread(target_id) or Object(id=target_id, type=Thread) + + def _convert_target_guild_scheduled_event(self, target_id: int) -> Union[ScheduledEvent, Object]: + return self.guild.get_scheduled_event(target_id) or Object(id=target_id, type=ScheduledEvent) + + def _convert_target_integration(self, target_id: int) -> Union[PartialIntegration, Object]: + return self._get_integration(target_id) or Object(target_id, type=PartialIntegration) + + def _convert_target_app_command(self, target_id: int) -> Union[AppCommand, Object]: + target = self._get_app_command(target_id) + if not target: + # circular import + from .app_commands import AppCommand + + target = Object(target_id, type=AppCommand) + + return target + + def _convert_target_integration_or_app_command(self, target_id: int) -> Union[PartialIntegration, AppCommand, Object]: + target = self._get_integration_by_app_id(target_id) or self._get_app_command(target_id) + if not target: + try: + # circular import + from .app_commands import AppCommand + + # get application id from extras + # if it matches target id, type should be integration + target_app = self.extra + # extra should be an Object or PartialIntegration + app_id = target_app.application_id if isinstance(target_app, PartialIntegration) else target_app.id # type: ignore + type = PartialIntegration if target_id == app_id else AppCommand + except AttributeError: + return Object(target_id) + else: + return Object(target_id, type=type) + + return target + + def _convert_target_auto_moderation(self, target_id: int) -> Union[AutoModRule, Object]: + return self._automod_rules.get(target_id) or Object(target_id, type=AutoModRule) + + def _convert_target_webhook(self, target_id: int) -> Union[Webhook, Object]: + # circular import + from .webhook import Webhook - def _convert_target_message(self, target_id): - return self._get_member(target_id) + return self._webhooks.get(target_id) or Object(target_id, type=Webhook) diff --git a/dist/ba_data/python-site-packages/discord/automod.py b/dist/ba_data/python-site-packages/discord/automod.py new file mode 100644 index 00000000..84a00c87 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/automod.py @@ -0,0 +1,600 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations +import datetime + +from typing import TYPE_CHECKING, Any, Dict, Optional, List, Set, Union, Sequence, overload + +from .enums import AutoModRuleTriggerType, AutoModRuleActionType, AutoModRuleEventType, try_enum +from .flags import AutoModPresets +from . import utils +from .utils import MISSING, cached_slot_property + +if TYPE_CHECKING: + from typing_extensions import Self + from .abc import Snowflake, GuildChannel + from .threads import Thread + from .guild import Guild + from .member import Member + from .state import ConnectionState + from .types.automod import ( + AutoModerationRule as AutoModerationRulePayload, + AutoModerationTriggerMetadata as AutoModerationTriggerMetadataPayload, + AutoModerationAction as AutoModerationActionPayload, + AutoModerationActionExecution as AutoModerationActionExecutionPayload, + ) + from .role import Role + +__all__ = ( + 'AutoModRuleAction', + 'AutoModTrigger', + 'AutoModRule', + 'AutoModAction', +) + + +class AutoModRuleAction: + """Represents an auto moderation's rule action. + + .. note:: + Only one of ``channel_id``, ``duration``, or ``custom_message`` can be used. + + .. versionadded:: 2.0 + + Attributes + ----------- + type: :class:`AutoModRuleActionType` + The type of action to take. + Defaults to :attr:`~AutoModRuleActionType.block_message`. + channel_id: Optional[:class:`int`] + The ID of the channel or thread to send the alert message to, if any. + Passing this sets :attr:`type` to :attr:`~AutoModRuleActionType.send_alert_message`. + duration: Optional[:class:`datetime.timedelta`] + The duration of the timeout to apply, if any. + Has a maximum of 28 days. + Passing this sets :attr:`type` to :attr:`~AutoModRuleActionType.timeout`. + custom_message: Optional[:class:`str`] + A custom message which will be shown to a user when their message is blocked. + Passing this sets :attr:`type` to :attr:`~AutoModRuleActionType.block_message`. + + .. versionadded:: 2.2 + """ + + __slots__ = ('type', 'channel_id', 'duration', 'custom_message') + + @overload + def __init__(self, *, channel_id: Optional[int] = ...) -> None: + ... + + @overload + def __init__(self, *, duration: Optional[datetime.timedelta] = ...) -> None: + ... + + @overload + def __init__(self, *, custom_message: Optional[str] = ...) -> None: + ... + + def __init__( + self, + *, + channel_id: Optional[int] = None, + duration: Optional[datetime.timedelta] = None, + custom_message: Optional[str] = None, + ) -> None: + self.channel_id: Optional[int] = channel_id + self.duration: Optional[datetime.timedelta] = duration + self.custom_message: Optional[str] = custom_message + + if sum(v is None for v in (channel_id, duration, custom_message)) < 2: + raise ValueError('Only one of channel_id, duration, or custom_message can be passed.') + + self.type: AutoModRuleActionType = AutoModRuleActionType.block_message + if channel_id: + self.type = AutoModRuleActionType.send_alert_message + elif duration: + self.type = AutoModRuleActionType.timeout + + def __repr__(self) -> str: + return f'' + + @classmethod + def from_data(cls, data: AutoModerationActionPayload) -> Self: + if data['type'] == AutoModRuleActionType.timeout.value: + duration_seconds = data['metadata']['duration_seconds'] + return cls(duration=datetime.timedelta(seconds=duration_seconds)) + elif data['type'] == AutoModRuleActionType.send_alert_message.value: + channel_id = int(data['metadata']['channel_id']) + return cls(channel_id=channel_id) + return cls(custom_message=data.get('metadata', {}).get('custom_message')) + + def to_dict(self) -> Dict[str, Any]: + ret = {'type': self.type.value, 'metadata': {}} + if self.type is AutoModRuleActionType.block_message and self.custom_message is not None: + ret['metadata'] = {'custom_message': self.custom_message} + elif self.type is AutoModRuleActionType.timeout: + ret['metadata'] = {'duration_seconds': int(self.duration.total_seconds())} # type: ignore # duration cannot be None here + elif self.type is AutoModRuleActionType.send_alert_message: + ret['metadata'] = {'channel_id': str(self.channel_id)} + return ret + + +class AutoModTrigger: + r"""Represents a trigger for an auto moderation rule. + + The following table illustrates relevant attributes for each :class:`AutoModRuleTriggerType`: + + +-----------------------------------------------+------------------------------------------------+ + | Type | Attributes | + +===============================================+================================================+ + | :attr:`AutoModRuleTriggerType.keyword` | :attr:`keyword_filter`, :attr:`regex_patterns`,| + | | :attr:`allow_list` | + +-----------------------------------------------+------------------------------------------------+ + | :attr:`AutoModRuleTriggerType.spam` | | + +-----------------------------------------------+------------------------------------------------+ + | :attr:`AutoModRuleTriggerType.keyword_preset` | :attr:`presets`\, :attr:`allow_list` | + +-----------------------------------------------+------------------------------------------------+ + | :attr:`AutoModRuleTriggerType.mention_spam` | :attr:`mention_limit` | + +-----------------------------------------------+------------------------------------------------+ + + .. versionadded:: 2.0 + + Attributes + ----------- + type: :class:`AutoModRuleTriggerType` + The type of trigger. + keyword_filter: List[:class:`str`] + The list of strings that will trigger the keyword filter. Maximum of 1000. + Keywords can only be up to 60 characters in length. + + This could be combined with :attr:`regex_patterns`. + regex_patterns: List[:class:`str`] + The regex pattern that will trigger the filter. The syntax is based off of + `Rust's regex syntax `_. + Maximum of 10. Regex strings can only be up to 260 characters in length. + + This could be combined with :attr:`keyword_filter` and/or :attr:`allow_list` + + .. versionadded:: 2.1 + presets: :class:`AutoModPresets` + The presets used with the preset keyword filter. + allow_list: List[:class:`str`] + The list of words that are exempt from the commonly flagged words. Maximum of 100. + Keywords can only be up to 60 characters in length. + mention_limit: :class:`int` + The total number of user and role mentions a message can contain. + Has a maximum of 50. + """ + + __slots__ = ( + 'type', + 'keyword_filter', + 'presets', + 'allow_list', + 'mention_limit', + 'regex_patterns', + ) + + def __init__( + self, + *, + type: Optional[AutoModRuleTriggerType] = None, + keyword_filter: Optional[List[str]] = None, + presets: Optional[AutoModPresets] = None, + allow_list: Optional[List[str]] = None, + mention_limit: Optional[int] = None, + regex_patterns: Optional[List[str]] = None, + ) -> None: + if type is None and sum(arg is not None for arg in (keyword_filter or regex_patterns, presets, mention_limit)) > 1: + raise ValueError('Please pass only one of keyword_filter, regex_patterns, presets, or mention_limit.') + + if type is not None: + self.type = type + elif keyword_filter is not None or regex_patterns is not None: + self.type = AutoModRuleTriggerType.keyword + elif presets is not None: + self.type = AutoModRuleTriggerType.keyword_preset + elif mention_limit is not None: + self.type = AutoModRuleTriggerType.mention_spam + else: + raise ValueError( + 'Please pass the trigger type explicitly if not using keyword_filter, presets, or mention_limit.' + ) + + self.keyword_filter: List[str] = keyword_filter if keyword_filter is not None else [] + self.presets: AutoModPresets = presets if presets is not None else AutoModPresets() + self.allow_list: List[str] = allow_list if allow_list is not None else [] + self.mention_limit: int = mention_limit if mention_limit is not None else 0 + self.regex_patterns: List[str] = regex_patterns if regex_patterns is not None else [] + + def __repr__(self) -> str: + data = self.to_metadata_dict() + if data: + joined = ' '.join(f'{k}={v!r}' for k, v in data.items()) + return f'' + + return f'' + + @classmethod + def from_data(cls, type: int, data: Optional[AutoModerationTriggerMetadataPayload]) -> Self: + type_ = try_enum(AutoModRuleTriggerType, type) + if data is None: + return cls(type=type_) + elif type_ is AutoModRuleTriggerType.keyword: + return cls( + type=type_, + keyword_filter=data.get('keyword_filter'), + regex_patterns=data.get('regex_patterns'), + allow_list=data.get('allow_list'), + ) + elif type_ is AutoModRuleTriggerType.keyword_preset: + return cls( + type=type_, presets=AutoModPresets._from_value(data.get('presets', [])), allow_list=data.get('allow_list') + ) + elif type_ is AutoModRuleTriggerType.mention_spam: + return cls(type=type_, mention_limit=data.get('mention_total_limit')) + else: + return cls(type=type_) + + def to_metadata_dict(self) -> Optional[Dict[str, Any]]: + if self.type is AutoModRuleTriggerType.keyword: + return { + 'keyword_filter': self.keyword_filter, + 'regex_patterns': self.regex_patterns, + 'allow_list': self.allow_list, + } + elif self.type is AutoModRuleTriggerType.keyword_preset: + return {'presets': self.presets.to_array(), 'allow_list': self.allow_list} + elif self.type is AutoModRuleTriggerType.mention_spam: + return {'mention_total_limit': self.mention_limit} + + +class AutoModRule: + """Represents an auto moderation rule. + + .. versionadded:: 2.0 + + Attributes + ----------- + id: :class:`int` + The ID of the rule. + guild: :class:`Guild` + The guild the rule is for. + name: :class:`str` + The name of the rule. + creator_id: :class:`int` + The ID of the user that created the rule. + trigger: :class:`AutoModTrigger` + The rule's trigger. + enabled: :class:`bool` + Whether the rule is enabled. + exempt_role_ids: Set[:class:`int`] + The IDs of the roles that are exempt from the rule. + exempt_channel_ids: Set[:class:`int`] + The IDs of the channels that are exempt from the rule. + """ + + __slots__ = ( + '_state', + '_cs_exempt_roles', + '_cs_exempt_channels', + '_cs_actions', + 'id', + 'guild', + 'name', + 'creator_id', + 'event_type', + 'trigger', + 'enabled', + 'exempt_role_ids', + 'exempt_channel_ids', + '_actions', + ) + + def __init__(self, *, data: AutoModerationRulePayload, guild: Guild, state: ConnectionState) -> None: + self._state: ConnectionState = state + self.guild: Guild = guild + self.id: int = int(data['id']) + self.name: str = data['name'] + self.creator_id = int(data['creator_id']) + self.event_type: AutoModRuleEventType = try_enum(AutoModRuleEventType, data['event_type']) + self.trigger: AutoModTrigger = AutoModTrigger.from_data(data['trigger_type'], data=data.get('trigger_metadata')) + self.enabled: bool = data['enabled'] + self.exempt_role_ids: Set[int] = {int(role_id) for role_id in data['exempt_roles']} + self.exempt_channel_ids: Set[int] = {int(channel_id) for channel_id in data['exempt_channels']} + self._actions: List[AutoModerationActionPayload] = data['actions'] + + def __repr__(self) -> str: + return f'' + + def to_dict(self) -> AutoModerationRulePayload: + ret: AutoModerationRulePayload = { + 'id': str(self.id), + 'guild_id': str(self.guild.id), + 'name': self.name, + 'creator_id': str(self.creator_id), + 'event_type': self.event_type.value, + 'trigger_type': self.trigger.type.value, + 'trigger_metadata': self.trigger.to_metadata_dict(), + 'actions': [action.to_dict() for action in self.actions], + 'enabled': self.enabled, + 'exempt_roles': [str(role_id) for role_id in self.exempt_role_ids], + 'exempt_channels': [str(channel_id) for channel_id in self.exempt_channel_ids], + } # type: ignore # trigger types break the flow here. + + return ret + + @property + def creator(self) -> Optional[Member]: + """Optional[:class:`Member`]: The member that created this rule.""" + return self.guild.get_member(self.creator_id) + + @cached_slot_property('_cs_exempt_roles') + def exempt_roles(self) -> List[Role]: + """List[:class:`Role`]: The roles that are exempt from this rule.""" + result = [] + get_role = self.guild.get_role + for role_id in self.exempt_role_ids: + role = get_role(role_id) + if role is not None: + result.append(role) + + return utils._unique(result) + + @cached_slot_property('_cs_exempt_channels') + def exempt_channels(self) -> List[Union[GuildChannel, Thread]]: + """List[Union[:class:`abc.GuildChannel`, :class:`Thread`]]: The channels that are exempt from this rule.""" + it = filter(None, map(self.guild._resolve_channel, self.exempt_channel_ids)) + return utils._unique(it) + + @cached_slot_property('_cs_actions') + def actions(self) -> List[AutoModRuleAction]: + """List[:class:`AutoModRuleAction`]: The actions that are taken when this rule is triggered.""" + return [AutoModRuleAction.from_data(action) for action in self._actions] + + def is_exempt(self, obj: Snowflake, /) -> bool: + """Check if an object is exempt from the automod rule. + + Parameters + ----------- + obj: :class:`abc.Snowflake` + The role, channel, or thread to check. + + Returns + -------- + :class:`bool` + Whether the object is exempt from the automod rule. + """ + return obj.id in self.exempt_channel_ids or obj.id in self.exempt_role_ids + + async def edit( + self, + *, + name: str = MISSING, + event_type: AutoModRuleEventType = MISSING, + actions: List[AutoModRuleAction] = MISSING, + trigger: AutoModTrigger = MISSING, + enabled: bool = MISSING, + exempt_roles: Sequence[Snowflake] = MISSING, + exempt_channels: Sequence[Snowflake] = MISSING, + reason: str = MISSING, + ) -> Self: + """|coro| + + Edits this auto moderation rule. + + You must have :attr:`Permissions.manage_guild` to edit rules. + + Parameters + ----------- + name: :class:`str` + The new name to change to. + event_type: :class:`AutoModRuleEventType` + The new event type to change to. + actions: List[:class:`AutoModRuleAction`] + The new rule actions to update. + trigger: :class:`AutoModTrigger` + The new trigger to update. + You can only change the trigger metadata, not the type. + enabled: :class:`bool` + Whether the rule should be enabled or not. + exempt_roles: Sequence[:class:`abc.Snowflake`] + The new roles to exempt from the rule. + exempt_channels: Sequence[:class:`abc.Snowflake`] + The new channels to exempt from the rule. + reason: :class:`str` + The reason for updating this rule. Shows up on the audit log. + + Raises + ------- + Forbidden + You do not have permission to edit this rule. + HTTPException + Editing the rule failed. + + Returns + -------- + :class:`AutoModRule` + The updated auto moderation rule. + """ + payload = {} + if actions is not MISSING: + payload['actions'] = [action.to_dict() for action in actions] + + if name is not MISSING: + payload['name'] = name + + if event_type is not MISSING: + payload['event_type'] = event_type + + if trigger is not MISSING: + trigger_metadata = trigger.to_metadata_dict() + if trigger_metadata is not None: + payload['trigger_metadata'] = trigger_metadata + + if enabled is not MISSING: + payload['enabled'] = enabled + + if exempt_roles is not MISSING: + payload['exempt_roles'] = [x.id for x in exempt_roles] + + if exempt_channels is not MISSING: + payload['exempt_channels'] = [x.id for x in exempt_channels] + + data = await self._state.http.edit_auto_moderation_rule( + self.guild.id, + self.id, + reason=reason, + **payload, + ) + + return AutoModRule(data=data, guild=self.guild, state=self._state) + + async def delete(self, *, reason: str = MISSING) -> None: + """|coro| + + Deletes the auto moderation rule. + + You must have :attr:`Permissions.manage_guild` to delete rules. + + Parameters + ----------- + reason: :class:`str` + The reason for deleting this rule. Shows up on the audit log. + + Raises + ------- + Forbidden + You do not have permissions to delete the rule. + HTTPException + Deleting the rule failed. + """ + await self._state.http.delete_auto_moderation_rule(self.guild.id, self.id, reason=reason) + + +class AutoModAction: + """Represents an action that was taken as the result of a moderation rule. + + .. versionadded:: 2.0 + + Attributes + ----------- + action: :class:`AutoModRuleAction` + The action that was taken. + message_id: Optional[:class:`int`] + The message ID that triggered the action. This is only available if the + action is done on an edited message. + rule_id: :class:`int` + The ID of the rule that was triggered. + rule_trigger_type: :class:`AutoModRuleTriggerType` + The trigger type of the rule that was triggered. + guild_id: :class:`int` + The ID of the guild where the rule was triggered. + user_id: :class:`int` + The ID of the user that triggered the rule. + channel_id: :class:`int` + The ID of the channel where the rule was triggered. + alert_system_message_id: Optional[:class:`int`] + The ID of the system message that was sent to the predefined alert channel. + content: :class:`str` + The content of the message that triggered the rule. + Requires the :attr:`Intents.message_content` or it will always return an empty string. + matched_keyword: Optional[:class:`str`] + The matched keyword from the triggering message. + matched_content: Optional[:class:`str`] + The matched content from the triggering message. + Requires the :attr:`Intents.message_content` or it will always return ``None``. + """ + + __slots__ = ( + '_state', + 'action', + 'rule_id', + 'rule_trigger_type', + 'guild_id', + 'user_id', + 'channel_id', + 'message_id', + 'alert_system_message_id', + 'content', + 'matched_keyword', + 'matched_content', + ) + + def __init__(self, *, data: AutoModerationActionExecutionPayload, state: ConnectionState) -> None: + self._state: ConnectionState = state + self.message_id: Optional[int] = utils._get_as_snowflake(data, 'message_id') + self.action: AutoModRuleAction = AutoModRuleAction.from_data(data['action']) + self.rule_id: int = int(data['rule_id']) + self.rule_trigger_type: AutoModRuleTriggerType = try_enum(AutoModRuleTriggerType, data['rule_trigger_type']) + self.guild_id: int = int(data['guild_id']) + self.channel_id: Optional[int] = utils._get_as_snowflake(data, 'channel_id') + self.user_id: int = int(data['user_id']) + self.alert_system_message_id: Optional[int] = utils._get_as_snowflake(data, 'alert_system_message_id') + self.content: str = data.get('content', '') + self.matched_keyword: Optional[str] = data['matched_keyword'] + self.matched_content: Optional[str] = data.get('matched_content') + + def __repr__(self) -> str: + return f'' + + @property + def guild(self) -> Guild: + """:class:`Guild`: The guild this action was taken in.""" + return self._state._get_or_create_unavailable_guild(self.guild_id) + + @property + def channel(self) -> Optional[Union[GuildChannel, Thread]]: + """Optional[Union[:class:`abc.GuildChannel`, :class:`Thread`]]: The channel this action was taken in.""" + if self.channel_id: + return self.guild.get_channel_or_thread(self.channel_id) + return None + + @property + def member(self) -> Optional[Member]: + """Optional[:class:`Member`]: The member this action was taken against /who triggered this rule.""" + return self.guild.get_member(self.user_id) + + async def fetch_rule(self) -> AutoModRule: + """|coro| + + Fetch the rule whose action was taken. + + You must have :attr:`Permissions.manage_guild` to do this. + + Raises + ------- + Forbidden + You do not have permissions to view the rule. + HTTPException + Fetching the rule failed. + + Returns + -------- + :class:`AutoModRule` + The rule that was executed. + """ + + data = await self._state.http.get_auto_moderation_rule(self.guild.id, self.rule_id) + return AutoModRule(data=data, guild=self.guild, state=self._state) diff --git a/dist/ba_data/python-site-packages/discord/backoff.py b/dist/ba_data/python-site-packages/discord/backoff.py index 0f49d155..cfb93ad2 100644 --- a/dist/ba_data/python-site-packages/discord/backoff.py +++ b/dist/ba_data/python-site-packages/discord/backoff.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,10 +22,23 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + + import time import random +from typing import Callable, Generic, Literal, TypeVar, overload, Union + +T = TypeVar('T', bool, Literal[True], Literal[False]) + +# fmt: off +__all__ = ( + 'ExponentialBackoff', +) +# fmt: on -class ExponentialBackoff: + +class ExponentialBackoff(Generic[T]): """An implementation of the exponential backoff algorithm Provides a convenient interface to implement an exponential backoff @@ -49,21 +60,33 @@ class ExponentialBackoff: number in between may be returned. """ - def __init__(self, base=1, *, integral=False): - self._base = base + def __init__(self, base: int = 1, *, integral: T = False): + self._base: int = base - self._exp = 0 - self._max = 10 - self._reset_time = base * 2 ** 11 - self._last_invocation = time.monotonic() + self._exp: int = 0 + self._max: int = 10 + self._reset_time: int = base * 2**11 + self._last_invocation: float = time.monotonic() # Use our own random instance to avoid messing with global one rand = random.Random() rand.seed() - self._randfunc = rand.randrange if integral else rand.uniform + self._randfunc: Callable[..., Union[int, float]] = rand.randrange if integral else rand.uniform + + @overload + def delay(self: ExponentialBackoff[Literal[False]]) -> float: + ... + + @overload + def delay(self: ExponentialBackoff[Literal[True]]) -> int: + ... + + @overload + def delay(self: ExponentialBackoff[bool]) -> Union[int, float]: + ... - def delay(self): + def delay(self) -> Union[int, float]: """Compute the next delay Returns the next delay to wait according to the exponential @@ -82,4 +105,4 @@ def delay(self): self._exp = 0 self._exp = min(self._exp + 1, self._max) - return self._randfunc(0, self._base * 2 ** self._exp) + return self._randfunc(0, self._base * 2**self._exp) diff --git a/dist/ba_data/python-site-packages/discord/calls.py b/dist/ba_data/python-site-packages/discord/calls.py deleted file mode 100644 index 2006b30a..00000000 --- a/dist/ba_data/python-site-packages/discord/calls.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -The MIT License (MIT) - -Copyright (c) 2015-present Rapptz - -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 datetime - -from . import utils -from .enums import VoiceRegion, try_enum -from .member import VoiceState - -class CallMessage: - """Represents a group call message from Discord. - - This is only received in cases where the message type is equivalent to - :attr:`MessageType.call`. - - .. deprecated:: 1.7 - - Attributes - ----------- - ended_timestamp: Optional[:class:`datetime.datetime`] - A naive UTC datetime object that represents the time that the call has ended. - participants: List[:class:`User`] - The list of users that are participating in this call. - message: :class:`Message` - The message associated with this call message. - """ - - def __init__(self, message, **kwargs): - self.message = message - self.ended_timestamp = utils.parse_time(kwargs.get('ended_timestamp')) - self.participants = kwargs.get('participants') - - @property - def call_ended(self): - """:class:`bool`: Indicates if the call has ended. - - .. deprecated:: 1.7 - """ - return self.ended_timestamp is not None - - @property - def channel(self): - r""":class:`GroupChannel`\: The private channel associated with this message. - - .. deprecated:: 1.7 - """ - return self.message.channel - - @property - def duration(self): - """Queries the duration of the call. - - If the call has not ended then the current duration will - be returned. - - .. deprecated:: 1.7 - - Returns - --------- - :class:`datetime.timedelta` - The timedelta object representing the duration. - """ - if self.ended_timestamp is None: - return datetime.datetime.utcnow() - self.message.created_at - else: - return self.ended_timestamp - self.message.created_at - -class GroupCall: - """Represents the actual group call from Discord. - - This is accompanied with a :class:`CallMessage` denoting the information. - - .. deprecated:: 1.7 - - Attributes - ----------- - call: :class:`CallMessage` - The call message associated with this group call. - unavailable: :class:`bool` - Denotes if this group call is unavailable. - ringing: List[:class:`User`] - A list of users that are currently being rung to join the call. - region: :class:`VoiceRegion` - The guild region the group call is being hosted on. - """ - - def __init__(self, **kwargs): - self.call = kwargs.get('call') - self.unavailable = kwargs.get('unavailable') - self._voice_states = {} - - for state in kwargs.get('voice_states', []): - self._update_voice_state(state) - - self._update(**kwargs) - - def _update(self, **kwargs): - self.region = try_enum(VoiceRegion, kwargs.get('region')) - lookup = {u.id: u for u in self.call.channel.recipients} - me = self.call.channel.me - lookup[me.id] = me - self.ringing = list(filter(None, map(lookup.get, kwargs.get('ringing', [])))) - - def _update_voice_state(self, data): - user_id = int(data['user_id']) - # left the voice channel? - if data['channel_id'] is None: - self._voice_states.pop(user_id, None) - else: - self._voice_states[user_id] = VoiceState(data=data, channel=self.channel) - - @property - def connected(self): - """List[:class:`User`]: A property that returns all users that are currently in this call. - - .. deprecated:: 1.7 - """ - ret = [u for u in self.channel.recipients if self.voice_state_for(u) is not None] - me = self.channel.me - if self.voice_state_for(me) is not None: - ret.append(me) - - return ret - - @property - def channel(self): - r""":class:`GroupChannel`\: Returns the channel the group call is in. - - .. deprecated:: 1.7 - """ - return self.call.channel - - @utils.deprecated() - def voice_state_for(self, user): - """Retrieves the :class:`VoiceState` for a specified :class:`User`. - - If the :class:`User` has no voice state then this function returns - ``None``. - - .. deprecated:: 1.7 - - Parameters - ------------ - user: :class:`User` - The user to retrieve the voice state for. - - Returns - -------- - Optional[:class:`VoiceState`] - The voice state associated with this user. - """ - - return self._voice_states.get(user.id) diff --git a/dist/ba_data/python-site-packages/discord/channel.py b/dist/ba_data/python-site-packages/discord/channel.py index 3510b80d..8c212c0c 100644 --- a/dist/ba_data/python-site-packages/discord/channel.py +++ b/dist/ba_data/python-site-packages/discord/channel.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,16 +22,42 @@ DEALINGS IN THE SOFTWARE. """ -import time -import asyncio +from __future__ import annotations + +from typing import ( + Any, + AsyncIterator, + Callable, + Dict, + Iterable, + List, + Literal, + Mapping, + NamedTuple, + Optional, + TYPE_CHECKING, + Sequence, + Tuple, + TypeVar, + Union, + overload, +) +import datetime import discord.abc -from .permissions import Permissions -from .enums import ChannelType, try_enum, VoiceRegion +from .scheduled_event import ScheduledEvent +from .permissions import PermissionOverwrite, Permissions +from .enums import ChannelType, ForumLayoutType, ForumOrderType, PrivacyLevel, try_enum, VideoQualityMode, EntityType from .mixins import Hashable from . import utils +from .utils import MISSING from .asset import Asset -from .errors import ClientException, NoMoreItems, InvalidArgument +from .errors import ClientException +from .stage_instance import StageInstance +from .threads import Thread +from .partial_emoji import _EmojiTag, PartialEmoji +from .flags import ChannelFlags +from .http import handle_message_parameters __all__ = ( 'TextChannel', @@ -41,14 +65,50 @@ 'StageChannel', 'DMChannel', 'CategoryChannel', - 'StoreChannel', + 'ForumTag', + 'ForumChannel', 'GroupChannel', - '_channel_factory', + 'PartialMessageable', ) -async def _single_delete_strategy(messages): - for m in messages: - await m.delete() +if TYPE_CHECKING: + from typing_extensions import Self + + from .types.threads import ThreadArchiveDuration + from .role import Role + from .object import Object + from .member import Member, VoiceState + from .abc import Snowflake, SnowflakeTime + from .embeds import Embed + from .message import Message, PartialMessage, EmojiInputType + from .mentions import AllowedMentions + from .webhook import Webhook + from .state import ConnectionState + from .sticker import GuildSticker, StickerItem + from .file import File + from .user import ClientUser, User, BaseUser + from .guild import Guild, GuildChannel as GuildChannelType + from .ui.view import View + from .types.channel import ( + TextChannel as TextChannelPayload, + NewsChannel as NewsChannelPayload, + VoiceChannel as VoiceChannelPayload, + StageChannel as StageChannelPayload, + DMChannel as DMChannelPayload, + CategoryChannel as CategoryChannelPayload, + GroupDMChannel as GroupChannelPayload, + ForumChannel as ForumChannelPayload, + ForumTag as ForumTagPayload, + ) + from .types.snowflake import SnowflakeList + + OverwriteKeyT = TypeVar('OverwriteKeyT', Role, BaseUser, Object, Union[Role, Member, Object]) + + +class ThreadWithMessage(NamedTuple): + thread: Thread + message: Message + class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable): """Represents a Discord guild text channel. @@ -91,60 +151,93 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable): *not* point to an existing or valid message. slowmode_delay: :class:`int` The number of seconds a member must wait between sending messages - in this channel. A value of `0` denotes that it is disabled. + in this channel. A value of ``0`` denotes that it is disabled. Bots and users with :attr:`~Permissions.manage_channels` or :attr:`~Permissions.manage_messages` bypass slowmode. - """ + nsfw: :class:`bool` + If the channel is marked as "not safe for work" or "age restricted". + default_auto_archive_duration: :class:`int` + The default auto archive duration in minutes for threads created in this channel. - __slots__ = ('name', 'id', 'guild', 'topic', '_state', 'nsfw', - 'category_id', 'position', 'slowmode_delay', '_overwrites', - '_type', 'last_message_id') + .. versionadded:: 2.0 + default_thread_slowmode_delay: :class:`int` + The default slowmode delay in seconds for threads created in this channel. - def __init__(self, *, state, guild, data): - self._state = state - self.id = int(data['id']) - self._type = data['type'] + .. versionadded:: 2.3 + """ + + __slots__ = ( + 'name', + 'id', + 'guild', + 'topic', + '_state', + 'nsfw', + 'category_id', + 'position', + 'slowmode_delay', + '_overwrites', + '_type', + 'last_message_id', + 'default_auto_archive_duration', + 'default_thread_slowmode_delay', + ) + + def __init__(self, *, state: ConnectionState, guild: Guild, data: Union[TextChannelPayload, NewsChannelPayload]): + self._state: ConnectionState = state + self.id: int = int(data['id']) + self._type: Literal[0, 5] = data['type'] self._update(guild, data) - def __repr__(self): + def __repr__(self) -> str: attrs = [ ('id', self.id), ('name', self.name), ('position', self.position), ('nsfw', self.nsfw), ('news', self.is_news()), - ('category_id', self.category_id) + ('category_id', self.category_id), ] - return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) - - def _update(self, guild, data): - self.guild = guild - self.name = data['name'] - self.category_id = utils._get_as_snowflake(data, 'parent_id') - self.topic = data.get('topic') - self.position = data['position'] - self.nsfw = data.get('nsfw', False) + joined = ' '.join('%s=%r' % t for t in attrs) + return f'<{self.__class__.__name__} {joined}>' + + def _update(self, guild: Guild, data: Union[TextChannelPayload, NewsChannelPayload]) -> None: + self.guild: Guild = guild + self.name: str = data['name'] + self.category_id: Optional[int] = utils._get_as_snowflake(data, 'parent_id') + self.topic: Optional[str] = data.get('topic') + self.position: int = data['position'] + self.nsfw: bool = data.get('nsfw', False) # Does this need coercion into `int`? No idea yet. - self.slowmode_delay = data.get('rate_limit_per_user', 0) - self._type = data.get('type', self._type) - self.last_message_id = utils._get_as_snowflake(data, 'last_message_id') + self.slowmode_delay: int = data.get('rate_limit_per_user', 0) + self.default_auto_archive_duration: ThreadArchiveDuration = data.get('default_auto_archive_duration', 1440) + self.default_thread_slowmode_delay: int = data.get('default_thread_rate_limit_per_user', 0) + self._type: Literal[0, 5] = data.get('type', self._type) + self.last_message_id: Optional[int] = utils._get_as_snowflake(data, 'last_message_id') self._fill_overwrites(data) - async def _get_channel(self): + async def _get_channel(self) -> Self: return self @property - def type(self): + def type(self) -> Literal[ChannelType.text, ChannelType.news]: """:class:`ChannelType`: The channel's Discord type.""" - return try_enum(ChannelType, self._type) + if self._type == 0: + return ChannelType.text + return ChannelType.news @property - def _sorting_bucket(self): + def _sorting_bucket(self) -> int: return ChannelType.text.value + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return None + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) - def permissions_for(self, member): - base = super().permissions_for(member) + def permissions_for(self, obj: Union[Member, Role], /) -> Permissions: + base = super().permissions_for(obj) + self._apply_implicit_permissions(base) # text channels do not have voice related permissions denied = Permissions.voice() @@ -152,21 +245,29 @@ def permissions_for(self, member): return base @property - def members(self): + def members(self) -> List[Member]: """List[:class:`Member`]: Returns all members that can see this channel.""" return [m for m in self.guild.members if self.permissions_for(m).read_messages] - def is_nsfw(self): + @property + def threads(self) -> List[Thread]: + """List[:class:`Thread`]: Returns all the threads that you can see. + + .. versionadded:: 2.0 + """ + return [thread for thread in self.guild._threads.values() if thread.parent_id == self.id] + + def is_nsfw(self) -> bool: """:class:`bool`: Checks if the channel is NSFW.""" return self.nsfw - def is_news(self): + def is_news(self) -> bool: """:class:`bool`: Checks if the channel is a news channel.""" return self._type == ChannelType.news.value @property - def last_message(self): - """Fetches the last message from this channel in cache. + def last_message(self) -> Optional[Message]: + """Retrieves the last message from this channel in cache. The message might not be valid or point to an existing message. @@ -185,13 +286,39 @@ def last_message(self): """ return self._state._get_message(self.last_message_id) if self.last_message_id else None - async def edit(self, *, reason=None, **options): + @overload + async def edit(self) -> Optional[TextChannel]: + ... + + @overload + async def edit(self, *, position: int, reason: Optional[str] = ...) -> None: + ... + + @overload + async def edit( + self, + *, + reason: Optional[str] = ..., + name: str = ..., + topic: str = ..., + position: int = ..., + nsfw: bool = ..., + sync_permissions: bool = ..., + category: Optional[CategoryChannel] = ..., + slowmode_delay: int = ..., + default_auto_archive_duration: ThreadArchiveDuration = ..., + default_thread_slowmode_delay: int = ..., + type: ChannelType = ..., + overwrites: Mapping[OverwriteKeyT, PermissionOverwrite] = ..., + ) -> TextChannel: + ... + + async def edit(self, *, reason: Optional[str] = None, **options: Any) -> Optional[TextChannel]: """|coro| Edits the channel. - You must have the :attr:`~Permissions.manage_channels` permission to - use this. + You must have :attr:`~Permissions.manage_channels` to do this. .. versionchanged:: 1.3 The ``overwrites`` keyword-only parameter was added. @@ -199,6 +326,13 @@ async def edit(self, *, reason=None, **options): .. versionchanged:: 1.4 The ``type`` keyword-only parameter was added. + .. versionchanged:: 2.0 + Edits are no longer in-place, the newly edited channel is returned instead. + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` or + :exc:`ValueError` instead of ``InvalidArgument``. + Parameters ---------- name: :class:`str` @@ -217,38 +351,55 @@ async def edit(self, *, reason=None, **options): category. slowmode_delay: :class:`int` Specifies the slowmode rate limit for user in this channel, in seconds. - A value of `0` disables slowmode. The maximum value possible is `21600`. + A value of ``0`` disables slowmode. The maximum value possible is ``21600``. type: :class:`ChannelType` Change the type of this text channel. Currently, only conversion between :attr:`ChannelType.text` and :attr:`ChannelType.news` is supported. This is only available to guilds that contain ``NEWS`` in :attr:`Guild.features`. reason: Optional[:class:`str`] The reason for editing this channel. Shows up on the audit log. - overwrites: :class:`dict` - A :class:`dict` of target (either a role or a member) to + overwrites: :class:`Mapping` + A :class:`Mapping` of target (either a role or a member) to :class:`PermissionOverwrite` to apply to the channel. + default_auto_archive_duration: :class:`int` + The new default auto archive duration in minutes for threads created in this channel. + Must be one of ``60``, ``1440``, ``4320``, or ``10080``. + + .. versionadded:: 2.0 + default_thread_slowmode_delay: :class:`int` + The new default slowmode delay in seconds for threads created in this channel. + .. versionadded:: 2.3 Raises ------ - InvalidArgument - If position is less than 0 or greater than the number of channels, or if - the permission overwrite information is not in proper form. + ValueError + The new ``position`` is less than 0 or greater than the number of channels. + TypeError + The permission overwrite information is not in proper form. Forbidden You do not have permissions to edit the channel. HTTPException Editing the channel failed. + + Returns + -------- + Optional[:class:`.TextChannel`] + The newly edited text channel. If the edit was only positional + then ``None`` is returned instead. """ - await self._edit(options, reason=reason) + + payload = await self._edit(options, reason=reason) + if payload is not None: + # the payload will always be the proper channel payload + return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore @utils.copy_doc(discord.abc.GuildChannel.clone) - async def clone(self, *, name=None, reason=None): - return await self._clone_impl({ - 'topic': self.topic, - 'nsfw': self.nsfw, - 'rate_limit_per_user': self.slowmode_delay - }, name=name, reason=reason) - - async def delete_messages(self, messages): + async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> TextChannel: + return await self._clone_impl( + {'topic': self.topic, 'nsfw': self.nsfw, 'rate_limit_per_user': self.slowmode_delay}, name=name, reason=reason + ) + + async def delete_messages(self, messages: Iterable[Snowflake], *, reason: Optional[str] = None) -> None: """|coro| Deletes a list of messages. This is similar to :meth:`Message.delete` @@ -261,23 +412,27 @@ async def delete_messages(self, messages): You cannot bulk delete more than 100 messages or messages that are older than 14 days old. - You must have the :attr:`~Permissions.manage_messages` permission to - use this. + You must have :attr:`~Permissions.manage_messages` to do this. + + .. versionchanged:: 2.0 - Usable only by bot accounts. + ``messages`` parameter is now positional-only. + + The ``reason`` keyword-only parameter was added. Parameters ----------- messages: Iterable[:class:`abc.Snowflake`] An iterable of messages denoting which ones to bulk delete. + reason: Optional[:class:`str`] + The reason for deleting the messages. Shows up on the audit log. Raises ------ ClientException The number of messages to delete was more than 100. Forbidden - You do not have proper permissions to delete the messages or - you're not using a bot account. + You do not have proper permissions to delete the messages. NotFound If single delete, then the message was already deleted. HTTPException @@ -287,34 +442,45 @@ async def delete_messages(self, messages): messages = list(messages) if len(messages) == 0: - return # do nothing + return # do nothing if len(messages) == 1: - message_id = messages[0].id + message_id: int = messages[0].id await self._state.http.delete_message(self.id, message_id) return if len(messages) > 100: raise ClientException('Can only bulk delete messages up to 100 messages') - message_ids = [m.id for m in messages] - await self._state.http.delete_messages(self.id, message_ids) - - async def purge(self, *, limit=100, check=None, before=None, after=None, around=None, oldest_first=False, bulk=True): + message_ids: SnowflakeList = [m.id for m in messages] + await self._state.http.delete_messages(self.id, message_ids, reason=reason) + + async def purge( + self, + *, + limit: Optional[int] = 100, + check: Callable[[Message], bool] = MISSING, + before: Optional[SnowflakeTime] = None, + after: Optional[SnowflakeTime] = None, + around: Optional[SnowflakeTime] = None, + oldest_first: Optional[bool] = None, + bulk: bool = True, + reason: Optional[str] = None, + ) -> List[Message]: """|coro| Purges a list of messages that meet the criteria given by the predicate ``check``. If a ``check`` is not provided then all messages are deleted without discrimination. - You must have the :attr:`~Permissions.manage_messages` permission to - delete messages even if they are your own (unless you are a user - account). The :attr:`~Permissions.read_message_history` permission is + You must have :attr:`~Permissions.manage_messages` to + delete messages even if they are your own. + Having :attr:`~Permissions.read_message_history` is also needed to retrieve message history. - Internally, this employs a different number of strategies depending - on the conditions met such as if a bulk delete is possible or if - the account is a user bot or not. + .. versionchanged:: 2.0 + + The ``reason`` keyword-only parameter was added. Examples --------- @@ -325,7 +491,7 @@ def is_me(m): return m.author == client.user deleted = await channel.purge(limit=100, check=is_me) - await channel.send('Deleted {} message(s)'.format(len(deleted))) + await channel.send(f'Deleted {len(deleted)} message(s)') Parameters ----------- @@ -346,8 +512,9 @@ def is_me(m): bulk: :class:`bool` If ``True``, use bulk delete. Setting this to ``False`` is useful for mass-deleting a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will - fall back to single delete if current account is a user bot (now deprecated), or if messages are - older than two weeks. + fall back to single delete if messages are older than two weeks. + reason: Optional[:class:`str`] + The reason for purging the messages. Shows up on the audit log. Raises ------- @@ -361,60 +528,24 @@ def is_me(m): List[:class:`.Message`] The list of messages that were deleted. """ - - if check is None: - check = lambda m: True - - iterator = self.history(limit=limit, before=before, after=after, oldest_first=oldest_first, around=around) - ret = [] - count = 0 - - minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22 - strategy = self.delete_messages if self._state.is_bot and bulk else _single_delete_strategy - - while True: - try: - msg = await iterator.next() - except NoMoreItems: - # no more messages to poll - if count >= 2: - # more than 2 messages -> bulk delete - to_delete = ret[-count:] - await strategy(to_delete) - elif count == 1: - # delete a single message - await ret[-1].delete() - - return ret - else: - if count == 100: - # we've reached a full 'queue' - to_delete = ret[-100:] - await strategy(to_delete) - count = 0 - await asyncio.sleep(1) - - if check(msg): - if msg.id < minimum_time: - # older than 14 days old - if count == 1: - await ret[-1].delete() - elif count >= 2: - to_delete = ret[-count:] - await strategy(to_delete) - - count = 0 - strategy = _single_delete_strategy - - count += 1 - ret.append(msg) - - async def webhooks(self): + return await discord.abc._purge_helper( + self, + limit=limit, + check=check, + before=before, + after=after, + around=around, + oldest_first=oldest_first, + bulk=bulk, + reason=reason, + ) + + async def webhooks(self) -> List[Webhook]: """|coro| Gets the list of webhooks from this channel. - Requires :attr:`~.Permissions.manage_webhooks` permissions. + You must have :attr:`~.Permissions.manage_webhooks` to do this. Raises ------- @@ -428,15 +559,16 @@ async def webhooks(self): """ from .webhook import Webhook + data = await self._state.http.channel_webhooks(self.id) return [Webhook.from_state(d, state=self._state) for d in data] - async def create_webhook(self, *, name, avatar=None, reason=None): + async def create_webhook(self, *, name: str, avatar: Optional[bytes] = None, reason: Optional[str] = None) -> Webhook: """|coro| Creates a webhook for this channel. - Requires :attr:`~.Permissions.manage_webhooks` permissions. + You must have :attr:`~.Permissions.manage_webhooks` to do this. .. versionchanged:: 1.1 Added the ``reason`` keyword-only parameter. @@ -465,14 +597,16 @@ async def create_webhook(self, *, name, avatar=None, reason=None): """ from .webhook import Webhook + if avatar is not None: - avatar = utils._bytes_to_base64_data(avatar) + avatar = utils._bytes_to_base64_data(avatar) # type: ignore # Silence reassignment error data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar, reason=reason) return Webhook.from_state(data, state=self._state) - async def follow(self, *, destination, reason=None): - """ + async def follow(self, *, destination: TextChannel, reason: Optional[str] = None) -> Webhook: + """|coro| + Follows a channel using a webhook. Only news channels can be followed. @@ -484,6 +618,10 @@ async def follow(self, *, destination, reason=None): .. versionadded:: 1.3 + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` instead of + ``InvalidArgument``. + Parameters ----------- destination: :class:`TextChannel` @@ -499,6 +637,10 @@ async def follow(self, *, destination, reason=None): Following the channel failed. Forbidden You do not have the permissions to create a webhook. + ClientException + The channel is not a news channel. + TypeError + The destination channel is not a text channel. Returns -------- @@ -510,13 +652,14 @@ async def follow(self, *, destination, reason=None): raise ClientException('The channel must be a news channel.') if not isinstance(destination, TextChannel): - raise InvalidArgument('Expected TextChannel received {0.__name__}'.format(type(destination))) + raise TypeError(f'Expected TextChannel received {destination.__class__.__name__}') from .webhook import Webhook + data = await self._state.http.follow_webhook(self.id, webhook_channel_id=destination.id, reason=reason) return Webhook._as_follower(data, channel=destination, user=self._state.user) - def get_partial_message(self, message_id): + def get_partial_message(self, message_id: int, /) -> PartialMessage: """Creates a :class:`PartialMessage` from the message ID. This is useful if you want to work with a message and only have its ID without @@ -524,6 +667,10 @@ def get_partial_message(self, message_id): .. versionadded:: 1.6 + .. versionchanged:: 2.0 + + ``message_id`` parameter is now positional-only. + Parameters ------------ message_id: :class:`int` @@ -536,42 +683,270 @@ def get_partial_message(self, message_id): """ from .message import PartialMessage + return PartialMessage(channel=self, id=message_id) -class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hashable): - __slots__ = ('name', 'id', 'guild', 'bitrate', 'user_limit', - '_state', 'position', '_overwrites', 'category_id', - 'rtc_region') + def get_thread(self, thread_id: int, /) -> Optional[Thread]: + """Returns a thread with the given ID. - def __init__(self, *, state, guild, data): - self._state = state - self.id = int(data['id']) + .. note:: + + This does not always retrieve archived threads, as they are not retained in the internal + cache. Use :func:`Guild.fetch_channel` instead. + + .. versionadded:: 2.0 + + Parameters + ----------- + thread_id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[:class:`Thread`] + The returned thread or ``None`` if not found. + """ + return self.guild.get_thread(thread_id) + + async def create_thread( + self, + *, + name: str, + message: Optional[Snowflake] = None, + auto_archive_duration: ThreadArchiveDuration = MISSING, + type: Optional[ChannelType] = None, + reason: Optional[str] = None, + invitable: bool = True, + slowmode_delay: Optional[int] = None, + ) -> Thread: + """|coro| + + Creates a thread in this text channel. + + To create a public thread, you must have :attr:`~discord.Permissions.create_public_threads`. + For a private thread, :attr:`~discord.Permissions.create_private_threads` is needed instead. + + .. versionadded:: 2.0 + + Parameters + ----------- + name: :class:`str` + The name of the thread. + message: Optional[:class:`abc.Snowflake`] + A snowflake representing the message to create the thread with. + If ``None`` is passed then a private thread is created. + Defaults to ``None``. + auto_archive_duration: :class:`int` + The duration in minutes before a thread is automatically hidden from the channel list. + If not provided, the channel's default auto archive duration is used. + + Must be one of ``60``, ``1440``, ``4320``, or ``10080``, if provided. + type: Optional[:class:`ChannelType`] + The type of thread to create. If a ``message`` is passed then this parameter + is ignored, as a thread created with a message is always a public thread. + By default this creates a private thread if this is ``None``. + reason: :class:`str` + The reason for creating a new thread. Shows up on the audit log. + invitable: :class:`bool` + Whether non-moderators can add users to the thread. Only applicable to private threads. + Defaults to ``True``. + slowmode_delay: Optional[:class:`int`] + Specifies the slowmode rate limit for user in this channel, in seconds. + The maximum value possible is ``21600``. By default no slowmode rate limit + if this is ``None``. + + Raises + ------- + Forbidden + You do not have permissions to create a thread. + HTTPException + Starting the thread failed. + + Returns + -------- + :class:`Thread` + The created thread + """ + + if type is None: + type = ChannelType.private_thread + + if message is None: + data = await self._state.http.start_thread_without_message( + self.id, + name=name, + auto_archive_duration=auto_archive_duration or self.default_auto_archive_duration, + type=type.value, + reason=reason, + invitable=invitable, + rate_limit_per_user=slowmode_delay, + ) + else: + data = await self._state.http.start_thread_with_message( + self.id, + message.id, + name=name, + auto_archive_duration=auto_archive_duration or self.default_auto_archive_duration, + reason=reason, + rate_limit_per_user=slowmode_delay, + ) + + return Thread(guild=self.guild, state=self._state, data=data) + + async def archived_threads( + self, + *, + private: bool = False, + joined: bool = False, + limit: Optional[int] = 100, + before: Optional[Union[Snowflake, datetime.datetime]] = None, + ) -> AsyncIterator[Thread]: + """Returns an :term:`asynchronous iterator` that iterates over all archived threads in this text channel, + in order of decreasing ID for joined threads, and decreasing :attr:`Thread.archive_timestamp` otherwise. + + You must have :attr:`~Permissions.read_message_history` to do this. If iterating over private threads + then :attr:`~Permissions.manage_threads` is also required. + + .. versionadded:: 2.0 + + Parameters + ----------- + limit: Optional[:class:`bool`] + The number of threads to retrieve. + If ``None``, retrieves every archived thread in the channel. Note, however, + that this would make it a slow operation. + before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Retrieve archived channels before the given date or ID. + private: :class:`bool` + Whether to retrieve private archived threads. + joined: :class:`bool` + Whether to retrieve private archived threads that you've joined. + You cannot set ``joined`` to ``True`` and ``private`` to ``False``. + + Raises + ------ + Forbidden + You do not have permissions to get archived threads. + HTTPException + The request to get the archived threads failed. + ValueError + ``joined`` was set to ``True`` and ``private`` was set to ``False``. You cannot retrieve public archived + threads that you have joined. + + Yields + ------- + :class:`Thread` + The archived threads. + """ + if joined and not private: + raise ValueError('Cannot retrieve joined public archived threads') + + before_timestamp = None + + if isinstance(before, datetime.datetime): + if joined: + before_timestamp = str(utils.time_snowflake(before, high=False)) + else: + before_timestamp = before.isoformat() + elif before is not None: + if joined: + before_timestamp = str(before.id) + else: + before_timestamp = utils.snowflake_time(before.id).isoformat() + + update_before = lambda data: data['thread_metadata']['archive_timestamp'] + endpoint = self.guild._state.http.get_public_archived_threads + + if joined: + update_before = lambda data: data['id'] + endpoint = self.guild._state.http.get_joined_private_archived_threads + elif private: + endpoint = self.guild._state.http.get_private_archived_threads + + while True: + retrieve = 100 + if limit is not None: + if limit <= 0: + return + retrieve = max(2, min(retrieve, limit)) + + data = await endpoint(self.id, before=before_timestamp, limit=retrieve) + + threads = data.get('threads', []) + for raw_thread in threads: + yield Thread(guild=self.guild, state=self.guild._state, data=raw_thread) + # Currently the API doesn't let you request less than 2 threads. + # Bail out early if we had to retrieve more than what the limit was. + if limit is not None: + limit -= 1 + if limit <= 0: + return + + if not data.get('has_more', False): + return + + before_timestamp = update_before(threads[-1]) + + +class VocalGuildChannel(discord.abc.Messageable, discord.abc.Connectable, discord.abc.GuildChannel, Hashable): + __slots__ = ( + 'name', + 'id', + 'guild', + 'nsfw', + 'bitrate', + 'user_limit', + '_state', + 'position', + 'slowmode_delay', + '_overwrites', + 'category_id', + 'rtc_region', + 'video_quality_mode', + 'last_message_id', + ) + + def __init__(self, *, state: ConnectionState, guild: Guild, data: Union[VoiceChannelPayload, StageChannelPayload]): + self._state: ConnectionState = state + self.id: int = int(data['id']) self._update(guild, data) - def _get_voice_client_key(self): + async def _get_channel(self) -> Self: + return self + + def _get_voice_client_key(self) -> Tuple[int, str]: return self.guild.id, 'guild_id' - def _get_voice_state_pair(self): + def _get_voice_state_pair(self) -> Tuple[int, int]: return self.guild.id, self.id - def _update(self, guild, data): - self.guild = guild - self.name = data['name'] - self.rtc_region = data.get('rtc_region') - if self.rtc_region: - self.rtc_region = try_enum(VoiceRegion, self.rtc_region) - self.category_id = utils._get_as_snowflake(data, 'parent_id') - self.position = data['position'] - self.bitrate = data.get('bitrate') - self.user_limit = data.get('user_limit') + def _update(self, guild: Guild, data: Union[VoiceChannelPayload, StageChannelPayload]) -> None: + self.guild: Guild = guild + self.name: str = data['name'] + self.nsfw: bool = data.get('nsfw', False) + self.rtc_region: Optional[str] = data.get('rtc_region') + self.video_quality_mode: VideoQualityMode = try_enum(VideoQualityMode, data.get('video_quality_mode', 1)) + self.category_id: Optional[int] = utils._get_as_snowflake(data, 'parent_id') + self.last_message_id: Optional[int] = utils._get_as_snowflake(data, 'last_message_id') + self.position: int = data['position'] + self.slowmode_delay = data.get('rate_limit_per_user', 0) + self.bitrate: int = data['bitrate'] + self.user_limit: int = data['user_limit'] self._fill_overwrites(data) @property - def _sorting_bucket(self): + def _sorting_bucket(self) -> int: return ChannelType.voice.value + def is_nsfw(self) -> bool: + """:class:`bool`: Checks if the channel is NSFW. + + .. versionadded:: 2.0 + """ + return self.nsfw + @property - def members(self): + def members(self) -> List[Member]: """List[:class:`Member`]: Returns all members that are currently inside this voice channel.""" ret = [] for user_id, state in self.guild._voice_states.items(): @@ -582,7 +957,7 @@ def members(self): return ret @property - def voice_states(self): + def voice_states(self) -> Dict[int, VoiceState]: """Returns a mapping of member IDs who have voice states in this channel. .. versionadded:: 1.3 @@ -597,11 +972,26 @@ def voice_states(self): Mapping[:class:`int`, :class:`VoiceState`] The mapping of member ID to a voice state. """ - return {key: value for key, value in self.guild._voice_states.items() if value.channel.id == self.id} + # fmt: off + return { + key: value + for key, value in self.guild._voice_states.items() + if value.channel and value.channel.id == self.id + } + # fmt: on + + @property + def scheduled_events(self) -> List[ScheduledEvent]: + """List[:class:`ScheduledEvent`]: Returns all scheduled events for this channel. + + .. versionadded:: 2.0 + """ + return [event for event in self.guild.scheduled_events if event.channel_id == self.id] @utils.copy_doc(discord.abc.GuildChannel.permissions_for) - def permissions_for(self, member): - base = super().permissions_for(member) + def permissions_for(self, obj: Union[Member, Role], /) -> Permissions: + base = super().permissions_for(obj) + self._apply_implicit_permissions(base) # voice channels cannot be edited by people who can't connect to them # It also implicitly denies all other voice perms @@ -611,135 +1001,260 @@ def permissions_for(self, member): base.value &= ~denied.value return base -class VoiceChannel(VocalGuildChannel): - """Represents a Discord guild voice channel. - - .. container:: operations + @property + def last_message(self) -> Optional[Message]: + """Retrieves the last message from this channel in cache. - .. describe:: x == y + The message might not be valid or point to an existing message. - Checks if two channels are equal. + .. versionadded:: 2.0 - .. describe:: x != y + .. admonition:: Reliable Fetching + :class: helpful - Checks if two channels are not equal. + For a slightly more reliable method of fetching the + last message, consider using either :meth:`history` + or :meth:`fetch_message` with the :attr:`last_message_id` + attribute. - .. describe:: hash(x) + Returns + --------- + Optional[:class:`Message`] + The last message in this channel or ``None`` if not found. + """ + return self._state._get_message(self.last_message_id) if self.last_message_id else None - Returns the channel's hash. + def get_partial_message(self, message_id: int, /) -> PartialMessage: + """Creates a :class:`PartialMessage` from the message ID. - .. describe:: str(x) + This is useful if you want to work with a message and only have its ID without + doing an unnecessary API call. - Returns the channel's name. + .. versionadded:: 2.0 - Attributes - ----------- - name: :class:`str` - The channel name. - guild: :class:`Guild` - The guild the channel belongs to. - id: :class:`int` - The channel ID. - category_id: Optional[:class:`int`] - The category channel ID this channel belongs to, if applicable. - position: :class:`int` - The position in the channel list. This is a number that starts at 0. e.g. the - top channel is position 0. - bitrate: :class:`int` - The channel's preferred audio bitrate in bits per second. - user_limit: :class:`int` - The channel's limit for number of members that can be in a voice channel. - rtc_region: Optional[:class:`VoiceRegion`] - The region for the voice channel's voice communication. - A value of ``None`` indicates automatic voice region detection. + Parameters + ------------ + message_id: :class:`int` + The message ID to create a partial message for. - .. versionadded:: 1.7 - """ + Returns + --------- + :class:`PartialMessage` + The partial message. + """ - __slots__ = () + from .message import PartialMessage - def __repr__(self): - attrs = [ - ('id', self.id), - ('name', self.name), - ('rtc_region', self.rtc_region), - ('position', self.position), - ('bitrate', self.bitrate), - ('user_limit', self.user_limit), - ('category_id', self.category_id) - ] - return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) + return PartialMessage(channel=self, id=message_id) # type: ignore # VocalGuildChannel is an impl detail - @property - def type(self): - """:class:`ChannelType`: The channel's Discord type.""" - return ChannelType.voice + async def delete_messages(self, messages: Iterable[Snowflake], *, reason: Optional[str] = None) -> None: + """|coro| - @utils.copy_doc(discord.abc.GuildChannel.clone) - async def clone(self, *, name=None, reason=None): - return await self._clone_impl({ - 'bitrate': self.bitrate, - 'user_limit': self.user_limit - }, name=name, reason=reason) + Deletes a list of messages. This is similar to :meth:`Message.delete` + except it bulk deletes multiple messages. - async def edit(self, *, reason=None, **options): - """|coro| + As a special case, if the number of messages is 0, then nothing + is done. If the number of messages is 1 then single message + delete is done. If it's more than two, then bulk delete is used. - Edits the channel. + You cannot bulk delete more than 100 messages or messages that + are older than 14 days old. - You must have the :attr:`~Permissions.manage_channels` permission to - use this. + You must have :attr:`~Permissions.manage_messages` to do this. - .. versionchanged:: 1.3 - The ``overwrites`` keyword-only parameter was added. + .. versionadded:: 2.0 Parameters - ---------- - name: :class:`str` - The new channel's name. - bitrate: :class:`int` - The new channel's bitrate. - user_limit: :class:`int` - The new channel's user limit. - position: :class:`int` - The new channel's position. - sync_permissions: :class:`bool` - Whether to sync permissions with the channel's new or pre-existing - category. Defaults to ``False``. - category: Optional[:class:`CategoryChannel`] - The new category for this channel. Can be ``None`` to remove the - category. + ----------- + messages: Iterable[:class:`abc.Snowflake`] + An iterable of messages denoting which ones to bulk delete. reason: Optional[:class:`str`] - The reason for editing this channel. Shows up on the audit log. - overwrites: :class:`dict` - A :class:`dict` of target (either a role or a member) to - :class:`PermissionOverwrite` to apply to the channel. - rtc_region: Optional[:class:`VoiceRegion`] - The new region for the voice channel's voice communication. - A value of ``None`` indicates automatic voice region detection. - - .. versionadded:: 1.7 + The reason for deleting the messages. Shows up on the audit log. Raises ------ - InvalidArgument - If the permission overwrite information is not in proper form. + ClientException + The number of messages to delete was more than 100. Forbidden - You do not have permissions to edit the channel. + You do not have proper permissions to delete the messages. + NotFound + If single delete, then the message was already deleted. HTTPException - Editing the channel failed. + Deleting the messages failed. """ + if not isinstance(messages, (list, tuple)): + messages = list(messages) - await self._edit(options, reason=reason) - -class StageChannel(VocalGuildChannel): - """Represents a Discord guild stage channel. + if len(messages) == 0: + return # do nothing - .. versionadded:: 1.7 + if len(messages) == 1: + message_id: int = messages[0].id + await self._state.http.delete_message(self.id, message_id) + return - .. container:: operations + if len(messages) > 100: + raise ClientException('Can only bulk delete messages up to 100 messages') - .. describe:: x == y + message_ids: SnowflakeList = [m.id for m in messages] + await self._state.http.delete_messages(self.id, message_ids, reason=reason) + + async def purge( + self, + *, + limit: Optional[int] = 100, + check: Callable[[Message], bool] = MISSING, + before: Optional[SnowflakeTime] = None, + after: Optional[SnowflakeTime] = None, + around: Optional[SnowflakeTime] = None, + oldest_first: Optional[bool] = None, + bulk: bool = True, + reason: Optional[str] = None, + ) -> List[Message]: + """|coro| + + Purges a list of messages that meet the criteria given by the predicate + ``check``. If a ``check`` is not provided then all messages are deleted + without discrimination. + + You must have :attr:`~Permissions.manage_messages` to + delete messages even if they are your own. + Having :attr:`~Permissions.read_message_history` is + also needed to retrieve message history. + + .. versionadded:: 2.0 + + Examples + --------- + + Deleting bot's messages :: + + def is_me(m): + return m.author == client.user + + deleted = await channel.purge(limit=100, check=is_me) + await channel.send(f'Deleted {len(deleted)} message(s)') + + Parameters + ----------- + limit: Optional[:class:`int`] + The number of messages to search through. This is not the number + of messages that will be deleted, though it can be. + check: Callable[[:class:`Message`], :class:`bool`] + The function used to check if a message should be deleted. + It must take a :class:`Message` as its sole parameter. + before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``before`` in :meth:`history`. + after: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``after`` in :meth:`history`. + around: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``around`` in :meth:`history`. + oldest_first: Optional[:class:`bool`] + Same as ``oldest_first`` in :meth:`history`. + bulk: :class:`bool` + If ``True``, use bulk delete. Setting this to ``False`` is useful for mass-deleting + a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will + fall back to single delete if messages are older than two weeks. + reason: Optional[:class:`str`] + The reason for purging the messages. Shows up on the audit log. + + Raises + ------- + Forbidden + You do not have proper permissions to do the actions required. + HTTPException + Purging the messages failed. + + Returns + -------- + List[:class:`.Message`] + The list of messages that were deleted. + """ + + return await discord.abc._purge_helper( + self, + limit=limit, + check=check, + before=before, + after=after, + around=around, + oldest_first=oldest_first, + bulk=bulk, + reason=reason, + ) + + async def webhooks(self) -> List[Webhook]: + """|coro| + + Gets the list of webhooks from this channel. + + You must have :attr:`~.Permissions.manage_webhooks` to do this. + + .. versionadded:: 2.0 + + Raises + ------- + Forbidden + You don't have permissions to get the webhooks. + + Returns + -------- + List[:class:`Webhook`] + The webhooks for this channel. + """ + + from .webhook import Webhook + + data = await self._state.http.channel_webhooks(self.id) + return [Webhook.from_state(d, state=self._state) for d in data] + + async def create_webhook(self, *, name: str, avatar: Optional[bytes] = None, reason: Optional[str] = None) -> Webhook: + """|coro| + + Creates a webhook for this channel. + + You must have :attr:`~.Permissions.manage_webhooks` to do this. + + .. versionadded:: 2.0 + + Parameters + ------------- + name: :class:`str` + The webhook's name. + avatar: Optional[:class:`bytes`] + A :term:`py:bytes-like object` representing the webhook's default avatar. + This operates similarly to :meth:`~ClientUser.edit`. + reason: Optional[:class:`str`] + The reason for creating this webhook. Shows up in the audit logs. + + Raises + ------- + HTTPException + Creating the webhook failed. + Forbidden + You do not have permissions to create a webhook. + + Returns + -------- + :class:`Webhook` + The created webhook. + """ + + from .webhook import Webhook + + if avatar is not None: + avatar = utils._bytes_to_base64_data(avatar) # type: ignore # Silence reassignment error + + data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar, reason=reason) + return Webhook.from_state(data, state=self._state) + + +class VoiceChannel(VocalGuildChannel): + """Represents a Discord guild voice channel. + + .. container:: operations + + .. describe:: x == y Checks if two channels are equal. @@ -763,8 +1278,10 @@ class StageChannel(VocalGuildChannel): The guild the channel belongs to. id: :class:`int` The channel ID. - topic: Optional[:class:`str`] - The channel's topic. ``None`` if it isn't set. + nsfw: :class:`bool` + If the channel is marked as "not safe for work" or "age restricted". + + .. versionadded:: 2.0 category_id: Optional[:class:`int`] The category channel ID this channel belongs to, if applicable. position: :class:`int` @@ -773,60 +1290,119 @@ class StageChannel(VocalGuildChannel): bitrate: :class:`int` The channel's preferred audio bitrate in bits per second. user_limit: :class:`int` - The channel's limit for number of members that can be in a stage channel. - rtc_region: Optional[:class:`VoiceRegion`] - The region for the stage channel's voice communication. + The channel's limit for number of members that can be in a voice channel. + rtc_region: Optional[:class:`str`] + The region for the voice channel's voice communication. A value of ``None`` indicates automatic voice region detection. + + .. versionadded:: 1.7 + + .. versionchanged:: 2.0 + The type of this attribute has changed to :class:`str`. + video_quality_mode: :class:`VideoQualityMode` + The camera video quality for the voice channel's participants. + + .. versionadded:: 2.0 + last_message_id: Optional[:class:`int`] + The last message ID of the message sent to this channel. It may + *not* point to an existing or valid message. + + .. versionadded:: 2.0 + slowmode_delay: :class:`int` + The number of seconds a member must wait between sending messages + in this channel. A value of ``0`` denotes that it is disabled. + Bots and users with :attr:`~Permissions.manage_channels` or + :attr:`~Permissions.manage_messages` bypass slowmode. + + .. versionadded:: 2.2 """ - __slots__ = ('topic',) - def __repr__(self): + __slots__ = () + + def __repr__(self) -> str: attrs = [ ('id', self.id), ('name', self.name), - ('topic', self.topic), ('rtc_region', self.rtc_region), ('position', self.position), ('bitrate', self.bitrate), + ('video_quality_mode', self.video_quality_mode), ('user_limit', self.user_limit), - ('category_id', self.category_id) + ('category_id', self.category_id), ] - return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) - - def _update(self, guild, data): - super()._update(guild, data) - self.topic = data.get('topic') + joined = ' '.join('%s=%r' % t for t in attrs) + return f'<{self.__class__.__name__} {joined}>' @property - def requesting_to_speak(self): - """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel.""" - return [member for member in self.members if member.voice.requested_to_speak_at is not None] + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return EntityType.voice @property - def type(self): + def type(self) -> Literal[ChannelType.voice]: """:class:`ChannelType`: The channel's Discord type.""" - return ChannelType.stage_voice + return ChannelType.voice @utils.copy_doc(discord.abc.GuildChannel.clone) - async def clone(self, *, name=None, reason=None): - return await self._clone_impl({ - 'topic': self.topic, - }, name=name, reason=reason) - - async def edit(self, *, reason=None, **options): + async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> VoiceChannel: + return await self._clone_impl({'bitrate': self.bitrate, 'user_limit': self.user_limit}, name=name, reason=reason) + + @overload + async def edit(self) -> None: + ... + + @overload + async def edit(self, *, position: int, reason: Optional[str] = ...) -> None: + ... + + @overload + async def edit( + self, + *, + name: str = ..., + nsfw: bool = ..., + bitrate: int = ..., + user_limit: int = ..., + position: int = ..., + sync_permissions: int = ..., + category: Optional[CategoryChannel] = ..., + overwrites: Mapping[OverwriteKeyT, PermissionOverwrite] = ..., + rtc_region: Optional[str] = ..., + video_quality_mode: VideoQualityMode = ..., + slowmode_delay: int = ..., + reason: Optional[str] = ..., + ) -> VoiceChannel: + ... + + async def edit(self, *, reason: Optional[str] = None, **options: Any) -> Optional[VoiceChannel]: """|coro| Edits the channel. - You must have the :attr:`~Permissions.manage_channels` permission to - use this. + You must have :attr:`~Permissions.manage_channels` to do this. + + .. versionchanged:: 1.3 + The ``overwrites`` keyword-only parameter was added. + + .. versionchanged:: 2.0 + Edits are no longer in-place, the newly edited channel is returned instead. + + .. versionchanged:: 2.0 + The ``region`` parameter now accepts :class:`str` instead of an enum. + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` instead of + ``InvalidArgument``. Parameters ---------- name: :class:`str` The new channel's name. - topic: :class:`str` - The new channel's topic. + bitrate: :class:`int` + The new channel's bitrate. + nsfw: :class:`bool` + To mark the channel as NSFW or not. + user_limit: :class:`int` + The new channel's user limit. position: :class:`int` The new channel's position. sync_permissions: :class:`bool` @@ -835,31 +1411,49 @@ async def edit(self, *, reason=None, **options): category: Optional[:class:`CategoryChannel`] The new category for this channel. Can be ``None`` to remove the category. + slowmode_delay: :class:`int` + Specifies the slowmode rate limit for user in this channel, in seconds. + A value of ``0`` disables slowmode. The maximum value possible is ``21600``. reason: Optional[:class:`str`] The reason for editing this channel. Shows up on the audit log. - overwrites: :class:`dict` - A :class:`dict` of target (either a role or a member) to + overwrites: :class:`Mapping` + A :class:`Mapping` of target (either a role or a member) to :class:`PermissionOverwrite` to apply to the channel. - rtc_region: Optional[:class:`VoiceRegion`] - The new region for the stage channel's voice communication. + rtc_region: Optional[:class:`str`] + The new region for the voice channel's voice communication. A value of ``None`` indicates automatic voice region detection. + .. versionadded:: 1.7 + video_quality_mode: :class:`VideoQualityMode` + The camera video quality for the voice channel's participants. + + .. versionadded:: 2.0 + Raises ------ - InvalidArgument + TypeError If the permission overwrite information is not in proper form. Forbidden You do not have permissions to edit the channel. HTTPException Editing the channel failed. + + Returns + -------- + Optional[:class:`.VoiceChannel`] + The newly edited voice channel. If the edit was only positional + then ``None`` is returned instead. """ + payload = await self._edit(options, reason=reason) + if payload is not None: + # the payload will always be the proper channel payload + return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore - await self._edit(options, reason=reason) -class CategoryChannel(discord.abc.GuildChannel, Hashable): - """Represents a Discord channel category. +class StageChannel(VocalGuildChannel): + """Represents a Discord guild stage channel. - These are useful to group channels to logical compartments. + .. versionadded:: 1.7 .. container:: operations @@ -873,73 +1467,430 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable): .. describe:: hash(x) - Returns the category's hash. + Returns the channel's hash. .. describe:: str(x) - Returns the category's name. + Returns the channel's name. Attributes ----------- name: :class:`str` - The category name. + The channel name. guild: :class:`Guild` - The guild the category belongs to. + The guild the channel belongs to. id: :class:`int` - The category channel ID. + The channel ID. + nsfw: :class:`bool` + If the channel is marked as "not safe for work" or "age restricted". + + .. versionadded:: 2.0 + topic: Optional[:class:`str`] + The channel's topic. ``None`` if it isn't set. + category_id: Optional[:class:`int`] + The category channel ID this channel belongs to, if applicable. position: :class:`int` - The position in the category list. This is a number that starts at 0. e.g. the - top category is position 0. + The position in the channel list. This is a number that starts at 0. e.g. the + top channel is position 0. + bitrate: :class:`int` + The channel's preferred audio bitrate in bits per second. + user_limit: :class:`int` + The channel's limit for number of members that can be in a stage channel. + rtc_region: Optional[:class:`str`] + The region for the stage channel's voice communication. + A value of ``None`` indicates automatic voice region detection. + video_quality_mode: :class:`VideoQualityMode` + The camera video quality for the stage channel's participants. + + .. versionadded:: 2.0 + last_message_id: Optional[:class:`int`] + The last message ID of the message sent to this channel. It may + *not* point to an existing or valid message. + + .. versionadded:: 2.2 + slowmode_delay: :class:`int` + The number of seconds a member must wait between sending messages + in this channel. A value of ``0`` denotes that it is disabled. + Bots and users with :attr:`~Permissions.manage_channels` or + :attr:`~Permissions.manage_messages` bypass slowmode. + + .. versionadded:: 2.2 """ - __slots__ = ('name', 'id', 'guild', 'nsfw', '_state', 'position', '_overwrites', 'category_id') + __slots__ = ('topic',) - def __init__(self, *, state, guild, data): - self._state = state - self.id = int(data['id']) - self._update(guild, data) + def __repr__(self) -> str: + attrs = [ + ('id', self.id), + ('name', self.name), + ('topic', self.topic), + ('rtc_region', self.rtc_region), + ('position', self.position), + ('bitrate', self.bitrate), + ('video_quality_mode', self.video_quality_mode), + ('user_limit', self.user_limit), + ('category_id', self.category_id), + ] + joined = ' '.join('%s=%r' % t for t in attrs) + return f'<{self.__class__.__name__} {joined}>' - def __repr__(self): - return ''.format(self) + def _update(self, guild: Guild, data: StageChannelPayload) -> None: + super()._update(guild, data) + self.topic: Optional[str] = data.get('topic') - def _update(self, guild, data): - self.guild = guild - self.name = data['name'] - self.category_id = utils._get_as_snowflake(data, 'parent_id') - self.nsfw = data.get('nsfw', False) - self.position = data['position'] - self._fill_overwrites(data) + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return EntityType.stage_instance @property - def _sorting_bucket(self): - return ChannelType.category.value + def requesting_to_speak(self) -> List[Member]: + """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel.""" + return [member for member in self.members if member.voice and member.voice.requested_to_speak_at is not None] @property - def type(self): - """:class:`ChannelType`: The channel's Discord type.""" - return ChannelType.category + def speakers(self) -> List[Member]: + """List[:class:`Member`]: A list of members who have been permitted to speak in the stage channel. - def is_nsfw(self): - """:class:`bool`: Checks if the category is NSFW.""" - return self.nsfw + .. versionadded:: 2.0 + """ + return [ + member + for member in self.members + if member.voice and not member.voice.suppress and member.voice.requested_to_speak_at is None + ] - @utils.copy_doc(discord.abc.GuildChannel.clone) - async def clone(self, *, name=None, reason=None): - return await self._clone_impl({ - 'nsfw': self.nsfw - }, name=name, reason=reason) + @property + def listeners(self) -> List[Member]: + """List[:class:`Member`]: A list of members who are listening in the stage channel. - async def edit(self, *, reason=None, **options): - """|coro| + .. versionadded:: 2.0 + """ + return [member for member in self.members if member.voice and member.voice.suppress] - Edits the channel. + @property + def moderators(self) -> List[Member]: + """List[:class:`Member`]: A list of members who are moderating the stage channel. - You must have the :attr:`~Permissions.manage_channels` permission to - use this. + .. versionadded:: 2.0 + """ + required_permissions = Permissions.stage_moderator() + return [member for member in self.members if self.permissions_for(member) >= required_permissions] + + @property + def type(self) -> Literal[ChannelType.stage_voice]: + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.stage_voice + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> StageChannel: + return await self._clone_impl({}, name=name, reason=reason) + + @property + def instance(self) -> Optional[StageInstance]: + """Optional[:class:`StageInstance`]: The running stage instance of the stage channel. + + .. versionadded:: 2.0 + """ + return utils.get(self.guild.stage_instances, channel_id=self.id) + + async def create_instance( + self, + *, + topic: str, + privacy_level: PrivacyLevel = MISSING, + send_start_notification: bool = False, + reason: Optional[str] = None, + ) -> StageInstance: + """|coro| + + Create a stage instance. + + You must have :attr:`~Permissions.manage_channels` to do this. + + .. versionadded:: 2.0 + + Parameters + ----------- + topic: :class:`str` + The stage instance's topic. + privacy_level: :class:`PrivacyLevel` + The stage instance's privacy level. Defaults to :attr:`PrivacyLevel.guild_only`. + send_start_notification: :class:`bool` + Whether to send a start notification. This sends a push notification to @everyone if ``True``. Defaults to ``False``. + You must have :attr:`~Permissions.mention_everyone` to do this. + + .. versionadded:: 2.3 + reason: :class:`str` + The reason the stage instance was created. Shows up on the audit log. + + Raises + ------ + TypeError + If the ``privacy_level`` parameter is not the proper type. + Forbidden + You do not have permissions to create a stage instance. + HTTPException + Creating a stage instance failed. + + Returns + -------- + :class:`StageInstance` + The newly created stage instance. + """ + + payload: Dict[str, Any] = {'channel_id': self.id, 'topic': topic} + + if privacy_level is not MISSING: + if not isinstance(privacy_level, PrivacyLevel): + raise TypeError('privacy_level field must be of type PrivacyLevel') + + payload['privacy_level'] = privacy_level.value + + payload['send_start_notification'] = send_start_notification + + data = await self._state.http.create_stage_instance(**payload, reason=reason) + return StageInstance(guild=self.guild, state=self._state, data=data) + + async def fetch_instance(self) -> StageInstance: + """|coro| + + Gets the running :class:`StageInstance`. + + .. versionadded:: 2.0 + + Raises + ------- + NotFound + The stage instance or channel could not be found. + HTTPException + Getting the stage instance failed. + + Returns + -------- + :class:`StageInstance` + The stage instance. + """ + data = await self._state.http.get_stage_instance(self.id) + return StageInstance(guild=self.guild, state=self._state, data=data) + + @overload + async def edit(self) -> None: + ... + + @overload + async def edit(self, *, position: int, reason: Optional[str] = ...) -> None: + ... + + @overload + async def edit( + self, + *, + name: str = ..., + nsfw: bool = ..., + user_limit: int = ..., + position: int = ..., + sync_permissions: int = ..., + category: Optional[CategoryChannel] = ..., + overwrites: Mapping[OverwriteKeyT, PermissionOverwrite] = ..., + rtc_region: Optional[str] = ..., + video_quality_mode: VideoQualityMode = ..., + slowmode_delay: int = ..., + reason: Optional[str] = ..., + ) -> StageChannel: + ... + + async def edit(self, *, reason: Optional[str] = None, **options: Any) -> Optional[StageChannel]: + """|coro| + + Edits the channel. + + You must have :attr:`~Permissions.manage_channels` to do this. + + .. versionchanged:: 2.0 + The ``topic`` parameter must now be set via :attr:`create_instance`. + + .. versionchanged:: 2.0 + Edits are no longer in-place, the newly edited channel is returned instead. + + .. versionchanged:: 2.0 + The ``region`` parameter now accepts :class:`str` instead of an enum. + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` instead of + ``InvalidArgument``. + + Parameters + ---------- + name: :class:`str` + The new channel's name. + position: :class:`int` + The new channel's position. + nsfw: :class:`bool` + To mark the channel as NSFW or not. + user_limit: :class:`int` + The new channel's user limit. + sync_permissions: :class:`bool` + Whether to sync permissions with the channel's new or pre-existing + category. Defaults to ``False``. + category: Optional[:class:`CategoryChannel`] + The new category for this channel. Can be ``None`` to remove the + category. + slowmode_delay: :class:`int` + Specifies the slowmode rate limit for user in this channel, in seconds. + A value of ``0`` disables slowmode. The maximum value possible is ``21600``. + reason: Optional[:class:`str`] + The reason for editing this channel. Shows up on the audit log. + overwrites: :class:`Mapping` + A :class:`Mapping` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the channel. + rtc_region: Optional[:class:`str`] + The new region for the stage channel's voice communication. + A value of ``None`` indicates automatic voice region detection. + video_quality_mode: :class:`VideoQualityMode` + The camera video quality for the stage channel's participants. + + .. versionadded:: 2.0 + + Raises + ------ + ValueError + If the permission overwrite information is not in proper form. + Forbidden + You do not have permissions to edit the channel. + HTTPException + Editing the channel failed. + + Returns + -------- + Optional[:class:`.StageChannel`] + The newly edited stage channel. If the edit was only positional + then ``None`` is returned instead. + """ + + payload = await self._edit(options, reason=reason) + if payload is not None: + # the payload will always be the proper channel payload + return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + + +class CategoryChannel(discord.abc.GuildChannel, Hashable): + """Represents a Discord channel category. + + These are useful to group channels to logical compartments. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the category's hash. + + .. describe:: str(x) + + Returns the category's name. + + Attributes + ----------- + name: :class:`str` + The category name. + guild: :class:`Guild` + The guild the category belongs to. + id: :class:`int` + The category channel ID. + position: :class:`int` + The position in the category list. This is a number that starts at 0. e.g. the + top category is position 0. + nsfw: :class:`bool` + If the channel is marked as "not safe for work". + + .. note:: + + To check if the channel or the guild of that channel are marked as NSFW, consider :meth:`is_nsfw` instead. + """ + + __slots__ = ('name', 'id', 'guild', 'nsfw', '_state', 'position', '_overwrites', 'category_id') + + def __init__(self, *, state: ConnectionState, guild: Guild, data: CategoryChannelPayload): + self._state: ConnectionState = state + self.id: int = int(data['id']) + self._update(guild, data) + + def __repr__(self) -> str: + return f'' + + def _update(self, guild: Guild, data: CategoryChannelPayload) -> None: + self.guild: Guild = guild + self.name: str = data['name'] + self.category_id: Optional[int] = utils._get_as_snowflake(data, 'parent_id') + self.nsfw: bool = data.get('nsfw', False) + self.position: int = data['position'] + self._fill_overwrites(data) + + @property + def _sorting_bucket(self) -> int: + return ChannelType.category.value + + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return None + + @property + def type(self) -> Literal[ChannelType.category]: + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.category + + def is_nsfw(self) -> bool: + """:class:`bool`: Checks if the category is NSFW.""" + return self.nsfw + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> CategoryChannel: + return await self._clone_impl({'nsfw': self.nsfw}, name=name, reason=reason) + + @overload + async def edit(self) -> None: + ... + + @overload + async def edit(self, *, position: int, reason: Optional[str] = ...) -> None: + ... + + @overload + async def edit( + self, + *, + name: str = ..., + position: int = ..., + nsfw: bool = ..., + overwrites: Mapping[OverwriteKeyT, PermissionOverwrite] = ..., + reason: Optional[str] = ..., + ) -> CategoryChannel: + ... + + async def edit(self, *, reason: Optional[str] = None, **options: Any) -> Optional[CategoryChannel]: + """|coro| + + Edits the channel. + + You must have :attr:`~Permissions.manage_channels` to do this. .. versionchanged:: 1.3 The ``overwrites`` keyword-only parameter was added. + .. versionchanged:: 2.0 + Edits are no longer in-place, the newly edited channel is returned instead. + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` or + :exc:`ValueError` instead of ``InvalidArgument``. + Parameters ---------- name: :class:`str` @@ -950,33 +1901,45 @@ async def edit(self, *, reason=None, **options): To mark the category as NSFW or not. reason: Optional[:class:`str`] The reason for editing this category. Shows up on the audit log. - overwrites: :class:`dict` - A :class:`dict` of target (either a role or a member) to + overwrites: :class:`Mapping` + A :class:`Mapping` of target (either a role or a member) to :class:`PermissionOverwrite` to apply to the channel. Raises ------ - InvalidArgument + ValueError If position is less than 0 or greater than the number of categories. + TypeError + The overwrite information is not in proper form. Forbidden You do not have permissions to edit the category. HTTPException Editing the category failed. + + Returns + -------- + Optional[:class:`.CategoryChannel`] + The newly edited category channel. If the edit was only positional + then ``None`` is returned instead. """ - await self._edit(options=options, reason=reason) + payload = await self._edit(options, reason=reason) + if payload is not None: + # the payload will always be the proper channel payload + return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore @utils.copy_doc(discord.abc.GuildChannel.move) - async def move(self, **kwargs): + async def move(self, **kwargs: Any) -> None: kwargs.pop('category', None) await super().move(**kwargs) @property - def channels(self): + def channels(self) -> List[GuildChannelType]: """List[:class:`abc.GuildChannel`]: Returns the channels that are under this category. These are sorted by the official Discord UI, which places voice channels below the text channels. """ + def comparator(channel): return (not isinstance(channel, TextChannel), channel.position) @@ -985,36 +1948,30 @@ def comparator(channel): return ret @property - def text_channels(self): + def text_channels(self) -> List[TextChannel]: """List[:class:`TextChannel`]: Returns the text channels that are under this category.""" - ret = [c for c in self.guild.channels - if c.category_id == self.id - and isinstance(c, TextChannel)] + ret = [c for c in self.guild.channels if c.category_id == self.id and isinstance(c, TextChannel)] ret.sort(key=lambda c: (c.position, c.id)) return ret @property - def voice_channels(self): + def voice_channels(self) -> List[VoiceChannel]: """List[:class:`VoiceChannel`]: Returns the voice channels that are under this category.""" - ret = [c for c in self.guild.channels - if c.category_id == self.id - and isinstance(c, VoiceChannel)] + ret = [c for c in self.guild.channels if c.category_id == self.id and isinstance(c, VoiceChannel)] ret.sort(key=lambda c: (c.position, c.id)) return ret @property - def stage_channels(self): - """List[:class:`StageChannel`]: Returns the voice channels that are under this category. + def stage_channels(self) -> List[StageChannel]: + """List[:class:`StageChannel`]: Returns the stage channels that are under this category. .. versionadded:: 1.7 """ - ret = [c for c in self.guild.channels - if c.category_id == self.id - and isinstance(c, StageChannel)] + ret = [c for c in self.guild.channels if c.category_id == self.id and isinstance(c, StageChannel)] ret.sort(key=lambda c: (c.position, c.id)) return ret - async def create_text_channel(self, name, *, overwrites=None, reason=None, **options): + async def create_text_channel(self, name: str, **options: Any) -> TextChannel: """|coro| A shortcut method to :meth:`Guild.create_text_channel` to create a :class:`TextChannel` in the category. @@ -1024,9 +1981,9 @@ async def create_text_channel(self, name, *, overwrites=None, reason=None, **opt :class:`TextChannel` The channel that was just created. """ - return await self.guild.create_text_channel(name, overwrites=overwrites, category=self, reason=reason, **options) + return await self.guild.create_text_channel(name, category=self, **options) - async def create_voice_channel(self, name, *, overwrites=None, reason=None, **options): + async def create_voice_channel(self, name: str, **options: Any) -> VoiceChannel: """|coro| A shortcut method to :meth:`Guild.create_voice_channel` to create a :class:`VoiceChannel` in the category. @@ -1036,9 +1993,9 @@ async def create_voice_channel(self, name, *, overwrites=None, reason=None, **op :class:`VoiceChannel` The channel that was just created. """ - return await self.guild.create_voice_channel(name, overwrites=overwrites, category=self, reason=reason, **options) + return await self.guild.create_voice_channel(name, category=self, **options) - async def create_stage_channel(self, name, *, overwrites=None, reason=None, **options): + async def create_stage_channel(self, name: str, **options: Any) -> StageChannel: """|coro| A shortcut method to :meth:`Guild.create_stage_channel` to create a :class:`StageChannel` in the category. @@ -1050,133 +2007,853 @@ async def create_stage_channel(self, name, *, overwrites=None, reason=None, **op :class:`StageChannel` The channel that was just created. """ - return await self.guild.create_stage_channel(name, overwrites=overwrites, category=self, reason=reason, **options) + return await self.guild.create_stage_channel(name, category=self, **options) + + async def create_forum(self, name: str, **options: Any) -> ForumChannel: + """|coro| + + A shortcut method to :meth:`Guild.create_forum` to create a :class:`ForumChannel` in the category. + + .. versionadded:: 2.0 + + Returns + -------- + :class:`ForumChannel` + The channel that was just created. + """ + return await self.guild.create_forum(name, category=self, **options) + + +class ForumTag(Hashable): + """Represents a forum tag that can be applied to a thread within a :class:`ForumChannel`. + + .. versionadded:: 2.1 + + .. container:: operations + + .. describe:: x == y + + Checks if two forum tags are equal. + + .. describe:: x != y + + Checks if two forum tags are not equal. + + .. describe:: hash(x) + + Returns the forum tag's hash. + + .. describe:: str(x) + + Returns the forum tag's name. + + + Attributes + ----------- + id: :class:`int` + The ID of the tag. If this was manually created then the ID will be ``0``. + name: :class:`str` + The name of the tag. Can only be up to 20 characters. + moderated: :class:`bool` + Whether this tag can only be added or removed by a moderator with + the :attr:`~Permissions.manage_threads` permission. + emoji: Optional[:class:`PartialEmoji`] + The emoji that is used to represent this tag. + Note that if the emoji is a custom emoji, it will *not* have name information. + """ + + __slots__ = ('name', 'id', 'moderated', 'emoji') + + def __init__(self, *, name: str, emoji: Optional[EmojiInputType] = None, moderated: bool = False) -> None: + self.name: str = name + self.id: int = 0 + self.moderated: bool = moderated + self.emoji: Optional[PartialEmoji] = None + if isinstance(emoji, _EmojiTag): + self.emoji = emoji._to_partial() + elif isinstance(emoji, str): + self.emoji = PartialEmoji.from_str(emoji) + elif emoji is not None: + raise TypeError(f'emoji must be a Emoji, PartialEmoji, str or None not {emoji.__class__.__name__}') + + @classmethod + def from_data(cls, *, state: ConnectionState, data: ForumTagPayload) -> Self: + self = cls.__new__(cls) + self.name = data['name'] + self.id = int(data['id']) + self.moderated = data.get('moderated', False) + + emoji_name = data['emoji_name'] or '' + emoji_id = utils._get_as_snowflake(data, 'emoji_id') or None # Coerce 0 -> None + if not emoji_name and not emoji_id: + self.emoji = None + else: + self.emoji = PartialEmoji.with_state(state=state, name=emoji_name, id=emoji_id) + return self + + def to_dict(self) -> Dict[str, Any]: + payload: Dict[str, Any] = { + 'name': self.name, + 'moderated': self.moderated, + } + if self.emoji is not None: + payload.update(self.emoji._to_forum_tag_payload()) + else: + payload.update(emoji_id=None, emoji_name=None) + + if self.id: + payload['id'] = self.id + + return payload + + def __repr__(self) -> str: + return f'' + + def __str__(self) -> str: + return self.name + + +class ForumChannel(discord.abc.GuildChannel, Hashable): + """Represents a Discord guild forum channel. + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two forums are equal. + + .. describe:: x != y + + Checks if two forums are not equal. + + .. describe:: hash(x) + + Returns the forum's hash. + + .. describe:: str(x) + + Returns the forum's name. + + Attributes + ----------- + name: :class:`str` + The forum name. + guild: :class:`Guild` + The guild the forum belongs to. + id: :class:`int` + The forum ID. + category_id: Optional[:class:`int`] + The category channel ID this forum belongs to, if applicable. + topic: Optional[:class:`str`] + The forum's topic. ``None`` if it doesn't exist. Called "Guidelines" in the UI. + Can be up to 4096 characters long. + position: :class:`int` + The position in the channel list. This is a number that starts at 0. e.g. the + top channel is position 0. + last_message_id: Optional[:class:`int`] + The last thread ID that was created on this forum. This technically also + coincides with the message ID that started the thread that was created. + It may *not* point to an existing or valid thread or message. + slowmode_delay: :class:`int` + The number of seconds a member must wait between creating threads + in this forum. A value of ``0`` denotes that it is disabled. + Bots and users with :attr:`~Permissions.manage_channels` or + :attr:`~Permissions.manage_messages` bypass slowmode. + nsfw: :class:`bool` + If the forum is marked as "not safe for work" or "age restricted". + default_auto_archive_duration: :class:`int` + The default auto archive duration in minutes for threads created in this forum. + default_thread_slowmode_delay: :class:`int` + The default slowmode delay in seconds for threads created in this forum. + + .. versionadded:: 2.1 + default_reaction_emoji: Optional[:class:`PartialEmoji`] + The default reaction emoji for threads created in this forum to show in the + add reaction button. + + .. versionadded:: 2.1 + default_layout: :class:`ForumLayoutType` + The default layout for posts in this forum channel. + Defaults to :attr:`ForumLayoutType.not_set`. + + .. versionadded:: 2.2 + default_sort_order: Optional[:class:`ForumOrderType`] + The default sort order for posts in this forum channel. + + .. versionadded:: 2.3 + """ + + __slots__ = ( + 'name', + 'id', + 'guild', + 'topic', + '_state', + '_flags', + 'nsfw', + 'category_id', + 'position', + 'slowmode_delay', + '_overwrites', + 'last_message_id', + 'default_auto_archive_duration', + 'default_thread_slowmode_delay', + 'default_reaction_emoji', + 'default_layout', + 'default_sort_order', + '_available_tags', + '_flags', + ) + + def __init__(self, *, state: ConnectionState, guild: Guild, data: ForumChannelPayload): + self._state: ConnectionState = state + self.id: int = int(data['id']) + self._update(guild, data) + + def __repr__(self) -> str: + attrs = [ + ('id', self.id), + ('name', self.name), + ('position', self.position), + ('nsfw', self.nsfw), + ('category_id', self.category_id), + ] + joined = ' '.join('%s=%r' % t for t in attrs) + return f'<{self.__class__.__name__} {joined}>' + + def _update(self, guild: Guild, data: ForumChannelPayload) -> None: + self.guild: Guild = guild + self.name: str = data['name'] + self.category_id: Optional[int] = utils._get_as_snowflake(data, 'parent_id') + self.topic: Optional[str] = data.get('topic') + self.position: int = data['position'] + self.nsfw: bool = data.get('nsfw', False) + self.slowmode_delay: int = data.get('rate_limit_per_user', 0) + self.default_auto_archive_duration: ThreadArchiveDuration = data.get('default_auto_archive_duration', 1440) + self.last_message_id: Optional[int] = utils._get_as_snowflake(data, 'last_message_id') + # This takes advantage of the fact that dicts are ordered since Python 3.7 + tags = [ForumTag.from_data(state=self._state, data=tag) for tag in data.get('available_tags', [])] + self.default_thread_slowmode_delay: int = data.get('default_thread_rate_limit_per_user', 0) + self.default_layout: ForumLayoutType = try_enum(ForumLayoutType, data.get('default_forum_layout', 0)) + self._available_tags: Dict[int, ForumTag] = {tag.id: tag for tag in tags} + + self.default_reaction_emoji: Optional[PartialEmoji] = None + default_reaction_emoji = data.get('default_reaction_emoji') + if default_reaction_emoji: + self.default_reaction_emoji = PartialEmoji.with_state( + state=self._state, + id=utils._get_as_snowflake(default_reaction_emoji, 'emoji_id') or None, # Coerce 0 -> None + name=default_reaction_emoji.get('emoji_name') or '', + ) + + self.default_sort_order: Optional[ForumOrderType] = None + default_sort_order = data.get('default_sort_order') + if default_sort_order is not None: + self.default_sort_order = try_enum(ForumOrderType, default_sort_order) + + self._flags: int = data.get('flags', 0) + self._fill_overwrites(data) + + @property + def type(self) -> Literal[ChannelType.forum]: + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.forum + + @property + def _sorting_bucket(self) -> int: + return ChannelType.text.value + + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return None + + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) + def permissions_for(self, obj: Union[Member, Role], /) -> Permissions: + base = super().permissions_for(obj) + self._apply_implicit_permissions(base) + + # text channels do not have voice related permissions + denied = Permissions.voice() + base.value &= ~denied.value + return base + + def get_thread(self, thread_id: int, /) -> Optional[Thread]: + """Returns a thread with the given ID. + + .. note:: + + This does not always retrieve archived threads, as they are not retained in the internal + cache. Use :func:`Guild.fetch_channel` instead. + + .. versionadded:: 2.2 + + Parameters + ----------- + thread_id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[:class:`Thread`] + The returned thread or ``None`` if not found. + """ + thread = self.guild.get_thread(thread_id) + if thread is not None and thread.parent_id == self.id: + return thread + return None + + @property + def threads(self) -> List[Thread]: + """List[:class:`Thread`]: Returns all the threads that you can see.""" + return [thread for thread in self.guild._threads.values() if thread.parent_id == self.id] + + @property + def flags(self) -> ChannelFlags: + """:class:`ChannelFlags`: The flags associated with this thread. + + .. versionadded:: 2.1 + """ + return ChannelFlags._from_value(self._flags) + + @property + def available_tags(self) -> Sequence[ForumTag]: + """Sequence[:class:`ForumTag`]: Returns all the available tags for this forum. + + .. versionadded:: 2.1 + """ + return utils.SequenceProxy(self._available_tags.values()) + + def get_tag(self, tag_id: int, /) -> Optional[ForumTag]: + """Returns the tag with the given ID. + + .. versionadded:: 2.1 + + Parameters + ---------- + tag_id: :class:`int` + The ID to search for. + + Returns + ------- + Optional[:class:`ForumTag`] + The tag with the given ID, or ``None`` if not found. + """ + return self._available_tags.get(tag_id) + + def is_nsfw(self) -> bool: + """:class:`bool`: Checks if the forum is NSFW.""" + return self.nsfw + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> ForumChannel: + return await self._clone_impl( + {'topic': self.topic, 'nsfw': self.nsfw, 'rate_limit_per_user': self.slowmode_delay}, name=name, reason=reason + ) + + @overload + async def edit(self) -> None: + ... + + @overload + async def edit(self, *, position: int, reason: Optional[str] = ...) -> None: + ... + + @overload + async def edit( + self, + *, + reason: Optional[str] = ..., + name: str = ..., + topic: str = ..., + position: int = ..., + nsfw: bool = ..., + sync_permissions: bool = ..., + category: Optional[CategoryChannel] = ..., + slowmode_delay: int = ..., + default_auto_archive_duration: ThreadArchiveDuration = ..., + type: ChannelType = ..., + overwrites: Mapping[OverwriteKeyT, PermissionOverwrite] = ..., + available_tags: Sequence[ForumTag] = ..., + default_thread_slowmode_delay: int = ..., + default_reaction_emoji: Optional[EmojiInputType] = ..., + default_layout: ForumLayoutType = ..., + default_sort_order: ForumOrderType = ..., + require_tag: bool = ..., + ) -> ForumChannel: + ... + + async def edit(self, *, reason: Optional[str] = None, **options: Any) -> Optional[ForumChannel]: + """|coro| + + Edits the forum. + + You must have :attr:`~Permissions.manage_channels` to do this. + + Parameters + ---------- + name: :class:`str` + The new forum name. + topic: :class:`str` + The new forum's topic. + position: :class:`int` + The new forum's position. + nsfw: :class:`bool` + To mark the forum as NSFW or not. + sync_permissions: :class:`bool` + Whether to sync permissions with the forum's new or pre-existing + category. Defaults to ``False``. + category: Optional[:class:`CategoryChannel`] + The new category for this forum. Can be ``None`` to remove the + category. + slowmode_delay: :class:`int` + Specifies the slowmode rate limit for user in this forum, in seconds. + A value of ``0`` disables slowmode. The maximum value possible is ``21600``. + type: :class:`ChannelType` + Change the type of this text forum. Currently, only conversion between + :attr:`ChannelType.text` and :attr:`ChannelType.news` is supported. This + is only available to guilds that contain ``NEWS`` in :attr:`Guild.features`. + reason: Optional[:class:`str`] + The reason for editing this forum. Shows up on the audit log. + overwrites: :class:`Mapping` + A :class:`Mapping` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the forum. + default_auto_archive_duration: :class:`int` + The new default auto archive duration in minutes for threads created in this channel. + Must be one of ``60``, ``1440``, ``4320``, or ``10080``. + available_tags: Sequence[:class:`ForumTag`] + The new available tags for this forum. + + .. versionadded:: 2.1 + default_thread_slowmode_delay: :class:`int` + The new default slowmode delay for threads in this channel. + + .. versionadded:: 2.1 + default_reaction_emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]] + The new default reaction emoji for threads in this channel. + + .. versionadded:: 2.1 + default_layout: :class:`ForumLayoutType` + The new default layout for posts in this forum. + + .. versionadded:: 2.2 + default_sort_order: Optional[:class:`ForumOrderType`] + The new default sort order for posts in this forum. + + .. versionadded:: 2.3 + require_tag: :class:`bool` + Whether to require a tag for threads in this channel or not. + + .. versionadded:: 2.1 + + Raises + ------ + ValueError + The new ``position`` is less than 0 or greater than the number of channels. + TypeError + The permission overwrite information is not in proper form or a type + is not the expected type. + Forbidden + You do not have permissions to edit the forum. + HTTPException + Editing the forum failed. + + Returns + -------- + Optional[:class:`.ForumChannel`] + The newly edited forum channel. If the edit was only positional + then ``None`` is returned instead. + """ + + try: + tags: Sequence[ForumTag] = options.pop('available_tags') + except KeyError: + pass + else: + options['available_tags'] = [tag.to_dict() for tag in tags] + + try: + default_reaction_emoji: Optional[EmojiInputType] = options.pop('default_reaction_emoji') + except KeyError: + pass + else: + if default_reaction_emoji is None: + options['default_reaction_emoji'] = None + elif isinstance(default_reaction_emoji, _EmojiTag): + options['default_reaction_emoji'] = default_reaction_emoji._to_partial()._to_forum_tag_payload() + elif isinstance(default_reaction_emoji, str): + options['default_reaction_emoji'] = PartialEmoji.from_str(default_reaction_emoji)._to_forum_tag_payload() + + try: + require_tag = options.pop('require_tag') + except KeyError: + pass + else: + flags = self.flags + flags.require_tag = require_tag + options['flags'] = flags.value + + try: + layout = options.pop('default_layout') + except KeyError: + pass + else: + if not isinstance(layout, ForumLayoutType): + raise TypeError(f'default_layout parameter must be a ForumLayoutType not {layout.__class__.__name__}') + + options['default_forum_layout'] = layout.value + + try: + sort_order = options.pop('default_sort_order') + except KeyError: + pass + else: + if sort_order is None: + options['default_sort_order'] = None + else: + if not isinstance(sort_order, ForumOrderType): + raise TypeError( + f'default_sort_order parameter must be a ForumOrderType not {sort_order.__class__.__name__}' + ) + + options['default_sort_order'] = sort_order.value + + payload = await self._edit(options, reason=reason) + if payload is not None: + # the payload will always be the proper channel payload + return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + + async def create_tag( + self, + *, + name: str, + emoji: Optional[PartialEmoji] = None, + moderated: bool = False, + reason: Optional[str] = None, + ) -> ForumTag: + """|coro| + + Creates a new tag in this forum. + + You must have :attr:`~Permissions.manage_channels` to do this. + + Parameters + ---------- + name: :class:`str` + The name of the tag. Can only be up to 20 characters. + emoji: Optional[Union[:class:`str`, :class:`PartialEmoji`]] + The emoji to use for the tag. + moderated: :class:`bool` + Whether the tag can only be applied by moderators. + reason: Optional[:class:`str`] + The reason for creating this tag. Shows up on the audit log. + + Raises + ------ + Forbidden + You do not have permissions to create a tag in this forum. + HTTPException + Creating the tag failed. + + Returns + ------- + :class:`ForumTag` + The newly created tag. + """ + + prior = list(self._available_tags.values()) + result = ForumTag(name=name, emoji=emoji, moderated=moderated) + prior.append(result) + payload = await self._state.http.edit_channel( + self.id, reason=reason, available_tags=[tag.to_dict() for tag in prior] + ) + try: + result.id = int(payload['available_tags'][-1]['id']) # type: ignore + except (KeyError, IndexError, ValueError): + pass + + return result + + async def create_thread( + self, + *, + name: str, + auto_archive_duration: ThreadArchiveDuration = MISSING, + slowmode_delay: Optional[int] = None, + content: Optional[str] = None, + tts: bool = False, + embed: Embed = MISSING, + embeds: Sequence[Embed] = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + stickers: Sequence[Union[GuildSticker, StickerItem]] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + mention_author: bool = MISSING, + applied_tags: Sequence[ForumTag] = MISSING, + view: View = MISSING, + suppress_embeds: bool = False, + reason: Optional[str] = None, + ) -> ThreadWithMessage: + """|coro| + + Creates a thread in this forum. + + This thread is a public thread with the initial message given. Currently in order + to start a thread in this forum, the user needs :attr:`~discord.Permissions.send_messages`. + + You must send at least one of ``content``, ``embed``, ``embeds``, ``file``, ``files``, + or ``view`` to create a thread in a forum, since forum channels must have a starter message. + + Parameters + ----------- + name: :class:`str` + The name of the thread. + auto_archive_duration: :class:`int` + The duration in minutes before a thread is automatically hidden from the channel list. + If not provided, the channel's default auto archive duration is used. + + Must be one of ``60``, ``1440``, ``4320``, or ``10080``, if provided. + slowmode_delay: Optional[:class:`int`] + Specifies the slowmode rate limit for user in this channel, in seconds. + The maximum value possible is ``21600``. By default no slowmode rate limit + if this is ``None``. + content: Optional[:class:`str`] + The content of the message to send with the thread. + tts: :class:`bool` + Indicates if the message should be sent using text-to-speech. + embed: :class:`~discord.Embed` + The rich embed for the content. + embeds: List[:class:`~discord.Embed`] + A list of embeds to upload. Must be a maximum of 10. + file: :class:`~discord.File` + The file to upload. + files: List[:class:`~discord.File`] + A list of files to upload. Must be a maximum of 10. + allowed_mentions: :class:`~discord.AllowedMentions` + Controls the mentions being processed in this message. If this is + passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`. + The merging behaviour only overrides attributes that have been explicitly passed + to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`. + If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions` + are used instead. + mention_author: :class:`bool` + If set, overrides the :attr:`~discord.AllowedMentions.replied_user` attribute of ``allowed_mentions``. + applied_tags: List[:class:`discord.ForumTag`] + A list of tags to apply to the thread. + view: :class:`discord.ui.View` + A Discord UI View to add to the message. + stickers: Sequence[Union[:class:`~discord.GuildSticker`, :class:`~discord.StickerItem`]] + A list of stickers to upload. Must be a maximum of 3. + suppress_embeds: :class:`bool` + Whether to suppress embeds for the message. This sends the message without any embeds if set to ``True``. + reason: :class:`str` + The reason for creating a new thread. Shows up on the audit log. + + Raises + ------- + Forbidden + You do not have permissions to create a thread. + HTTPException + Starting the thread failed. + ValueError + The ``files`` or ``embeds`` list is not of the appropriate size. + TypeError + You specified both ``file`` and ``files``, + or you specified both ``embed`` and ``embeds``. + + Returns + -------- + Tuple[:class:`Thread`, :class:`Message`] + The created thread with the created message. + This is also accessible as a namedtuple with ``thread`` and ``message`` fields. + """ + + state = self._state + previous_allowed_mention = state.allowed_mentions + if stickers is MISSING: + sticker_ids = MISSING + else: + sticker_ids: SnowflakeList = [s.id for s in stickers] + + if view and not hasattr(view, '__discord_ui_view__'): + raise TypeError(f'view parameter must be View not {view.__class__.__name__}') + + if suppress_embeds: + from .message import MessageFlags # circular import + + flags = MessageFlags._from_value(4) + else: + flags = MISSING + + content = str(content) if content else MISSING + + channel_payload = { + 'name': name, + 'auto_archive_duration': auto_archive_duration or self.default_auto_archive_duration, + 'rate_limit_per_user': slowmode_delay, + 'type': 11, # Private threads don't seem to be allowed + } + + if applied_tags is not MISSING: + channel_payload['applied_tags'] = [str(tag.id) for tag in applied_tags] + + with handle_message_parameters( + content=content, + tts=tts, + file=file, + files=files, + embed=embed, + embeds=embeds, + allowed_mentions=allowed_mentions, + previous_allowed_mentions=previous_allowed_mention, + mention_author=None if mention_author is MISSING else mention_author, + stickers=sticker_ids, + view=view, + flags=flags, + channel_payload=channel_payload, + ) as params: + # Circular import + from .message import Message + + data = await state.http.start_thread_in_forum(self.id, params=params, reason=reason) + thread = Thread(guild=self.guild, state=self._state, data=data) + message = Message(state=self._state, channel=thread, data=data['message']) + if view and not view.is_finished(): + self._state.store_view(view, message.id) + + return ThreadWithMessage(thread=thread, message=message) + + async def webhooks(self) -> List[Webhook]: + """|coro| + + Gets the list of webhooks from this channel. + + You must have :attr:`~.Permissions.manage_webhooks` to do this. + + Raises + ------- + Forbidden + You don't have permissions to get the webhooks. + + Returns + -------- + List[:class:`Webhook`] + The webhooks for this channel. + """ -class StoreChannel(discord.abc.GuildChannel, Hashable): - """Represents a Discord guild store channel. - - .. container:: operations + from .webhook import Webhook - .. describe:: x == y + data = await self._state.http.channel_webhooks(self.id) + return [Webhook.from_state(d, state=self._state) for d in data] - Checks if two channels are equal. + async def create_webhook(self, *, name: str, avatar: Optional[bytes] = None, reason: Optional[str] = None) -> Webhook: + """|coro| - .. describe:: x != y + Creates a webhook for this channel. - Checks if two channels are not equal. + You must have :attr:`~.Permissions.manage_webhooks` to do this. - .. describe:: hash(x) + Parameters + ------------- + name: :class:`str` + The webhook's name. + avatar: Optional[:class:`bytes`] + A :term:`py:bytes-like object` representing the webhook's default avatar. + This operates similarly to :meth:`~ClientUser.edit`. + reason: Optional[:class:`str`] + The reason for creating this webhook. Shows up in the audit logs. - Returns the channel's hash. + Raises + ------- + HTTPException + Creating the webhook failed. + Forbidden + You do not have permissions to create a webhook. - .. describe:: str(x) + Returns + -------- + :class:`Webhook` + The created webhook. + """ - Returns the channel's name. + from .webhook import Webhook - Attributes - ----------- - name: :class:`str` - The channel name. - guild: :class:`Guild` - The guild the channel belongs to. - id: :class:`int` - The channel ID. - category_id: :class:`int` - The category channel ID this channel belongs to. - position: :class:`int` - The position in the channel list. This is a number that starts at 0. e.g. the - top channel is position 0. - """ - __slots__ = ('name', 'id', 'guild', '_state', 'nsfw', - 'category_id', 'position', '_overwrites',) + if avatar is not None: + avatar = utils._bytes_to_base64_data(avatar) # type: ignore # Silence reassignment error - def __init__(self, *, state, guild, data): - self._state = state - self.id = int(data['id']) - self._update(guild, data) + data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar, reason=reason) + return Webhook.from_state(data, state=self._state) - def __repr__(self): - return ''.format(self) + async def archived_threads( + self, + *, + limit: Optional[int] = 100, + before: Optional[Union[Snowflake, datetime.datetime]] = None, + ) -> AsyncIterator[Thread]: + """Returns an :term:`asynchronous iterator` that iterates over all archived threads in this forum + in order of decreasing :attr:`Thread.archive_timestamp`. - def _update(self, guild, data): - self.guild = guild - self.name = data['name'] - self.category_id = utils._get_as_snowflake(data, 'parent_id') - self.position = data['position'] - self.nsfw = data.get('nsfw', False) - self._fill_overwrites(data) + You must have :attr:`~Permissions.read_message_history` to do this. - @property - def _sorting_bucket(self): - return ChannelType.text.value + .. versionadded:: 2.0 - @property - def type(self): - """:class:`ChannelType`: The channel's Discord type.""" - return ChannelType.store + Parameters + ----------- + limit: Optional[:class:`bool`] + The number of threads to retrieve. + If ``None``, retrieves every archived thread in the channel. Note, however, + that this would make it a slow operation. + before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Retrieve archived channels before the given date or ID. - @utils.copy_doc(discord.abc.GuildChannel.permissions_for) - def permissions_for(self, member): - base = super().permissions_for(member) + Raises + ------ + Forbidden + You do not have permissions to get archived threads. + HTTPException + The request to get the archived threads failed. - # store channels do not have voice related permissions - denied = Permissions.voice() - base.value &= ~denied.value - return base + Yields + ------- + :class:`Thread` + The archived threads. + """ + before_timestamp = None - def is_nsfw(self): - """:class:`bool`: Checks if the channel is NSFW.""" - return self.nsfw + if isinstance(before, datetime.datetime): + before_timestamp = before.isoformat() + elif before is not None: + before_timestamp = utils.snowflake_time(before.id).isoformat() - @utils.copy_doc(discord.abc.GuildChannel.clone) - async def clone(self, *, name=None, reason=None): - return await self._clone_impl({ - 'nsfw': self.nsfw - }, name=name, reason=reason) + update_before = lambda data: data['thread_metadata']['archive_timestamp'] - async def edit(self, *, reason=None, **options): - """|coro| + while True: + retrieve = 100 + if limit is not None: + if limit <= 0: + return + retrieve = max(2, min(retrieve, limit)) - Edits the channel. + data = await self.guild._state.http.get_public_archived_threads(self.id, before=before_timestamp, limit=retrieve) - You must have the :attr:`~Permissions.manage_channels` permission to - use this. + threads = data.get('threads', []) + for raw_thread in threads: + yield Thread(guild=self.guild, state=self.guild._state, data=raw_thread) + # Currently the API doesn't let you request less than 2 threads. + # Bail out early if we had to retrieve more than what the limit was. + if limit is not None: + limit -= 1 + if limit <= 0: + return - Parameters - ---------- - name: :class:`str` - The new channel name. - position: :class:`int` - The new channel's position. - nsfw: :class:`bool` - To mark the channel as NSFW or not. - sync_permissions: :class:`bool` - Whether to sync permissions with the channel's new or pre-existing - category. Defaults to ``False``. - category: Optional[:class:`CategoryChannel`] - The new category for this channel. Can be ``None`` to remove the - category. - reason: Optional[:class:`str`] - The reason for editing this channel. Shows up on the audit log. - overwrites: :class:`dict` - A :class:`dict` of target (either a role or a member) to - :class:`PermissionOverwrite` to apply to the channel. + if not data.get('has_more', False): + return - .. versionadded:: 1.3 + before_timestamp = update_before(threads[-1]) - Raises - ------ - InvalidArgument - If position is less than 0 or greater than the number of channels, or if - the permission overwrite information is not in proper form. - Forbidden - You do not have permissions to edit the channel. - HTTPException - Editing the channel failed. - """ - await self._edit(options, reason=reason) -class DMChannel(discord.abc.Messageable, Hashable): +class DMChannel(discord.abc.Messageable, discord.abc.PrivateChannel, Hashable): """Represents a Discord direct message channel. .. container:: operations @@ -1199,8 +2876,10 @@ class DMChannel(discord.abc.Messageable, Hashable): Attributes ---------- - recipient: :class:`User` + recipient: Optional[:class:`User`] The user you are participating with in the direct message channel. + If this channel is received through the gateway, the recipient information + may not be always available. me: :class:`ClientUser` The user presenting yourself. id: :class:`int` @@ -1209,32 +2888,67 @@ class DMChannel(discord.abc.Messageable, Hashable): __slots__ = ('id', 'recipient', 'me', '_state') - def __init__(self, *, me, state, data): - self._state = state - self.recipient = state.store_user(data['recipients'][0]) - self.me = me - self.id = int(data['id']) + def __init__(self, *, me: ClientUser, state: ConnectionState, data: DMChannelPayload): + self._state: ConnectionState = state + self.recipient: Optional[User] = None + + recipients = data.get('recipients') + if recipients is not None: + self.recipient = state.store_user(recipients[0]) + + self.me: ClientUser = me + self.id: int = int(data['id']) - async def _get_channel(self): + async def _get_channel(self) -> Self: return self - def __str__(self): - return 'Direct Message with %s' % self.recipient + def __str__(self) -> str: + if self.recipient: + return f'Direct Message with {self.recipient}' + return 'Direct Message with Unknown User' - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' + + @classmethod + def _from_message(cls, state: ConnectionState, channel_id: int) -> Self: + self = cls.__new__(cls) + self._state = state + self.id = channel_id + self.recipient = None + # state.user won't be None here + self.me = state.user # type: ignore + return self @property - def type(self): + def type(self) -> Literal[ChannelType.private]: """:class:`ChannelType`: The channel's Discord type.""" return ChannelType.private @property - def created_at(self): + def guild(self) -> Optional[Guild]: + """Optional[:class:`Guild`]: The guild this DM channel belongs to. Always ``None``. + + This is mainly provided for compatibility purposes in duck typing. + + .. versionadded:: 2.0 + """ + return None + + @property + def jump_url(self) -> str: + """:class:`str`: Returns a URL that allows the client to jump to the channel. + + .. versionadded:: 2.0 + """ + return f'https://discord.com/channels/@me/{self.id}' + + @property + def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the direct message channel's creation time in UTC.""" return utils.snowflake_time(self.id) - def permissions_for(self, user=None): + def permissions_for(self, obj: Any = None, /) -> Permissions: """Handles permission resolution for a :class:`User`. This function is there for compatibility with other channel types. @@ -1245,26 +2959,33 @@ def permissions_for(self, user=None): - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM. - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM. + - :attr:`~Permissions.create_private_threads`: There are no threads in a DM. + - :attr:`~Permissions.create_public_threads`: There are no threads in a DM. + - :attr:`~Permissions.manage_threads`: There are no threads in a DM. + - :attr:`~Permissions.send_messages_in_threads`: There are no threads in a DM. + + .. versionchanged:: 2.0 + + ``obj`` parameter is now positional-only. + + .. versionchanged:: 2.1 + + Thread related permissions are now set to ``False``. Parameters ----------- - user: :class:`User` + obj: :class:`User` The user to check permissions for. This parameter is ignored - but kept for compatibility. + but kept for compatibility with other ``permissions_for`` methods. Returns -------- :class:`Permissions` The resolved permissions. """ + return Permissions._dm_permissions() - base = Permissions.text() - base.read_messages = True - base.send_tts_messages = False - base.manage_messages = False - return base - - def get_partial_message(self, message_id): + def get_partial_message(self, message_id: int, /) -> PartialMessage: """Creates a :class:`PartialMessage` from the message ID. This is useful if you want to work with a message and only have its ID without @@ -1272,6 +2993,10 @@ def get_partial_message(self, message_id): .. versionadded:: 1.6 + .. versionchanged:: 2.0 + + ``message_id`` parameter is now positional-only. + Parameters ------------ message_id: :class:`int` @@ -1284,9 +3009,11 @@ def get_partial_message(self, message_id): """ from .message import PartialMessage + return PartialMessage(channel=self, id=message_id) -class GroupChannel(discord.abc.Messageable, Hashable): + +class GroupChannel(discord.abc.Messageable, discord.abc.PrivateChannel, Hashable): """Represents a Discord group channel. .. container:: operations @@ -1315,41 +3042,40 @@ class GroupChannel(discord.abc.Messageable, Hashable): The user presenting yourself. id: :class:`int` The group channel ID. - owner: :class:`User` + owner: Optional[:class:`User`] The user that owns the group channel. - icon: Optional[:class:`str`] - The group channel's icon hash if provided. + owner_id: :class:`int` + The owner ID that owns the group channel. + + .. versionadded:: 2.0 name: Optional[:class:`str`] The group channel's name if provided. """ - __slots__ = ('id', 'recipients', 'owner', 'icon', 'name', 'me', '_state') + __slots__ = ('id', 'recipients', 'owner_id', 'owner', '_icon', 'name', 'me', '_state') - def __init__(self, *, me, state, data): - self._state = state - self.id = int(data['id']) - self.me = me + def __init__(self, *, me: ClientUser, state: ConnectionState, data: GroupChannelPayload): + self._state: ConnectionState = state + self.id: int = int(data['id']) + self.me: ClientUser = me self._update_group(data) - def _update_group(self, data): - owner_id = utils._get_as_snowflake(data, 'owner_id') - self.icon = data.get('icon') - self.name = data.get('name') + def _update_group(self, data: GroupChannelPayload) -> None: + self.owner_id: Optional[int] = utils._get_as_snowflake(data, 'owner_id') + self._icon: Optional[str] = data.get('icon') + self.name: Optional[str] = data.get('name') + self.recipients: List[User] = [self._state.store_user(u) for u in data.get('recipients', [])] - try: - self.recipients = [self._state.store_user(u) for u in data['recipients']] - except KeyError: - pass - - if owner_id == self.me.id: + self.owner: Optional[BaseUser] + if self.owner_id == self.me.id: self.owner = self.me else: - self.owner = utils.find(lambda u: u.id == owner_id, self.recipients) + self.owner = utils.find(lambda u: u.id == self.owner_id, self.recipients) - async def _get_channel(self): + async def _get_channel(self) -> Self: return self - def __str__(self): + def __str__(self) -> str: if self.name: return self.name @@ -1358,56 +3084,45 @@ def __str__(self): return ', '.join(map(lambda x: x.name, self.recipients)) - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' @property - def type(self): + def type(self) -> Literal[ChannelType.group]: """:class:`ChannelType`: The channel's Discord type.""" return ChannelType.group @property - def icon_url(self): - """:class:`Asset`: Returns the channel's icon asset if available. + def guild(self) -> Optional[Guild]: + """Optional[:class:`Guild`]: The guild this group channel belongs to. Always ``None``. - This is equivalent to calling :meth:`icon_url_as` with - the default parameters ('webp' format and a size of 1024). - """ - return self.icon_url_as() - - def icon_url_as(self, *, format='webp', size=1024): - """Returns an :class:`Asset` for the icon the channel has. - - The format must be one of 'webp', 'jpeg', 'jpg' or 'png'. - The size must be a power of 2 between 16 and 4096. + This is mainly provided for compatibility purposes in duck typing. .. versionadded:: 2.0 - - Parameters - ----------- - format: :class:`str` - The format to attempt to convert the icon to. Defaults to 'webp'. - size: :class:`int` - The size of the image to display. - - Raises - ------ - InvalidArgument - Bad image format passed to ``format`` or invalid ``size``. - - Returns - -------- - :class:`Asset` - The resulting CDN asset. """ - return Asset._from_icon(self._state, self, 'channel', format=format, size=size) + return None @property - def created_at(self): + def icon(self) -> Optional[Asset]: + """Optional[:class:`Asset`]: Returns the channel's icon asset if available.""" + if self._icon is None: + return None + return Asset._from_icon(self._state, self.id, self._icon, path='channel') + + @property + def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return utils.snowflake_time(self.id) - def permissions_for(self, user): + @property + def jump_url(self) -> str: + """:class:`str`: Returns a URL that allows the client to jump to the channel. + + .. versionadded:: 2.0 + """ + return f'https://discord.com/channels/@me/{self.id}' + + def permissions_for(self, obj: Snowflake, /) -> Permissions: """Handles permission resolution for a :class:`User`. This function is there for compatibility with other channel types. @@ -1418,12 +3133,24 @@ def permissions_for(self, user): - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM. - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM. + - :attr:`~Permissions.create_private_threads`: There are no threads in a DM. + - :attr:`~Permissions.create_public_threads`: There are no threads in a DM. + - :attr:`~Permissions.manage_threads`: There are no threads in a DM. + - :attr:`~Permissions.send_messages_in_threads`: There are no threads in a DM. This also checks the kick_members permission if the user is the owner. + .. versionchanged:: 2.0 + + ``obj`` parameter is now positional-only. + + .. versionchanged:: 2.1 + + Thread related permissions are now set to ``False``. + Parameters ----------- - user: :class:`User` + obj: :class:`~discord.abc.Snowflake` The user to check permissions for. Returns @@ -1432,138 +3159,174 @@ def permissions_for(self, user): The resolved permissions for the user. """ - base = Permissions.text() - base.read_messages = True - base.send_tts_messages = False - base.manage_messages = False + base = Permissions._dm_permissions() base.mention_everyone = True - if user.id == self.owner.id: + if obj.id == self.owner_id: base.kick_members = True return base - @utils.deprecated() - async def add_recipients(self, *recipients): - r"""|coro| - - Adds recipients to this group. - - A group can only have a maximum of 10 members. - Attempting to add more ends up in an exception. To - add a recipient to the group, you must have a relationship - with the user of type :attr:`RelationshipType.friend`. + async def leave(self) -> None: + """|coro| - .. deprecated:: 1.7 + Leave the group. - Parameters - ----------- - \*recipients: :class:`User` - An argument list of users to add to this group. + If you are the only one in the group, this deletes it as well. Raises ------- HTTPException - Adding a recipient to this group failed. + Leaving the group failed. """ - # TODO: wait for the corresponding WS event + await self._state.http.leave_group(self.id) - req = self._state.http.add_group_recipient - for recipient in recipients: - await req(self.id, recipient.id) - @utils.deprecated() - async def remove_recipients(self, *recipients): - r"""|coro| +class PartialMessageable(discord.abc.Messageable, Hashable): + """Represents a partial messageable to aid with working messageable channels when + only a channel ID is present. - Removes recipients from this group. + The only way to construct this class is through :meth:`Client.get_partial_messageable`. - .. deprecated:: 1.7 + Note that this class is trimmed down and has no rich attributes. - Parameters - ----------- - \*recipients: :class:`User` - An argument list of users to remove from this group. + .. versionadded:: 2.0 - Raises - ------- - HTTPException - Removing a recipient from this group failed. - """ + .. container:: operations + + .. describe:: x == y + + Checks if two partial messageables are equal. - # TODO: wait for the corresponding WS event + .. describe:: x != y - req = self._state.http.remove_group_recipient - for recipient in recipients: - await req(self.id, recipient.id) + Checks if two partial messageables are not equal. - @utils.deprecated() - async def edit(self, **fields): - """|coro| + .. describe:: hash(x) + + Returns the partial messageable's hash. + + Attributes + ----------- + id: :class:`int` + The channel ID associated with this partial messageable. + guild_id: Optional[:class:`int`] + The guild ID associated with this partial messageable. + type: Optional[:class:`ChannelType`] + The channel type associated with this partial messageable, if given. + """ + + def __init__(self, state: ConnectionState, id: int, guild_id: Optional[int] = None, type: Optional[ChannelType] = None): + self._state: ConnectionState = state + self.id: int = id + self.guild_id: Optional[int] = guild_id + self.type: Optional[ChannelType] = type - Edits the group. + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id={self.id} type={self.type!r}>' - .. deprecated:: 1.7 + async def _get_channel(self) -> PartialMessageable: + return self + + @property + def guild(self) -> Optional[Guild]: + """Optional[:class:`Guild`]: The guild this partial messageable is in.""" + return self._state._get_guild(self.guild_id) + + @property + def jump_url(self) -> str: + """:class:`str`: Returns a URL that allows the client to jump to the channel.""" + if self.guild_id is None: + return f'https://discord.com/channels/@me/{self.id}' + return f'https://discord.com/channels/{self.guild_id}/{self.id}' + + @property + def created_at(self) -> datetime.datetime: + """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" + return utils.snowflake_time(self.id) + + def permissions_for(self, obj: Any = None, /) -> Permissions: + """Handles permission resolution for a :class:`User`. + + This function is there for compatibility with other channel types. + + Since partial messageables cannot reasonably have the concept of + permissions, this will always return :meth:`Permissions.none`. Parameters ----------- - name: Optional[:class:`str`] - The new name to change the group to. - Could be ``None`` to remove the name. - icon: Optional[:class:`bytes`] - A :term:`py:bytes-like object` representing the new icon. - Could be ``None`` to remove the icon. + obj: :class:`User` + The user to check permissions for. This parameter is ignored + but kept for compatibility with other ``permissions_for`` methods. - Raises - ------- - HTTPException - Editing the group failed. + Returns + -------- + :class:`Permissions` + The resolved permissions. """ - try: - icon_bytes = fields['icon'] - except KeyError: - pass - else: - if icon_bytes is not None: - fields['icon'] = utils._bytes_to_base64_data(icon_bytes) - - data = await self._state.http.edit_group(self.id, **fields) - self._update_group(data) + return Permissions.none() - async def leave(self): - """|coro| + def get_partial_message(self, message_id: int, /) -> PartialMessage: + """Creates a :class:`PartialMessage` from the message ID. - Leave the group. + This is useful if you want to work with a message and only have its ID without + doing an unnecessary API call. - If you are the only one in the group, this deletes it as well. + Parameters + ------------ + message_id: :class:`int` + The message ID to create a partial message for. - Raises - ------- - HTTPException - Leaving the group failed. + Returns + --------- + :class:`PartialMessage` + The partial message. """ - await self._state.http.leave_group(self.id) + from .message import PartialMessage -def _channel_factory(channel_type): + return PartialMessage(channel=self, id=message_id) + + +def _guild_channel_factory(channel_type: int): value = try_enum(ChannelType, channel_type) if value is ChannelType.text: return TextChannel, value elif value is ChannelType.voice: return VoiceChannel, value - elif value is ChannelType.private: - return DMChannel, value elif value is ChannelType.category: return CategoryChannel, value - elif value is ChannelType.group: - return GroupChannel, value elif value is ChannelType.news: return TextChannel, value - elif value is ChannelType.store: - return StoreChannel, value elif value is ChannelType.stage_voice: return StageChannel, value + elif value is ChannelType.forum: + return ForumChannel, value else: return None, value + + +def _channel_factory(channel_type: int): + cls, value = _guild_channel_factory(channel_type) + if value is ChannelType.private: + return DMChannel, value + elif value is ChannelType.group: + return GroupChannel, value + else: + return cls, value + + +def _threaded_channel_factory(channel_type: int): + cls, value = _channel_factory(channel_type) + if value in (ChannelType.private_thread, ChannelType.public_thread, ChannelType.news_thread): + return Thread, value + return cls, value + + +def _threaded_guild_channel_factory(channel_type: int): + cls, value = _guild_channel_factory(channel_type) + if value in (ChannelType.private_thread, ChannelType.public_thread, ChannelType.news_thread): + return Thread, value + return cls, value diff --git a/dist/ba_data/python-site-packages/discord/client.py b/dist/ba_data/python-site-packages/discord/client.py index 1c35fddf..c4c59e75 100644 --- a/dist/ba_data/python-site-packages/discord/client.py +++ b/dist/ba_data/python-site-packages/discord/client.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,96 +22,139 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + import asyncio +import datetime import logging -import signal -import sys -import traceback +from typing import ( + TYPE_CHECKING, + Any, + AsyncIterator, + Callable, + Coroutine, + Dict, + Generator, + List, + Literal, + Optional, + Sequence, + Tuple, + Type, + TypeVar, + Union, + overload, +) import aiohttp -from .user import User, Profile +from .user import User, ClientUser from .invite import Invite from .template import Template from .widget import Widget from .guild import Guild -from .channel import _channel_factory +from .emoji import Emoji +from .channel import _threaded_channel_factory, PartialMessageable from .enums import ChannelType from .mentions import AllowedMentions from .errors import * -from .enums import Status, VoiceRegion +from .enums import Status +from .flags import ApplicationFlags, Intents from .gateway import * -from .activity import BaseActivity, create_activity +from .activity import ActivityTypes, BaseActivity, create_activity from .voice_client import VoiceClient from .http import HTTPClient from .state import ConnectionState from . import utils +from .utils import MISSING, time_snowflake from .object import Object from .backoff import ExponentialBackoff from .webhook import Webhook -from .iterators import GuildIterator from .appinfo import AppInfo +from .ui.view import View +from .stage_instance import StageInstance +from .threads import Thread +from .sticker import GuildSticker, StandardSticker, StickerPack, _sticker_factory + +if TYPE_CHECKING: + from types import TracebackType + + from typing_extensions import Self + + from .abc import Messageable, PrivateChannel, Snowflake, SnowflakeTime + from .app_commands import Command, ContextMenu + from .automod import AutoModAction, AutoModRule + from .channel import DMChannel, GroupChannel + from .ext.commands import AutoShardedBot, Bot, Context, CommandError + from .guild import GuildChannel + from .integrations import Integration + from .interactions import Interaction + from .member import Member, VoiceState + from .message import Message + from .raw_models import ( + RawAppCommandPermissionsUpdateEvent, + RawBulkMessageDeleteEvent, + RawIntegrationDeleteEvent, + RawMemberRemoveEvent, + RawMessageDeleteEvent, + RawMessageUpdateEvent, + RawReactionActionEvent, + RawReactionClearEmojiEvent, + RawReactionClearEvent, + RawThreadDeleteEvent, + RawThreadMembersUpdate, + RawThreadUpdateEvent, + RawTypingEvent, + ) + from .reaction import Reaction + from .role import Role + from .scheduled_event import ScheduledEvent + from .threads import ThreadMember + from .types.guild import Guild as GuildPayload + from .voice_client import VoiceProtocol + from .audit_logs import AuditLogEntry + + +# fmt: off +__all__ = ( + 'Client', +) +# fmt: on + +T = TypeVar('T') +Coro = Coroutine[Any, Any, T] +CoroT = TypeVar('CoroT', bound=Callable[..., Coro[Any]]) + +_log = logging.getLogger(__name__) + + +class _LoopSentinel: + __slots__ = () + + def __getattr__(self, attr: str) -> None: + msg = ( + 'loop attribute cannot be accessed in non-async contexts. ' + 'Consider using either an asynchronous main function and passing it to asyncio.run or ' + 'using asynchronous initialisation hooks such as Client.setup_hook' + ) + raise AttributeError(msg) + + +_loop: Any = _LoopSentinel() -log = logging.getLogger(__name__) - -def _cancel_tasks(loop): - try: - task_retriever = asyncio.Task.all_tasks - except AttributeError: - # future proofing for 3.9 I guess - task_retriever = asyncio.all_tasks - - tasks = {t for t in task_retriever(loop=loop) if not t.done()} - - if not tasks: - return - - log.info('Cleaning up after %d tasks.', len(tasks)) - for task in tasks: - task.cancel() - - loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True)) - log.info('All tasks finished cancelling.') - - for task in tasks: - if task.cancelled(): - continue - if task.exception() is not None: - loop.call_exception_handler({ - 'message': 'Unhandled exception during Client.run shutdown.', - 'exception': task.exception(), - 'task': task - }) - -def _cleanup_loop(loop): - try: - _cancel_tasks(loop) - if sys.version_info >= (3, 6): - loop.run_until_complete(loop.shutdown_asyncgens()) - finally: - log.info('Closing the event loop.') - loop.close() - -class _ClientEventTask(asyncio.Task): - def __init__(self, original_coro, event_name, coro, *, loop): - super().__init__(coro, loop=loop) - self.__event_name = event_name - self.__original_coro = original_coro - - def __repr__(self): - info = [ - ('state', self._state.lower()), - ('event', self.__event_name), - ('coro', repr(self.__original_coro)), - ] - if self._exception is not None: - info.append(('exception', repr(self._exception))) - return ''.format(' '.join('%s=%s' % t for t in info)) class Client: r"""Represents a client connection that connects to Discord. This class is used to interact with the Discord WebSocket and API. + .. container:: operations + + .. describe:: async with x + + Asynchronously initialises the client and automatically cleans up. + + .. versionadded:: 2.0 + A number of options can be passed to the :class:`Client`. Parameters @@ -124,12 +165,6 @@ class Client: .. versionchanged:: 1.3 Allow disabling the message cache and change the default size to ``1000``. - loop: Optional[:class:`asyncio.AbstractEventLoop`] - The :class:`asyncio.AbstractEventLoop` to use for asynchronous operations. - Defaults to ``None``, in which case the default event loop is used via - :func:`asyncio.get_event_loop()`. - connector: :class:`aiohttp.BaseConnector` - The connector to use for connection pooling. proxy: Optional[:class:`str`] Proxy URL. proxy_auth: Optional[:class:`aiohttp.BasicAuth`] @@ -138,20 +173,22 @@ class Client: Integer starting at ``0`` and less than :attr:`.shard_count`. shard_count: Optional[:class:`int`] The total number of shards. + application_id: :class:`int` + The client's application ID. intents: :class:`Intents` The intents that you want to enable for the session. This is a way of disabling and enabling certain gateway events from triggering and being sent. - If not given, defaults to a regularly constructed :class:`Intents` class. .. versionadded:: 1.5 + + .. versionchanged:: 2.0 + Parameter is now required. member_cache_flags: :class:`MemberCacheFlags` Allows for finer control over how the library caches members. If not given, defaults to cache as much as possible with the currently selected intents. .. versionadded:: 1.5 - fetch_offline_members: :class:`bool` - A deprecated alias of ``chunk_guilds_at_startup``. chunk_guilds_at_startup: :class:`bool` Indicates if :func:`.on_ready` should be delayed to chunk all guilds at start-up if necessary. This operation is incredibly slow for large @@ -177,37 +214,6 @@ class Client: preparing the member cache and firing READY. The default timeout is 2 seconds. .. versionadded:: 1.4 - guild_subscriptions: :class:`bool` - Whether to dispatch presence or typing events. Defaults to ``True``. - - .. versionadded:: 1.3 - - .. warning:: - - If this is set to ``False`` then the following features will be disabled: - - - No user related updates (:func:`on_user_update` will not dispatch) - - All member related events will be disabled. - - :func:`on_member_update` - - :func:`on_member_join` - - :func:`on_member_remove` - - - Typing events will be disabled (:func:`on_typing`). - - If ``fetch_offline_members`` is set to ``False`` then the user cache will not exist. - This makes it difficult or impossible to do many things, for example: - - - Computing permissions - - Querying members in a voice channel via :attr:`VoiceChannel.members` will be empty. - - Most forms of receiving :class:`Member` will be - receiving :class:`User` instead, except for message events. - - :attr:`Guild.owner` will usually resolve to ``None``. - - :meth:`Guild.get_member` will usually be unavailable. - - Anything that involves using :class:`Member`. - - :attr:`users` will not be as populated. - - etc. - - In short, this makes it so the only member you can reliably query is the - message author. Useful for bots that do not require any state. assume_unsync_clock: :class:`bool` Whether to assume the system clock is unsynced. This applies to the ratelimit handling code. If this is set to ``True``, the default, then the library uses the time to reset @@ -216,63 +222,104 @@ class Client: sync your system clock to Google's NTP server. .. versionadded:: 1.3 + enable_debug_events: :class:`bool` + Whether to enable events that are useful only for debugging gateway related information. + + Right now this involves :func:`on_socket_raw_receive` and :func:`on_socket_raw_send`. If + this is ``False`` then those events will not be dispatched (due to performance considerations). + To enable these events, this must be set to ``True``. Defaults to ``False``. + + .. versionadded:: 2.0 + http_trace: :class:`aiohttp.TraceConfig` + The trace configuration to use for tracking HTTP requests the library does using ``aiohttp``. + This allows you to check requests the library is using. For more information, check the + `aiohttp documentation `_. + + .. versionadded:: 2.0 + max_ratelimit_timeout: Optional[:class:`float`] + The maximum number of seconds to wait when a non-global rate limit is encountered. + If a request requires sleeping for more than the seconds passed in, then + :exc:`~discord.RateLimited` will be raised. By default, there is no timeout limit. + In order to prevent misuse and unnecessary bans, the minimum value this can be + set to is ``30.0`` seconds. + + .. versionadded:: 2.0 Attributes ----------- ws The websocket gateway the client is currently connected to. Could be ``None``. - loop: :class:`asyncio.AbstractEventLoop` - The event loop that the client uses for HTTP requests and websocket operations. """ - def __init__(self, *, loop=None, **options): - self.ws = None - self.loop = asyncio.get_event_loop() if loop is None else loop - self._listeners = {} - self.shard_id = options.get('shard_id') - self.shard_count = options.get('shard_count') - - connector = options.pop('connector', None) - proxy = options.pop('proxy', None) - proxy_auth = options.pop('proxy_auth', None) - unsync_clock = options.pop('assume_unsync_clock', True) - self.http = HTTPClient(connector, proxy=proxy, proxy_auth=proxy_auth, unsync_clock=unsync_clock, loop=self.loop) - - self._handlers = { - 'ready': self._handle_ready + + def __init__(self, *, intents: Intents, **options: Any) -> None: + self.loop: asyncio.AbstractEventLoop = _loop + # self.ws is set in the connect method + self.ws: DiscordWebSocket = None # type: ignore + self._listeners: Dict[str, List[Tuple[asyncio.Future, Callable[..., bool]]]] = {} + self.shard_id: Optional[int] = options.get('shard_id') + self.shard_count: Optional[int] = options.get('shard_count') + + proxy: Optional[str] = options.pop('proxy', None) + proxy_auth: Optional[aiohttp.BasicAuth] = options.pop('proxy_auth', None) + unsync_clock: bool = options.pop('assume_unsync_clock', True) + http_trace: Optional[aiohttp.TraceConfig] = options.pop('http_trace', None) + max_ratelimit_timeout: Optional[float] = options.pop('max_ratelimit_timeout', None) + self.http: HTTPClient = HTTPClient( + self.loop, + proxy=proxy, + proxy_auth=proxy_auth, + unsync_clock=unsync_clock, + http_trace=http_trace, + max_ratelimit_timeout=max_ratelimit_timeout, + ) + + self._handlers: Dict[str, Callable[..., None]] = { + 'ready': self._handle_ready, } - self._hooks = { - 'before_identify': self._call_before_identify_hook + self._hooks: Dict[str, Callable[..., Coroutine[Any, Any, Any]]] = { + 'before_identify': self._call_before_identify_hook, } - self._connection = self._get_state(**options) + self._enable_debug_events: bool = options.pop('enable_debug_events', False) + self._connection: ConnectionState[Self] = self._get_state(intents=intents, **options) self._connection.shard_count = self.shard_count - self._closed = False - self._ready = asyncio.Event() + self._closed: bool = False + self._ready: asyncio.Event = MISSING + self._application: Optional[AppInfo] = None self._connection._get_websocket = self._get_websocket self._connection._get_client = lambda: self if VoiceClient.warn_nacl: VoiceClient.warn_nacl = False - log.warning("PyNaCl is not installed, voice will NOT be supported") + _log.warning("PyNaCl is not installed, voice will NOT be supported") + + async def __aenter__(self) -> Self: + await self._async_setup_hook() + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> None: + if not self.is_closed(): + await self.close() # internals - def _get_websocket(self, guild_id=None, *, shard_id=None): + def _get_websocket(self, guild_id: Optional[int] = None, *, shard_id: Optional[int] = None) -> DiscordWebSocket: return self.ws - def _get_state(self, **options): - return ConnectionState(dispatch=self.dispatch, handlers=self._handlers, - hooks=self._hooks, syncer=self._syncer, http=self.http, loop=self.loop, **options) + def _get_state(self, **options: Any) -> ConnectionState: + return ConnectionState(dispatch=self.dispatch, handlers=self._handlers, hooks=self._hooks, http=self.http, **options) - async def _syncer(self, guilds): - await self.ws.request_sync(guilds) - - def _handle_ready(self): + def _handle_ready(self) -> None: self._ready.set() @property - def latency(self): + def latency(self) -> float: """:class:`float`: Measures latency between a HEARTBEAT and a HEARTBEAT_ACK in seconds. This could be referred to as the Discord WebSocket protocol latency. @@ -280,7 +327,7 @@ def latency(self): ws = self.ws return float('nan') if not ws else ws.latency - def is_ws_ratelimited(self): + def is_ws_ratelimited(self) -> bool: """:class:`bool`: Whether the websocket is currently rate limited. This can be useful to know when deciding whether you should query members @@ -293,22 +340,30 @@ def is_ws_ratelimited(self): return False @property - def user(self): + def user(self) -> Optional[ClientUser]: """Optional[:class:`.ClientUser`]: Represents the connected client. ``None`` if not logged in.""" return self._connection.user @property - def guilds(self): - """List[:class:`.Guild`]: The guilds that the connected client is a member of.""" + def guilds(self) -> Sequence[Guild]: + """Sequence[:class:`.Guild`]: The guilds that the connected client is a member of.""" return self._connection.guilds @property - def emojis(self): - """List[:class:`.Emoji`]: The emojis that the connected client has.""" + def emojis(self) -> Sequence[Emoji]: + """Sequence[:class:`.Emoji`]: The emojis that the connected client has.""" return self._connection.emojis @property - def cached_messages(self): + def stickers(self) -> Sequence[GuildSticker]: + """Sequence[:class:`.GuildSticker`]: The stickers that the connected client has. + + .. versionadded:: 2.0 + """ + return self._connection.stickers + + @property + def cached_messages(self) -> Sequence[Message]: """Sequence[:class:`.Message`]: Read-only list of messages the connected client has cached. .. versionadded:: 1.1 @@ -316,8 +371,8 @@ def cached_messages(self): return utils.SequenceProxy(self._connection._messages or []) @property - def private_channels(self): - """List[:class:`.abc.PrivateChannel`]: The private channels that the connected client is participating on. + def private_channels(self) -> Sequence[PrivateChannel]: + """Sequence[:class:`.abc.PrivateChannel`]: The private channels that the connected client is participating on. .. note:: @@ -327,18 +382,61 @@ def private_channels(self): return self._connection.private_channels @property - def voice_clients(self): + def voice_clients(self) -> List[VoiceProtocol]: """List[:class:`.VoiceProtocol`]: Represents a list of voice connections. These are usually :class:`.VoiceClient` instances. """ return self._connection.voice_clients - def is_ready(self): - """:class:`bool`: Specifies if the client's internal cache is ready for use.""" - return self._ready.is_set() + @property + def application_id(self) -> Optional[int]: + """Optional[:class:`int`]: The client's application ID. + + If this is not passed via ``__init__`` then this is retrieved + through the gateway when an event contains the data or after a call + to :meth:`~discord.Client.login`. Usually after :func:`~discord.on_connect` + is called. + + .. versionadded:: 2.0 + """ + return self._connection.application_id - async def _run_event(self, coro, event_name, *args, **kwargs): + @property + def application_flags(self) -> ApplicationFlags: + """:class:`~discord.ApplicationFlags`: The client's application flags. + + .. versionadded:: 2.0 + """ + return self._connection.application_flags + + @property + def application(self) -> Optional[AppInfo]: + """Optional[:class:`~discord.AppInfo`]: The client's application info. + + This is retrieved on :meth:`~discord.Client.login` and is not updated + afterwards. This allows populating the application_id without requiring a + gateway connection. + + This is ``None`` if accessed before :meth:`~discord.Client.login` is called. + + .. seealso:: The :meth:`~discord.Client.application_info` API call + + .. versionadded:: 2.0 + """ + return self._application + + def is_ready(self) -> bool: + """:class:`bool`: Specifies if the client's internal cache is ready for use.""" + return self._ready is not MISSING and self._ready.is_set() + + async def _run_event( + self, + coro: Callable[..., Coroutine[Any, Any, Any]], + event_name: str, + *args: Any, + **kwargs: Any, + ) -> None: try: await coro(*args, **kwargs) except asyncio.CancelledError: @@ -349,13 +447,19 @@ async def _run_event(self, coro, event_name, *args, **kwargs): except asyncio.CancelledError: pass - def _schedule_event(self, coro, event_name, *args, **kwargs): + def _schedule_event( + self, + coro: Callable[..., Coroutine[Any, Any, Any]], + event_name: str, + *args: Any, + **kwargs: Any, + ) -> asyncio.Task: wrapped = self._run_event(coro, event_name, *args, **kwargs) # Schedules the task - return _ClientEventTask(original_coro=coro, event_name=event_name, coro=wrapped, loop=self.loop) + return self.loop.create_task(wrapped, name=f'discord.py: {event_name}') - def dispatch(self, event, *args, **kwargs): - log.debug('Dispatching event %s', event) + def dispatch(self, event: str, /, *args: Any, **kwargs: Any) -> None: + _log.debug('Dispatching event %s', event) method = 'on_' + event listeners = self._listeners.get(event) @@ -394,61 +498,31 @@ def dispatch(self, event, *args, **kwargs): else: self._schedule_event(coro, method, *args, **kwargs) - async def on_error(self, event_method, *args, **kwargs): + async def on_error(self, event_method: str, /, *args: Any, **kwargs: Any) -> None: """|coro| The default error handler provided by the client. - By default this prints to :data:`sys.stderr` however it could be + By default this logs to the library logger however it could be overridden to have a different implementation. Check :func:`~discord.on_error` for more details. - """ - print('Ignoring exception in {}'.format(event_method), file=sys.stderr) - traceback.print_exc() - - @utils.deprecated('Guild.chunk') - async def request_offline_members(self, *guilds): - r"""|coro| - - Requests previously offline members from the guild to be filled up - into the :attr:`.Guild.members` cache. This function is usually not - called. It should only be used if you have the ``fetch_offline_members`` - parameter set to ``False``. - When the client logs on and connects to the websocket, Discord does - not provide the library with offline members if the number of members - in the guild is larger than 250. You can check if a guild is large - if :attr:`.Guild.large` is ``True``. - - .. warning:: - - This method is deprecated. Use :meth:`Guild.chunk` instead. - - Parameters - ----------- - \*guilds: :class:`.Guild` - An argument list of guilds to request offline members for. + .. versionchanged:: 2.0 - Raises - ------- - :exc:`.InvalidArgument` - If any guild is unavailable in the collection. + ``event_method`` parameter is now positional-only + and instead of writing to ``sys.stderr`` it logs instead. """ - if any(g.unavailable for g in guilds): - raise InvalidArgument('An unavailable guild was passed.') - - for guild in guilds: - await self._connection.chunk_guild(guild) + _log.exception('Ignoring exception in %s', event_method) # hooks - async def _call_before_identify_hook(self, shard_id, *, initial=False): + async def _call_before_identify_hook(self, shard_id: Optional[int], *, initial: bool = False) -> None: # This hook is an internal hook that actually calls the public one. # It allows the library to have its own hook without stepping on the # toes of those who need to override their own hook. await self.before_identify_hook(shard_id, initial=initial) - async def before_identify_hook(self, shard_id, *, initial=False): + async def before_identify_hook(self, shard_id: Optional[int], *, initial: bool = False) -> None: """|coro| A hook that is called before IDENTIFYing a session. This is useful @@ -470,64 +544,83 @@ async def before_identify_hook(self, shard_id, *, initial=False): if not initial: await asyncio.sleep(5.0) - # login state management + async def _async_setup_hook(self) -> None: + # Called whenever the client needs to initialise asyncio objects with a running loop + loop = asyncio.get_running_loop() + self.loop = loop + self.http.loop = loop + self._connection.loop = loop - async def login(self, token, *, bot=True): + self._ready = asyncio.Event() + + async def setup_hook(self) -> None: """|coro| - Logs in the client with the specified credentials. + A coroutine to be called to setup the bot, by default this is blank. + + To perform asynchronous setup after the bot is logged in but before + it has connected to the Websocket, overwrite this coroutine. - This function can be used in two different ways. + This is only called once, in :meth:`login`, and will be called before + any events are dispatched, making it a better solution than doing such + setup in the :func:`~discord.on_ready` event. .. warning:: - Logging on with a user token is against the Discord - `Terms of Service `_ - and doing so might potentially get your account banned. - Use this at your own risk. + Since this is called *before* the websocket connection is made therefore + anything that waits for the websocket will deadlock, this includes things + like :meth:`wait_for` and :meth:`wait_until_ready`. + + .. versionadded:: 2.0 + """ + pass + + # login state management + + async def login(self, token: str) -> None: + """|coro| + + Logs in the client with the specified credentials and + calls the :meth:`setup_hook`. + Parameters ----------- token: :class:`str` The authentication token. Do not prefix this token with anything as the library will do it for you. - bot: :class:`bool` - Keyword argument that specifies if the account logging on is a bot - token or not. - - .. deprecated:: 1.7 Raises ------ - :exc:`.LoginFailure` + LoginFailure The wrong credentials are passed. - :exc:`.HTTPException` + HTTPException An unknown HTTP related error occurred, usually when it isn't 200 or the known incorrect credentials passing status code. """ - log.info('logging in using static token') - await self.http.static_login(token.strip(), bot=bot) - self._connection.is_bot = bot + _log.info('logging in using static token') - @utils.deprecated('Client.close') - async def logout(self): - """|coro| + if self.loop is _loop: + await self._async_setup_hook() - Logs out of Discord and closes all connections. - - .. deprecated:: 1.7 + if not isinstance(token, str): + raise TypeError(f'expected token to be a str, received {token.__class__.__name__} instead') + token = token.strip() - .. note:: + data = await self.http.static_login(token) + self._connection.user = ClientUser(state=self._connection, data=data) + self._application = await self.application_info() + if self._connection.application_id is None: + self._connection.application_id = self._application.id - This is just an alias to :meth:`close`. If you want - to do extraneous cleanup when subclassing, it is suggested - to override :meth:`close` instead. - """ - await self.close() + if not self._connection.application_flags: + self._connection.application_flags = self._application.flags - async def connect(self, *, reconnect=True): + await self.setup_hook() + + async def connect(self, *, reconnect: bool = True) -> None: """|coro| Creates a websocket connection and lets the websocket listen @@ -545,10 +638,10 @@ async def connect(self, *, reconnect=True): Raises ------- - :exc:`.GatewayNotFound` + GatewayNotFound If the gateway to connect to Discord is not found. Usually if this is thrown then there is a Discord API outage. - :exc:`.ConnectionClosed` + ConnectionClosed The websocket connection has been terminated. """ @@ -565,16 +658,20 @@ async def connect(self, *, reconnect=True): while True: await self.ws.poll_event() except ReconnectWebSocket as e: - log.info('Got a request to %s the websocket.', e.op) + _log.debug('Got a request to %s the websocket.', e.op) self.dispatch('disconnect') ws_params.update(sequence=self.ws.sequence, resume=e.resume, session=self.ws.session_id) + if e.resume: + ws_params['gateway'] = self.ws.gateway continue - except (OSError, - HTTPException, - GatewayNotFound, - ConnectionClosed, - aiohttp.ClientError, - asyncio.TimeoutError) as exc: + except ( + OSError, + HTTPException, + GatewayNotFound, + ConnectionClosed, + aiohttp.ClientError, + asyncio.TimeoutError, + ) as exc: self.dispatch('disconnect') if not reconnect: @@ -589,7 +686,13 @@ async def connect(self, *, reconnect=True): # If we get connection reset by peer then try to RESUME if isinstance(exc, OSError) and exc.errno in (54, 10054): - ws_params.update(sequence=self.ws.sequence, initial=False, resume=True, session=self.ws.session_id) + ws_params.update( + sequence=self.ws.sequence, + gateway=self.ws.gateway, + initial=False, + resume=True, + session=self.ws.session_id, + ) continue # We should only get this when an unhandled close code happens, @@ -604,14 +707,19 @@ async def connect(self, *, reconnect=True): raise retry = backoff.delay() - log.exception("Attempting a reconnect in %.2fs", retry) + _log.exception("Attempting a reconnect in %.2fs", retry) await asyncio.sleep(retry) # Always try to RESUME the connection # If the connection is not RESUME-able then the gateway will invalidate the session. # This is apparently what the official Discord client does. - ws_params.update(sequence=self.ws.sequence, resume=True, session=self.ws.session_id) - - async def close(self): + ws_params.update( + sequence=self.ws.sequence, + gateway=self.ws.gateway, + resume=True, + session=self.ws.session_id, + ) + + async def close(self) -> None: """|coro| Closes the connection to Discord. @@ -619,22 +727,21 @@ async def close(self): if self._closed: return - await self.http.close() self._closed = True - for voice in self.voice_clients: - try: - await voice.disconnect() - except Exception: - # if an error happens during disconnects, disregard it. - pass + await self._connection.close() if self.ws is not None and self.ws.open: await self.ws.close(code=1000) - self._ready.clear() + await self.http.close() + + if self._ready is not MISSING: + self._ready.clear() - def clear(self): + self.loop = MISSING + + def clear(self) -> None: """Clears the internal state of the bot. After this, the bot can be considered "re-opened", i.e. :meth:`is_closed` @@ -644,28 +751,42 @@ def clear(self): self._closed = False self._ready.clear() self._connection.clear() - self.http.recreate() + self.http.clear() - async def start(self, *args, **kwargs): + async def start(self, token: str, *, reconnect: bool = True) -> None: """|coro| A shorthand coroutine for :meth:`login` + :meth:`connect`. + Parameters + ----------- + token: :class:`str` + The authentication token. Do not prefix this token with + anything as the library will do it for you. + reconnect: :class:`bool` + If we should attempt reconnecting, either due to internet + failure or a specific failure on Discord's part. Certain + disconnects that lead to bad state will not be handled (such as + invalid sharding payloads or bad tokens). + Raises ------- TypeError An unexpected keyword argument was received. """ - bot = kwargs.pop('bot', True) - reconnect = kwargs.pop('reconnect', True) - - if kwargs: - raise TypeError("unexpected keyword argument(s) %s" % list(kwargs.keys())) - - await self.login(*args, bot=bot) + await self.login(token) await self.connect(reconnect=reconnect) - def run(self, *args, **kwargs): + def run( + self, + token: str, + *, + reconnect: bool = True, + log_handler: Optional[logging.Handler] = MISSING, + log_formatter: logging.Formatter = MISSING, + log_level: int = MISSING, + root_logger: bool = False, + ) -> None: """A blocking call that abstracts away the event loop initialisation from you. @@ -673,82 +794,121 @@ def run(self, *args, **kwargs): function should not be used. Use :meth:`start` coroutine or :meth:`connect` + :meth:`login`. - Roughly Equivalent to: :: - - try: - loop.run_until_complete(start(*args, **kwargs)) - except KeyboardInterrupt: - loop.run_until_complete(close()) - # cancel all tasks lingering - finally: - loop.close() + This function also sets up the logging library to make it easier + for beginners to know what is going on with the library. For more + advanced users, this can be disabled by passing ``None`` to + the ``log_handler`` parameter. .. warning:: This function must be the last function to call due to the fact that it is blocking. That means that registration of events or anything being called after this function call will not execute until it returns. - """ - loop = self.loop - try: - loop.add_signal_handler(signal.SIGINT, lambda: loop.stop()) - loop.add_signal_handler(signal.SIGTERM, lambda: loop.stop()) - except NotImplementedError: - pass + Parameters + ----------- + token: :class:`str` + The authentication token. Do not prefix this token with + anything as the library will do it for you. + reconnect: :class:`bool` + If we should attempt reconnecting, either due to internet + failure or a specific failure on Discord's part. Certain + disconnects that lead to bad state will not be handled (such as + invalid sharding payloads or bad tokens). + log_handler: Optional[:class:`logging.Handler`] + The log handler to use for the library's logger. If this is ``None`` + then the library will not set up anything logging related. Logging + will still work if ``None`` is passed, though it is your responsibility + to set it up. + + The default log handler if not provided is :class:`logging.StreamHandler`. + + .. versionadded:: 2.0 + log_formatter: :class:`logging.Formatter` + The formatter to use with the given log handler. If not provided then it + defaults to a colour based logging formatter (if available). + + .. versionadded:: 2.0 + log_level: :class:`int` + The default log level for the library's logger. This is only applied if the + ``log_handler`` parameter is not ``None``. Defaults to ``logging.INFO``. + + .. versionadded:: 2.0 + root_logger: :class:`bool` + Whether to set up the root logger rather than the library logger. + By default, only the library logger (``'discord'``) is set up. If this + is set to ``True`` then the root logger is set up as well. + + Defaults to ``False``. + + .. versionadded:: 2.0 + """ async def runner(): - try: - await self.start(*args, **kwargs) - finally: - if not self.is_closed(): - await self.close() + async with self: + await self.start(token, reconnect=reconnect) - def stop_loop_on_completion(f): - loop.stop() + if log_handler is not None: + utils.setup_logging( + handler=log_handler, + formatter=log_formatter, + level=log_level, + root=root_logger, + ) - future = asyncio.ensure_future(runner(), loop=loop) - future.add_done_callback(stop_loop_on_completion) try: - loop.run_forever() + asyncio.run(runner()) except KeyboardInterrupt: - log.info('Received signal to terminate bot and event loop.') - finally: - future.remove_done_callback(stop_loop_on_completion) - log.info('Cleaning up tasks.') - _cleanup_loop(loop) - - if not future.cancelled(): - try: - return future.result() - except KeyboardInterrupt: - # I am unsure why this gets raised here but suppress it anyway - return None + # nothing to do here + # `asyncio.run` handles the loop cleanup + # and `self.start` closes all sockets and the HTTPClient instance. + return # properties - def is_closed(self): + def is_closed(self) -> bool: """:class:`bool`: Indicates if the websocket connection is closed.""" return self._closed @property - def activity(self): + def activity(self) -> Optional[ActivityTypes]: """Optional[:class:`.BaseActivity`]: The activity being used upon logging in. """ - return create_activity(self._connection._activity) + return create_activity(self._connection._activity, self._connection) @activity.setter - def activity(self, value): + def activity(self, value: Optional[ActivityTypes]) -> None: if value is None: self._connection._activity = None elif isinstance(value, BaseActivity): - self._connection._activity = value.to_dict() + # ConnectionState._activity is typehinted as ActivityPayload, we're passing Dict[str, Any] + self._connection._activity = value.to_dict() # type: ignore else: raise TypeError('activity must derive from BaseActivity.') @property - def allowed_mentions(self): + def status(self) -> Status: + """:class:`.Status`: + The status being used upon logging on to Discord. + + .. versionadded: 2.0 + """ + if self._connection._status in set(state.value for state in Status): + return Status(self._connection._status) + return Status.online + + @status.setter + def status(self, value: Status) -> None: + if value is Status.offline: + self._connection._status = 'invisible' + elif isinstance(value, Status): + self._connection._status = str(value) + else: + raise TypeError('status must derive from Status.') + + @property + def allowed_mentions(self) -> Optional[AllowedMentions]: """Optional[:class:`~discord.AllowedMentions`]: The allowed mention configuration. .. versionadded:: 1.4 @@ -756,14 +916,14 @@ def allowed_mentions(self): return self._connection.allowed_mentions @allowed_mentions.setter - def allowed_mentions(self, value): + def allowed_mentions(self, value: Optional[AllowedMentions]) -> None: if value is None or isinstance(value, AllowedMentions): self._connection.allowed_mentions = value else: - raise TypeError('allowed_mentions must be AllowedMentions not {0.__class__!r}'.format(value)) + raise TypeError(f'allowed_mentions must be AllowedMentions not {value.__class__.__name__}') @property - def intents(self): + def intents(self) -> Intents: """:class:`~discord.Intents`: The intents configured for this connection. .. versionadded:: 1.5 @@ -773,12 +933,16 @@ def intents(self): # helpers/getters @property - def users(self): + def users(self) -> List[User]: """List[:class:`~discord.User`]: Returns a list of all the users the bot can see.""" return list(self._connection._users.values()) - def get_channel(self, id): - """Returns a channel with the given ID. + def get_channel(self, id: int, /) -> Optional[Union[GuildChannel, Thread, PrivateChannel]]: + """Returns a channel or thread with the given ID. + + .. versionchanged:: 2.0 + + ``id`` parameter is now positional-only. Parameters ----------- @@ -787,14 +951,70 @@ def get_channel(self, id): Returns -------- - Optional[Union[:class:`.abc.GuildChannel`, :class:`.abc.PrivateChannel`]] + Optional[Union[:class:`.abc.GuildChannel`, :class:`.Thread`, :class:`.abc.PrivateChannel`]] The returned channel or ``None`` if not found. """ - return self._connection.get_channel(id) + return self._connection.get_channel(id) # type: ignore # The cache contains all channel types + + def get_partial_messageable( + self, id: int, *, guild_id: Optional[int] = None, type: Optional[ChannelType] = None + ) -> PartialMessageable: + """Returns a partial messageable with the given channel ID. + + This is useful if you have a channel_id but don't want to do an API call + to send messages to it. + + .. versionadded:: 2.0 + + Parameters + ----------- + id: :class:`int` + The channel ID to create a partial messageable for. + guild_id: Optional[:class:`int`] + The optional guild ID to create a partial messageable for. + + This is not required to actually send messages, but it does allow the + :meth:`~discord.PartialMessageable.jump_url` and + :attr:`~discord.PartialMessageable.guild` properties to function properly. + type: Optional[:class:`.ChannelType`] + The underlying channel type for the partial messageable. + + Returns + -------- + :class:`.PartialMessageable` + The partial messageable + """ + return PartialMessageable(state=self._connection, id=id, guild_id=guild_id, type=type) + + def get_stage_instance(self, id: int, /) -> Optional[StageInstance]: + """Returns a stage instance with the given stage channel ID. + + .. versionadded:: 2.0 + + Parameters + ----------- + id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[:class:`.StageInstance`] + The stage instance or ``None`` if not found. + """ + from .channel import StageChannel + + channel = self._connection.get_channel(id) - def get_guild(self, id): + if isinstance(channel, StageChannel): + return channel.instance + + def get_guild(self, id: int, /) -> Optional[Guild]: """Returns a guild with the given ID. + .. versionchanged:: 2.0 + + ``id`` parameter is now positional-only. + Parameters ----------- id: :class:`int` @@ -807,9 +1027,13 @@ def get_guild(self, id): """ return self._connection._get_guild(id) - def get_user(self, id): + def get_user(self, id: int, /) -> Optional[User]: """Returns a user with the given ID. + .. versionchanged:: 2.0 + + ``id`` parameter is now positional-only. + Parameters ----------- id: :class:`int` @@ -822,9 +1046,13 @@ def get_user(self, id): """ return self._connection.get_user(id) - def get_emoji(self, id): + def get_emoji(self, id: int, /) -> Optional[Emoji]: """Returns an emoji with the given ID. + .. versionchanged:: 2.0 + + ``id`` parameter is now positional-only. + Parameters ----------- id: :class:`int` @@ -837,7 +1065,24 @@ def get_emoji(self, id): """ return self._connection.get_emoji(id) - def get_all_channels(self): + def get_sticker(self, id: int, /) -> Optional[GuildSticker]: + """Returns a guild sticker with the given ID. + + .. versionadded:: 2.0 + + .. note:: + + To retrieve standard stickers, use :meth:`.fetch_sticker`. + or :meth:`.fetch_premium_sticker_packs`. + + Returns + -------- + Optional[:class:`.GuildSticker`] + The sticker or ``None`` if not found. + """ + return self._connection.get_sticker(id) + + def get_all_channels(self) -> Generator[GuildChannel, None, None]: """A generator that retrieves every :class:`.abc.GuildChannel` the client can 'access'. This is equivalent to: :: @@ -859,10 +1104,9 @@ def get_all_channels(self): """ for guild in self.guilds: - for channel in guild.channels: - yield channel + yield from guild.channels - def get_all_members(self): + def get_all_members(self) -> Generator[Member, None, None]: """Returns a generator with every :class:`.Member` the client can see. This is equivalent to: :: @@ -877,19 +1121,736 @@ def get_all_members(self): A member the client can see. """ for guild in self.guilds: - for member in guild.members: - yield member + yield from guild.members # listeners/waiters - async def wait_until_ready(self): + async def wait_until_ready(self) -> None: """|coro| Waits until the client's internal cache is all ready. - """ - await self._ready.wait() - def wait_for(self, event, *, check=None, timeout=None): + .. warning:: + + Calling this inside :meth:`setup_hook` can lead to a deadlock. + """ + if self._ready is not MISSING: + await self._ready.wait() + else: + raise RuntimeError( + 'Client has not been properly initialised. ' + 'Please use the login method or asynchronous context manager before calling this method' + ) + + # App Commands + + @overload + async def wait_for( + self, + event: Literal['raw_app_command_permissions_update'], + /, + *, + check: Optional[Callable[[RawAppCommandPermissionsUpdateEvent], bool]], + timeout: Optional[float] = None, + ) -> RawAppCommandPermissionsUpdateEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['app_command_completion'], + /, + *, + check: Optional[Callable[[Interaction[Self], Union[Command[Any, ..., Any], ContextMenu]], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Interaction[Self], Union[Command[Any, ..., Any], ContextMenu]]: + ... + + # AutoMod + + @overload + async def wait_for( + self, + event: Literal['automod_rule_create', 'automod_rule_update', 'automod_rule_delete'], + /, + *, + check: Optional[Callable[[AutoModRule], bool]], + timeout: Optional[float] = None, + ) -> AutoModRule: + ... + + @overload + async def wait_for( + self, + event: Literal['automod_action'], + /, + *, + check: Optional[Callable[[AutoModAction], bool]], + timeout: Optional[float] = None, + ) -> AutoModAction: + ... + + # Channels + + @overload + async def wait_for( + self, + event: Literal['private_channel_update'], + /, + *, + check: Optional[Callable[[GroupChannel, GroupChannel], bool]], + timeout: Optional[float] = None, + ) -> Tuple[GroupChannel, GroupChannel]: + ... + + @overload + async def wait_for( + self, + event: Literal['private_channel_pins_update'], + /, + *, + check: Optional[Callable[[PrivateChannel, datetime.datetime], bool]], + timeout: Optional[float] = None, + ) -> Tuple[PrivateChannel, datetime.datetime]: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_channel_delete', 'guild_channel_create'], + /, + *, + check: Optional[Callable[[GuildChannel], bool]], + timeout: Optional[float] = None, + ) -> GuildChannel: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_channel_update'], + /, + *, + check: Optional[Callable[[GuildChannel, GuildChannel], bool]], + timeout: Optional[float] = None, + ) -> Tuple[GuildChannel, GuildChannel]: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_channel_pins_update'], + /, + *, + check: Optional[ + Callable[ + [Union[GuildChannel, Thread], Optional[datetime.datetime]], + bool, + ] + ], + timeout: Optional[float] = None, + ) -> Tuple[Union[GuildChannel, Thread], Optional[datetime.datetime]]: + ... + + @overload + async def wait_for( + self, + event: Literal['typing'], + /, + *, + check: Optional[Callable[[Messageable, Union[User, Member], datetime.datetime], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Messageable, Union[User, Member], datetime.datetime]: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_typing'], + /, + *, + check: Optional[Callable[[RawTypingEvent], bool]], + timeout: Optional[float] = None, + ) -> RawTypingEvent: + ... + + # Debug & Gateway events + + @overload + async def wait_for( + self, + event: Literal['connect', 'disconnect', 'ready', 'resumed'], + /, + *, + check: Optional[Callable[[], bool]], + timeout: Optional[float] = None, + ) -> None: + ... + + @overload + async def wait_for( + self, + event: Literal['shard_connect', 'shard_disconnect', 'shard_ready', 'shard_resumed'], + /, + *, + check: Optional[Callable[[int], bool]], + timeout: Optional[float] = None, + ) -> int: + ... + + @overload + async def wait_for( + self, + event: Literal['socket_event_type', 'socket_raw_receive'], + /, + *, + check: Optional[Callable[[str], bool]], + timeout: Optional[float] = None, + ) -> str: + ... + + @overload + async def wait_for( + self, + event: Literal['socket_raw_send'], + /, + *, + check: Optional[Callable[[Union[str, bytes]], bool]], + timeout: Optional[float] = None, + ) -> Union[str, bytes]: + ... + + # Guilds + + @overload + async def wait_for( + self, + event: Literal[ + 'guild_available', + 'guild_unavailable', + 'guild_join', + 'guild_remove', + ], + /, + *, + check: Optional[Callable[[Guild], bool]], + timeout: Optional[float] = None, + ) -> Guild: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_update'], + /, + *, + check: Optional[Callable[[Guild, Guild], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Guild, Guild]: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_emojis_update'], + /, + *, + check: Optional[Callable[[Guild, Sequence[Emoji], Sequence[Emoji]], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Guild, Sequence[Emoji], Sequence[Emoji]]: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_stickers_update'], + /, + *, + check: Optional[Callable[[Guild, Sequence[GuildSticker], Sequence[GuildSticker]], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Guild, Sequence[GuildSticker], Sequence[GuildSticker]]: + ... + + @overload + async def wait_for( + self, + event: Literal['invite_create', 'invite_delete'], + /, + *, + check: Optional[Callable[[Invite], bool]], + timeout: Optional[float] = None, + ) -> Invite: + ... + + @overload + async def wait_for( + self, + event: Literal['audit_log_entry_create'], + /, + *, + check: Optional[Callable[[AuditLogEntry], bool]], + timeout: Optional[float] = None, + ) -> AuditLogEntry: + ... + + # Integrations + + @overload + async def wait_for( + self, + event: Literal['integration_create', 'integration_update'], + /, + *, + check: Optional[Callable[[Integration], bool]], + timeout: Optional[float] = None, + ) -> Integration: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_integrations_update'], + /, + *, + check: Optional[Callable[[Guild], bool]], + timeout: Optional[float] = None, + ) -> Guild: + ... + + @overload + async def wait_for( + self, + event: Literal['webhooks_update'], + /, + *, + check: Optional[Callable[[GuildChannel], bool]], + timeout: Optional[float] = None, + ) -> GuildChannel: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_integration_delete'], + /, + *, + check: Optional[Callable[[RawIntegrationDeleteEvent], bool]], + timeout: Optional[float] = None, + ) -> RawIntegrationDeleteEvent: + ... + + # Interactions + + @overload + async def wait_for( + self, + event: Literal['interaction'], + /, + *, + check: Optional[Callable[[Interaction[Self]], bool]], + timeout: Optional[float] = None, + ) -> Interaction[Self]: + ... + + # Members + + @overload + async def wait_for( + self, + event: Literal['member_join', 'member_remove'], + /, + *, + check: Optional[Callable[[Member], bool]], + timeout: Optional[float] = None, + ) -> Member: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_member_remove'], + /, + *, + check: Optional[Callable[[RawMemberRemoveEvent], bool]], + timeout: Optional[float] = None, + ) -> RawMemberRemoveEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['member_update', 'presence_update'], + /, + *, + check: Optional[Callable[[Member, Member], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Member, Member]: + ... + + @overload + async def wait_for( + self, + event: Literal['user_update'], + /, + *, + check: Optional[Callable[[User, User], bool]], + timeout: Optional[float] = None, + ) -> Tuple[User, User]: + ... + + @overload + async def wait_for( + self, + event: Literal['member_ban'], + /, + *, + check: Optional[Callable[[Guild, Union[User, Member]], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Guild, Union[User, Member]]: + ... + + @overload + async def wait_for( + self, + event: Literal['member_unban'], + /, + *, + check: Optional[Callable[[Guild, User], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Guild, User]: + ... + + # Messages + + @overload + async def wait_for( + self, + event: Literal['message', 'message_delete'], + /, + *, + check: Optional[Callable[[Message], bool]], + timeout: Optional[float] = None, + ) -> Message: + ... + + @overload + async def wait_for( + self, + event: Literal['message_edit'], + /, + *, + check: Optional[Callable[[Message, Message], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Message, Message]: + ... + + @overload + async def wait_for( + self, + event: Literal['bulk_message_delete'], + /, + *, + check: Optional[Callable[[List[Message]], bool]], + timeout: Optional[float] = None, + ) -> List[Message]: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_message_edit'], + /, + *, + check: Optional[Callable[[RawMessageUpdateEvent], bool]], + timeout: Optional[float] = None, + ) -> RawMessageUpdateEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_message_delete'], + /, + *, + check: Optional[Callable[[RawMessageDeleteEvent], bool]], + timeout: Optional[float] = None, + ) -> RawMessageDeleteEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_bulk_message_delete'], + /, + *, + check: Optional[Callable[[RawBulkMessageDeleteEvent], bool]], + timeout: Optional[float] = None, + ) -> RawBulkMessageDeleteEvent: + ... + + # Reactions + + @overload + async def wait_for( + self, + event: Literal['reaction_add', 'reaction_remove'], + /, + *, + check: Optional[Callable[[Reaction, Union[Member, User]], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Reaction, Union[Member, User]]: + ... + + @overload + async def wait_for( + self, + event: Literal['reaction_clear'], + /, + *, + check: Optional[Callable[[Message, List[Reaction]], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Message, List[Reaction]]: + ... + + @overload + async def wait_for( + self, + event: Literal['reaction_clear_emoji'], + /, + *, + check: Optional[Callable[[Reaction], bool]], + timeout: Optional[float] = None, + ) -> Reaction: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_reaction_add', 'raw_reaction_remove'], + /, + *, + check: Optional[Callable[[RawReactionActionEvent], bool]], + timeout: Optional[float] = None, + ) -> RawReactionActionEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_reaction_clear'], + /, + *, + check: Optional[Callable[[RawReactionClearEvent], bool]], + timeout: Optional[float] = None, + ) -> RawReactionClearEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_reaction_clear_emoji'], + /, + *, + check: Optional[Callable[[RawReactionClearEmojiEvent], bool]], + timeout: Optional[float] = None, + ) -> RawReactionClearEmojiEvent: + ... + + # Roles + + @overload + async def wait_for( + self, + event: Literal['guild_role_create', 'guild_role_delete'], + /, + *, + check: Optional[Callable[[Role], bool]], + timeout: Optional[float] = None, + ) -> Role: + ... + + @overload + async def wait_for( + self, + event: Literal['guild_role_update'], + /, + *, + check: Optional[Callable[[Role, Role], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Role, Role]: + ... + + # Scheduled Events + + @overload + async def wait_for( + self, + event: Literal['scheduled_event_create', 'scheduled_event_delete'], + /, + *, + check: Optional[Callable[[ScheduledEvent], bool]], + timeout: Optional[float] = None, + ) -> ScheduledEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['scheduled_event_user_add', 'scheduled_event_user_remove'], + /, + *, + check: Optional[Callable[[ScheduledEvent, User], bool]], + timeout: Optional[float] = None, + ) -> Tuple[ScheduledEvent, User]: + ... + + # Stages + + @overload + async def wait_for( + self, + event: Literal['stage_instance_create', 'stage_instance_delete'], + /, + *, + check: Optional[Callable[[StageInstance], bool]], + timeout: Optional[float] = None, + ) -> StageInstance: + ... + + @overload + async def wait_for( + self, + event: Literal['stage_instance_update'], + /, + *, + check: Optional[Callable[[StageInstance, StageInstance], bool]], + timeout: Optional[float] = None, + ) -> Coroutine[Any, Any, Tuple[StageInstance, StageInstance]]: + ... + + # Threads + @overload + async def wait_for( + self, + event: Literal['thread_create', 'thread_join', 'thread_remove', 'thread_delete'], + /, + *, + check: Optional[Callable[[Thread], bool]], + timeout: Optional[float] = None, + ) -> Thread: + ... + + @overload + async def wait_for( + self, + event: Literal['thread_update'], + /, + *, + check: Optional[Callable[[Thread, Thread], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Thread, Thread]: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_thread_update'], + /, + *, + check: Optional[Callable[[RawThreadUpdateEvent], bool]], + timeout: Optional[float] = None, + ) -> RawThreadUpdateEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_thread_delete'], + /, + *, + check: Optional[Callable[[RawThreadDeleteEvent], bool]], + timeout: Optional[float] = None, + ) -> RawThreadDeleteEvent: + ... + + @overload + async def wait_for( + self, + event: Literal['thread_member_join', 'thread_member_remove'], + /, + *, + check: Optional[Callable[[ThreadMember], bool]], + timeout: Optional[float] = None, + ) -> ThreadMember: + ... + + @overload + async def wait_for( + self, + event: Literal['raw_thread_member_remove'], + /, + *, + check: Optional[Callable[[RawThreadMembersUpdate], bool]], + timeout: Optional[float] = None, + ) -> RawThreadMembersUpdate: + ... + + # Voice + + @overload + async def wait_for( + self, + event: Literal['voice_state_update'], + /, + *, + check: Optional[Callable[[Member, VoiceState, VoiceState], bool]], + timeout: Optional[float] = None, + ) -> Tuple[Member, VoiceState, VoiceState]: + ... + + # Commands + + @overload + async def wait_for( + self: Union[Bot, AutoShardedBot], + event: Literal["command", "command_completion"], + /, + *, + check: Optional[Callable[[Context[Any]], bool]] = None, + timeout: Optional[float] = None, + ) -> Context[Any]: + ... + + @overload + async def wait_for( + self: Union[Bot, AutoShardedBot], + event: Literal["command_error"], + /, + *, + check: Optional[Callable[[Context[Any], CommandError], bool]] = None, + timeout: Optional[float] = None, + ) -> Tuple[Context[Any], CommandError]: + ... + + @overload + async def wait_for( + self, + event: str, + /, + *, + check: Optional[Callable[..., bool]] = None, + timeout: Optional[float] = None, + ) -> Any: + ... + + def wait_for( + self, + event: str, + /, + *, + check: Optional[Callable[..., bool]] = None, + timeout: Optional[float] = None, + ) -> Coro[Any]: """|coro| Waits for a WebSocket event to be dispatched. @@ -925,7 +1886,7 @@ def check(m): return m.content == 'hello' and m.channel == channel msg = await client.wait_for('message', check=check) - await channel.send('Hello {.author}!'.format(msg)) + await channel.send(f'Hello {msg.author}!') Waiting for a thumbs up reaction from the message author: :: @@ -945,6 +1906,10 @@ def check(reaction, user): else: await channel.send('\N{THUMBS UP SIGN}') + .. versionchanged:: 2.0 + + ``event`` parameter is now positional-only. + Parameters ------------ @@ -973,8 +1938,10 @@ def check(reaction, user): future = self.loop.create_future() if check is None: + def _check(*args): return True + check = _check ev = event.lower() @@ -989,7 +1956,7 @@ def _check(*args): # event registration - def event(self, coro): + def event(self, coro: CoroT, /) -> CoroT: """A decorator that registers an event to listen to. You can find more info about the events on the :ref:`documentation below `. @@ -1005,6 +1972,10 @@ def event(self, coro): async def on_ready(): print('Ready!') + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Raises -------- TypeError @@ -1015,10 +1986,15 @@ async def on_ready(): raise TypeError('event registered must be a coroutine function') setattr(self, coro.__name__, coro) - log.debug('%s has successfully been registered as an event', coro.__name__) + _log.debug('%s has successfully been registered as an event', coro.__name__) return coro - async def change_presence(self, *, activity=None, status=None, afk=False): + async def change_presence( + self, + *, + activity: Optional[BaseActivity] = None, + status: Optional[Status] = None, + ) -> None: """|coro| Changes the client's presence. @@ -1031,6 +2007,13 @@ async def change_presence(self, *, activity=None, status=None, afk=False): game = discord.Game("with the API") await client.change_presence(status=discord.Status.idle, activity=game) + .. versionchanged:: 2.0 + Removed the ``afk`` keyword-only parameter. + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` instead of + ``InvalidArgument``. + Parameters ---------- activity: Optional[:class:`.BaseActivity`] @@ -1038,28 +2021,23 @@ async def change_presence(self, *, activity=None, status=None, afk=False): status: Optional[:class:`.Status`] Indicates what status to change to. If ``None``, then :attr:`.Status.online` is used. - afk: Optional[:class:`bool`] - Indicates if you are going AFK. This allows the discord - client to know how to handle push notifications better - for you in case you are actually idle and not lying. Raises ------ - :exc:`.InvalidArgument` + TypeError If the ``activity`` parameter is not the proper type. """ if status is None: - status = 'online' - status_enum = Status.online + status_str = 'online' + status = Status.online elif status is Status.offline: - status = 'invisible' - status_enum = Status.offline + status_str = 'invisible' + status = Status.offline else: - status_enum = status - status = str(status) + status_str = str(status) - await self.ws.change_presence(activity=activity, status=status, afk=afk) + await self.ws.change_presence(activity=activity, status=status_str) for guild in self._connection.guilds: me = guild.me @@ -1067,21 +2045,29 @@ async def change_presence(self, *, activity=None, status=None, afk=False): continue if activity is not None: - me.activities = (activity,) + me.activities = (activity,) # type: ignore # Type checker does not understand the downcast here else: me.activities = () - me.status = status_enum + me.status = status # Guild stuff - def fetch_guilds(self, *, limit=100, before=None, after=None): - """Retrieves an :class:`.AsyncIterator` that enables receiving your guilds. + async def fetch_guilds( + self, + *, + limit: Optional[int] = 200, + before: Optional[SnowflakeTime] = None, + after: Optional[SnowflakeTime] = None, + with_counts: bool = True, + ) -> AsyncIterator[Guild]: + """Retrieves an :term:`asynchronous iterator` that enables receiving your guilds. .. note:: Using this, you will only receive :attr:`.Guild.owner`, :attr:`.Guild.icon`, - :attr:`.Guild.id`, and :attr:`.Guild.name` per :class:`.Guild`. + :attr:`.Guild.id`, :attr:`.Guild.name`, :attr:`.Guild.approximate_member_count`, + and :attr:`.Guild.approximate_presence_count` per :class:`.Guild`. .. note:: @@ -1097,7 +2083,7 @@ def fetch_guilds(self, *, limit=100, before=None, after=None): Flattening into a list :: - guilds = await client.fetch_guilds(limit=150).flatten() + guilds = [guild async for guild in client.fetch_guilds(limit=150)] # guilds is now a list of Guild... All parameters are optional. @@ -1108,17 +2094,30 @@ def fetch_guilds(self, *, limit=100, before=None, after=None): The number of guilds to retrieve. If ``None``, it retrieves every guild you have access to. Note, however, that this would make it a slow operation. - Defaults to ``100``. + Defaults to ``200``. + + .. versionchanged:: 2.0 + + The default has been changed to 200. + before: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`] Retrieves guilds before this date or object. - If a date is provided it must be a timezone-naive datetime representing UTC time. + If a datetime is provided, it is recommended to use a UTC aware datetime. + If the datetime is naive, it is assumed to be local time. after: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`] Retrieve guilds after this date or object. - If a date is provided it must be a timezone-naive datetime representing UTC time. + If a datetime is provided, it is recommended to use a UTC aware datetime. + If the datetime is naive, it is assumed to be local time. + with_counts: :class:`bool` + Whether to include count information in the guilds. This fills the + :attr:`.Guild.approximate_member_count` and :attr:`.Guild.approximate_presence_count` + attributes without needing any privileged intents. Defaults to ``True``. + + .. versionadded:: 2.3 Raises ------ - :exc:`.HTTPException` + HTTPException Getting the guilds failed. Yields @@ -1126,9 +2125,65 @@ def fetch_guilds(self, *, limit=100, before=None, after=None): :class:`.Guild` The guild with the guild data parsed. """ - return GuildIterator(self, limit=limit, before=before, after=after) - async def fetch_template(self, code): + async def _before_strategy(retrieve: int, before: Optional[Snowflake], limit: Optional[int]): + before_id = before.id if before else None + data = await self.http.get_guilds(retrieve, before=before_id, with_counts=with_counts) + + if data: + if limit is not None: + limit -= len(data) + + before = Object(id=int(data[0]['id'])) + + return data, before, limit + + async def _after_strategy(retrieve: int, after: Optional[Snowflake], limit: Optional[int]): + after_id = after.id if after else None + data = await self.http.get_guilds(retrieve, after=after_id, with_counts=with_counts) + + if data: + if limit is not None: + limit -= len(data) + + after = Object(id=int(data[-1]['id'])) + + return data, after, limit + + if isinstance(before, datetime.datetime): + before = Object(id=time_snowflake(before, high=False)) + if isinstance(after, datetime.datetime): + after = Object(id=time_snowflake(after, high=True)) + + predicate: Optional[Callable[[GuildPayload], bool]] = None + strategy, state = _after_strategy, after + + if before: + strategy, state = _before_strategy, before + + if before and after: + predicate = lambda m: int(m['id']) > after.id + + while True: + retrieve = 200 if limit is None else min(limit, 200) + if retrieve < 1: + return + + data, state, limit = await strategy(retrieve, state, limit) + + if predicate: + data = filter(predicate, data) + + count = 0 + + for count, raw_guild in enumerate(data, 1): + yield Guild(state=self._connection, data=raw_guild) + + if count < 200: + # There's no data left after this + break + + async def fetch_template(self, code: Union[Template, str]) -> Template: """|coro| Gets a :class:`.Template` from a discord.new URL or code. @@ -1140,9 +2195,9 @@ async def fetch_template(self, code): Raises ------- - :exc:`.NotFound` + NotFound The template is invalid. - :exc:`.HTTPException` + HTTPException Getting the template failed. Returns @@ -1154,7 +2209,7 @@ async def fetch_template(self, code): data = await self.http.get_template(code) return Template(data=data, state=self._connection) - async def fetch_guild(self, guild_id): + async def fetch_guild(self, guild_id: int, /, *, with_counts: bool = True) -> Guild: """|coro| Retrieves a :class:`.Guild` from an ID. @@ -1168,16 +2223,27 @@ async def fetch_guild(self, guild_id): This method is an API call. For general usage, consider :meth:`get_guild` instead. + .. versionchanged:: 2.0 + + ``guild_id`` parameter is now positional-only. + + Parameters ----------- guild_id: :class:`int` The guild's ID to fetch from. + with_counts: :class:`bool` + Whether to include count information in the guild. This fills the + :attr:`.Guild.approximate_member_count` and :attr:`.Guild.approximate_presence_count` + attributes without needing any privileged intents. Defaults to ``True``. + + .. versionadded:: 2.0 Raises ------ - :exc:`.Forbidden` + Forbidden You do not have access to the guild. - :exc:`.HTTPException` + HTTPException Getting the guild failed. Returns @@ -1185,36 +2251,46 @@ async def fetch_guild(self, guild_id): :class:`.Guild` The guild from the ID. """ - data = await self.http.get_guild(guild_id) + data = await self.http.get_guild(guild_id, with_counts=with_counts) return Guild(data=data, state=self._connection) - async def create_guild(self, name, region=None, icon=None, *, code=None): + async def create_guild( + self, + *, + name: str, + icon: bytes = MISSING, + code: str = MISSING, + ) -> Guild: """|coro| Creates a :class:`.Guild`. Bot accounts in more than 10 guilds are not allowed to create guilds. + .. versionchanged:: 2.0 + ``name`` and ``icon`` parameters are now keyword-only. The ``region`` parameter has been removed. + + .. versionchanged:: 2.0 + This function will now raise :exc:`ValueError` instead of + ``InvalidArgument``. + Parameters ---------- name: :class:`str` The name of the guild. - region: :class:`.VoiceRegion` - The region for the voice communication server. - Defaults to :attr:`.VoiceRegion.us_west`. - icon: :class:`bytes` + icon: Optional[:class:`bytes`] The :term:`py:bytes-like object` representing the icon. See :meth:`.ClientUser.edit` for more details on what is expected. - code: Optional[:class:`str`] + code: :class:`str` The code for a template to create the guild with. .. versionadded:: 1.4 Raises ------ - :exc:`.HTTPException` + HTTPException Guild creation failed. - :exc:`.InvalidArgument` + ValueError Invalid icon image format given. Must be PNG or JPG. Returns @@ -1223,21 +2299,56 @@ async def create_guild(self, name, region=None, icon=None, *, code=None): The guild created. This is not the same guild that is added to cache. """ - if icon is not None: - icon = utils._bytes_to_base64_data(icon) - - region = region or VoiceRegion.us_west - region_value = region.value + if icon is not MISSING: + icon_base64 = utils._bytes_to_base64_data(icon) + else: + icon_base64 = None if code: - data = await self.http.create_from_template(code, name, region_value, icon) + data = await self.http.create_from_template(code, name, icon_base64) else: - data = await self.http.create_guild(name, region_value, icon) + data = await self.http.create_guild(name, icon_base64) return Guild(data=data, state=self._connection) + async def fetch_stage_instance(self, channel_id: int, /) -> StageInstance: + """|coro| + + Gets a :class:`.StageInstance` for a stage channel id. + + .. versionadded:: 2.0 + + Parameters + ----------- + channel_id: :class:`int` + The stage channel ID. + + Raises + ------- + NotFound + The stage instance or channel could not be found. + HTTPException + Getting the stage instance failed. + + Returns + -------- + :class:`.StageInstance` + The stage instance from the stage channel ID. + """ + data = await self.http.get_stage_instance(channel_id) + guild = self.get_guild(int(data['guild_id'])) + # Guild can technically be None here but this is being explicitly silenced right now. + return StageInstance(guild=guild, state=self._connection, data=data) # type: ignore + # Invite management - async def fetch_invite(self, url, *, with_counts=True): + async def fetch_invite( + self, + url: Union[Invite, str], + *, + with_counts: bool = True, + with_expiration: bool = True, + scheduled_event_id: Optional[int] = None, + ) -> Invite: """|coro| Gets an :class:`.Invite` from a discord.gg URL or ID. @@ -1256,12 +2367,28 @@ async def fetch_invite(self, url, *, with_counts=True): Whether to include count information in the invite. This fills the :attr:`.Invite.approximate_member_count` and :attr:`.Invite.approximate_presence_count` fields. + with_expiration: :class:`bool` + Whether to include the expiration date of the invite. This fills the + :attr:`.Invite.expires_at` field. + + .. versionadded:: 2.0 + scheduled_event_id: Optional[:class:`int`] + The ID of the scheduled event this invite is for. + + .. note:: + + It is not possible to provide a url that contains an ``event_id`` parameter + when using this parameter. + + .. versionadded:: 2.0 Raises ------- - :exc:`.NotFound` + ValueError + The url contains an ``event_id``, but ``scheduled_event_id`` has also been provided. + NotFound The invite has expired or is invalid. - :exc:`.HTTPException` + HTTPException Getting the invite failed. Returns @@ -1270,18 +2397,33 @@ async def fetch_invite(self, url, *, with_counts=True): The invite from the URL/ID. """ - invite_id = utils.resolve_invite(url) - data = await self.http.get_invite(invite_id, with_counts=with_counts) + resolved = utils.resolve_invite(url) + + if scheduled_event_id and resolved.event: + raise ValueError('Cannot specify scheduled_event_id and contain an event_id in the url.') + + scheduled_event_id = scheduled_event_id or resolved.event + + data = await self.http.get_invite( + resolved.code, + with_counts=with_counts, + with_expiration=with_expiration, + guild_scheduled_event_id=scheduled_event_id, + ) return Invite.from_incomplete(state=self._connection, data=data) - async def delete_invite(self, invite): + async def delete_invite(self, invite: Union[Invite, str], /) -> None: """|coro| Revokes an :class:`.Invite`, URL, or ID to an invite. - You must have the :attr:`~.Permissions.manage_channels` permission in + You must have :attr:`~.Permissions.manage_channels` in the associated guild to do this. + .. versionchanged:: 2.0 + + ``invite`` parameter is now positional-only. + Parameters ---------- invite: Union[:class:`.Invite`, :class:`str`] @@ -1289,20 +2431,20 @@ async def delete_invite(self, invite): Raises ------- - :exc:`.Forbidden` + Forbidden You do not have permissions to revoke invites. - :exc:`.NotFound` + NotFound The invite is invalid or expired. - :exc:`.HTTPException` + HTTPException Revoking the invite failed. """ - invite_id = utils.resolve_invite(invite) - await self.http.delete_invite(invite_id) + resolved = utils.resolve_invite(invite) + await self.http.delete_invite(resolved.code) # Miscellaneous stuff - async def fetch_widget(self, guild_id): + async def fetch_widget(self, guild_id: int, /) -> Widget: """|coro| Gets a :class:`.Widget` from a guild ID. @@ -1311,6 +2453,10 @@ async def fetch_widget(self, guild_id): The guild must have the widget enabled to get this information. + .. versionchanged:: 2.0 + + ``guild_id`` parameter is now positional-only. + Parameters ----------- guild_id: :class:`int` @@ -1318,9 +2464,9 @@ async def fetch_widget(self, guild_id): Raises ------- - :exc:`.Forbidden` + Forbidden The widget for this guild is disabled. - :exc:`.HTTPException` + HTTPException Retrieving the widget failed. Returns @@ -1332,14 +2478,14 @@ async def fetch_widget(self, guild_id): return Widget(state=self._connection, data=data) - async def application_info(self): + async def application_info(self) -> AppInfo: """|coro| Retrieves the bot's application information. Raises ------- - :exc:`.HTTPException` + HTTPException Retrieving the information failed somehow. Returns @@ -1348,21 +2494,22 @@ async def application_info(self): The bot's application information. """ data = await self.http.application_info() - if 'rpc_origins' not in data: - data['rpc_origins'] = None return AppInfo(self._connection, data) - async def fetch_user(self, user_id): + async def fetch_user(self, user_id: int, /) -> User: """|coro| - Retrieves a :class:`~discord.User` based on their ID. This can only - be used by bot accounts. You do not have to share any guilds - with the user to get this information, however many operations - do require that you do. + Retrieves a :class:`~discord.User` based on their ID. + You do not have to share any guilds with the user to get this information, + however many operations do require that you do. .. note:: - This method is an API call. If you have :attr:`Intents.members` and member cache enabled, consider :meth:`get_user` instead. + This method is an API call. If you have :attr:`discord.Intents.members` and member cache enabled, consider :meth:`get_user` instead. + + .. versionchanged:: 2.0 + + ``user_id`` parameter is now positional-only. Parameters ----------- @@ -1371,9 +2518,9 @@ async def fetch_user(self, user_id): Raises ------- - :exc:`.NotFound` + NotFound A user with this ID does not exist. - :exc:`.HTTPException` + HTTPException Fetching the user failed. Returns @@ -1384,55 +2531,10 @@ async def fetch_user(self, user_id): data = await self.http.get_user(user_id) return User(state=self._connection, data=data) - @utils.deprecated() - async def fetch_user_profile(self, user_id): - """|coro| - - Gets an arbitrary user's profile. - - .. deprecated:: 1.7 - - .. note:: - - This can only be used by non-bot accounts. - - Parameters - ------------ - user_id: :class:`int` - The ID of the user to fetch their profile for. - - Raises - ------- - :exc:`.Forbidden` - Not allowed to fetch profiles. - :exc:`.HTTPException` - Fetching the profile failed. - - Returns - -------- - :class:`.Profile` - The profile of the user. - """ - - state = self._connection - data = await self.http.get_user_profile(user_id) - - def transform(d): - return state._get_guild(int(d['id'])) - - since = data.get('premium_since') - mutual_guilds = list(filter(None, map(transform, data.get('mutual_guilds', [])))) - user = data['user'] - return Profile(flags=user.get('flags', 0), - premium_since=utils.parse_time(since), - mutual_guilds=mutual_guilds, - user=User(data=user, state=state), - connected_accounts=data['connected_accounts']) - - async def fetch_channel(self, channel_id): + async def fetch_channel(self, channel_id: int, /) -> Union[GuildChannel, PrivateChannel, Thread]: """|coro| - Retrieves a :class:`.abc.GuildChannel` or :class:`.abc.PrivateChannel` with the specified ID. + Retrieves a :class:`.abc.GuildChannel`, :class:`.abc.PrivateChannel`, or :class:`.Thread` with the specified ID. .. note:: @@ -1440,49 +2542,60 @@ async def fetch_channel(self, channel_id): .. versionadded:: 1.2 + .. versionchanged:: 2.0 + + ``channel_id`` parameter is now positional-only. + Raises ------- - :exc:`.InvalidData` + InvalidData An unknown channel type was received from Discord. - :exc:`.HTTPException` + HTTPException Retrieving the channel failed. - :exc:`.NotFound` + NotFound Invalid Channel ID. - :exc:`.Forbidden` + Forbidden You do not have permission to fetch this channel. Returns -------- - Union[:class:`.abc.GuildChannel`, :class:`.abc.PrivateChannel`] + Union[:class:`.abc.GuildChannel`, :class:`.abc.PrivateChannel`, :class:`.Thread`] The channel from the ID. """ data = await self.http.get_channel(channel_id) - factory, ch_type = _channel_factory(data['type']) + factory, ch_type = _threaded_channel_factory(data['type']) if factory is None: raise InvalidData('Unknown channel type {type} for channel ID {id}.'.format_map(data)) if ch_type in (ChannelType.group, ChannelType.private): - channel = factory(me=self.user, data=data, state=self._connection) + # the factory will be a DMChannel or GroupChannel here + channel = factory(me=self.user, data=data, state=self._connection) # type: ignore else: - guild_id = int(data['guild_id']) - guild = self.get_guild(guild_id) or Object(id=guild_id) - channel = factory(guild=guild, state=self._connection, data=data) + # the factory can't be a DMChannel or GroupChannel here + guild_id = int(data['guild_id']) # type: ignore + guild = self._connection._get_or_create_unavailable_guild(guild_id) + # the factory should be a GuildChannel or Thread + channel = factory(guild=guild, state=self._connection, data=data) # type: ignore return channel - async def fetch_webhook(self, webhook_id): + async def fetch_webhook(self, webhook_id: int, /) -> Webhook: """|coro| Retrieves a :class:`.Webhook` with the specified ID. + .. versionchanged:: 2.0 + + ``webhook_id`` parameter is now positional-only. + Raises -------- - :exc:`.HTTPException` + HTTPException Retrieving the webhook failed. - :exc:`.NotFound` + NotFound Invalid webhook ID. - :exc:`.Forbidden` + Forbidden You do not have permission to fetch this webhook. Returns @@ -1492,3 +2605,120 @@ async def fetch_webhook(self, webhook_id): """ data = await self.http.get_webhook(webhook_id) return Webhook.from_state(data, state=self._connection) + + async def fetch_sticker(self, sticker_id: int, /) -> Union[StandardSticker, GuildSticker]: + """|coro| + + Retrieves a :class:`.Sticker` with the specified ID. + + .. versionadded:: 2.0 + + Raises + -------- + HTTPException + Retrieving the sticker failed. + NotFound + Invalid sticker ID. + + Returns + -------- + Union[:class:`.StandardSticker`, :class:`.GuildSticker`] + The sticker you requested. + """ + data = await self.http.get_sticker(sticker_id) + cls, _ = _sticker_factory(data['type']) + # The type checker is not smart enough to figure out the constructor is correct + return cls(state=self._connection, data=data) # type: ignore + + async def fetch_premium_sticker_packs(self) -> List[StickerPack]: + """|coro| + + Retrieves all available premium sticker packs. + + .. versionadded:: 2.0 + + Raises + ------- + HTTPException + Retrieving the sticker packs failed. + + Returns + --------- + List[:class:`.StickerPack`] + All available premium sticker packs. + """ + data = await self.http.list_premium_sticker_packs() + return [StickerPack(state=self._connection, data=pack) for pack in data['sticker_packs']] + + async def create_dm(self, user: Snowflake) -> DMChannel: + """|coro| + + Creates a :class:`.DMChannel` with this user. + + This should be rarely called, as this is done transparently for most + people. + + .. versionadded:: 2.0 + + Parameters + ----------- + user: :class:`~discord.abc.Snowflake` + The user to create a DM with. + + Returns + ------- + :class:`.DMChannel` + The channel that was created. + """ + state = self._connection + found = state._get_private_channel_by_user(user.id) + if found: + return found + + data = await state.http.start_private_message(user.id) + return state.add_dm_channel(data) + + def add_view(self, view: View, *, message_id: Optional[int] = None) -> None: + """Registers a :class:`~discord.ui.View` for persistent listening. + + This method should be used for when a view is comprised of components + that last longer than the lifecycle of the program. + + .. versionadded:: 2.0 + + Parameters + ------------ + view: :class:`discord.ui.View` + The view to register for dispatching. + message_id: Optional[:class:`int`] + The message ID that the view is attached to. This is currently used to + refresh the view's state during message update events. If not given + then message update events are not propagated for the view. + + Raises + ------- + TypeError + A view was not passed. + ValueError + The view is not persistent or is already finished. A persistent view has no timeout + and all their components have an explicitly provided custom_id. + """ + + if not isinstance(view, View): + raise TypeError(f'expected an instance of View not {view.__class__.__name__}') + + if not view.is_persistent(): + raise ValueError('View is not persistent. Items need to have a custom_id set and View must have no timeout') + + if view.is_finished(): + raise ValueError('View is already finished.') + + self._connection.store_view(view, message_id) + + @property + def persistent_views(self) -> Sequence[View]: + """Sequence[:class:`.View`]: A sequence of persistent views added to the client. + + .. versionadded:: 2.0 + """ + return self._connection.persistent_views diff --git a/dist/ba_data/python-site-packages/discord/colour.py b/dist/ba_data/python-site-packages/discord/colour.py index fbf9aaef..e640f9df 100644 --- a/dist/ba_data/python-site-packages/discord/colour.py +++ b/dist/ba_data/python-site-packages/discord/colour.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -23,9 +21,60 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations import colorsys import random +import re + +from typing import TYPE_CHECKING, Optional, Tuple, Union + +if TYPE_CHECKING: + from typing_extensions import Self + +__all__ = ( + 'Colour', + 'Color', +) + +RGB_REGEX = re.compile(r'rgb\s*\((?P[0-9.]+%?)\s*,\s*(?P[0-9.]+%?)\s*,\s*(?P[0-9.]+%?)\s*\)') + + +def parse_hex_number(argument: str) -> Colour: + arg = ''.join(i * 2 for i in argument) if len(argument) == 3 else argument + try: + value = int(arg, base=16) + if not (0 <= value <= 0xFFFFFF): + raise ValueError('hex number out of range for 24-bit colour') + except ValueError: + raise ValueError('invalid hex digit given') from None + else: + return Color(value=value) + + +def parse_rgb_number(number: str) -> int: + if number[-1] == '%': + value = float(number[:-1]) + if not (0 <= value <= 100): + raise ValueError('rgb percentage can only be between 0 to 100') + return round(255 * (value / 100)) + + value = int(number) + if not (0 <= value <= 255): + raise ValueError('rgb number can only be between 0 to 255') + return value + + +def parse_rgb(argument: str, *, regex: re.Pattern[str] = RGB_REGEX) -> Colour: + match = regex.match(argument) + if match is None: + raise ValueError('invalid rgb syntax found') + + red = parse_rgb_number(match.group('r')) + green = parse_rgb_number(match.group('g')) + blue = parse_rgb_number(match.group('b')) + return Color.from_rgb(red, green, blue) + class Colour: """Represents a Discord role colour. This class is similar @@ -51,6 +100,15 @@ class Colour: Returns the hex format for the colour. + .. describe:: int(x) + + Returns the raw colour value. + + .. note:: + + The colour values in the classmethods are mostly provided as-is and can change between + versions should the Discord client's representation of that colour also change. + Attributes ------------ value: :class:`int` @@ -59,67 +117,111 @@ class Colour: __slots__ = ('value',) - def __init__(self, value): + def __init__(self, value: int): if not isinstance(value, int): - raise TypeError('Expected int parameter, received %s instead.' % value.__class__.__name__) + raise TypeError(f'Expected int parameter, received {value.__class__.__name__} instead.') - self.value = value + self.value: int = value - def _get_byte(self, byte): - return (self.value >> (8 * byte)) & 0xff + def _get_byte(self, byte: int) -> int: + return (self.value >> (8 * byte)) & 0xFF - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return isinstance(other, Colour) and self.value == other.value - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __str__(self): - return '#{:0>6x}'.format(self.value) + def __str__(self) -> str: + return f'#{self.value:0>6x}' - def __repr__(self): - return '' % self.value + def __int__(self) -> int: + return self.value - def __hash__(self): + def __repr__(self) -> str: + return f'' + + def __hash__(self) -> int: return hash(self.value) @property - def r(self): + def r(self) -> int: """:class:`int`: Returns the red component of the colour.""" return self._get_byte(2) @property - def g(self): + def g(self) -> int: """:class:`int`: Returns the green component of the colour.""" return self._get_byte(1) @property - def b(self): + def b(self) -> int: """:class:`int`: Returns the blue component of the colour.""" return self._get_byte(0) - def to_rgb(self): + def to_rgb(self) -> Tuple[int, int, int]: """Tuple[:class:`int`, :class:`int`, :class:`int`]: Returns an (r, g, b) tuple representing the colour.""" return (self.r, self.g, self.b) @classmethod - def from_rgb(cls, r, g, b): + def from_rgb(cls, r: int, g: int, b: int) -> Self: """Constructs a :class:`Colour` from an RGB tuple.""" return cls((r << 16) + (g << 8) + b) @classmethod - def from_hsv(cls, h, s, v): + def from_hsv(cls, h: float, s: float, v: float) -> Self: """Constructs a :class:`Colour` from an HSV tuple.""" rgb = colorsys.hsv_to_rgb(h, s, v) return cls.from_rgb(*(int(x * 255) for x in rgb)) @classmethod - def default(cls): - """A factory method that returns a :class:`Colour` with a value of ``0``.""" + def from_str(cls, value: str) -> Self: + """Constructs a :class:`Colour` from a string. + + The following formats are accepted: + + - ``0x`` + - ``#`` + - ``0x#`` + - ``rgb(, , )`` + + Like CSS, ```` can be either 0-255 or 0-100% and ```` can be + either a 6 digit hex number or a 3 digit hex shortcut (e.g. #FFF). + + .. versionadded:: 2.0 + + Raises + ------- + ValueError + The string could not be converted into a colour. + """ + + if value[0] == '#': + return parse_hex_number(value[1:]) + + if value[0:2] == '0x': + rest = value[2:] + # Legacy backwards compatible syntax + if rest.startswith('#'): + return parse_hex_number(rest[1:]) + return parse_hex_number(rest) + + arg = value.lower() + if arg[0:3] == 'rgb': + return parse_rgb(arg) + + raise ValueError('unknown colour format given') + + @classmethod + def default(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0``. + + .. colour:: #000000 + """ return cls(0) @classmethod - def random(cls, *, seed=None): + def random(cls, *, seed: Optional[Union[int, str, float, bytes, bytearray]] = None) -> Self: """A factory method that returns a :class:`Colour` with a random hue. .. note:: @@ -132,7 +234,7 @@ def random(cls, *, seed=None): Parameters ------------ seed: Optional[Union[:class:`int`, :class:`str`, :class:`float`, :class:`bytes`, :class:`bytearray`]] - The seed to initialize the RNG with. If ``None`` is passed the default RNG is used. + The seed to initialize the RNG with. If ``None`` is passed the default RNG is used. .. versionadded:: 1.7 """ @@ -140,130 +242,282 @@ def random(cls, *, seed=None): return cls.from_hsv(rand.random(), 1, 1) @classmethod - def teal(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x1abc9c``.""" - return cls(0x1abc9c) + def teal(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x1ABC9C``. + + .. colour:: #1ABC9C + """ + return cls(0x1ABC9C) @classmethod - def dark_teal(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x11806a``.""" - return cls(0x11806a) + def dark_teal(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x11806A``. + + .. colour:: #11806A + """ + return cls(0x11806A) @classmethod - def green(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x2ecc71``.""" - return cls(0x2ecc71) + def brand_green(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x57F287``. + + .. colour:: #57F287 + + + .. versionadded:: 2.0 + """ + return cls(0x57F287) @classmethod - def dark_green(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x1f8b4c``.""" - return cls(0x1f8b4c) + def green(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x2ECC71``. + + .. colour:: #2ECC71 + """ + return cls(0x2ECC71) + + @classmethod + def dark_green(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x1F8B4C``. + + .. colour:: #1F8B4C + """ + return cls(0x1F8B4C) @classmethod - def blue(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x3498db``.""" - return cls(0x3498db) + def blue(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x3498DB``. + + .. colour:: #3498DB + """ + return cls(0x3498DB) @classmethod - def dark_blue(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x206694``.""" + def dark_blue(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x206694``. + + .. colour:: #206694 + """ return cls(0x206694) @classmethod - def purple(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x9b59b6``.""" - return cls(0x9b59b6) + def purple(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x9B59B6``. + + .. colour:: #9B59B6 + """ + return cls(0x9B59B6) @classmethod - def dark_purple(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x71368a``.""" - return cls(0x71368a) + def dark_purple(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x71368A``. + + .. colour:: #71368A + """ + return cls(0x71368A) @classmethod - def magenta(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xe91e63``.""" - return cls(0xe91e63) + def magenta(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xE91E63``. + + .. colour:: #E91E63 + """ + return cls(0xE91E63) @classmethod - def dark_magenta(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xad1457``.""" - return cls(0xad1457) + def dark_magenta(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xAD1457``. + + .. colour:: #AD1457 + """ + return cls(0xAD1457) @classmethod - def gold(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xf1c40f``.""" - return cls(0xf1c40f) + def gold(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xF1C40F``. + + .. colour:: #F1C40F + """ + return cls(0xF1C40F) @classmethod - def dark_gold(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xc27c0e``.""" - return cls(0xc27c0e) + def dark_gold(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xC27C0E``. + + .. colour:: #C27C0E + """ + return cls(0xC27C0E) @classmethod - def orange(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xe67e22``.""" - return cls(0xe67e22) + def orange(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xE67E22``. + + .. colour:: #E67E22 + """ + return cls(0xE67E22) @classmethod - def dark_orange(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xa84300``.""" - return cls(0xa84300) + def dark_orange(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xA84300``. + + .. colour:: #A84300 + """ + return cls(0xA84300) @classmethod - def red(cls): - """A factory method that returns a :class:`Colour` with a value of ``0xe74c3c``.""" - return cls(0xe74c3c) + def brand_red(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xED4245``. + + .. colour:: #ED4245 + + .. versionadded:: 2.0 + """ + return cls(0xED4245) @classmethod - def dark_red(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x992d22``.""" - return cls(0x992d22) + def red(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xE74C3C``. + + .. colour:: #E74C3C + """ + return cls(0xE74C3C) + + @classmethod + def dark_red(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x992D22``. + + .. colour:: #992D22 + """ + return cls(0x992D22) @classmethod - def lighter_grey(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x95a5a6``.""" - return cls(0x95a5a6) + def lighter_grey(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x95A5A6``. + + .. colour:: #95A5A6 + """ + return cls(0x95A5A6) lighter_gray = lighter_grey @classmethod - def dark_grey(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x607d8b``.""" - return cls(0x607d8b) + def dark_grey(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x607d8b``. + + .. colour:: #607d8b + """ + return cls(0x607D8B) dark_gray = dark_grey @classmethod - def light_grey(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x979c9f``.""" - return cls(0x979c9f) + def light_grey(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x979C9F``. + + .. colour:: #979C9F + """ + return cls(0x979C9F) light_gray = light_grey @classmethod - def darker_grey(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x546e7a``.""" - return cls(0x546e7a) + def darker_grey(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x546E7A``. + + .. colour:: #546E7A + """ + return cls(0x546E7A) darker_gray = darker_grey @classmethod - def blurple(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x7289da``.""" - return cls(0x7289da) + def og_blurple(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x7289DA``. + + .. colour:: #7289DA + """ + return cls(0x7289DA) @classmethod - def greyple(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x99aab5``.""" - return cls(0x99aab5) + def blurple(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x5865F2``. + + .. colour:: #5865F2 + """ + return cls(0x5865F2) + + @classmethod + def greyple(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x99AAB5``. + + .. colour:: #99AAB5 + """ + return cls(0x99AAB5) @classmethod - def dark_theme(cls): - """A factory method that returns a :class:`Colour` with a value of ``0x36393F``. + def dark_theme(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x313338``. + This will appear transparent on Discord's dark theme. + .. colour:: #313338 + .. versionadded:: 1.5 + + .. versionchanged:: 2.2 + Updated colour from previous ``0x36393F`` to reflect discord theme changes. + """ + return cls(0x313338) + + @classmethod + def fuchsia(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xEB459E``. + + .. colour:: #EB459E + + .. versionadded:: 2.0 + """ + return cls(0xEB459E) + + @classmethod + def yellow(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xFEE75C``. + + .. colour:: #FEE75C + + .. versionadded:: 2.0 + """ + return cls(0xFEE75C) + + @classmethod + def dark_embed(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0x2B2D31``. + + .. colour:: #2B2D31 + + .. versionadded:: 2.2 """ - return cls(0x36393F) + return cls(0x2B2D31) + + @classmethod + def light_embed(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xEEEFF1``. + + .. colour:: #EEEFF1 + + .. versionadded:: 2.2 + """ + return cls(0xEEEFF1) + + @classmethod + def pink(cls) -> Self: + """A factory method that returns a :class:`Colour` with a value of ``0xEB459F``. + + .. colour:: #EB459F + + .. versionadded:: 2.3 + """ + return cls(0xEB459F) + Color = Colour diff --git a/dist/ba_data/python-site-packages/discord/components.py b/dist/ba_data/python-site-packages/discord/components.py new file mode 100644 index 00000000..5c3679b1 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/components.py @@ -0,0 +1,533 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +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. +""" + +from __future__ import annotations + +from typing import ClassVar, List, Literal, Optional, TYPE_CHECKING, Tuple, Union, overload +from .enums import try_enum, ComponentType, ButtonStyle, TextStyle, ChannelType +from .utils import get_slots, MISSING +from .partial_emoji import PartialEmoji, _EmojiTag + +if TYPE_CHECKING: + from typing_extensions import Self + + from .types.components import ( + Component as ComponentPayload, + ButtonComponent as ButtonComponentPayload, + SelectMenu as SelectMenuPayload, + SelectOption as SelectOptionPayload, + ActionRow as ActionRowPayload, + TextInput as TextInputPayload, + ActionRowChildComponent as ActionRowChildComponentPayload, + ) + from .emoji import Emoji + + ActionRowChildComponentType = Union['Button', 'SelectMenu', 'TextInput'] + + +__all__ = ( + 'Component', + 'ActionRow', + 'Button', + 'SelectMenu', + 'SelectOption', + 'TextInput', +) + + +class Component: + """Represents a Discord Bot UI Kit Component. + + Currently, the only components supported by Discord are: + + - :class:`ActionRow` + - :class:`Button` + - :class:`SelectMenu` + - :class:`TextInput` + + This class is abstract and cannot be instantiated. + + .. versionadded:: 2.0 + """ + + __slots__: Tuple[str, ...] = () + + __repr_info__: ClassVar[Tuple[str, ...]] + + def __repr__(self) -> str: + attrs = ' '.join(f'{key}={getattr(self, key)!r}' for key in self.__repr_info__) + return f'<{self.__class__.__name__} {attrs}>' + + @property + def type(self) -> ComponentType: + """:class:`ComponentType`: The type of component.""" + raise NotImplementedError + + @classmethod + def _raw_construct(cls, **kwargs) -> Self: + self = cls.__new__(cls) + for slot in get_slots(cls): + try: + value = kwargs[slot] + except KeyError: + pass + else: + setattr(self, slot, value) + return self + + def to_dict(self) -> ComponentPayload: + raise NotImplementedError + + +class ActionRow(Component): + """Represents a Discord Bot UI Kit Action Row. + + This is a component that holds up to 5 children components in a row. + + This inherits from :class:`Component`. + + .. versionadded:: 2.0 + + Attributes + ------------ + children: List[Union[:class:`Button`, :class:`SelectMenu`, :class:`TextInput`]] + The children components that this holds, if any. + """ + + __slots__: Tuple[str, ...] = ('children',) + + __repr_info__: ClassVar[Tuple[str, ...]] = __slots__ + + def __init__(self, data: ActionRowPayload, /) -> None: + self.children: List[ActionRowChildComponentType] = [] + + for component_data in data.get('components', []): + component = _component_factory(component_data) + + if component is not None: + self.children.append(component) + + @property + def type(self) -> Literal[ComponentType.action_row]: + """:class:`ComponentType`: The type of component.""" + return ComponentType.action_row + + def to_dict(self) -> ActionRowPayload: + return { + 'type': self.type.value, + 'components': [child.to_dict() for child in self.children], + } + + +class Button(Component): + """Represents a button from the Discord Bot UI Kit. + + This inherits from :class:`Component`. + + .. note:: + + The user constructible and usable type to create a button is :class:`discord.ui.Button` + not this one. + + .. versionadded:: 2.0 + + Attributes + ----------- + style: :class:`.ButtonStyle` + The style of the button. + custom_id: Optional[:class:`str`] + The ID of the button that gets received during an interaction. + If this button is for a URL, it does not have a custom ID. + url: Optional[:class:`str`] + The URL this button sends you to. + disabled: :class:`bool` + Whether the button is disabled or not. + label: Optional[:class:`str`] + The label of the button, if any. + emoji: Optional[:class:`PartialEmoji`] + The emoji of the button, if available. + """ + + __slots__: Tuple[str, ...] = ( + 'style', + 'custom_id', + 'url', + 'disabled', + 'label', + 'emoji', + ) + + __repr_info__: ClassVar[Tuple[str, ...]] = __slots__ + + def __init__(self, data: ButtonComponentPayload, /) -> None: + self.style: ButtonStyle = try_enum(ButtonStyle, data['style']) + self.custom_id: Optional[str] = data.get('custom_id') + self.url: Optional[str] = data.get('url') + self.disabled: bool = data.get('disabled', False) + self.label: Optional[str] = data.get('label') + self.emoji: Optional[PartialEmoji] + try: + self.emoji = PartialEmoji.from_dict(data['emoji']) + except KeyError: + self.emoji = None + + @property + def type(self) -> Literal[ComponentType.button]: + """:class:`ComponentType`: The type of component.""" + return ComponentType.button + + def to_dict(self) -> ButtonComponentPayload: + payload: ButtonComponentPayload = { + 'type': 2, + 'style': self.style.value, + 'disabled': self.disabled, + } + + if self.label: + payload['label'] = self.label + + if self.custom_id: + payload['custom_id'] = self.custom_id + + if self.url: + payload['url'] = self.url + + if self.emoji: + payload['emoji'] = self.emoji.to_dict() + + return payload + + +class SelectMenu(Component): + """Represents a select menu from the Discord Bot UI Kit. + + A select menu is functionally the same as a dropdown, however + on mobile it renders a bit differently. + + .. note:: + + The user constructible and usable type to create a select menu is + :class:`discord.ui.Select` not this one. + + .. versionadded:: 2.0 + + Attributes + ------------ + type: :class:`ComponentType` + The type of component. + custom_id: Optional[:class:`str`] + The ID of the select menu that gets received during an interaction. + placeholder: Optional[:class:`str`] + The placeholder text that is shown if nothing is selected, if any. + min_values: :class:`int` + The minimum number of items that must be chosen for this select menu. + Defaults to 1 and must be between 0 and 25. + max_values: :class:`int` + The maximum number of items that must be chosen for this select menu. + Defaults to 1 and must be between 1 and 25. + options: List[:class:`SelectOption`] + A list of options that can be selected in this menu. + disabled: :class:`bool` + Whether the select is disabled or not. + channel_types: List[:class:`.ChannelType`] + A list of channel types that are allowed to be chosen in this select menu. + """ + + __slots__: Tuple[str, ...] = ( + 'type', + 'custom_id', + 'placeholder', + 'min_values', + 'max_values', + 'options', + 'disabled', + 'channel_types', + ) + + __repr_info__: ClassVar[Tuple[str, ...]] = __slots__ + + def __init__(self, data: SelectMenuPayload, /) -> None: + self.type: ComponentType = try_enum(ComponentType, data['type']) + self.custom_id: str = data['custom_id'] + self.placeholder: Optional[str] = data.get('placeholder') + self.min_values: int = data.get('min_values', 1) + self.max_values: int = data.get('max_values', 1) + self.options: List[SelectOption] = [SelectOption.from_dict(option) for option in data.get('options', [])] + self.disabled: bool = data.get('disabled', False) + self.channel_types: List[ChannelType] = [try_enum(ChannelType, t) for t in data.get('channel_types', [])] + + def to_dict(self) -> SelectMenuPayload: + payload: SelectMenuPayload = { + 'type': self.type.value, + 'custom_id': self.custom_id, + 'min_values': self.min_values, + 'max_values': self.max_values, + 'disabled': self.disabled, + } + if self.placeholder: + payload['placeholder'] = self.placeholder + if self.options: + payload['options'] = [op.to_dict() for op in self.options] + if self.channel_types: + payload['channel_types'] = [t.value for t in self.channel_types] + + return payload + + +class SelectOption: + """Represents a select menu's option. + + These can be created by users. + + .. versionadded:: 2.0 + + Parameters + ----------- + label: :class:`str` + The label of the option. This is displayed to users. + Can only be up to 100 characters. + value: :class:`str` + The value of the option. This is not displayed to users. + If not provided when constructed then it defaults to the + label. Can only be up to 100 characters. + description: Optional[:class:`str`] + An additional description of the option, if any. + Can only be up to 100 characters. + emoji: Optional[Union[:class:`str`, :class:`Emoji`, :class:`PartialEmoji`]] + The emoji of the option, if available. + default: :class:`bool` + Whether this option is selected by default. + + Attributes + ----------- + label: :class:`str` + The label of the option. This is displayed to users. + Can only be up to 100 characters. + value: :class:`str` + The value of the option. This is not displayed to users. + If not provided when constructed then it defaults to the + label. Can only be up to 100 characters. + description: Optional[:class:`str`] + An additional description of the option, if any. + Can only be up to 100 characters. + default: :class:`bool` + Whether this option is selected by default. + """ + + __slots__: Tuple[str, ...] = ( + 'label', + 'value', + 'description', + '_emoji', + 'default', + ) + + def __init__( + self, + *, + label: str, + value: str = MISSING, + description: Optional[str] = None, + emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + default: bool = False, + ) -> None: + self.label: str = label + self.value: str = label if value is MISSING else value + self.description: Optional[str] = description + + self.emoji = emoji + self.default: bool = default + + def __repr__(self) -> str: + return ( + f'' + ) + + def __str__(self) -> str: + if self.emoji: + base = f'{self.emoji} {self.label}' + else: + base = self.label + + if self.description: + return f'{base}\n{self.description}' + return base + + @property + def emoji(self) -> Optional[PartialEmoji]: + """Optional[:class:`.PartialEmoji`]: The emoji of the option, if available.""" + return self._emoji + + @emoji.setter + def emoji(self, value: Optional[Union[str, Emoji, PartialEmoji]]) -> None: + if value is not None: + if isinstance(value, str): + self._emoji = PartialEmoji.from_str(value) + elif isinstance(value, _EmojiTag): + self._emoji = value._to_partial() + else: + raise TypeError(f'expected str, Emoji, or PartialEmoji, received {value.__class__.__name__} instead') + else: + self._emoji = None + + @classmethod + def from_dict(cls, data: SelectOptionPayload) -> SelectOption: + try: + emoji = PartialEmoji.from_dict(data['emoji']) + except KeyError: + emoji = None + + return cls( + label=data['label'], + value=data['value'], + description=data.get('description'), + emoji=emoji, + default=data.get('default', False), + ) + + def to_dict(self) -> SelectOptionPayload: + payload: SelectOptionPayload = { + 'label': self.label, + 'value': self.value, + 'default': self.default, + } + + if self.emoji: + payload['emoji'] = self.emoji.to_dict() + + if self.description: + payload['description'] = self.description + + return payload + + +class TextInput(Component): + """Represents a text input from the Discord Bot UI Kit. + + .. note:: + The user constructible and usable type to create a text input is + :class:`discord.ui.TextInput` not this one. + + .. versionadded:: 2.0 + + Attributes + ------------ + custom_id: Optional[:class:`str`] + The ID of the text input that gets received during an interaction. + label: :class:`str` + The label to display above the text input. + style: :class:`TextStyle` + The style of the text input. + placeholder: Optional[:class:`str`] + The placeholder text to display when the text input is empty. + value: Optional[:class:`str`] + The default value of the text input. + required: :class:`bool` + Whether the text input is required. + min_length: Optional[:class:`int`] + The minimum length of the text input. + max_length: Optional[:class:`int`] + The maximum length of the text input. + """ + + __slots__: Tuple[str, ...] = ( + 'style', + 'label', + 'custom_id', + 'placeholder', + 'value', + 'required', + 'min_length', + 'max_length', + ) + + __repr_info__: ClassVar[Tuple[str, ...]] = __slots__ + + def __init__(self, data: TextInputPayload, /) -> None: + self.style: TextStyle = try_enum(TextStyle, data['style']) + self.label: str = data['label'] + self.custom_id: str = data['custom_id'] + self.placeholder: Optional[str] = data.get('placeholder') + self.value: Optional[str] = data.get('value') + self.required: bool = data.get('required', True) + self.min_length: Optional[int] = data.get('min_length') + self.max_length: Optional[int] = data.get('max_length') + + @property + def type(self) -> Literal[ComponentType.text_input]: + """:class:`ComponentType`: The type of component.""" + return ComponentType.text_input + + def to_dict(self) -> TextInputPayload: + payload: TextInputPayload = { + 'type': self.type.value, + 'style': self.style.value, + 'label': self.label, + 'custom_id': self.custom_id, + 'required': self.required, + } + + if self.placeholder: + payload['placeholder'] = self.placeholder + + if self.value: + payload['value'] = self.value + + if self.min_length: + payload['min_length'] = self.min_length + + if self.max_length: + payload['max_length'] = self.max_length + + return payload + + @property + def default(self) -> Optional[str]: + """Optional[:class:`str`]: The default value of the text input. + + This is an alias to :attr:`value`. + """ + return self.value + + +@overload +def _component_factory(data: ActionRowChildComponentPayload) -> Optional[ActionRowChildComponentType]: + ... + + +@overload +def _component_factory(data: ComponentPayload) -> Optional[Union[ActionRow, ActionRowChildComponentType]]: + ... + + +def _component_factory(data: ComponentPayload) -> Optional[Union[ActionRow, ActionRowChildComponentType]]: + if data['type'] == 1: + return ActionRow(data) + elif data['type'] == 2: + return Button(data) + elif data['type'] == 4: + return TextInput(data) + elif data['type'] in (3, 5, 6, 7, 8): + return SelectMenu(data) diff --git a/dist/ba_data/python-site-packages/discord/context_managers.py b/dist/ba_data/python-site-packages/discord/context_managers.py index e4fde6b3..09803c95 100644 --- a/dist/ba_data/python-site-packages/discord/context_managers.py +++ b/dist/ba_data/python-site-packages/discord/context_managers.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,44 +22,71 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + import asyncio +from typing import TYPE_CHECKING, Generator, Optional, Type, TypeVar + +if TYPE_CHECKING: + from .abc import Messageable, MessageableChannel + + from types import TracebackType + + BE = TypeVar('BE', bound=BaseException) -def _typing_done_callback(fut): +# fmt: off +__all__ = ( + 'Typing', +) +# fmt: on + + +def _typing_done_callback(fut: asyncio.Future) -> None: # just retrieve any exception and call it a day try: fut.exception() except (asyncio.CancelledError, Exception): pass + class Typing: - def __init__(self, messageable): - self.loop = messageable._state.loop - self.messageable = messageable + def __init__(self, messageable: Messageable) -> None: + self.loop: asyncio.AbstractEventLoop = messageable._state.loop + self.messageable: Messageable = messageable + self.channel: Optional[MessageableChannel] = None - async def do_typing(self): - try: - channel = self._channel - except AttributeError: - channel = await self.messageable._get_channel() + async def _get_channel(self) -> MessageableChannel: + if self.channel: + return self.channel + self.channel = channel = await self.messageable._get_channel() + return channel + + async def wrapped_typer(self) -> None: + channel = await self._get_channel() + await channel._state.http.send_typing(channel.id) + + def __await__(self) -> Generator[None, None, None]: + return self.wrapped_typer().__await__() + + async def do_typing(self) -> None: + channel = await self._get_channel() typing = channel._state.http.send_typing while True: - await typing(channel.id) await asyncio.sleep(5) + await typing(channel.id) - def __enter__(self): - self.task = asyncio.ensure_future(self.do_typing(), loop=self.loop) - self.task.add_done_callback(_typing_done_callback) - return self - - def __exit__(self, exc_type, exc, tb): - self.task.cancel() - - async def __aenter__(self): - self._channel = channel = await self.messageable._get_channel() + async def __aenter__(self) -> None: + channel = await self._get_channel() await channel._state.http.send_typing(channel.id) - return self.__enter__() + self.task: asyncio.Task[None] = self.loop.create_task(self.do_typing()) + self.task.add_done_callback(_typing_done_callback) - async def __aexit__(self, exc_type, exc, tb): + async def __aexit__( + self, + exc_type: Optional[Type[BE]], + exc: Optional[BE], + traceback: Optional[TracebackType], + ) -> None: self.task.cancel() diff --git a/dist/ba_data/python-site-packages/discord/embeds.py b/dist/ba_data/python-site-packages/discord/embeds.py index cbe1146e..6a79fef7 100644 --- a/dist/ba_data/python-site-packages/discord/embeds.py +++ b/dist/ba_data/python-site-packages/discord/embeds.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,35 +22,76 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + import datetime +from typing import Any, Dict, List, Mapping, Optional, Protocol, TYPE_CHECKING, TypeVar, Union from . import utils from .colour import Colour -class _EmptyEmbed: - def __bool__(self): - return False - - def __repr__(self): - return 'Embed.Empty' +# fmt: off +__all__ = ( + 'Embed', +) +# fmt: on - def __len__(self): - return 0 - -EmptyEmbed = _EmptyEmbed() class EmbedProxy: - def __init__(self, layer): + def __init__(self, layer: Dict[str, Any]): self.__dict__.update(layer) - def __len__(self): + def __len__(self) -> int: return len(self.__dict__) - def __repr__(self): - return 'EmbedProxy(%s)' % ', '.join(('%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_'))) + def __repr__(self) -> str: + inner = ', '.join((f'{k}={v!r}' for k, v in self.__dict__.items() if not k.startswith('_'))) + return f'EmbedProxy({inner})' + + def __getattr__(self, attr: str) -> None: + return None + + def __eq__(self, other: object) -> bool: + return isinstance(other, EmbedProxy) and self.__dict__ == other.__dict__ + + +if TYPE_CHECKING: + from typing_extensions import Self + + from .types.embed import Embed as EmbedData, EmbedType + + T = TypeVar('T') + + class _EmbedFooterProxy(Protocol): + text: Optional[str] + icon_url: Optional[str] + + class _EmbedFieldProxy(Protocol): + name: Optional[str] + value: Optional[str] + inline: bool + + class _EmbedMediaProxy(Protocol): + url: Optional[str] + proxy_url: Optional[str] + height: Optional[int] + width: Optional[int] + + class _EmbedVideoProxy(Protocol): + url: Optional[str] + height: Optional[int] + width: Optional[int] + + class _EmbedProviderProxy(Protocol): + name: Optional[str] + url: Optional[str] + + class _EmbedAuthorProxy(Protocol): + name: Optional[str] + url: Optional[str] + icon_url: Optional[str] + proxy_icon_url: Optional[str] - def __getattr__(self, attr): - return EmptyEmbed class Embed: """Represents a Discord embed. @@ -64,86 +103,103 @@ class Embed: Returns the total size of the embed. Useful for checking if it's within the 6000 character limit. - Certain properties return an ``EmbedProxy``, a type - that acts similar to a regular :class:`dict` except using dotted access, - e.g. ``embed.author.icon_url``. If the attribute - is invalid or empty, then a special sentinel value is returned, - :attr:`Embed.Empty`. + .. describe:: bool(b) + + Returns whether the embed has any data set. + + .. versionadded:: 2.0 + + .. describe:: x == y + + Checks if two embeds are equal. + + .. versionadded:: 2.0 For ease of use, all parameters that expect a :class:`str` are implicitly casted to :class:`str` for you. + .. versionchanged:: 2.0 + ``Embed.Empty`` has been removed in favour of ``None``. + Attributes ----------- - title: :class:`str` + title: Optional[:class:`str`] The title of the embed. This can be set during initialisation. + Can only be up to 256 characters. type: :class:`str` The type of embed. Usually "rich". This can be set during initialisation. Possible strings for embed types can be found on discord's - `api docs `_ - description: :class:`str` + :ddocs:`api docs ` + description: Optional[:class:`str`] The description of the embed. This can be set during initialisation. - url: :class:`str` + Can only be up to 4096 characters. + url: Optional[:class:`str`] The URL of the embed. This can be set during initialisation. - timestamp: :class:`datetime.datetime` - The timestamp of the embed content. This could be a naive or aware datetime. - colour: Union[:class:`Colour`, :class:`int`] + timestamp: Optional[:class:`datetime.datetime`] + The timestamp of the embed content. This is an aware datetime. + If a naive datetime is passed, it is converted to an aware + datetime with the local timezone. + colour: Optional[Union[:class:`Colour`, :class:`int`]] The colour code of the embed. Aliased to ``color`` as well. This can be set during initialisation. - Empty - A special sentinel value used by ``EmbedProxy`` and this class - to denote that the value or attribute is empty. """ - __slots__ = ('title', 'url', 'type', '_timestamp', '_colour', '_footer', - '_image', '_thumbnail', '_video', '_provider', '_author', - '_fields', 'description') - - Empty = EmptyEmbed - - def __init__(self, **kwargs): - # swap the colour/color aliases - try: - colour = kwargs['colour'] - except KeyError: - colour = kwargs.get('color', EmptyEmbed) - - self.colour = colour - self.title = kwargs.get('title', EmptyEmbed) - self.type = kwargs.get('type', 'rich') - self.url = kwargs.get('url', EmptyEmbed) - self.description = kwargs.get('description', EmptyEmbed) - - if self.title is not EmptyEmbed: + __slots__ = ( + 'title', + 'url', + 'type', + '_timestamp', + '_colour', + '_footer', + '_image', + '_thumbnail', + '_video', + '_provider', + '_author', + '_fields', + 'description', + ) + + def __init__( + self, + *, + colour: Optional[Union[int, Colour]] = None, + color: Optional[Union[int, Colour]] = None, + title: Optional[Any] = None, + type: EmbedType = 'rich', + url: Optional[Any] = None, + description: Optional[Any] = None, + timestamp: Optional[datetime.datetime] = None, + ): + + self.colour = colour if colour is not None else color + self.title: Optional[str] = title + self.type: EmbedType = type + self.url: Optional[str] = url + self.description: Optional[str] = description + + if self.title is not None: self.title = str(self.title) - if self.description is not EmptyEmbed: + if self.description is not None: self.description = str(self.description) - if self.url is not EmptyEmbed: + if self.url is not None: self.url = str(self.url) - try: - timestamp = kwargs['timestamp'] - except KeyError: - pass - else: + if timestamp is not None: self.timestamp = timestamp @classmethod - def from_dict(cls, data): + def from_dict(cls, data: Mapping[str, Any]) -> Self: """Converts a :class:`dict` to a :class:`Embed` provided it is in the format that Discord expects it to be in. - You can find out about this format in the `official Discord documentation`__. - - .. _DiscordDocs: https://discord.com/developers/docs/resources/channel#embed-object - - __ DiscordDocs_ + You can find out about this format in the :ddocs:`official Discord documentation `. Parameters ----------- @@ -155,18 +211,18 @@ def from_dict(cls, data): # fill in the basic fields - self.title = data.get('title', EmptyEmbed) - self.type = data.get('type', EmptyEmbed) - self.description = data.get('description', EmptyEmbed) - self.url = data.get('url', EmptyEmbed) + self.title = data.get('title', None) + self.type = data.get('type', None) + self.description = data.get('description', None) + self.url = data.get('url', None) - if self.title is not EmptyEmbed: + if self.title is not None: self.title = str(self.title) - if self.description is not EmptyEmbed: + if self.description is not None: self.description = str(self.description) - if self.url is not EmptyEmbed: + if self.url is not None: self.url = str(self.url) # try to fill in the more rich fields @@ -191,21 +247,21 @@ def from_dict(cls, data): return self - def copy(self): + def copy(self) -> Self: """Returns a shallow copy of the embed.""" - return Embed.from_dict(self.to_dict()) + return self.__class__.from_dict(self.to_dict()) - def __len__(self): - total = len(self.title) + len(self.description) + def __len__(self) -> int: + total = len(self.title or '') + len(self.description or '') for field in getattr(self, '_fields', []): total += len(field['name']) + len(field['value']) try: - footer = self._footer - except AttributeError: + footer_text = self._footer['text'] + except (AttributeError, KeyError): pass else: - total += len(footer['text']) + total += len(footer_text) try: author = self._author @@ -216,43 +272,85 @@ def __len__(self): return total + def __bool__(self) -> bool: + return any( + ( + self.title, + self.url, + self.description, + self.colour, + self.fields, + self.timestamp, + self.author, + self.thumbnail, + self.footer, + self.image, + self.provider, + self.video, + ) + ) + + def __eq__(self, other: Embed) -> bool: + return isinstance(other, Embed) and ( + self.type == other.type + and self.title == other.title + and self.url == other.url + and self.description == other.description + and self.colour == other.colour + and self.fields == other.fields + and self.timestamp == other.timestamp + and self.author == other.author + and self.thumbnail == other.thumbnail + and self.footer == other.footer + and self.image == other.image + and self.provider == other.provider + and self.video == other.video + ) + @property - def colour(self): - return getattr(self, '_colour', EmptyEmbed) + def colour(self) -> Optional[Colour]: + return getattr(self, '_colour', None) @colour.setter - def colour(self, value): - if isinstance(value, (Colour, _EmptyEmbed)): + def colour(self, value: Optional[Union[int, Colour]]) -> None: + if value is None: + self._colour = None + elif isinstance(value, Colour): self._colour = value elif isinstance(value, int): self._colour = Colour(value=value) else: - raise TypeError('Expected discord.Colour, int, or Embed.Empty but received %s instead.' % value.__class__.__name__) + raise TypeError(f'Expected discord.Colour, int, or None but received {value.__class__.__name__} instead.') color = colour @property - def timestamp(self): - return getattr(self, '_timestamp', EmptyEmbed) + def timestamp(self) -> Optional[datetime.datetime]: + return getattr(self, '_timestamp', None) @timestamp.setter - def timestamp(self, value): - if isinstance(value, (datetime.datetime, _EmptyEmbed)): + def timestamp(self, value: Optional[datetime.datetime]) -> None: + if isinstance(value, datetime.datetime): + if value.tzinfo is None: + value = value.astimezone() self._timestamp = value + elif value is None: + self._timestamp = None else: - raise TypeError("Expected datetime.datetime or Embed.Empty received %s instead" % value.__class__.__name__) + raise TypeError(f"Expected datetime.datetime or None received {value.__class__.__name__} instead") @property - def footer(self): - """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the footer contents. + def footer(self) -> _EmbedFooterProxy: + """Returns an ``EmbedProxy`` denoting the footer contents. See :meth:`set_footer` for possible values you can access. - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return EmbedProxy(getattr(self, '_footer', {})) + # Lying to the type checker for better developer UX. + return EmbedProxy(getattr(self, '_footer', {})) # type: ignore - def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed): + def set_footer(self, *, text: Optional[Any] = None, icon_url: Optional[Any] = None) -> Self: """Sets the footer for the embed content. This function returns the class instance to allow for fluent-style @@ -261,23 +359,39 @@ def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed): Parameters ----------- text: :class:`str` - The footer text. + The footer text. Can only be up to 2048 characters. icon_url: :class:`str` The URL of the footer icon. Only HTTP(S) is supported. + Inline attachment URLs are also supported, see :ref:`local_image`. """ self._footer = {} - if text is not EmptyEmbed: + if text is not None: self._footer['text'] = str(text) - if icon_url is not EmptyEmbed: + if icon_url is not None: self._footer['icon_url'] = str(icon_url) return self + def remove_footer(self) -> Self: + """Clears embed's footer information. + + This function returns the class instance to allow for fluent-style + chaining. + + .. versionadded:: 2.0 + """ + try: + del self._footer + except AttributeError: + pass + + return self + @property - def image(self): - """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the image contents. + def image(self) -> _EmbedMediaProxy: + """Returns an ``EmbedProxy`` denoting the image contents. Possible attributes you can access are: @@ -286,40 +400,39 @@ def image(self): - ``width`` - ``height`` - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return EmbedProxy(getattr(self, '_image', {})) + # Lying to the type checker for better developer UX. + return EmbedProxy(getattr(self, '_image', {})) # type: ignore - def set_image(self, *, url): + def set_image(self, *, url: Optional[Any]) -> Self: """Sets the image for the embed content. This function returns the class instance to allow for fluent-style chaining. - .. versionchanged:: 1.4 - Passing :attr:`Empty` removes the image. - Parameters ----------- url: :class:`str` The source URL for the image. Only HTTP(S) is supported. + Inline attachment URLs are also supported, see :ref:`local_image`. """ - if url is EmptyEmbed: + if url is None: try: del self._image except AttributeError: pass else: self._image = { - 'url': str(url) + 'url': str(url), } return self @property - def thumbnail(self): - """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the thumbnail contents. + def thumbnail(self) -> _EmbedMediaProxy: + """Returns an ``EmbedProxy`` denoting the thumbnail contents. Possible attributes you can access are: @@ -328,40 +441,42 @@ def thumbnail(self): - ``width`` - ``height`` - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return EmbedProxy(getattr(self, '_thumbnail', {})) + # Lying to the type checker for better developer UX. + return EmbedProxy(getattr(self, '_thumbnail', {})) # type: ignore - def set_thumbnail(self, *, url): + def set_thumbnail(self, *, url: Optional[Any]) -> Self: """Sets the thumbnail for the embed content. This function returns the class instance to allow for fluent-style chaining. .. versionchanged:: 1.4 - Passing :attr:`Empty` removes the thumbnail. + Passing ``None`` removes the thumbnail. Parameters ----------- url: :class:`str` The source URL for the thumbnail. Only HTTP(S) is supported. + Inline attachment URLs are also supported, see :ref:`local_image`. """ - if url is EmptyEmbed: + if url is None: try: del self._thumbnail except AttributeError: pass else: self._thumbnail = { - 'url': str(url) + 'url': str(url), } return self @property - def video(self): - """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the video contents. + def video(self) -> _EmbedVideoProxy: + """Returns an ``EmbedProxy`` denoting the video contents. Possible attributes include: @@ -369,31 +484,34 @@ def video(self): - ``height`` for the video height. - ``width`` for the video width. - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return EmbedProxy(getattr(self, '_video', {})) + # Lying to the type checker for better developer UX. + return EmbedProxy(getattr(self, '_video', {})) # type: ignore @property - def provider(self): - """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the provider contents. + def provider(self) -> _EmbedProviderProxy: + """Returns an ``EmbedProxy`` denoting the provider contents. The only attributes that might be accessed are ``name`` and ``url``. - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return EmbedProxy(getattr(self, '_provider', {})) + # Lying to the type checker for better developer UX. + return EmbedProxy(getattr(self, '_provider', {})) # type: ignore @property - def author(self): - """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the author contents. + def author(self) -> _EmbedAuthorProxy: + """Returns an ``EmbedProxy`` denoting the author contents. See :meth:`set_author` for possible values you can access. - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return EmbedProxy(getattr(self, '_author', {})) + # Lying to the type checker for better developer UX. + return EmbedProxy(getattr(self, '_author', {})) # type: ignore - def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed): + def set_author(self, *, name: Any, url: Optional[Any] = None, icon_url: Optional[Any] = None) -> Self: """Sets the author for the embed content. This function returns the class instance to allow for fluent-style @@ -402,26 +520,27 @@ def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed): Parameters ----------- name: :class:`str` - The name of the author. + The name of the author. Can only be up to 256 characters. url: :class:`str` The URL for the author. icon_url: :class:`str` The URL of the author icon. Only HTTP(S) is supported. + Inline attachment URLs are also supported, see :ref:`local_image`. """ self._author = { - 'name': str(name) + 'name': str(name), } - if url is not EmptyEmbed: + if url is not None: self._author['url'] = str(url) - if icon_url is not EmptyEmbed: + if icon_url is not None: self._author['icon_url'] = str(icon_url) return self - def remove_author(self): + def remove_author(self) -> Self: """Clears embed's author information. This function returns the class instance to allow for fluent-style @@ -437,27 +556,28 @@ def remove_author(self): return self @property - def fields(self): - """List[Union[``EmbedProxy``, :attr:`Empty`]]: Returns a :class:`list` of ``EmbedProxy`` denoting the field contents. + def fields(self) -> List[_EmbedFieldProxy]: + """List[``EmbedProxy``]: Returns a :class:`list` of ``EmbedProxy`` denoting the field contents. See :meth:`add_field` for possible values you can access. - If the attribute has no value then :attr:`Empty` is returned. + If the attribute has no value then ``None`` is returned. """ - return [EmbedProxy(d) for d in getattr(self, '_fields', [])] + # Lying to the type checker for better developer UX. + return [EmbedProxy(d) for d in getattr(self, '_fields', [])] # type: ignore - def add_field(self, *, name, value, inline=True): + def add_field(self, *, name: Any, value: Any, inline: bool = True) -> Self: """Adds a field to the embed object. This function returns the class instance to allow for fluent-style - chaining. + chaining. Can only be up to 25 fields. Parameters ----------- name: :class:`str` - The name of the field. + The name of the field. Can only be up to 256 characters. value: :class:`str` - The value of the field. + The value of the field. Can only be up to 1024 characters. inline: :class:`bool` Whether the field should be displayed inline. """ @@ -465,7 +585,7 @@ def add_field(self, *, name, value, inline=True): field = { 'inline': inline, 'name': str(name), - 'value': str(value) + 'value': str(value), } try: @@ -475,11 +595,11 @@ def add_field(self, *, name, value, inline=True): return self - def insert_field_at(self, index, *, name, value, inline=True): + def insert_field_at(self, index: int, *, name: Any, value: Any, inline: bool = True) -> Self: """Inserts a field before a specified index to the embed. This function returns the class instance to allow for fluent-style - chaining. + chaining. Can only be up to 25 fields. .. versionadded:: 1.2 @@ -488,9 +608,9 @@ def insert_field_at(self, index, *, name, value, inline=True): index: :class:`int` The index of where to insert the field. name: :class:`str` - The name of the field. + The name of the field. Can only be up to 256 characters. value: :class:`str` - The value of the field. + The value of the field. Can only be up to 1024 characters. inline: :class:`bool` Whether the field should be displayed inline. """ @@ -498,7 +618,7 @@ def insert_field_at(self, index, *, name, value, inline=True): field = { 'inline': inline, 'name': str(name), - 'value': str(value) + 'value': str(value), } try: @@ -508,24 +628,39 @@ def insert_field_at(self, index, *, name, value, inline=True): return self - def clear_fields(self): - """Removes all fields from this embed.""" + def clear_fields(self) -> Self: + """Removes all fields from this embed. + + This function returns the class instance to allow for fluent-style + chaining. + + .. versionchanged:: 2.0 + This function now returns the class instance. + """ try: self._fields.clear() except AttributeError: self._fields = [] - def remove_field(self, index): + return self + + def remove_field(self, index: int) -> Self: """Removes a field at a specified index. If the index is invalid or out of bounds then the error is silently swallowed. + This function returns the class instance to allow for fluent-style + chaining. + .. note:: When deleting a field by index, the index of the other fields shift to fill the gap just like a regular list. + .. versionchanged:: 2.0 + This function now returns the class instance. + Parameters ----------- index: :class:`int` @@ -536,10 +671,12 @@ def remove_field(self, index): except (AttributeError, IndexError): pass - def set_field_at(self, index, *, name, value, inline=True): + return self + + def set_field_at(self, index: int, *, name: Any, value: Any, inline: bool = True) -> Self: """Modifies a field to the embed object. - The index must point to a valid pre-existing field. + The index must point to a valid pre-existing field. Can only be up to 25 fields. This function returns the class instance to allow for fluent-style chaining. @@ -549,9 +686,9 @@ def set_field_at(self, index, *, name, value, inline=True): index: :class:`int` The index of the field to modify. name: :class:`str` - The name of the field. + The name of the field. Can only be up to 256 characters. value: :class:`str` - The value of the field. + The value of the field. Can only be up to 1024 characters. inline: :class:`bool` Whether the field should be displayed inline. @@ -571,15 +708,17 @@ def set_field_at(self, index, *, name, value, inline=True): field['inline'] = inline return self - def to_dict(self): + def to_dict(self) -> EmbedData: """Converts this embed object into a dict.""" # add in the raw data into the dict + # fmt: off result = { key[1:]: getattr(self, key) for key in self.__slots__ if key[0] == '_' and hasattr(self, key) } + # fmt: on # deal with basic convenience wrappers @@ -615,4 +754,4 @@ def to_dict(self): if self.title: result['title'] = self.title - return result + return result # type: ignore # This payload is equivalent to the EmbedData type diff --git a/dist/ba_data/python-site-packages/discord/emoji.py b/dist/ba_data/python-site-packages/discord/emoji.py index 735d508c..045486d5 100644 --- a/dist/ba_data/python-site-packages/discord/emoji.py +++ b/dist/ba_data/python-site-packages/discord/emoji.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,12 +22,30 @@ DEALINGS IN THE SOFTWARE. """ -from .asset import Asset -from . import utils -from .partial_emoji import _EmojiTag +from __future__ import annotations +from typing import Any, Collection, Iterator, List, Optional, TYPE_CHECKING, Tuple + +from .asset import Asset, AssetMixin +from .utils import SnowflakeList, snowflake_time, MISSING +from .partial_emoji import _EmojiTag, PartialEmoji from .user import User -class Emoji(_EmojiTag): +# fmt: off +__all__ = ( + 'Emoji', +) +# fmt: on + +if TYPE_CHECKING: + from .types.emoji import Emoji as EmojiPayload + from .guild import Guild + from .state import ConnectionState + from .abc import Snowflake + from .role import Role + from datetime import datetime + + +class Emoji(_EmojiTag, AssetMixin): """Represents a custom emoji. Depending on the way this object was created, some of the attributes can @@ -76,70 +92,78 @@ class Emoji(_EmojiTag): Whether the emoji is available for use. user: Optional[:class:`User`] The user that created the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and - having the :attr:`~Permissions.manage_emojis` permission. + having :attr:`~Permissions.manage_emojis`. """ - __slots__ = ('require_colons', 'animated', 'managed', 'id', 'name', '_roles', 'guild_id', - '_state', 'user', 'available') - def __init__(self, *, guild, state, data): - self.guild_id = guild.id - self._state = state + __slots__: Tuple[str, ...] = ( + 'require_colons', + 'animated', + 'managed', + 'id', + 'name', + '_roles', + 'guild_id', + '_state', + 'user', + 'available', + ) + + def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload) -> None: + self.guild_id: int = guild.id + self._state: ConnectionState = state self._from_data(data) - def _from_data(self, emoji): - self.require_colons = emoji['require_colons'] - self.managed = emoji['managed'] - self.id = int(emoji['id']) - self.name = emoji['name'] - self.animated = emoji.get('animated', False) - self.available = emoji.get('available', True) - self._roles = utils.SnowflakeList(map(int, emoji.get('roles', []))) + def _from_data(self, emoji: EmojiPayload) -> None: + self.require_colons: bool = emoji.get('require_colons', False) + self.managed: bool = emoji.get('managed', False) + self.id: int = int(emoji['id']) # type: ignore # This won't be None for full emoji objects. + self.name: str = emoji['name'] # type: ignore # This won't be None for full emoji objects. + self.animated: bool = emoji.get('animated', False) + self.available: bool = emoji.get('available', True) + self._roles: SnowflakeList = SnowflakeList(map(int, emoji.get('roles', []))) user = emoji.get('user') - self.user = User(state=self._state, data=user) if user else None + self.user: Optional[User] = User(state=self._state, data=user) if user else None + + def _to_partial(self) -> PartialEmoji: + return PartialEmoji(name=self.name, animated=self.animated, id=self.id) - def _iterator(self): + def __iter__(self) -> Iterator[Tuple[str, Any]]: for attr in self.__slots__: if attr[0] != '_': value = getattr(self, attr, None) if value is not None: yield (attr, value) - def __iter__(self): - return self._iterator() - - def __str__(self): + def __str__(self) -> str: if self.animated: - return ''.format(self) - return "<:{0.name}:{0.id}>".format(self) + return f'' + return f'<:{self.name}:{self.id}>' - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' - def __eq__(self, other): + def __eq__(self, other: object) -> bool: return isinstance(other, _EmojiTag) and self.id == other.id - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: return self.id >> 22 @property - def created_at(self): + def created_at(self) -> datetime: """:class:`datetime.datetime`: Returns the emoji's creation time in UTC.""" - return utils.snowflake_time(self.id) + return snowflake_time(self.id) @property - def url(self): - """:class:`Asset`: Returns the asset of the emoji. - - This is equivalent to calling :meth:`url_as` with - the default parameters (i.e. png/gif detection). - """ - return self.url_as(format=None) + def url(self) -> str: + """:class:`str`: Returns the URL of the emoji.""" + fmt = 'gif' if self.animated else 'png' + return f'{Asset.BASE}/emojis/{self.id}.{fmt}' @property - def roles(self): + def roles(self) -> List[Role]: """List[:class:`Role`]: A :class:`list` of roles that is allowed to use this emoji. If roles is empty, the emoji is unrestricted. @@ -151,62 +175,28 @@ def roles(self): return [role for role in guild.roles if self._roles.has(role.id)] @property - def guild(self): + def guild(self) -> Optional[Guild]: """:class:`Guild`: The guild this emoji belongs to.""" return self._state._get_guild(self.guild_id) - - def url_as(self, *, format=None, static_format="png"): - """Returns an :class:`Asset` for the emoji's url. - - The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif'. - 'gif' is only valid for animated emojis. - - .. versionadded:: 1.6 - - Parameters - ----------- - format: Optional[:class:`str`] - The format to attempt to convert the emojis to. - If the format is ``None``, then it is automatically - detected as either 'gif' or static_format, depending on whether the - emoji is animated or not. - static_format: Optional[:class:`str`] - Format to attempt to convert only non-animated emoji's to. - Defaults to 'png' - - Raises - ------- - InvalidArgument - Bad image format passed to ``format`` or ``static_format``. - - Returns - -------- - :class:`Asset` - The resulting CDN asset. - """ - return Asset._from_emoji(self._state, self, format=format, static_format=static_format) - - - def is_usable(self): + def is_usable(self) -> bool: """:class:`bool`: Whether the bot can use this emoji. .. versionadded:: 1.3 """ - if not self.available: + if not self.available or not self.guild or self.guild.unavailable: return False if not self._roles: return True emoji_roles, my_roles = self._roles, self.guild.me._roles return any(my_roles.has(role_id) for role_id in emoji_roles) - async def delete(self, *, reason=None): + async def delete(self, *, reason: Optional[str] = None) -> None: """|coro| Deletes the custom emoji. - You must have :attr:`~Permissions.manage_emojis` permission to - do this. + You must have :attr:`~Permissions.manage_emojis` to do this. Parameters ----------- @@ -221,22 +211,26 @@ async def delete(self, *, reason=None): An error occurred deleting the emoji. """ - await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason) + await self._state.http.delete_custom_emoji(self.guild_id, self.id, reason=reason) - async def edit(self, *, name=None, roles=None, reason=None): + async def edit( + self, *, name: str = MISSING, roles: Collection[Snowflake] = MISSING, reason: Optional[str] = None + ) -> Emoji: r"""|coro| Edits the custom emoji. - You must have :attr:`~Permissions.manage_emojis` permission to - do this. + You must have :attr:`~Permissions.manage_emojis` to do this. + + .. versionchanged:: 2.0 + The newly updated emoji is returned. Parameters ----------- name: :class:`str` The new emoji name. - roles: Optional[list[:class:`Role`]] - A :class:`list` of :class:`Role`\s that can use this emoji. Leave empty to make it available to everyone. + roles: List[:class:`~discord.abc.Snowflake`] + A list of roles that can use this emoji. An empty list can be passed to make it available to everyone. reason: Optional[:class:`str`] The reason for editing this emoji. Shows up on the audit log. @@ -246,9 +240,18 @@ async def edit(self, *, name=None, roles=None, reason=None): You are not allowed to edit emojis. HTTPException An error occurred editing the emoji. + + Returns + -------- + :class:`Emoji` + The newly updated emoji. """ - name = name or self.name - if roles: - roles = [role.id for role in roles] - await self._state.http.edit_custom_emoji(self.guild.id, self.id, name=name, roles=roles, reason=reason) + payload = {} + if name is not MISSING: + payload['name'] = name + if roles is not MISSING: + payload['roles'] = [role.id for role in roles] + + data = await self._state.http.edit_custom_emoji(self.guild_id, self.id, payload=payload, reason=reason) + return Emoji(guild=self.guild, data=data, state=self._state) # type: ignore # if guild is None, the http request would have failed diff --git a/dist/ba_data/python-site-packages/discord/enums.py b/dist/ba_data/python-site-packages/discord/enums.py index 91592a61..81d5cb44 100644 --- a/dist/ba_data/python-site-packages/discord/enums.py +++ b/dist/ba_data/python-site-packages/discord/enums.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -23,54 +21,90 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations import types from collections import namedtuple +from typing import Any, ClassVar, Dict, List, Optional, TYPE_CHECKING, Tuple, Type, TypeVar, Iterator, Mapping __all__ = ( 'Enum', 'ChannelType', 'MessageType', - 'VoiceRegion', 'SpeakingState', 'VerificationLevel', 'ContentFilter', 'Status', 'DefaultAvatar', - 'RelationshipType', 'AuditLogAction', 'AuditLogActionCategory', 'UserFlags', 'ActivityType', - 'HypeSquadHouse', 'NotificationLevel', - 'PremiumType', - 'UserContentFilter', - 'FriendFlags', 'TeamMembershipState', - 'Theme', 'WebhookType', 'ExpireBehaviour', 'ExpireBehavior', 'StickerType', + 'StickerFormatType', + 'InviteTarget', + 'VideoQualityMode', + 'ComponentType', + 'ButtonStyle', + 'TextStyle', + 'PrivacyLevel', + 'InteractionType', + 'InteractionResponseType', + 'NSFWLevel', + 'MFALevel', + 'Locale', + 'EntityType', + 'EventStatus', + 'AppCommandType', + 'AppCommandOptionType', + 'AppCommandPermissionType', + 'AutoModRuleTriggerType', + 'AutoModRuleEventType', + 'AutoModRuleActionType', + 'ForumLayoutType', + 'ForumOrderType', ) -def _create_value_cls(name): +if TYPE_CHECKING: + from typing_extensions import Self + + +def _create_value_cls(name: str, comparable: bool): + # All the type ignores here are due to the type checker being unable to recognise + # Runtime type creation without exploding. cls = namedtuple('_EnumValue_' + name, 'name value') - cls.__repr__ = lambda self: '<%s.%s: %r>' % (name, self.name, self.value) - cls.__str__ = lambda self: '%s.%s' % (name, self.name) + cls.__repr__ = lambda self: f'<{name}.{self.name}: {self.value!r}>' # type: ignore + cls.__str__ = lambda self: f'{name}.{self.name}' # type: ignore + if comparable: + cls.__le__ = lambda self, other: isinstance(other, self.__class__) and self.value <= other.value # type: ignore + cls.__ge__ = lambda self, other: isinstance(other, self.__class__) and self.value >= other.value # type: ignore + cls.__lt__ = lambda self, other: isinstance(other, self.__class__) and self.value < other.value # type: ignore + cls.__gt__ = lambda self, other: isinstance(other, self.__class__) and self.value > other.value # type: ignore return cls + def _is_descriptor(obj): return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj, '__delete__') + class EnumMeta(type): - def __new__(cls, name, bases, attrs): + if TYPE_CHECKING: + __name__: ClassVar[str] + _enum_member_names_: ClassVar[List[str]] + _enum_member_map_: ClassVar[Dict[str, Any]] + _enum_value_map_: ClassVar[Dict[Any, Any]] + + def __new__(cls, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any], *, comparable: bool = False) -> Self: value_mapping = {} member_mapping = {} member_names = [] - value_cls = _create_value_cls(name) + value_cls = _create_value_cls(name, comparable) for key, value in list(attrs.items()): is_descriptor = _is_descriptor(value) if key[0] == '_' and not is_descriptor: @@ -98,42 +132,43 @@ def __new__(cls, name, bases, attrs): attrs['_enum_value_map_'] = value_mapping attrs['_enum_member_map_'] = member_mapping attrs['_enum_member_names_'] = member_names + attrs['_enum_value_cls_'] = value_cls actual_cls = super().__new__(cls, name, bases, attrs) - value_cls._actual_enum_cls_ = actual_cls + value_cls._actual_enum_cls_ = actual_cls # type: ignore # Runtime attribute isn't understood return actual_cls - def __iter__(cls): + def __iter__(cls) -> Iterator[Any]: return (cls._enum_member_map_[name] for name in cls._enum_member_names_) - def __reversed__(cls): + def __reversed__(cls) -> Iterator[Any]: return (cls._enum_member_map_[name] for name in reversed(cls._enum_member_names_)) - def __len__(cls): + def __len__(cls) -> int: return len(cls._enum_member_names_) - def __repr__(cls): - return '' % cls.__name__ + def __repr__(cls) -> str: + return f'' @property - def __members__(cls): + def __members__(cls) -> Mapping[str, Any]: return types.MappingProxyType(cls._enum_member_map_) - def __call__(cls, value): + def __call__(cls, value: str) -> Any: try: return cls._enum_value_map_[value] except (KeyError, TypeError): - raise ValueError("%r is not a valid %s" % (value, cls.__name__)) + raise ValueError(f"{value!r} is not a valid {cls.__name__}") - def __getitem__(cls, key): + def __getitem__(cls, key: str) -> Any: return cls._enum_member_map_[key] - def __setattr__(cls, name, value): + def __setattr__(cls, name: str, value: Any) -> None: raise TypeError('Enums are immutable.') - def __delattr__(cls, attr): + def __delattr__(cls, attr: str) -> None: raise TypeError('Enums are immutable') - def __instancecheck__(self, instance): + def __instancecheck__(self, instance: Any) -> bool: # isinstance(x, Y) # -> __instancecheck__(Y, x) try: @@ -141,124 +176,105 @@ def __instancecheck__(self, instance): except AttributeError: return False -class Enum(metaclass=EnumMeta): - @classmethod - def try_value(cls, value): - try: - return cls._enum_value_map_[value] - except (KeyError, TypeError): - return value + +if TYPE_CHECKING: + from enum import Enum +else: + + class Enum(metaclass=EnumMeta): + @classmethod + def try_value(cls, value): + try: + return cls._enum_value_map_[value] + except (KeyError, TypeError): + return value class ChannelType(Enum): - text = 0 - private = 1 - voice = 2 - group = 3 + text = 0 + private = 1 + voice = 2 + group = 3 category = 4 - news = 5 - store = 6 + news = 5 + news_thread = 10 + public_thread = 11 + private_thread = 12 stage_voice = 13 + forum = 15 - def __str__(self): + def __str__(self) -> str: return self.name + class MessageType(Enum): - default = 0 - recipient_add = 1 - recipient_remove = 2 - call = 3 - channel_name_change = 4 - channel_icon_change = 5 - pins_add = 6 - new_member = 7 - premium_guild_subscription = 8 - premium_guild_tier_1 = 9 - premium_guild_tier_2 = 10 - premium_guild_tier_3 = 11 - channel_follow_add = 12 - guild_stream = 13 - guild_discovery_disqualified = 14 - guild_discovery_requalified = 15 + default = 0 + recipient_add = 1 + recipient_remove = 2 + call = 3 + channel_name_change = 4 + channel_icon_change = 5 + pins_add = 6 + new_member = 7 + premium_guild_subscription = 8 + premium_guild_tier_1 = 9 + premium_guild_tier_2 = 10 + premium_guild_tier_3 = 11 + channel_follow_add = 12 + guild_stream = 13 + guild_discovery_disqualified = 14 + guild_discovery_requalified = 15 guild_discovery_grace_period_initial_warning = 16 - guild_discovery_grace_period_final_warning = 17 - -class VoiceRegion(Enum): - us_west = 'us-west' - us_east = 'us-east' - us_south = 'us-south' - us_central = 'us-central' - eu_west = 'eu-west' - eu_central = 'eu-central' - singapore = 'singapore' - london = 'london' - sydney = 'sydney' - amsterdam = 'amsterdam' - frankfurt = 'frankfurt' - brazil = 'brazil' - hongkong = 'hongkong' - russia = 'russia' - japan = 'japan' - southafrica = 'southafrica' - south_korea = 'south-korea' - india = 'india' - europe = 'europe' - dubai = 'dubai' - vip_us_east = 'vip-us-east' - vip_us_west = 'vip-us-west' - vip_amsterdam = 'vip-amsterdam' - - def __str__(self): - return self.value + guild_discovery_grace_period_final_warning = 17 + thread_created = 18 + reply = 19 + chat_input_command = 20 + thread_starter_message = 21 + guild_invite_reminder = 22 + context_menu_command = 23 + auto_moderation_action = 24 + role_subscription_purchase = 25 + interaction_premium_upsell = 26 + stage_start = 27 + stage_end = 28 + stage_speaker = 29 + stage_raise_hand = 30 + stage_topic = 31 + guild_application_premium_subscription = 32 + class SpeakingState(Enum): - none = 0 - voice = 1 + none = 0 + voice = 1 soundshare = 2 - priority = 4 + priority = 4 - def __str__(self): + def __str__(self) -> str: return self.name - def __int__(self): + def __int__(self) -> int: return self.value -class VerificationLevel(Enum): - none = 0 - low = 1 - medium = 2 - high = 3 - table_flip = 3 - extreme = 4 - double_table_flip = 4 - very_high = 4 - - def __str__(self): - return self.name -class ContentFilter(Enum): - disabled = 0 - no_role = 1 - all_members = 2 +class VerificationLevel(Enum, comparable=True): + none = 0 + low = 1 + medium = 2 + high = 3 + highest = 4 - def __str__(self): + def __str__(self) -> str: return self.name -class UserContentFilter(Enum): - disabled = 0 - friends = 1 - all_messages = 2 -class FriendFlags(Enum): - noone = 0 - mutual_guilds = 1 - mutual_friends = 2 - guild_and_friends = 3 - everyone = 4 +class ContentFilter(Enum, comparable=True): + disabled = 0 + no_role = 1 + all_members = 2 + + def __str__(self) -> str: + return self.name -class Theme(Enum): - light = 'light' - dark = 'dark' class Status(Enum): online = 'online' @@ -268,115 +284,156 @@ class Status(Enum): do_not_disturb = 'dnd' invisible = 'invisible' - def __str__(self): + def __str__(self) -> str: return self.value + class DefaultAvatar(Enum): blurple = 0 - grey = 1 - gray = 1 - green = 2 - orange = 3 - red = 4 - - def __str__(self): + grey = 1 + gray = 1 + green = 2 + orange = 3 + red = 4 + pink = 5 + + def __str__(self) -> str: return self.name -class RelationshipType(Enum): - friend = 1 - blocked = 2 - incoming_request = 3 - outgoing_request = 4 -class NotificationLevel(Enum): - all_messages = 0 +class NotificationLevel(Enum, comparable=True): + all_messages = 0 only_mentions = 1 + class AuditLogActionCategory(Enum): create = 1 delete = 2 update = 3 + class AuditLogAction(Enum): - guild_update = 1 - channel_create = 10 - channel_update = 11 - channel_delete = 12 - overwrite_create = 13 - overwrite_update = 14 - overwrite_delete = 15 - kick = 20 - member_prune = 21 - ban = 22 - unban = 23 - member_update = 24 - member_role_update = 25 - member_move = 26 - member_disconnect = 27 - bot_add = 28 - role_create = 30 - role_update = 31 - role_delete = 32 - invite_create = 40 - invite_update = 41 - invite_delete = 42 - webhook_create = 50 - webhook_update = 51 - webhook_delete = 52 - emoji_create = 60 - emoji_update = 61 - emoji_delete = 62 - message_delete = 72 - message_bulk_delete = 73 - message_pin = 74 - message_unpin = 75 - integration_create = 80 - integration_update = 81 - integration_delete = 82 + # fmt: off + guild_update = 1 + channel_create = 10 + channel_update = 11 + channel_delete = 12 + overwrite_create = 13 + overwrite_update = 14 + overwrite_delete = 15 + kick = 20 + member_prune = 21 + ban = 22 + unban = 23 + member_update = 24 + member_role_update = 25 + member_move = 26 + member_disconnect = 27 + bot_add = 28 + role_create = 30 + role_update = 31 + role_delete = 32 + invite_create = 40 + invite_update = 41 + invite_delete = 42 + webhook_create = 50 + webhook_update = 51 + webhook_delete = 52 + emoji_create = 60 + emoji_update = 61 + emoji_delete = 62 + message_delete = 72 + message_bulk_delete = 73 + message_pin = 74 + message_unpin = 75 + integration_create = 80 + integration_update = 81 + integration_delete = 82 + stage_instance_create = 83 + stage_instance_update = 84 + stage_instance_delete = 85 + sticker_create = 90 + sticker_update = 91 + sticker_delete = 92 + scheduled_event_create = 100 + scheduled_event_update = 101 + scheduled_event_delete = 102 + thread_create = 110 + thread_update = 111 + thread_delete = 112 + app_command_permission_update = 121 + automod_rule_create = 140 + automod_rule_update = 141 + automod_rule_delete = 142 + automod_block_message = 143 + automod_flag_message = 144 + automod_timeout_member = 145 + # fmt: on @property - def category(self): - lookup = { - AuditLogAction.guild_update: AuditLogActionCategory.update, - AuditLogAction.channel_create: AuditLogActionCategory.create, - AuditLogAction.channel_update: AuditLogActionCategory.update, - AuditLogAction.channel_delete: AuditLogActionCategory.delete, - AuditLogAction.overwrite_create: AuditLogActionCategory.create, - AuditLogAction.overwrite_update: AuditLogActionCategory.update, - AuditLogAction.overwrite_delete: AuditLogActionCategory.delete, - AuditLogAction.kick: None, - AuditLogAction.member_prune: None, - AuditLogAction.ban: None, - AuditLogAction.unban: None, - AuditLogAction.member_update: AuditLogActionCategory.update, - AuditLogAction.member_role_update: AuditLogActionCategory.update, - AuditLogAction.member_move: None, - AuditLogAction.member_disconnect: None, - AuditLogAction.bot_add: None, - AuditLogAction.role_create: AuditLogActionCategory.create, - AuditLogAction.role_update: AuditLogActionCategory.update, - AuditLogAction.role_delete: AuditLogActionCategory.delete, - AuditLogAction.invite_create: AuditLogActionCategory.create, - AuditLogAction.invite_update: AuditLogActionCategory.update, - AuditLogAction.invite_delete: AuditLogActionCategory.delete, - AuditLogAction.webhook_create: AuditLogActionCategory.create, - AuditLogAction.webhook_update: AuditLogActionCategory.update, - AuditLogAction.webhook_delete: AuditLogActionCategory.delete, - AuditLogAction.emoji_create: AuditLogActionCategory.create, - AuditLogAction.emoji_update: AuditLogActionCategory.update, - AuditLogAction.emoji_delete: AuditLogActionCategory.delete, - AuditLogAction.message_delete: AuditLogActionCategory.delete, - AuditLogAction.message_bulk_delete: AuditLogActionCategory.delete, - AuditLogAction.message_pin: None, - AuditLogAction.message_unpin: None, - AuditLogAction.integration_create: AuditLogActionCategory.create, - AuditLogAction.integration_update: AuditLogActionCategory.update, - AuditLogAction.integration_delete: AuditLogActionCategory.delete, + def category(self) -> Optional[AuditLogActionCategory]: + # fmt: off + lookup: Dict[AuditLogAction, Optional[AuditLogActionCategory]] = { + AuditLogAction.guild_update: AuditLogActionCategory.update, + AuditLogAction.channel_create: AuditLogActionCategory.create, + AuditLogAction.channel_update: AuditLogActionCategory.update, + AuditLogAction.channel_delete: AuditLogActionCategory.delete, + AuditLogAction.overwrite_create: AuditLogActionCategory.create, + AuditLogAction.overwrite_update: AuditLogActionCategory.update, + AuditLogAction.overwrite_delete: AuditLogActionCategory.delete, + AuditLogAction.kick: None, + AuditLogAction.member_prune: None, + AuditLogAction.ban: None, + AuditLogAction.unban: None, + AuditLogAction.member_update: AuditLogActionCategory.update, + AuditLogAction.member_role_update: AuditLogActionCategory.update, + AuditLogAction.member_move: None, + AuditLogAction.member_disconnect: None, + AuditLogAction.bot_add: None, + AuditLogAction.role_create: AuditLogActionCategory.create, + AuditLogAction.role_update: AuditLogActionCategory.update, + AuditLogAction.role_delete: AuditLogActionCategory.delete, + AuditLogAction.invite_create: AuditLogActionCategory.create, + AuditLogAction.invite_update: AuditLogActionCategory.update, + AuditLogAction.invite_delete: AuditLogActionCategory.delete, + AuditLogAction.webhook_create: AuditLogActionCategory.create, + AuditLogAction.webhook_update: AuditLogActionCategory.update, + AuditLogAction.webhook_delete: AuditLogActionCategory.delete, + AuditLogAction.emoji_create: AuditLogActionCategory.create, + AuditLogAction.emoji_update: AuditLogActionCategory.update, + AuditLogAction.emoji_delete: AuditLogActionCategory.delete, + AuditLogAction.message_delete: AuditLogActionCategory.delete, + AuditLogAction.message_bulk_delete: AuditLogActionCategory.delete, + AuditLogAction.message_pin: None, + AuditLogAction.message_unpin: None, + AuditLogAction.integration_create: AuditLogActionCategory.create, + AuditLogAction.integration_update: AuditLogActionCategory.update, + AuditLogAction.integration_delete: AuditLogActionCategory.delete, + AuditLogAction.stage_instance_create: AuditLogActionCategory.create, + AuditLogAction.stage_instance_update: AuditLogActionCategory.update, + AuditLogAction.stage_instance_delete: AuditLogActionCategory.delete, + AuditLogAction.sticker_create: AuditLogActionCategory.create, + AuditLogAction.sticker_update: AuditLogActionCategory.update, + AuditLogAction.sticker_delete: AuditLogActionCategory.delete, + AuditLogAction.scheduled_event_create: AuditLogActionCategory.create, + AuditLogAction.scheduled_event_update: AuditLogActionCategory.update, + AuditLogAction.scheduled_event_delete: AuditLogActionCategory.delete, + AuditLogAction.thread_create: AuditLogActionCategory.create, + AuditLogAction.thread_delete: AuditLogActionCategory.delete, + AuditLogAction.thread_update: AuditLogActionCategory.update, + AuditLogAction.app_command_permission_update: AuditLogActionCategory.update, + AuditLogAction.automod_rule_create: AuditLogActionCategory.create, + AuditLogAction.automod_rule_update: AuditLogActionCategory.update, + AuditLogAction.automod_rule_delete: AuditLogActionCategory.delete, + AuditLogAction.automod_block_message: None, + AuditLogAction.automod_flag_message: None, + AuditLogAction.automod_timeout_member: None, } + # fmt: on return lookup[self] @property - def target_type(self): + def target_type(self) -> Optional[str]: v = self.value if v == -1: return 'all' @@ -398,8 +455,23 @@ def target_type(self): return 'channel' elif v < 80: return 'message' - elif v < 90: + elif v < 83: return 'integration' + elif v < 90: + return 'stage_instance' + elif v < 93: + return 'sticker' + elif v < 103: + return 'guild_scheduled_event' + elif v < 113: + return 'thread' + elif v < 122: + return 'integration_or_app_command' + elif v < 143: + return 'auto_moderation' + elif v < 146: + return 'user' + class UserFlags(Enum): staff = 1 @@ -418,6 +490,11 @@ class UserFlags(Enum): bug_hunter_level_2 = 16384 verified_bot = 65536 verified_bot_developer = 131072 + discord_certified_moderator = 262144 + bot_http_interactions = 524288 + spammer = 1048576 + active_developer = 4194304 + class ActivityType(Enum): unknown = -1 @@ -428,44 +505,272 @@ class ActivityType(Enum): custom = 4 competing = 5 - def __int__(self): + def __int__(self) -> int: return self.value -class HypeSquadHouse(Enum): - bravery = 1 - brilliance = 2 - balance = 3 - -class PremiumType(Enum): - nitro_classic = 1 - nitro = 2 class TeamMembershipState(Enum): invited = 1 accepted = 2 + class WebhookType(Enum): incoming = 1 channel_follower = 2 + application = 3 + class ExpireBehaviour(Enum): remove_role = 0 kick = 1 + ExpireBehavior = ExpireBehaviour + class StickerType(Enum): + standard = 1 + guild = 2 + + +class StickerFormatType(Enum): png = 1 apng = 2 lottie = 3 + gif = 4 + + @property + def file_extension(self) -> str: + # fmt: off + lookup: Dict[StickerFormatType, str] = { + StickerFormatType.png: 'png', + StickerFormatType.apng: 'png', + StickerFormatType.lottie: 'json', + StickerFormatType.gif: 'gif', + } + # fmt: on + return lookup.get(self, 'png') + + +class InviteTarget(Enum): + unknown = 0 + stream = 1 + embedded_application = 2 + + +class InteractionType(Enum): + ping = 1 + application_command = 2 + component = 3 + autocomplete = 4 + modal_submit = 5 + + +class InteractionResponseType(Enum): + pong = 1 + # ack = 2 (deprecated) + # channel_message = 3 (deprecated) + channel_message = 4 # (with source) + deferred_channel_message = 5 # (with source) + deferred_message_update = 6 # for components + message_update = 7 # for components + autocomplete_result = 8 + modal = 9 # for modals + + +class VideoQualityMode(Enum): + auto = 1 + full = 2 + + def __int__(self) -> int: + return self.value + + +class ComponentType(Enum): + action_row = 1 + button = 2 + select = 3 + string_select = 3 + text_input = 4 + user_select = 5 + role_select = 6 + mentionable_select = 7 + channel_select = 8 + + def __int__(self) -> int: + return self.value + + +class ButtonStyle(Enum): + primary = 1 + secondary = 2 + success = 3 + danger = 4 + link = 5 + + # Aliases + blurple = 1 + grey = 2 + gray = 2 + green = 3 + red = 4 + url = 5 + + def __int__(self) -> int: + return self.value + + +class TextStyle(Enum): + short = 1 + paragraph = 2 + + # Aliases + long = 2 + + def __int__(self) -> int: + return self.value + + +class PrivacyLevel(Enum): + guild_only = 2 + + +class NSFWLevel(Enum, comparable=True): + default = 0 + explicit = 1 + safe = 2 + age_restricted = 3 + + +class MFALevel(Enum, comparable=True): + disabled = 0 + require_2fa = 1 + + +class Locale(Enum): + american_english = 'en-US' + british_english = 'en-GB' + bulgarian = 'bg' + chinese = 'zh-CN' + taiwan_chinese = 'zh-TW' + croatian = 'hr' + czech = 'cs' + indonesian = 'id' + danish = 'da' + dutch = 'nl' + finnish = 'fi' + french = 'fr' + german = 'de' + greek = 'el' + hindi = 'hi' + hungarian = 'hu' + italian = 'it' + japanese = 'ja' + korean = 'ko' + lithuanian = 'lt' + norwegian = 'no' + polish = 'pl' + brazil_portuguese = 'pt-BR' + romanian = 'ro' + russian = 'ru' + spain_spanish = 'es-ES' + swedish = 'sv-SE' + thai = 'th' + turkish = 'tr' + ukrainian = 'uk' + vietnamese = 'vi' + + def __str__(self) -> str: + return self.value + + +E = TypeVar('E', bound='Enum') + + +class EntityType(Enum): + stage_instance = 1 + voice = 2 + external = 3 + + +class EventStatus(Enum): + scheduled = 1 + active = 2 + completed = 3 + canceled = 4 + + ended = 3 + cancelled = 4 + + +class AppCommandOptionType(Enum): + subcommand = 1 + subcommand_group = 2 + string = 3 + integer = 4 + boolean = 5 + user = 6 + channel = 7 + role = 8 + mentionable = 9 + number = 10 + attachment = 11 + + +class AppCommandType(Enum): + chat_input = 1 + user = 2 + message = 3 + + +class AppCommandPermissionType(Enum): + role = 1 + user = 2 + channel = 3 + + +class AutoModRuleTriggerType(Enum): + keyword = 1 + harmful_link = 2 + spam = 3 + keyword_preset = 4 + mention_spam = 5 + + +class AutoModRuleEventType(Enum): + message_send = 1 + + +class AutoModRuleActionType(Enum): + block_message = 1 + send_alert_message = 2 + timeout = 3 + + +class ForumLayoutType(Enum): + not_set = 0 + list_view = 1 + gallery_view = 2 + + +class ForumOrderType(Enum): + latest_activity = 0 + creation_date = 1 + + +def create_unknown_value(cls: Type[E], val: Any) -> E: + value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below + name = f'unknown_{val}' + return value_cls(name=name, value=val) + -def try_enum(cls, val): +def try_enum(cls: Type[E], val: Any) -> E: """A function that tries to turn the value into enum ``cls``. - If it fails it returns the value instead. + If it fails it returns a proxy invalid value instead. """ try: - return cls._enum_value_map_[val] + return cls._enum_value_map_[val] # type: ignore # All errors are caught below except (KeyError, TypeError, AttributeError): - return val + return create_unknown_value(cls, val) diff --git a/dist/ba_data/python-site-packages/discord/errors.py b/dist/ba_data/python-site-packages/discord/errors.py index 72470510..6035ace7 100644 --- a/dist/ba_data/python-site-packages/discord/errors.py +++ b/dist/ba_data/python-site-packages/discord/errors.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,42 +22,70 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations +from typing import Dict, List, Optional, TYPE_CHECKING, Any, Tuple, Union + +if TYPE_CHECKING: + from aiohttp import ClientResponse, ClientWebSocketResponse + from requests import Response + + _ResponseType = Union[ClientResponse, Response] + + from .interactions import Interaction + +__all__ = ( + 'DiscordException', + 'ClientException', + 'GatewayNotFound', + 'HTTPException', + 'RateLimited', + 'Forbidden', + 'NotFound', + 'DiscordServerError', + 'InvalidData', + 'LoginFailure', + 'ConnectionClosed', + 'PrivilegedIntentsRequired', + 'InteractionResponded', +) + + class DiscordException(Exception): """Base exception class for discord.py - Ideally speaking, this could be caught to handle any exceptions thrown from this library. + Ideally speaking, this could be caught to handle any exceptions raised from this library. """ + pass + class ClientException(DiscordException): - """Exception that's thrown when an operation in the :class:`Client` fails. + """Exception that's raised when an operation in the :class:`Client` fails. These are usually for exceptions that happened due to user input. """ - pass -class NoMoreItems(DiscordException): - """Exception that is thrown when an async iteration operation has no more - items.""" pass + class GatewayNotFound(DiscordException): - """An exception that is usually thrown when the gateway hub - for the :class:`Client` websocket is not found.""" + """An exception that is raised when the gateway for Discord could not be found""" + def __init__(self): message = 'The gateway to connect to discord was not found.' - super(GatewayNotFound, self).__init__(message) + super().__init__(message) -def flatten_error_dict(d, key=''): - items = [] + +def _flatten_error_dict(d: Dict[str, Any], key: str = '') -> Dict[str, str]: + items: List[Tuple[str, str]] = [] for k, v in d.items(): new_key = key + '.' + k if key else k if isinstance(v, dict): try: - _errors = v['_errors'] + _errors: List[Dict[str, Any]] = v['_errors'] except KeyError: - items.extend(flatten_error_dict(v, new_key).items()) + items.extend(_flatten_error_dict(v, new_key).items()) else: items.append((new_key, ' '.join(x.get('message', '') for x in _errors))) else: @@ -67,8 +93,9 @@ def flatten_error_dict(d, key=''): return dict(items) + class HTTPException(DiscordException): - """Exception that's thrown when an HTTP request operation fails. + """Exception that's raised when an HTTP request operation fails. Attributes ------------ @@ -85,21 +112,24 @@ class HTTPException(DiscordException): The Discord specific error code for the failure. """ - def __init__(self, response, message): - self.response = response - self.status = response.status + def __init__(self, response: _ResponseType, message: Optional[Union[str, Dict[str, Any]]]): + self.response: _ResponseType = response + self.status: int = response.status # type: ignore # This attribute is filled by the library even if using requests + self.code: int + self.text: str if isinstance(message, dict): self.code = message.get('code', 0) base = message.get('message', '') errors = message.get('errors') + self._errors: Optional[Dict[str, Any]] = errors if errors: - errors = flatten_error_dict(errors) + errors = _flatten_error_dict(errors) helpful = '\n'.join('In %s: %s' % t for t in errors.items()) self.text = base + '\n' + helpful else: self.text = base else: - self.text = message + self.text = message or '' self.code = 0 fmt = '{0.status} {0.reason} (error code: {1})' @@ -108,54 +138,79 @@ def __init__(self, response, message): super().__init__(fmt.format(self.response, self.code, self.text)) + +class RateLimited(DiscordException): + """Exception that's raised for when status code 429 occurs + and the timeout is greater than the configured maximum using + the ``max_ratelimit_timeout`` parameter in :class:`Client`. + + This is not raised during global ratelimits. + + Since sometimes requests are halted pre-emptively before they're + even made, this **does not** subclass :exc:`HTTPException`. + + .. versionadded:: 2.0 + + Attributes + ------------ + retry_after: :class:`float` + The amount of seconds that the client should wait before retrying + the request. + """ + + def __init__(self, retry_after: float): + self.retry_after = retry_after + super().__init__(f'Too many requests. Retry in {retry_after:.2f} seconds.') + + class Forbidden(HTTPException): - """Exception that's thrown for when status code 403 occurs. + """Exception that's raised for when status code 403 occurs. Subclass of :exc:`HTTPException` """ + pass + class NotFound(HTTPException): - """Exception that's thrown for when status code 404 occurs. + """Exception that's raised for when status code 404 occurs. Subclass of :exc:`HTTPException` """ + pass + class DiscordServerError(HTTPException): - """Exception that's thrown for when a 500 range status code occurs. + """Exception that's raised for when a 500 range status code occurs. Subclass of :exc:`HTTPException`. .. versionadded:: 1.5 """ + pass + class InvalidData(ClientException): """Exception that's raised when the library encounters unknown or invalid data from Discord. """ - pass - -class InvalidArgument(ClientException): - """Exception that's thrown when an argument to a function - is invalid some way (e.g. wrong value or wrong type). - This could be considered the analogous of ``ValueError`` and - ``TypeError`` except inherited from :exc:`ClientException` and thus - :exc:`DiscordException`. - """ pass + class LoginFailure(ClientException): - """Exception that's thrown when the :meth:`Client.login` function + """Exception that's raised when the :meth:`Client.login` function fails to log you in from improper credentials or some other misc. failure. """ + pass + class ConnectionClosed(ClientException): - """Exception that's thrown when the gateway connection is + """Exception that's raised when the gateway connection is closed for reasons that could not be handled internally. Attributes @@ -167,17 +222,19 @@ class ConnectionClosed(ClientException): shard_id: Optional[:class:`int`] The shard ID that got closed if applicable. """ - def __init__(self, socket, *, shard_id, code=None): + + def __init__(self, socket: ClientWebSocketResponse, *, shard_id: Optional[int], code: Optional[int] = None): # This exception is just the same exception except # reconfigured to subclass ClientException for users - self.code = code or socket.close_code + self.code: int = code or socket.close_code or -1 # aiohttp doesn't seem to consistently provide close reason - self.reason = '' - self.shard_id = shard_id - super().__init__('Shard ID %s WebSocket closed with %s' % (self.shard_id, self.code)) + self.reason: str = '' + self.shard_id: Optional[int] = shard_id + super().__init__(f'Shard ID {self.shard_id} WebSocket closed with {self.code}') + class PrivilegedIntentsRequired(ClientException): - """Exception that's thrown when the gateway is requesting privileged intents + """Exception that's raised when the gateway is requesting privileged intents but they're not ticked in the developer page yet. Go to https://discord.com/developers/applications/ and enable the intents @@ -185,6 +242,7 @@ class PrivilegedIntentsRequired(ClientException): - :attr:`Intents.members` - :attr:`Intents.presences` + - :attr:`Intents.message_content` Attributes ----------- @@ -192,10 +250,31 @@ class PrivilegedIntentsRequired(ClientException): The shard ID that got closed if applicable. """ - def __init__(self, shard_id): - self.shard_id = shard_id - msg = 'Shard ID %s is requesting privileged intents that have not been explicitly enabled in the ' \ - 'developer portal. It is recommended to go to https://discord.com/developers/applications/ ' \ - 'and explicitly enable the privileged intents within your application\'s page. If this is not ' \ - 'possible, then consider disabling the privileged intents instead.' + def __init__(self, shard_id: Optional[int]): + self.shard_id: Optional[int] = shard_id + msg = ( + 'Shard ID %s is requesting privileged intents that have not been explicitly enabled in the ' + 'developer portal. It is recommended to go to https://discord.com/developers/applications/ ' + 'and explicitly enable the privileged intents within your application\'s page. If this is not ' + 'possible, then consider disabling the privileged intents instead.' + ) super().__init__(msg % shard_id) + + +class InteractionResponded(ClientException): + """Exception that's raised when sending another interaction response using + :class:`InteractionResponse` when one has already been done before. + + An interaction can only respond once. + + .. versionadded:: 2.0 + + Attributes + ----------- + interaction: :class:`Interaction` + The interaction that's already been responded to. + """ + + def __init__(self, interaction: Interaction): + self.interaction: Interaction = interaction + super().__init__('This interaction has already been responded to before') diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py b/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py index 6f356c5d..08dab54d 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ discord.ext.commands ~~~~~~~~~~~~~~~~~~~~~ @@ -10,11 +8,14 @@ :license: MIT, see LICENSE for more details. """ -from .bot import Bot, AutoShardedBot, when_mentioned, when_mentioned_or -from .context import Context +from .bot import * +from .cog import * +from .context import * +from .converter import * +from .cooldowns import * from .core import * from .errors import * +from .flags import * from .help import * -from .converter import * -from .cooldowns import * -from .cog import * +from .parameters import * +from .hybrid import * diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/_types.py b/dist/ba_data/python-site-packages/discord/ext/commands/_types.py index 36d0efc9..1331c9f3 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/_types.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/_types.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,6 +22,51 @@ DEALINGS IN THE SOFTWARE. """ + +from typing import Any, Awaitable, Callable, Coroutine, TYPE_CHECKING, Protocol, TypeVar, Union, Tuple, Optional + + +T = TypeVar('T') + +if TYPE_CHECKING: + from typing_extensions import ParamSpec + + from .bot import Bot, AutoShardedBot + from .context import Context + from .cog import Cog + from .errors import CommandError + + P = ParamSpec('P') + MaybeAwaitableFunc = Callable[P, 'MaybeAwaitable[T]'] +else: + P = TypeVar('P') + MaybeAwaitableFunc = Tuple[P, T] + +_Bot = Union['Bot', 'AutoShardedBot'] +Coro = Coroutine[Any, Any, T] +CoroFunc = Callable[..., Coro[Any]] +MaybeCoro = Union[T, Coro[T]] +MaybeAwaitable = Union[T, Awaitable[T]] + +CogT = TypeVar('CogT', bound='Optional[Cog]') +UserCheck = Callable[["ContextT"], MaybeCoro[bool]] +Hook = Union[Callable[["CogT", "ContextT"], Coro[Any]], Callable[["ContextT"], Coro[Any]]] +Error = Union[Callable[["CogT", "ContextT", "CommandError"], Coro[Any]], Callable[["ContextT", "CommandError"], Coro[Any]]] + +ContextT = TypeVar('ContextT', bound='Context[Any]') +BotT = TypeVar('BotT', bound=_Bot, covariant=True) + +ContextT_co = TypeVar('ContextT_co', bound='Context[Any]', covariant=True) + + +class Check(Protocol[ContextT_co]): # type: ignore # TypeVar is expected to be invariant + + predicate: Callable[[ContextT_co], Coroutine[Any, Any, bool]] + + def __call__(self, coro_or_commands: T) -> T: + ... + + # This is merely a tag type to avoid circular import issues. # Yes, this is a terrible solution but ultimately it is the only solution. class _BaseCommand: diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/bot.py b/dist/ba_data/python-site-packages/discord/ext/commands/bot.py index ee0308e2..363b6656 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/bot.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/bot.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,15 +22,38 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + + import asyncio import collections +import collections.abc import inspect import importlib.util import sys -import traceback +import logging import types +from typing import ( + Any, + Callable, + Mapping, + List, + Dict, + TYPE_CHECKING, + Optional, + Sequence, + TypeVar, + Type, + Union, + Iterable, + Collection, + overload, +) import discord +from discord import app_commands +from discord.app_commands.tree import _retrieve_guild_ids +from discord.utils import MISSING, _is_submodule from .core import GroupMixin from .view import StringView @@ -40,15 +61,58 @@ from . import errors from .help import HelpCommand, DefaultHelpCommand from .cog import Cog +from .hybrid import hybrid_command, hybrid_group, HybridCommand, HybridGroup + +if TYPE_CHECKING: + from typing_extensions import Self + + import importlib.machinery + + from discord.message import Message + from discord.interactions import Interaction + from discord.abc import User, Snowflake + from ._types import ( + _Bot, + BotT, + UserCheck, + CoroFunc, + ContextT, + MaybeAwaitableFunc, + ) + from .core import Command + from .hybrid import CommandCallback, ContextT, P + + _Prefix = Union[Iterable[str], str] + _PrefixCallable = MaybeAwaitableFunc[[BotT, Message], _Prefix] + PrefixType = Union[_Prefix, _PrefixCallable[BotT]] + +__all__ = ( + 'when_mentioned', + 'when_mentioned_or', + 'Bot', + 'AutoShardedBot', +) + +T = TypeVar('T') +CFT = TypeVar('CFT', bound='CoroFunc') -def when_mentioned(bot, msg): +_log = logging.getLogger(__name__) + + +def when_mentioned(bot: _Bot, msg: Message, /) -> List[str]: """A callable that implements a command prefix equivalent to being mentioned. These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. + + .. versionchanged:: 2.0 + + ``bot`` and ``msg`` parameters are now positional-only. """ - return [bot.user.mention + ' ', '<@!%s> ' % bot.user.id] + # bot.user will never be None when this is called + return [f'<@{bot.user.id}> ', f'<@!{bot.user.id}> '] # type: ignore + -def when_mentioned_or(*prefixes): +def when_mentioned_or(*prefixes: str) -> Callable[[_Bot, Message], List[str]]: """A callable that implements when mentioned or other prefixes provided. These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. @@ -77,6 +141,7 @@ async def get_prefix(bot, message): ---------- :func:`.when_mentioned` """ + def inner(bot, msg): r = list(prefixes) r = when_mentioned(bot, msg) + r @@ -84,42 +149,48 @@ def inner(bot, msg): return inner -def _is_submodule(parent, child): - return parent == child or child.startswith(parent + ".") class _DefaultRepr: def __repr__(self): return '' -_default = _DefaultRepr() - -class BotBase(GroupMixin): - def __init__(self, command_prefix, help_command=_default, description=None, **options): - super().__init__(**options) - self.command_prefix = command_prefix - self.extra_events = {} - self.__cogs = {} - self.__extensions = {} - self._checks = [] - self._check_once = [] - self._before_invoke = None - self._after_invoke = None - self._help_command = None - self.description = inspect.cleandoc(description) if description else '' - self.owner_id = options.get('owner_id') - self.owner_ids = options.get('owner_ids', set()) - self.strip_after_prefix = options.get('strip_after_prefix', False) + +_default: Any = _DefaultRepr() + + +class BotBase(GroupMixin[None]): + def __init__( + self, + command_prefix: PrefixType[BotT], + *, + help_command: Optional[HelpCommand] = _default, + tree_cls: Type[app_commands.CommandTree[Any]] = app_commands.CommandTree, + description: Optional[str] = None, + intents: discord.Intents, + **options: Any, + ) -> None: + super().__init__(intents=intents, **options) + self.command_prefix: PrefixType[BotT] = command_prefix + self.extra_events: Dict[str, List[CoroFunc]] = {} + # Self doesn't have the ClientT bound, but since this is a mixin it technically does + self.__tree: app_commands.CommandTree[Self] = tree_cls(self) # type: ignore + self.__cogs: Dict[str, Cog] = {} + self.__extensions: Dict[str, types.ModuleType] = {} + self._checks: List[UserCheck] = [] + self._check_once: List[UserCheck] = [] + self._before_invoke: Optional[CoroFunc] = None + self._after_invoke: Optional[CoroFunc] = None + self._help_command: Optional[HelpCommand] = None + self.description: str = inspect.cleandoc(description) if description else '' + self.owner_id: Optional[int] = options.get('owner_id') + self.owner_ids: Optional[Collection[int]] = options.get('owner_ids', set()) + self.strip_after_prefix: bool = options.get('strip_after_prefix', False) if self.owner_id and self.owner_ids: raise TypeError('Both owner_id and owner_ids are set.') if self.owner_ids and not isinstance(self.owner_ids, collections.abc.Collection): - raise TypeError('owner_ids must be a collection not {0.__class__!r}'.format(self.owner_ids)) - - if options.pop('self_bot', False): - self._skip_check = lambda x, y: x != y - else: - self._skip_check = lambda x, y: x == y + raise TypeError(f'owner_ids must be a collection not {self.owner_ids.__class__.__name__}') if help_command is _default: self.help_command = DefaultHelpCommand() @@ -128,53 +199,157 @@ def __init__(self, command_prefix, help_command=_default, description=None, **op # internal helpers - def dispatch(self, event_name, *args, **kwargs): - super().dispatch(event_name, *args, **kwargs) + async def _async_setup_hook(self) -> None: + # self/super() resolves to Client/AutoShardedClient + await super()._async_setup_hook() # type: ignore + prefix = self.command_prefix + + # This has to be here because for the default logging set up to capture + # the logging calls, they have to come after the `Client.run` call. + # The best place to do this is in an async init scenario + if not self.intents.message_content: # type: ignore + trigger_warning = ( + (callable(prefix) and prefix is not when_mentioned) + or isinstance(prefix, str) + or (isinstance(prefix, collections.abc.Iterable) and len(list(prefix)) >= 1) + ) + if trigger_warning: + _log.warning('Privileged message content intent is missing, commands may not work as expected.') + + def dispatch(self, event_name: str, /, *args: Any, **kwargs: Any) -> None: + # super() will resolve to Client + super().dispatch(event_name, *args, **kwargs) # type: ignore ev = 'on_' + event_name for event in self.extra_events.get(ev, []): - self._schedule_event(event, ev, *args, **kwargs) + self._schedule_event(event, ev, *args, **kwargs) # type: ignore - async def close(self): + @discord.utils.copy_doc(discord.Client.close) + async def close(self) -> None: for extension in tuple(self.__extensions): try: - self.unload_extension(extension) + await self.unload_extension(extension) except Exception: pass for cog in tuple(self.__cogs): try: - self.remove_cog(cog) + await self.remove_cog(cog) except Exception: pass - await super().close() + await super().close() # type: ignore + + # GroupMixin overrides + + @discord.utils.copy_doc(GroupMixin.add_command) + def add_command(self, command: Command[Any, ..., Any], /) -> None: + super().add_command(command) + if isinstance(command, (HybridCommand, HybridGroup)) and command.app_command: + # If a cog is also inheriting from app_commands.Group then it'll also + # add the hybrid commands as text commands, which would recursively add the + # hybrid commands as slash commands. This check just terminates that recursion + # from happening + if command.cog is None or not command.cog.__cog_is_app_commands_group__: + self.tree.add_command(command.app_command) + + @discord.utils.copy_doc(GroupMixin.remove_command) + def remove_command(self, name: str, /) -> Optional[Command[Any, ..., Any]]: + cmd: Optional[Command[Any, ..., Any]] = super().remove_command(name) + if isinstance(cmd, (HybridCommand, HybridGroup)) and cmd.app_command: + # See above + if cmd.cog is not None and cmd.cog.__cog_is_app_commands_group__: + return cmd + + guild_ids: Optional[List[int]] = cmd.app_command._guild_ids + if guild_ids is None: + self.__tree.remove_command(name) + else: + for guild_id in guild_ids: + self.__tree.remove_command(name, guild=discord.Object(id=guild_id)) + + return cmd + + def hybrid_command( + self, + name: Union[str, app_commands.locale_str] = MISSING, + with_app_command: bool = True, + *args: Any, + **kwargs: Any, + ) -> Callable[[CommandCallback[Any, ContextT, P, T]], HybridCommand[Any, P, T]]: + """A shortcut decorator that invokes :func:`~discord.ext.commands.hybrid_command` and adds it to + the internal command list via :meth:`add_command`. + + Returns + -------- + Callable[..., :class:`HybridCommand`] + A decorator that converts the provided method into a Command, adds it to the bot, then returns it. + """ + + def decorator(func: CommandCallback[Any, ContextT, P, T]): + kwargs.setdefault('parent', self) + result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func) + self.add_command(result) + return result + + return decorator + + def hybrid_group( + self, + name: Union[str, app_commands.locale_str] = MISSING, + with_app_command: bool = True, + *args: Any, + **kwargs: Any, + ) -> Callable[[CommandCallback[Any, ContextT, P, T]], HybridGroup[Any, P, T]]: + """A shortcut decorator that invokes :func:`~discord.ext.commands.hybrid_group` and adds it to + the internal command list via :meth:`add_command`. + + Returns + -------- + Callable[..., :class:`HybridGroup`] + A decorator that converts the provided method into a Group, adds it to the bot, then returns it. + """ + + def decorator(func: CommandCallback[Any, ContextT, P, T]): + kwargs.setdefault('parent', self) + result = hybrid_group(name=name, *args, with_app_command=with_app_command, **kwargs)(func) + self.add_command(result) + return result + + return decorator + + # Error handler - async def on_command_error(self, context, exception): + async def on_command_error(self, context: Context[BotT], exception: errors.CommandError, /) -> None: """|coro| The default command error handler provided by the bot. - By default this prints to :data:`sys.stderr` however it could be + By default this logs to the library logger, however it could be overridden to have a different implementation. This only fires if you do not specify any listeners for command error. + + .. versionchanged:: 2.0 + + ``context`` and ``exception`` parameters are now positional-only. + Instead of writing to ``sys.stderr`` this now uses the library logger. """ if self.extra_events.get('on_command_error', None): return - if hasattr(context.command, 'on_error'): + command = context.command + if command and command.has_error_handler(): return cog = context.cog - if cog and Cog._get_overridden_method(cog.cog_command_error) is not None: + if cog and cog.has_error_handler(): return - print('Ignoring exception in command {}:'.format(context.command), file=sys.stderr) - traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr) + _log.error('Ignoring exception in command %s', command, exc_info=exception) # global check registration - def check(self, func): + def check(self, func: T, /) -> T: r"""A decorator that adds a global check to the bot. A global check is similar to a :func:`.check` that is applied @@ -198,23 +373,33 @@ def check(self, func): def check_commands(ctx): return ctx.command.qualified_name in allowed_commands + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. """ - self.add_check(func) + # T was used instead of Check to ensure the type matches on return + self.add_check(func) # type: ignore return func - def add_check(self, func, *, call_once=False): + def add_check(self, func: UserCheck[ContextT], /, *, call_once: bool = False) -> None: """Adds a global check to the bot. This is the non-decorator interface to :meth:`.check` and :meth:`.check_once`. + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + + .. seealso:: The :func:`~discord.ext.commands.check` decorator + Parameters ----------- func The function that was used as a global check. call_once: :class:`bool` If the function should only be called once per - :meth:`.Command.invoke` call. + :meth:`.invoke` call. """ if call_once: @@ -222,12 +407,16 @@ def add_check(self, func, *, call_once=False): else: self._checks.append(func) - def remove_check(self, func, *, call_once=False): + def remove_check(self, func: UserCheck[ContextT], /, *, call_once: bool = False) -> None: """Removes a global check from the bot. This function is idempotent and will not raise an exception if the function is not in the global checks. + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + Parameters ----------- func @@ -243,11 +432,11 @@ def remove_check(self, func, *, call_once=False): except ValueError: pass - def check_once(self, func): + def check_once(self, func: CFT, /) -> CFT: r"""A decorator that adds a "call once" global check to the bot. Unlike regular global checks, this one is called only once - per :meth:`.Command.invoke` call. + per :meth:`.invoke` call. Regular global checks are called whenever a command is called or :meth:`.Command.can_run` is called. This type of check @@ -277,11 +466,15 @@ def check_once(self, func): def whitelist(ctx): return ctx.message.author.id in my_whitelist + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + """ self.add_check(func, call_once=True) return func - async def can_run(self, ctx, *, call_once=False): + async def can_run(self, ctx: Context[BotT], /, *, call_once: bool = False) -> bool: data = self._check_once if call_once else self._checks if len(data) == 0: @@ -289,7 +482,7 @@ async def can_run(self, ctx, *, call_once=False): return await discord.utils.async_all(f(ctx) for f in data) - async def is_owner(self, user): + async def is_owner(self, user: User, /) -> bool: """|coro| Checks if a :class:`~discord.User` or :class:`~discord.Member` is the owner of @@ -302,6 +495,10 @@ async def is_owner(self, user): The function also checks if the application is team-owned if :attr:`owner_ids` is not set. + .. versionchanged:: 2.0 + + ``user`` parameter is now positional-only. + Parameters ----------- user: :class:`.abc.User` @@ -318,7 +515,8 @@ async def is_owner(self, user): elif self.owner_ids: return user.id in self.owner_ids else: - app = await self.application_info() + + app = await self.application_info() # type: ignore if app.team: self.owner_ids = ids = {m.id for m in app.team.members} return user.id in ids @@ -326,7 +524,7 @@ async def is_owner(self, user): self.owner_id = owner_id = app.owner.id return user.id == owner_id - def before_invoke(self, coro): + def before_invoke(self, coro: CFT, /) -> CFT: """A decorator that registers a coroutine as a pre-invoke hook. A pre-invoke hook is called directly before the command is @@ -342,6 +540,10 @@ def before_invoke(self, coro): without error. If any check or argument parsing procedures fail then the hooks are not called. + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Parameters ----------- coro: :ref:`coroutine ` @@ -358,7 +560,7 @@ def before_invoke(self, coro): self._before_invoke = coro return coro - def after_invoke(self, coro): + def after_invoke(self, coro: CFT, /) -> CFT: r"""A decorator that registers a coroutine as a post-invoke hook. A post-invoke hook is called directly after the command is @@ -375,6 +577,10 @@ def after_invoke(self, coro): callback raising an error (i.e. :exc:`.CommandInvokeError`\). This makes it ideal for clean-up scenarios. + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Parameters ----------- coro: :ref:`coroutine ` @@ -393,14 +599,18 @@ def after_invoke(self, coro): # listener registration - def add_listener(self, func, name=None): + def add_listener(self, func: CoroFunc, /, name: str = MISSING) -> None: """The non decorator alternative to :meth:`.listen`. + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + Parameters ----------- func: :ref:`coroutine ` The function to call. - name: Optional[:class:`str`] + name: :class:`str` The name of the event to listen for. Defaults to ``func.__name__``. Example @@ -415,7 +625,7 @@ async def my_message(message): pass bot.add_listener(my_message, 'on_message') """ - name = func.__name__ if name is None else name + name = func.__name__ if name is MISSING else name if not asyncio.iscoroutinefunction(func): raise TypeError('Listeners must be coroutines') @@ -425,9 +635,13 @@ async def my_message(message): pass else: self.extra_events[name] = [func] - def remove_listener(self, func, name=None): + def remove_listener(self, func: CoroFunc, /, name: str = MISSING) -> None: """Removes a listener from the pool of listeners. + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + Parameters ----------- func @@ -437,7 +651,7 @@ def remove_listener(self, func, name=None): ``func.__name__``. """ - name = func.__name__ if name is None else name + name = func.__name__ if name is MISSING else name if name in self.extra_events: try: @@ -445,7 +659,7 @@ def remove_listener(self, func, name=None): except ValueError: pass - def listen(self, name=None): + def listen(self, name: str = MISSING) -> Callable[[CFT], CFT]: """A decorator that registers another function as an external event listener. Basically this allows you to listen to multiple events from different places e.g. such as :func:`.on_ready` @@ -475,7 +689,7 @@ async def my_message(message): The function being listened to is not a coroutine. """ - def decorator(func): + def decorator(func: CFT) -> CFT: self.add_listener(func, name) return func @@ -483,15 +697,64 @@ def decorator(func): # cogs - def add_cog(self, cog): - """Adds a "cog" to the bot. + async def add_cog( + self, + cog: Cog, + /, + *, + override: bool = False, + guild: Optional[Snowflake] = MISSING, + guilds: Sequence[Snowflake] = MISSING, + ) -> None: + """|coro| + + Adds a "cog" to the bot. A cog is a class that has its own event listeners and commands. + If the cog is a :class:`.app_commands.Group` then it is added to + the bot's :class:`~discord.app_commands.CommandTree` as well. + + .. note:: + + Exceptions raised inside a :class:`.Cog`'s :meth:`~.Cog.cog_load` method will be + propagated to the caller. + + .. versionchanged:: 2.0 + + :exc:`.ClientException` is raised when a cog with the same name + is already loaded. + + .. versionchanged:: 2.0 + + ``cog`` parameter is now positional-only. + + .. versionchanged:: 2.0 + + This method is now a :term:`coroutine`. + Parameters ----------- cog: :class:`.Cog` The cog to register to the bot. + override: :class:`bool` + If a previously loaded cog with the same name should be ejected + instead of raising an error. + + .. versionadded:: 2.0 + guild: Optional[:class:`~discord.abc.Snowflake`] + If the cog is an application command group, then this would be the + guild where the cog group would be added to. If not given then + it becomes a global command instead. + + .. versionadded:: 2.0 + guilds: List[:class:`~discord.abc.Snowflake`] + If the cog is an application command group, then this would be the + guilds where the cog group would be added to. If not given then + it becomes a global command instead. Cannot be mixed with + ``guild``. + + .. versionadded:: 2.0 Raises ------- @@ -499,19 +762,36 @@ def add_cog(self, cog): The cog does not inherit from :class:`.Cog`. CommandError An error happened during loading. + ClientException + A cog with the same name is already loaded. """ if not isinstance(cog, Cog): raise TypeError('cogs must derive from Cog') - cog = cog._inject(self) - self.__cogs[cog.__cog_name__] = cog + cog_name = cog.__cog_name__ + existing = self.__cogs.get(cog_name) + + if existing is not None: + if not override: + raise discord.ClientException(f'Cog named {cog_name!r} already loaded') + await self.remove_cog(cog_name, guild=guild, guilds=guilds) - def get_cog(self, name): + if cog.__cog_app_commands_group__: + self.__tree.add_command(cog.__cog_app_commands_group__, override=override, guild=guild, guilds=guilds) + + cog = await cog._inject(self, override=override, guild=guild, guilds=guilds) + self.__cogs[cog_name] = cog + + def get_cog(self, name: str, /) -> Optional[Cog]: """Gets the cog instance requested. If the cog is not found, ``None`` is returned instead. + .. versionchanged:: 2.0 + + ``name`` parameter is now positional-only. + Parameters ----------- name: :class:`str` @@ -526,18 +806,53 @@ def get_cog(self, name): """ return self.__cogs.get(name) - def remove_cog(self, name): - """Removes a cog from the bot. + async def remove_cog( + self, + name: str, + /, + *, + guild: Optional[Snowflake] = MISSING, + guilds: Sequence[Snowflake] = MISSING, + ) -> Optional[Cog]: + """|coro| + + Removes a cog from the bot and returns it. All registered commands and event listeners that the cog has registered will be removed as well. If no cog is found then this method has no effect. + .. versionchanged:: 2.0 + + ``name`` parameter is now positional-only. + + .. versionchanged:: 2.0 + + This method is now a :term:`coroutine`. + Parameters ----------- name: :class:`str` The name of the cog to remove. + guild: Optional[:class:`~discord.abc.Snowflake`] + If the cog is an application command group, then this would be the + guild where the cog group would be removed from. If not given then + a global command is removed instead instead. + + .. versionadded:: 2.0 + guilds: List[:class:`~discord.abc.Snowflake`] + If the cog is an application command group, then this would be the + guilds where the cog group would be removed from. If not given then + a global command is removed instead instead. Cannot be mixed with + ``guild``. + + .. versionadded:: 2.0 + + Returns + ------- + Optional[:class:`.Cog`] + The cog that was removed. ``None`` if not found. """ cog = self.__cogs.pop(name, None) @@ -547,21 +862,32 @@ def remove_cog(self, name): help_command = self._help_command if help_command and help_command.cog is cog: help_command.cog = None - cog._eject(self) + + guild_ids = _retrieve_guild_ids(cog, guild, guilds) + if cog.__cog_app_commands_group__: + if guild_ids is None: + self.__tree.remove_command(name) + else: + for guild_id in guild_ids: + self.__tree.remove_command(name, guild=discord.Object(guild_id)) + + await cog._eject(self, guild_ids=guild_ids) + + return cog @property - def cogs(self): + def cogs(self) -> Mapping[str, Cog]: """Mapping[:class:`str`, :class:`Cog`]: A read-only mapping of cog name to cog.""" return types.MappingProxyType(self.__cogs) # extensions - def _remove_module_references(self, name): + async def _remove_module_references(self, name: str) -> None: # find all references to the module # remove the cogs registered from the module for cogname, cog in self.__cogs.copy().items(): if _is_submodule(name, cog.__module__): - self.remove_cog(cogname) + await self.remove_cog(cogname) # remove all the commands from the module for cmd in self.all_commands.copy().values(): @@ -580,14 +906,17 @@ def _remove_module_references(self, name): for index in reversed(remove): del event_list[index] - def _call_module_finalizers(self, lib, key): + # remove all relevant application commands from the tree + self.__tree._remove_with_module(name) + + async def _call_module_finalizers(self, lib: types.ModuleType, key: str) -> None: try: func = getattr(lib, 'teardown') except AttributeError: pass else: try: - func(self) + await func(self) except Exception: pass finally: @@ -598,12 +927,12 @@ def _call_module_finalizers(self, lib, key): if _is_submodule(name, module): del sys.modules[module] - def _load_from_module_spec(self, spec, key): + async def _load_from_module_spec(self, spec: importlib.machinery.ModuleSpec, key: str) -> None: # precondition: key not in self.__extensions lib = importlib.util.module_from_spec(spec) sys.modules[key] = lib try: - spec.loader.exec_module(lib) + spec.loader.exec_module(lib) # type: ignore except Exception as e: del sys.modules[key] raise errors.ExtensionFailed(key, e) from e @@ -615,23 +944,25 @@ def _load_from_module_spec(self, spec, key): raise errors.NoEntryPointError(key) try: - setup(self) + await setup(self) except Exception as e: del sys.modules[key] - self._remove_module_references(lib.__name__) - self._call_module_finalizers(lib, key) + await self._remove_module_references(lib.__name__) + await self._call_module_finalizers(lib, key) raise errors.ExtensionFailed(key, e) from e else: self.__extensions[key] = lib - def _resolve_name(self, name, package): + def _resolve_name(self, name: str, package: Optional[str]) -> str: try: return importlib.util.resolve_name(name, package) except ImportError: raise errors.ExtensionNotFound(name) - def load_extension(self, name, *, package=None): - """Loads an extension. + async def load_extension(self, name: str, *, package: Optional[str] = None) -> None: + """|coro| + + Loads an extension. An extension is a python module that contains commands, cogs, or listeners. @@ -640,6 +971,10 @@ def load_extension(self, name, *, package=None): the entry point on what to do when the extension is loaded. This entry point must have a single argument, the ``bot``. + .. versionchanged:: 2.0 + + This method is now a :term:`coroutine`. + Parameters ------------ name: :class:`str` @@ -675,10 +1010,12 @@ def load_extension(self, name, *, package=None): if spec is None: raise errors.ExtensionNotFound(name) - self._load_from_module_spec(spec, name) + await self._load_from_module_spec(spec, name) + + async def unload_extension(self, name: str, *, package: Optional[str] = None) -> None: + """|coro| - def unload_extension(self, name, *, package=None): - """Unloads an extension. + Unloads an extension. When the extension is unloaded, all commands, listeners, and cogs are removed from the bot and the module is un-imported. @@ -688,6 +1025,10 @@ def unload_extension(self, name, *, package=None): parameter, the ``bot``, similar to ``setup`` from :meth:`~.Bot.load_extension`. + .. versionchanged:: 2.0 + + This method is now a :term:`coroutine`. + Parameters ------------ name: :class:`str` @@ -715,11 +1056,13 @@ def unload_extension(self, name, *, package=None): if lib is None: raise errors.ExtensionNotLoaded(name) - self._remove_module_references(lib.__name__) - self._call_module_finalizers(lib, name) + await self._remove_module_references(lib.__name__) + await self._call_module_finalizers(lib, name) + + async def reload_extension(self, name: str, *, package: Optional[str] = None) -> None: + """|coro| - def reload_extension(self, name, *, package=None): - """Atomically reloads an extension. + Atomically reloads an extension. This replaces the extension with the same extension, only refreshed. This is equivalent to a :meth:`unload_extension` followed by a :meth:`load_extension` @@ -759,22 +1102,24 @@ def reload_extension(self, name, *, package=None): raise errors.ExtensionNotLoaded(name) # get the previous module states from sys modules + # fmt: off modules = { name: module for name, module in sys.modules.items() if _is_submodule(lib.__name__, name) } + # fmt: on try: # Unload and then load the module... - self._remove_module_references(lib.__name__) - self._call_module_finalizers(lib, name) - self.load_extension(name) + await self._remove_module_references(lib.__name__) + await self._call_module_finalizers(lib, name) + await self.load_extension(name) except Exception: # if the load failed, the remnants should have been # cleaned from the load_extension function call # so let's load it from our old compiled library. - lib.setup(self) + await lib.setup(self) self.__extensions[name] = lib # revert sys.modules back to normal and raise back to caller @@ -782,18 +1127,18 @@ def reload_extension(self, name, *, package=None): raise @property - def extensions(self): + def extensions(self) -> Mapping[str, types.ModuleType]: """Mapping[:class:`str`, :class:`py:types.ModuleType`]: A read-only mapping of extension name to extension.""" return types.MappingProxyType(self.__extensions) # help command stuff @property - def help_command(self): + def help_command(self) -> Optional[HelpCommand]: return self._help_command @help_command.setter - def help_command(self, value): + def help_command(self, value: Optional[HelpCommand]) -> None: if value is not None: if not isinstance(value, HelpCommand): raise TypeError('help_command must be a subclass of HelpCommand') @@ -807,14 +1152,32 @@ def help_command(self, value): else: self._help_command = None + # application command interop + + # As mentioned above, this is a mixin so the Self type hint fails here. + # However, since the only classes that can use this are subclasses of Client + # anyway, then this is sound. + @property + def tree(self) -> app_commands.CommandTree[Self]: # type: ignore + """:class:`~discord.app_commands.CommandTree`: The command tree responsible for handling the application commands + in this bot. + + .. versionadded:: 2.0 + """ + return self.__tree + # command processing - async def get_prefix(self, message): + async def get_prefix(self, message: Message, /) -> Union[List[str], str]: """|coro| Retrieves the prefix the bot is listening to with the message as a context. + .. versionchanged:: 2.0 + + ``message`` parameter is now positional-only. + Parameters ----------- message: :class:`discord.Message` @@ -827,30 +1190,55 @@ async def get_prefix(self, message): listening for. """ prefix = ret = self.command_prefix + if callable(prefix): - ret = await discord.utils.maybe_coroutine(prefix, self, message) + # self will be a Bot or AutoShardedBot + ret = await discord.utils.maybe_coroutine(prefix, self, message) # type: ignore if not isinstance(ret, str): try: - ret = list(ret) + ret = list(ret) # type: ignore except TypeError: # It's possible that a generator raised this exception. Don't # replace it with our own error if that's the case. if isinstance(ret, collections.abc.Iterable): raise - raise TypeError("command_prefix must be plain string, iterable of strings, or callable " - "returning either of these, not {}".format(ret.__class__.__name__)) - - if not ret: - raise ValueError("Iterable command_prefix must contain at least one prefix") + raise TypeError( + "command_prefix must be plain string, iterable of strings, or callable " + f"returning either of these, not {ret.__class__.__name__}" + ) return ret - async def get_context(self, message, *, cls=Context): + @overload + async def get_context( + self, + origin: Union[Message, Interaction], + /, + ) -> Context[Self]: # type: ignore + ... + + @overload + async def get_context( + self, + origin: Union[Message, Interaction], + /, + *, + cls: Type[ContextT], + ) -> ContextT: + ... + + async def get_context( + self, + origin: Union[Message, Interaction], + /, + *, + cls: Type[ContextT] = MISSING, + ) -> Any: r"""|coro| - Returns the invocation context from the message. + Returns the invocation context from the message or interaction. This is a more low-level counter-part for :meth:`.process_commands` to allow users more fine grained control over the processing. @@ -860,10 +1248,20 @@ async def get_context(self, message, *, cls=Context): If the context is not valid then it is not a valid candidate to be invoked under :meth:`~.Bot.invoke`. + .. note:: + + In order for the custom context to be used inside an interaction-based + context (such as :class:`HybridCommand`) then this method must be + overridden to return that class. + + .. versionchanged:: 2.0 + + ``message`` parameter is now positional-only and renamed to ``origin``. + Parameters ----------- - message: :class:`discord.Message` - The message to get the invocation context from. + origin: Union[:class:`discord.Message`, :class:`discord.Interaction`] + The message or interaction to get the invocation context from. cls The factory class that will be used to create the context. By default, this is :class:`.Context`. Should a custom @@ -876,14 +1274,19 @@ class be provided, it must be similar enough to :class:`.Context`\'s The invocation context. The type of this can change via the ``cls`` parameter. """ + if cls is MISSING: + cls = Context # type: ignore - view = StringView(message.content) - ctx = cls(prefix=None, view=view, bot=self, message=message) + if isinstance(origin, discord.Interaction): + return await cls.from_interaction(origin) - if self._skip_check(message.author.id, self.user.id): + view = StringView(origin.content) + ctx = cls(prefix=None, view=view, bot=self, message=origin) + + if origin.author.id == self.user.id: # type: ignore return ctx - prefix = await self.get_prefix(message) + prefix = await self.get_prefix(origin) invoked_prefix = prefix if isinstance(prefix, str): @@ -893,21 +1296,24 @@ class be provided, it must be similar enough to :class:`.Context`\'s try: # if the context class' __init__ consumes something from the view this # will be wrong. That seems unreasonable though. - if message.content.startswith(tuple(prefix)): + if origin.content.startswith(tuple(prefix)): invoked_prefix = discord.utils.find(view.skip_string, prefix) else: return ctx except TypeError: if not isinstance(prefix, list): - raise TypeError("get_prefix must return either a string or a list of string, " - "not {}".format(prefix.__class__.__name__)) + raise TypeError( + "get_prefix must return either a string or a list of string, " f"not {prefix.__class__.__name__}" + ) # It's possible a bad command_prefix got us here. for value in prefix: if not isinstance(value, str): - raise TypeError("Iterable command_prefix or list returned from get_prefix must " - "contain only strings, not {}".format(value.__class__.__name__)) + raise TypeError( + "Iterable command_prefix or list returned from get_prefix must " + f"contain only strings, not {value.__class__.__name__}" + ) # Getting here shouldn't happen raise @@ -917,16 +1323,21 @@ class be provided, it must be similar enough to :class:`.Context`\'s invoker = view.get_word() ctx.invoked_with = invoker - ctx.prefix = invoked_prefix + # type-checker fails to narrow invoked_prefix type. + ctx.prefix = invoked_prefix # type: ignore ctx.command = self.all_commands.get(invoker) return ctx - async def invoke(self, ctx): + async def invoke(self, ctx: Context[BotT], /) -> None: """|coro| Invokes the command given under the invocation context and handles all the internal event dispatch mechanisms. + .. versionchanged:: 2.0 + + ``ctx`` parameter is now positional-only. + Parameters ----------- ctx: :class:`.Context` @@ -944,10 +1355,10 @@ async def invoke(self, ctx): else: self.dispatch('command_completion', ctx) elif ctx.invoked_with: - exc = errors.CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with)) + exc = errors.CommandNotFound(f'Command "{ctx.invoked_with}" is not found') self.dispatch('command_error', ctx, exc) - async def process_commands(self, message): + async def process_commands(self, message: Message, /) -> None: """|coro| This function processes the commands that have been registered @@ -964,6 +1375,10 @@ async def process_commands(self, message): This also checks if the message's author is a bot and doesn't call :meth:`~.Bot.get_context` or :meth:`~.Bot.invoke` if so. + .. versionchanged:: 2.0 + + ``message`` parameter is now positional-only. + Parameters ----------- message: :class:`discord.Message` @@ -973,13 +1388,15 @@ async def process_commands(self, message): return ctx = await self.get_context(message) - await self.invoke(ctx) + # the type of the invocation context's bot attribute will be correct + await self.invoke(ctx) # type: ignore - async def on_message(self, message): + async def on_message(self, message: Message, /) -> None: await self.process_commands(message) + class Bot(BotBase, discord.Client): - """Represents a discord bot. + """Represents a Discord bot. This class is a subclass of :class:`discord.Client` and as a result anything that you can do with a :class:`discord.Client` you can do with @@ -988,6 +1405,18 @@ class Bot(BotBase, discord.Client): This class also subclasses :class:`.GroupMixin` to provide the functionality to manage commands. + Unlike :class:`discord.Client`, this class does not require manually setting + a :class:`~discord.app_commands.CommandTree` and is automatically set upon + instantiating the class. + + .. container:: operations + + .. describe:: async with x + + Asynchronously initialises the bot and automatically cleans up. + + .. versionadded:: 2.0 + Attributes ----------- command_prefix @@ -1007,8 +1436,7 @@ class Bot(BotBase, discord.Client): The command prefix could also be an iterable of strings indicating that multiple checks for the prefix should be used and the first one to match will be the invocation prefix. You can get this prefix via - :attr:`.Context.prefix`. To avoid confusion empty iterables are not - allowed. + :attr:`.Context.prefix`. .. note:: @@ -1025,10 +1453,6 @@ class Bot(BotBase, discord.Client): you require group commands to be case insensitive as well. description: :class:`str` The content prefixed into the default help message. - self_bot: :class:`bool` - If ``True``, the bot will only listen to commands invoked by itself rather - than ignoring itself. If ``False`` (the default) then the bot will ignore - itself. This cannot be changed once initialised. help_command: Optional[:class:`.HelpCommand`] The help command implementation to use. This can be dynamically set at runtime. To remove the help command pass ``None``. For more @@ -1051,11 +1475,26 @@ class Bot(BotBase, discord.Client): the ``command_prefix`` is set to ``!``. Defaults to ``False``. .. versionadded:: 1.7 + tree_cls: Type[:class:`~discord.app_commands.CommandTree`] + The type of application command tree to use. Defaults to :class:`~discord.app_commands.CommandTree`. + + .. versionadded:: 2.0 """ + pass + class AutoShardedBot(BotBase, discord.AutoShardedClient): """This is similar to :class:`.Bot` except that it is inherited from :class:`discord.AutoShardedClient` instead. + + .. container:: operations + + .. describe:: async with x + + Asynchronously initialises the bot and automatically cleans. + + .. versionadded:: 2.0 """ + pass diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/cog.py b/dist/ba_data/python-site-packages/discord/ext/commands/cog.py index e12b2398..319f85b8 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/cog.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/cog.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -23,16 +21,52 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations import inspect -import copy -from ._types import _BaseCommand +import discord +from discord import app_commands +from discord.utils import maybe_coroutine, _to_kebab_case + +from typing import ( + Any, + Callable, + ClassVar, + Coroutine, + Dict, + Generator, + Iterable, + List, + Optional, + TYPE_CHECKING, + Sequence, + Tuple, + TypeVar, + Union, +) + +from ._types import _BaseCommand, BotT + +if TYPE_CHECKING: + from typing_extensions import Self + from discord.abc import Snowflake + from discord._types import ClientT + + from .bot import BotBase + from .context import Context + from .core import Command __all__ = ( 'CogMeta', 'Cog', + 'GroupCog', ) +FuncT = TypeVar('FuncT', bound=Callable[..., Any]) + +MISSING: Any = discord.utils.MISSING + + class CogMeta(type): """A metaclass for defining a cog. @@ -91,19 +125,84 @@ async def foo(self, ctx): @commands.command(hidden=False) async def bar(self, ctx): pass # hidden -> False + + group_name: Union[:class:`str`, :class:`~discord.app_commands.locale_str`] + The group name of a cog. This is only applicable for :class:`GroupCog` instances. + By default, it's the same value as :attr:`name`. + + .. versionadded:: 2.0 + group_description: Union[:class:`str`, :class:`~discord.app_commands.locale_str`] + The group description of a cog. This is only applicable for :class:`GroupCog` instances. + By default, it's the same value as :attr:`description`. + + .. versionadded:: 2.0 + group_nsfw: :class:`bool` + Whether the application command group is NSFW. This is only applicable for :class:`GroupCog` instances. + By default, it's ``False``. + + .. versionadded:: 2.0 + group_auto_locale_strings: :class:`bool` + If this is set to ``True``, then all translatable strings will implicitly + be wrapped into :class:`~discord.app_commands.locale_str` rather + than :class:`str`. Defaults to ``True``. + + .. versionadded:: 2.0 + group_extras: :class:`dict` + A dictionary that can be used to store extraneous data. + This is only applicable for :class:`GroupCog` instances. + The library will not touch any values or keys within this dictionary. + + .. versionadded:: 2.1 """ - def __new__(cls, *args, **kwargs): + __cog_name__: str + __cog_description__: str + __cog_group_name__: Union[str, app_commands.locale_str] + __cog_group_description__: Union[str, app_commands.locale_str] + __cog_group_nsfw__: bool + __cog_group_auto_locale_strings__: bool + __cog_group_extras__: Dict[Any, Any] + __cog_settings__: Dict[str, Any] + __cog_commands__: List[Command[Any, ..., Any]] + __cog_app_commands__: List[Union[app_commands.Group, app_commands.Command[Any, ..., Any]]] + __cog_listeners__: List[Tuple[str, str]] + + def __new__(cls, *args: Any, **kwargs: Any) -> Self: name, bases, attrs = args - attrs['__cog_name__'] = kwargs.pop('name', name) + if any(issubclass(base, app_commands.Group) for base in bases): + raise TypeError( + 'Cannot inherit from app_commands.Group with commands.Cog, consider using commands.GroupCog instead' + ) + + # If name='...' is given but not group_name='...' then name='...' is used for both. + # If neither is given then cog name is the class name but group name is kebab case + try: + cog_name = kwargs.pop('name') + except KeyError: + cog_name = name + try: + group_name = kwargs.pop('group_name') + except KeyError: + group_name = _to_kebab_case(name) + else: + group_name = kwargs.pop('group_name', cog_name) + attrs['__cog_settings__'] = kwargs.pop('command_attrs', {}) + attrs['__cog_name__'] = cog_name + attrs['__cog_group_name__'] = group_name + attrs['__cog_group_nsfw__'] = kwargs.pop('group_nsfw', False) + attrs['__cog_group_auto_locale_strings__'] = kwargs.pop('group_auto_locale_strings', True) + attrs['__cog_group_extras__'] = kwargs.pop('group_extras', {}) description = kwargs.pop('description', None) if description is None: description = inspect.cleandoc(attrs.get('__doc__', '')) + attrs['__cog_description__'] = description + attrs['__cog_group_description__'] = kwargs.pop('group_description', description or '\u2026') commands = {} + cog_app_commands = {} listeners = {} no_bot_cog = 'Commands or listeners must not start with cog_ or bot_ (in method {0.__name__}.{1})' @@ -120,10 +219,16 @@ def __new__(cls, *args, **kwargs): value = value.__func__ if isinstance(value, _BaseCommand): if is_static_method: - raise TypeError('Command in method {0}.{1!r} must not be staticmethod.'.format(base, elem)) + raise TypeError(f'Command in method {base}.{elem!r} must not be staticmethod.') if elem.startswith(('cog_', 'bot_')): raise TypeError(no_bot_cog.format(base, elem)) commands[elem] = value + elif isinstance(value, (app_commands.Group, app_commands.Command)) and value.parent is None: + if is_static_method: + raise TypeError(f'Command in method {base}.{elem!r} must not be staticmethod.') + if elem.startswith(('cog_', 'bot_')): + raise TypeError(no_bot_cog.format(base, elem)) + cog_app_commands[elem] = value elif inspect.iscoroutinefunction(value): try: getattr(value, '__cog_listener__') @@ -134,7 +239,8 @@ def __new__(cls, *args, **kwargs): raise TypeError(no_bot_cog.format(base, elem)) listeners[elem] = value - new_cls.__cog_commands__ = list(commands.values()) # this will be copied in Cog.__new__ + new_cls.__cog_commands__ = list(commands.values()) # this will be copied in Cog.__new__ + new_cls.__cog_app_commands__ = list(cog_app_commands.values()) listeners_as_list = [] for listener in listeners.values(): @@ -146,17 +252,19 @@ def __new__(cls, *args, **kwargs): new_cls.__cog_listeners__ = listeners_as_list return new_cls - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args) @classmethod - def qualified_name(cls): + def qualified_name(cls) -> str: return cls.__cog_name__ -def _cog_special_method(func): + +def _cog_special_method(func: FuncT) -> FuncT: func.__cog_special_method__ = None return func + class Cog(metaclass=CogMeta): """The base class that all cogs must inherit from. @@ -168,7 +276,21 @@ class Cog(metaclass=CogMeta): are equally valid here. """ - def __new__(cls, *args, **kwargs): + __cog_name__: str + __cog_description__: str + __cog_group_name__: Union[str, app_commands.locale_str] + __cog_group_description__: Union[str, app_commands.locale_str] + __cog_settings__: Dict[str, Any] + __cog_commands__: List[Command[Self, ..., Any]] + __cog_app_commands__: List[Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] + __cog_listeners__: List[Tuple[str, str]] + __cog_is_app_commands_group__: ClassVar[bool] = False + __cog_app_commands_group__: Optional[app_commands.Group] + __discord_app_commands_error_handler__: Optional[ + Callable[[discord.Interaction, app_commands.AppCommandError], Coroutine[Any, Any, None]] + ] + + def __new__(cls, *args: Any, **kwargs: Any) -> Self: # For issue 426, we need to store a copy of the command objects # since we modify them to inject `self` to them. # To do this, we need to interfere with the Cog creation process. @@ -176,12 +298,30 @@ def __new__(cls, *args, **kwargs): cmd_attrs = cls.__cog_settings__ # Either update the command with the cog provided defaults or copy it. - self.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in cls.__cog_commands__) - - lookup = { - cmd.qualified_name: cmd - for cmd in self.__cog_commands__ - } + # r.e type ignore, type-checker complains about overriding a ClassVar + self.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in cls.__cog_commands__) # type: ignore + + lookup = {cmd.qualified_name: cmd for cmd in self.__cog_commands__} + + # Register the application commands + children: List[Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] = [] + + if cls.__cog_is_app_commands_group__: + group = app_commands.Group( + name=cls.__cog_group_name__, + description=cls.__cog_group_description__, + nsfw=cls.__cog_group_nsfw__, + auto_locale_strings=cls.__cog_group_auto_locale_strings__, + parent=None, + guild_ids=getattr(cls, '__discord_app_commands_default_guilds__', None), + guild_only=getattr(cls, '__discord_app_commands_guild_only__', False), + default_permissions=getattr(cls, '__discord_app_commands_default_permissions__', None), + extras=cls.__cog_group_extras__, + ) + else: + group = None + + self.__cog_app_commands_group__ = group # Update the Command instances dynamically as well for command in self.__cog_commands__: @@ -189,43 +329,98 @@ def __new__(cls, *args, **kwargs): parent = command.parent if parent is not None: # Get the latest parent reference - parent = lookup[parent.qualified_name] + parent = lookup[parent.qualified_name] # type: ignore # Update our parent's reference to our self - parent.remove_command(command.name) - parent.add_command(command) + parent.remove_command(command.name) # type: ignore + parent.add_command(command) # type: ignore + + if hasattr(command, '__commands_is_hybrid__') and parent is None: + app_command: Optional[Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] = getattr( + command, 'app_command', None + ) + if app_command: + group_parent = self.__cog_app_commands_group__ + app_command = app_command._copy_with(parent=group_parent, binding=self) + # The type checker does not see the app_command attribute even though it exists + command.app_command = app_command # type: ignore + + if self.__cog_app_commands_group__: + children.append(app_command) # type: ignore # Somehow it thinks it can be None here + + if Cog._get_overridden_method(self.cog_app_command_error) is not None: + error_handler = self.cog_app_command_error + else: + error_handler = None + + self.__discord_app_commands_error_handler__ = error_handler + + for command in cls.__cog_app_commands__: + copy = command._copy_with(parent=self.__cog_app_commands_group__, binding=self) + + # Update set bindings + if copy._attr: + setattr(self, copy._attr, copy) + + if isinstance(copy, app_commands.Group): + copy.__discord_app_commands_error_handler__ = error_handler + for command in copy._children.values(): + if isinstance(command, app_commands.Group): + command.__discord_app_commands_error_handler__ = error_handler + + children.append(copy) + + self.__cog_app_commands__ = children + if self.__cog_app_commands_group__: + self.__cog_app_commands_group__.module = cls.__module__ + mapping = {cmd.name: cmd for cmd in children} + if len(mapping) > 25: + raise TypeError('maximum number of application command children exceeded') + + self.__cog_app_commands_group__._children = mapping # type: ignore # Variance issue return self - def get_commands(self): - r""" + def get_commands(self) -> List[Command[Self, ..., Any]]: + r"""Returns the commands that are defined inside this cog. + + This does *not* include :class:`discord.app_commands.Command` or :class:`discord.app_commands.Group` + instances. + Returns -------- List[:class:`.Command`] A :class:`list` of :class:`.Command`\s that are - defined inside this cog. + defined inside this cog, not including subcommands. + """ + return [c for c in self.__cog_commands__ if c.parent is None] - .. note:: + def get_app_commands(self) -> List[Union[app_commands.Command[Self, ..., Any], app_commands.Group]]: + r"""Returns the app commands that are defined inside this cog. - This does not include subcommands. + Returns + -------- + List[Union[:class:`discord.app_commands.Command`, :class:`discord.app_commands.Group`]] + A :class:`list` of :class:`discord.app_commands.Command`\s and :class:`discord.app_commands.Group`\s that are + defined inside this cog, not including subcommands. """ - return [c for c in self.__cog_commands__ if c.parent is None] + return [c for c in self.__cog_app_commands__ if c.parent is None] @property - def qualified_name(self): + def qualified_name(self) -> str: """:class:`str`: Returns the cog's specified name, not the class name.""" return self.__cog_name__ @property - def description(self): + def description(self) -> str: """:class:`str`: Returns the cog's description, typically the cleaned docstring.""" return self.__cog_description__ @description.setter - def description(self, description): + def description(self, description: str) -> None: self.__cog_description__ = description - def walk_commands(self): + def walk_commands(self) -> Generator[Command[Self, ..., Any], None, None]: """An iterator that recursively walks through this cog's commands and subcommands. Yields @@ -234,13 +429,35 @@ def walk_commands(self): A command or group from the cog. """ from .core import GroupMixin + for command in self.__cog_commands__: if command.parent is None: yield command if isinstance(command, GroupMixin): yield from command.walk_commands() - def get_listeners(self): + def walk_app_commands(self) -> Generator[Union[app_commands.Command[Self, ..., Any], app_commands.Group], None, None]: + """An iterator that recursively walks through this cog's app commands and subcommands. + + Yields + ------ + Union[:class:`discord.app_commands.Command`, :class:`discord.app_commands.Group`] + An app command or group from the cog. + """ + for command in self.__cog_app_commands__: + yield command + if isinstance(command, app_commands.Group): + yield from command.walk_commands() + + @property + def app_command(self) -> Optional[app_commands.Group]: + """Optional[:class:`discord.app_commands.Group`]: Returns the associated group with this cog. + + This is only available if inheriting from :class:`GroupCog`. + """ + return self.__cog_app_commands_group__ + + def get_listeners(self) -> List[Tuple[str, Callable[..., Any]]]: """Returns a :class:`list` of (name, function) listener pairs that are defined in this cog. Returns @@ -251,12 +468,12 @@ def get_listeners(self): return [(name, getattr(self, method_name)) for name, method_name in self.__cog_listeners__] @classmethod - def _get_overridden_method(cls, method): + def _get_overridden_method(cls, method: FuncT) -> Optional[FuncT]: """Return None if the method is not overridden. Otherwise returns the overridden method.""" return getattr(method.__func__, '__cog_special_method__', method) @classmethod - def listener(cls, name=None): + def listener(cls, name: str = MISSING) -> Callable[[FuncT], FuncT]: """A decorator that marks a function as a listener. This is the cog equivalent of :meth:`.Bot.listen`. @@ -274,10 +491,10 @@ def listener(cls, name=None): the name. """ - if name is not None and not isinstance(name, str): - raise TypeError('Cog.listener expected str but received {0.__class__.__name__!r} instead.'.format(name)) + if name is not MISSING and not isinstance(name, str): + raise TypeError(f'Cog.listener expected str but received {name.__class__.__name__} instead.') - def decorator(func): + def decorator(func: FuncT) -> FuncT: actual = func if isinstance(actual, staticmethod): actual = actual.__func__ @@ -294,28 +511,55 @@ def decorator(func): # to pick it up but the metaclass unfurls the function and # thus the assignments need to be on the actual function return func + return decorator - def has_error_handler(self): + def has_error_handler(self) -> bool: """:class:`bool`: Checks whether the cog has an error handler. .. versionadded:: 1.7 """ return not hasattr(self.cog_command_error.__func__, '__cog_special_method__') + def has_app_command_error_handler(self) -> bool: + """:class:`bool`: Checks whether the cog has an app error handler. + + .. versionadded:: 2.1 + """ + return not hasattr(self.cog_app_command_error.__func__, '__cog_special_method__') + @_cog_special_method - def cog_unload(self): - """A special method that is called when the cog gets removed. + async def cog_load(self) -> None: + """|maybecoro| - This function **cannot** be a coroutine. It must be a regular - function. + A special method that is called when the cog gets loaded. + + Subclasses must replace this if they want special asynchronous loading behaviour. + Note that the ``__init__`` special method does not allow asynchronous code to run + inside it, thus this is helpful for setting up code that needs to be asynchronous. + + .. versionadded:: 2.0 + """ + pass + + @_cog_special_method + async def cog_unload(self) -> None: + """|maybecoro| + + A special method that is called when the cog gets removed. Subclasses must replace this if they want special unloading behaviour. + + Exceptions raised in this method are ignored during extension unloading. + + .. versionchanged:: 2.0 + + This method can now be a :term:`coroutine`. """ pass @_cog_special_method - def bot_check_once(self, ctx): + def bot_check_once(self, ctx: Context[BotT]) -> bool: """A special method that registers as a :meth:`.Bot.check_once` check. @@ -325,7 +569,7 @@ def bot_check_once(self, ctx): return True @_cog_special_method - def bot_check(self, ctx): + def bot_check(self, ctx: Context[BotT]) -> bool: """A special method that registers as a :meth:`.Bot.check` check. @@ -335,8 +579,8 @@ def bot_check(self, ctx): return True @_cog_special_method - def cog_check(self, ctx): - """A special method that registers as a :func:`commands.check` + def cog_check(self, ctx: Context[BotT]) -> bool: + """A special method that registers as a :func:`~discord.ext.commands.check` for every command and subcommand in this cog. This function **can** be a coroutine and must take a sole parameter, @@ -345,8 +589,22 @@ def cog_check(self, ctx): return True @_cog_special_method - async def cog_command_error(self, ctx, error): - """A special method that is called whenever an error + def interaction_check(self, interaction: discord.Interaction[ClientT], /) -> bool: + """A special method that registers as a :func:`discord.app_commands.check` + for every app command and subcommand in this cog. + + This function **can** be a coroutine and must take a sole parameter, + ``interaction``, to represent the :class:`~discord.Interaction`. + + .. versionadded:: 2.0 + """ + return True + + @_cog_special_method + async def cog_command_error(self, ctx: Context[BotT], error: Exception) -> None: + """|coro| + + A special method that is called whenever an error is dispatched inside this cog. This is similar to :func:`.on_command_error` except only applying @@ -364,8 +622,31 @@ async def cog_command_error(self, ctx, error): pass @_cog_special_method - async def cog_before_invoke(self, ctx): - """A special method that acts as a cog local pre-invoke hook. + async def cog_app_command_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError) -> None: + """|coro| + + A special method that is called whenever an error within + an application command is dispatched inside this cog. + + This is similar to :func:`discord.app_commands.CommandTree.on_error` except + only applying to the application commands inside this cog. + + This **must** be a coroutine. + + Parameters + ----------- + interaction: :class:`~discord.Interaction` + The interaction that is being handled. + error: :exc:`~discord.app_commands.AppCommandError` + The exception that was raised. + """ + pass + + @_cog_special_method + async def cog_before_invoke(self, ctx: Context[BotT]) -> None: + """|coro| + + A special method that acts as a cog local pre-invoke hook. This is similar to :meth:`.Command.before_invoke`. @@ -379,8 +660,10 @@ async def cog_before_invoke(self, ctx): pass @_cog_special_method - async def cog_after_invoke(self, ctx): - """A special method that acts as a cog local post-invoke hook. + async def cog_after_invoke(self, ctx: Context[BotT]) -> None: + """|coro| + + A special method that acts as a cog local post-invoke hook. This is similar to :meth:`.Command.after_invoke`. @@ -393,9 +676,13 @@ async def cog_after_invoke(self, ctx): """ pass - def _inject(self, bot): + async def _inject(self, bot: BotBase, override: bool, guild: Optional[Snowflake], guilds: Sequence[Snowflake]) -> Self: cls = self.__class__ + # we'll call this first so that errors can propagate without + # having to worry about undoing anything + await maybe_coroutine(self.cog_load) + # realistically, the only thing that can cause loading errors # is essentially just the command loading, which raises if there are # duplicates. When this condition is met, we want to undo all what @@ -410,7 +697,10 @@ def _inject(self, bot): for to_undo in self.__cog_commands__[:index]: if to_undo.parent is None: bot.remove_command(to_undo.name) - raise e + try: + await maybe_coroutine(self.cog_unload) + finally: + raise e # check if we're overriding the default if cls.bot_check is not Cog.bot_check: @@ -426,9 +716,15 @@ def _inject(self, bot): for name, method_name in self.__cog_listeners__: bot.add_listener(getattr(self, method_name), name) + # Only do this if these are "top level" commands + if not self.__cog_app_commands_group__: + for command in self.__cog_app_commands__: + # This is already atomic + bot.tree.add_command(command, override=override, guild=guild, guilds=guilds) + return self - def _eject(self, bot): + async def _eject(self, bot: BotBase, guild_ids: Optional[Iterable[int]]) -> None: cls = self.__class__ try: @@ -436,8 +732,17 @@ def _eject(self, bot): if command.parent is None: bot.remove_command(command.name) - for _, method_name in self.__cog_listeners__: - bot.remove_listener(getattr(self, method_name)) + if not self.__cog_app_commands_group__: + for command in self.__cog_app_commands__: + guild_ids = guild_ids or command._guild_ids + if guild_ids is None: + bot.tree.remove_command(command.name) + else: + for guild_id in guild_ids: + bot.tree.remove_command(command.name, guild=discord.Object(id=guild_id)) + + for name, method_name in self.__cog_listeners__: + bot.remove_listener(getattr(self, method_name), name) if cls.bot_check is not Cog.bot_check: bot.remove_check(self.bot_check) @@ -446,6 +751,37 @@ def _eject(self, bot): bot.remove_check(self.bot_check_once, call_once=True) finally: try: - self.cog_unload() + await maybe_coroutine(self.cog_unload) except Exception: pass + + +class GroupCog(Cog): + """Represents a cog that also doubles as a parent :class:`discord.app_commands.Group` for + the application commands defined within it. + + This inherits from :class:`Cog` and the options in :class:`CogMeta` also apply to this. + See the :class:`Cog` documentation for methods. + + Decorators such as :func:`~discord.app_commands.guild_only`, :func:`~discord.app_commands.guilds`, + and :func:`~discord.app_commands.default_permissions` will apply to the group if used on top of the + cog. + + Hybrid commands will also be added to the Group, giving the ability to categorize slash commands into + groups, while keeping the prefix-style command as a root-level command. + + For example: + + .. code-block:: python3 + + from discord import app_commands + from discord.ext import commands + + @app_commands.guild_only() + class MyCog(commands.GroupCog, group_name='my-cog'): + pass + + .. versionadded:: 2.0 + """ + + __cog_is_app_commands_group__: ClassVar[bool] = True diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/context.py b/dist/ba_data/python-site-packages/discord/ext/commands/context.py index 8df4f730..40ef48cf 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/context.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/context.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -23,11 +21,87 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + +import re +from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, List, Optional, TypeVar, Union, Sequence, Type, overload import discord.abc import discord.utils +from discord import Interaction, Message, Attachment, MessageType, User, PartialMessageable, Permissions, ChannelType, Thread +from discord.context_managers import Typing +from .view import StringView + +from ._types import BotT + +if TYPE_CHECKING: + from typing_extensions import Self, ParamSpec, TypeGuard + + from discord.abc import MessageableChannel + from discord.guild import Guild + from discord.member import Member + from discord.state import ConnectionState + from discord.user import ClientUser + from discord.voice_client import VoiceProtocol + from discord.embeds import Embed + from discord.file import File + from discord.mentions import AllowedMentions + from discord.sticker import GuildSticker, StickerItem + from discord.message import MessageReference, PartialMessage + from discord.ui import View + from discord.types.interactions import ApplicationCommandInteractionData + + from .cog import Cog + from .core import Command + from .parameters import Parameter + + from types import TracebackType + + BE = TypeVar('BE', bound=BaseException) + +# fmt: off +__all__ = ( + 'Context', +) +# fmt: on + +MISSING: Any = discord.utils.MISSING + + +T = TypeVar('T') +CogT = TypeVar('CogT', bound="Cog") + +if TYPE_CHECKING: + P = ParamSpec('P') +else: + P = TypeVar('P') + + +def is_cog(obj: Any) -> TypeGuard[Cog]: + return hasattr(obj, '__cog_commands__') + + +class DeferTyping: + def __init__(self, ctx: Context[BotT], *, ephemeral: bool): + self.ctx: Context[BotT] = ctx + self.ephemeral: bool = ephemeral -class Context(discord.abc.Messageable): + def __await__(self) -> Generator[Any, None, None]: + return self.ctx.defer(ephemeral=self.ephemeral).__await__() + + async def __aenter__(self) -> None: + await self.ctx.defer(ephemeral=self.ephemeral) + + async def __aexit__( + self, + exc_type: Optional[Type[BE]], + exc: Optional[BE], + traceback: Optional[TracebackType], + ) -> None: + pass + + +class Context(discord.abc.Messageable, Generic[BotT]): r"""Represents the context in which a command is being invoked under. This class contains a lot of meta data to help you understand more about @@ -40,21 +114,42 @@ class Context(discord.abc.Messageable): ----------- message: :class:`.Message` The message that triggered the command being executed. + + .. note:: + + In the case of an interaction based context, this message is "synthetic" + and does not actually exist. Therefore, the ID on it is invalid similar + to ephemeral messages. bot: :class:`.Bot` The bot that contains the command being executed. args: :class:`list` The list of transformed arguments that were passed into the command. - If this is accessed during the :func:`on_command_error` event + If this is accessed during the :func:`.on_command_error` event then this list could be incomplete. kwargs: :class:`dict` A dictionary of transformed arguments that were passed into the command. Similar to :attr:`args`\, if this is accessed in the - :func:`on_command_error` event then this dict could be incomplete. - prefix: :class:`str` - The prefix that was used to invoke the command. - command: :class:`Command` + :func:`.on_command_error` event then this dict could be incomplete. + current_parameter: Optional[:class:`Parameter`] + The parameter that is currently being inspected and converted. + This is only of use for within converters. + + .. versionadded:: 2.0 + current_argument: Optional[:class:`str`] + The argument string of the :attr:`current_parameter` that is currently being converted. + This is only of use for within converters. + + .. versionadded:: 2.0 + interaction: Optional[:class:`~discord.Interaction`] + The interaction associated with this context. + + .. versionadded:: 2.0 + prefix: Optional[:class:`str`] + The prefix that was used to invoke the command. For interaction based contexts, + this is ``/`` for slash commands and ``\u200b`` for context menu commands. + command: Optional[:class:`Command`] The command that is being invoked currently. - invoked_with: :class:`str` + invoked_with: Optional[:class:`str`] The command name that triggered this invocation. Useful for finding out which alias called the command. invoked_parents: List[:class:`str`] @@ -65,7 +160,7 @@ class Context(discord.abc.Messageable): .. versionadded:: 1.7 - invoked_subcommand: :class:`Command` + invoked_subcommand: Optional[:class:`Command`] The subcommand that was invoked. If no valid subcommand was invoked then this is equal to ``None``. subcommand_passed: Optional[:class:`str`] @@ -78,22 +173,132 @@ class Context(discord.abc.Messageable): or invoked. """ - def __init__(self, **attrs): - self.message = attrs.pop('message', None) - self.bot = attrs.pop('bot', None) - self.args = attrs.pop('args', []) - self.kwargs = attrs.pop('kwargs', {}) - self.prefix = attrs.pop('prefix') - self.command = attrs.pop('command', None) - self.view = attrs.pop('view', None) - self.invoked_with = attrs.pop('invoked_with', None) - self.invoked_parents = attrs.pop('invoked_parents', []) - self.invoked_subcommand = attrs.pop('invoked_subcommand', None) - self.subcommand_passed = attrs.pop('subcommand_passed', None) - self.command_failed = attrs.pop('command_failed', False) - self._state = self.message._state - - async def invoke(self, *args, **kwargs): + def __init__( + self, + *, + message: Message, + bot: BotT, + view: StringView, + args: List[Any] = MISSING, + kwargs: Dict[str, Any] = MISSING, + prefix: Optional[str] = None, + command: Optional[Command[Any, ..., Any]] = None, + invoked_with: Optional[str] = None, + invoked_parents: List[str] = MISSING, + invoked_subcommand: Optional[Command[Any, ..., Any]] = None, + subcommand_passed: Optional[str] = None, + command_failed: bool = False, + current_parameter: Optional[Parameter] = None, + current_argument: Optional[str] = None, + interaction: Optional[Interaction[BotT]] = None, + ): + self.message: Message = message + self.bot: BotT = bot + self.args: List[Any] = args or [] + self.kwargs: Dict[str, Any] = kwargs or {} + self.prefix: Optional[str] = prefix + self.command: Optional[Command[Any, ..., Any]] = command + self.view: StringView = view + self.invoked_with: Optional[str] = invoked_with + self.invoked_parents: List[str] = invoked_parents or [] + self.invoked_subcommand: Optional[Command[Any, ..., Any]] = invoked_subcommand + self.subcommand_passed: Optional[str] = subcommand_passed + self.command_failed: bool = command_failed + self.current_parameter: Optional[Parameter] = current_parameter + self.current_argument: Optional[str] = current_argument + self.interaction: Optional[Interaction[BotT]] = interaction + self._state: ConnectionState = self.message._state + + @classmethod + async def from_interaction(cls, interaction: Interaction[BotT], /) -> Self: + """|coro| + + Creates a context from a :class:`discord.Interaction`. This only + works on application command based interactions, such as slash commands + or context menus. + + On slash command based interactions this creates a synthetic :class:`~discord.Message` + that points to an ephemeral message that the command invoker has executed. This means + that :attr:`Context.author` returns the member that invoked the command. + + In a message context menu based interaction, the :attr:`Context.message` attribute + is the message that the command is being executed on. This means that :attr:`Context.author` + returns the author of the message being targetted. To get the member that invoked + the command then :attr:`discord.Interaction.user` should be used instead. + + .. versionadded:: 2.0 + + Parameters + ----------- + interaction: :class:`discord.Interaction` + The interaction to create a context with. + + Raises + ------- + ValueError + The interaction does not have a valid command. + TypeError + The interaction client is not derived from :class:`Bot` or :class:`AutoShardedBot`. + """ + + # Circular import + from .bot import BotBase + + if not isinstance(interaction.client, BotBase): + raise TypeError('Interaction client is not derived from commands.Bot or commands.AutoShardedBot') + + command = interaction.command + if command is None: + raise ValueError('interaction does not have command data') + + bot: BotT = interaction.client # type: ignore + data: ApplicationCommandInteractionData = interaction.data # type: ignore + if interaction.message is None: + synthetic_payload = { + 'id': interaction.id, + 'reactions': [], + 'embeds': [], + 'mention_everyone': False, + 'tts': False, + 'pinned': False, + 'edited_timestamp': None, + 'type': MessageType.chat_input_command if data.get('type', 1) == 1 else MessageType.context_menu_command, + 'flags': 64, + 'content': '', + 'mentions': [], + 'mention_roles': [], + 'attachments': [], + } + + if interaction.channel_id is None: + raise RuntimeError('interaction channel ID is null, this is probably a Discord bug') + + channel = interaction.channel or PartialMessageable( + state=interaction._state, guild_id=interaction.guild_id, id=interaction.channel_id + ) + message = Message(state=interaction._state, channel=channel, data=synthetic_payload) # type: ignore + message.author = interaction.user + message.attachments = [a for _, a in interaction.namespace if isinstance(a, Attachment)] + else: + message = interaction.message + + prefix = '/' if data.get('type', 1) == 1 else '\u200b' # Mock the prefix + ctx = cls( + message=message, + bot=bot, + view=StringView(''), + args=[], + kwargs={}, + prefix=prefix, + interaction=interaction, + invoked_with=command.name, + command=command, # type: ignore # this will be a hybrid command, technically + ) + interaction._baton = ctx + ctx.command_failed = interaction.command_failed + return ctx + + async def invoke(self, command: Command[CogT, P, T], /, *args: P.args, **kwargs: P.kwargs) -> T: r"""|coro| Calls a command with the arguments given. @@ -110,16 +315,16 @@ async def invoke(self, *args, **kwargs): You must take care in passing the proper arguments when using this function. - .. warning:: + .. versionchanged:: 2.0 - The first parameter passed **must** be the command being invoked. + ``command`` parameter is now positional-only. Parameters ----------- command: :class:`.Command` The command that is going to be called. \*args - The arguments to to use. + The arguments to use. \*\*kwargs The keyword arguments to use. @@ -128,23 +333,9 @@ async def invoke(self, *args, **kwargs): TypeError The command argument to invoke is missing. """ + return await command(self, *args, **kwargs) - try: - command = args[0] - except IndexError: - raise TypeError('Missing command to invoke.') from None - - arguments = [] - if command.cog is not None: - arguments.append(command.cog) - - arguments.append(self) - arguments.extend(args[1:]) - - ret = await command.callback(*arguments, **kwargs) - return ret - - async def reinvoke(self, *, call_hooks=False, restart=True): + async def reinvoke(self, *, call_hooks: bool = False, restart: bool = True) -> None: """|coro| Calls the command again. @@ -188,10 +379,10 @@ async def reinvoke(self, *, call_hooks=False, restart=True): if restart: to_call = cmd.root_parent or cmd - view.index = len(self.prefix) + view.index = len(self.prefix or '') view.previous = 0 self.invoked_parents = [] - self.invoked_with = view.get_word() # advance to get the root command + self.invoked_with = view.get_word() # advance to get the root command else: to_call = cmd @@ -207,54 +398,150 @@ async def reinvoke(self, *, call_hooks=False, restart=True): self.subcommand_passed = subcommand_passed @property - def valid(self): + def valid(self) -> bool: """:class:`bool`: Checks if the invocation context is valid to be invoked with.""" return self.prefix is not None and self.command is not None - async def _get_channel(self): + async def _get_channel(self) -> discord.abc.Messageable: return self.channel @property - def cog(self): + def clean_prefix(self) -> str: + """:class:`str`: The cleaned up invoke prefix. i.e. mentions are ``@name`` instead of ``<@id>``. + + .. versionadded:: 2.0 + """ + if self.prefix is None: + return '' + + user = self.me + # this breaks if the prefix mention is not the bot itself but I + # consider this to be an *incredibly* strange use case. I'd rather go + # for this common use case rather than waste performance for the + # odd one. + pattern = re.compile(r"<@!?%s>" % user.id) + return pattern.sub("@%s" % user.display_name.replace('\\', r'\\'), self.prefix) + + @property + def cog(self) -> Optional[Cog]: """Optional[:class:`.Cog`]: Returns the cog associated with this context's command. None if it does not exist.""" if self.command is None: return None return self.command.cog + @property + def filesize_limit(self) -> int: + """:class:`int`: Returns the maximum number of bytes files can have when uploaded to this guild or DM channel associated with this context. + + .. versionadded:: 2.3 + """ + return self.guild.filesize_limit if self.guild is not None else discord.utils.DEFAULT_FILE_SIZE_LIMIT_BYTES + @discord.utils.cached_property - def guild(self): + def guild(self) -> Optional[Guild]: """Optional[:class:`.Guild`]: Returns the guild associated with this context's command. None if not available.""" return self.message.guild @discord.utils.cached_property - def channel(self): + def channel(self) -> MessageableChannel: """Union[:class:`.abc.Messageable`]: Returns the channel associated with this context's command. Shorthand for :attr:`.Message.channel`. """ return self.message.channel @discord.utils.cached_property - def author(self): + def author(self) -> Union[User, Member]: """Union[:class:`~discord.User`, :class:`.Member`]: Returns the author associated with this context's command. Shorthand for :attr:`.Message.author` """ return self.message.author @discord.utils.cached_property - def me(self): + def me(self) -> Union[Member, ClientUser]: """Union[:class:`.Member`, :class:`.ClientUser`]: Similar to :attr:`.Guild.me` except it may return the :class:`.ClientUser` in private message contexts. """ - return self.guild.me if self.guild is not None else self.bot.user + # bot.user will never be None at this point. + return self.guild.me if self.guild is not None else self.bot.user # type: ignore + + @discord.utils.cached_property + def permissions(self) -> Permissions: + """:class:`.Permissions`: Returns the resolved permissions for the invoking user in this channel. + Shorthand for :meth:`.abc.GuildChannel.permissions_for` or :attr:`.Interaction.permissions`. + + .. versionadded:: 2.0 + """ + if self.channel.type is ChannelType.private: + return Permissions._dm_permissions() + if not self.interaction: + # channel and author will always match relevant types here + return self.channel.permissions_for(self.author) # type: ignore + base = self.interaction.permissions + if self.channel.type in (ChannelType.voice, ChannelType.stage_voice): + if not base.connect: + # voice channels cannot be edited by people who can't connect to them + # It also implicitly denies all other voice perms + denied = Permissions.voice() + denied.update(manage_channels=True, manage_roles=True) + base.value &= ~denied.value + else: + # text channels do not have voice related permissions + denied = Permissions.voice() + base.value &= ~denied.value + return base + + @discord.utils.cached_property + def bot_permissions(self) -> Permissions: + """:class:`.Permissions`: Returns the resolved permissions for the bot in this channel. + Shorthand for :meth:`.abc.GuildChannel.permissions_for` or :attr:`.Interaction.app_permissions`. + + For interaction-based commands, this will reflect the effective permissions + for :class:`Context` calls, which may differ from calls through + other :class:`.abc.Messageable` endpoints, like :attr:`channel`. + + Notably, sending messages, embedding links, and attaching files are always + permitted, while reading messages might not be. + + .. versionadded:: 2.0 + """ + channel = self.channel + if channel.type == ChannelType.private: + return Permissions._dm_permissions() + if not self.interaction: + # channel and me will always match relevant types here + return channel.permissions_for(self.me) # type: ignore + guild = channel.guild + base = self.interaction.app_permissions + if self.channel.type in (ChannelType.voice, ChannelType.stage_voice): + if not base.connect: + # voice channels cannot be edited by people who can't connect to them + # It also implicitly denies all other voice perms + denied = Permissions.voice() + denied.update(manage_channels=True, manage_roles=True) + base.value &= ~denied.value + else: + # text channels do not have voice related permissions + denied = Permissions.voice() + base.value &= ~denied.value + base.update( + embed_links=True, + attach_files=True, + send_tts_messages=False, + ) + if isinstance(channel, Thread): + base.send_messages_in_threads = True + else: + base.send_messages = True + return base @property - def voice_client(self): + def voice_client(self) -> Optional[VoiceProtocol]: r"""Optional[:class:`.VoiceProtocol`]: A shortcut to :attr:`.Guild.voice_client`\, if applicable.""" g = self.guild return g.voice_client if g else None - async def send_help(self, *args): + async def send_help(self, *args: Any) -> Any: """send_help(entity=) |coro| @@ -272,7 +559,7 @@ async def send_help(self, *args): Due to the way this function works, instead of returning something similar to :meth:`~.commands.HelpCommand.command_not_found` - this returns :class:`None` on bad input or no help command. + this returns ``None`` on bad input or no help command. Parameters ------------ @@ -284,7 +571,7 @@ async def send_help(self, *args): Any The result of the help command, if any. """ - from .core import Group, Command, wrap_callback + from .core import Command, Group, wrap_callback from .errors import CommandError bot = self.bot @@ -295,6 +582,7 @@ async def send_help(self, *args): cmd = cmd.copy() cmd.context = self + if len(args) == 0: await cmd.prepare_help_command(self, None) mapping = cmd.get_bot_mapping() @@ -306,12 +594,12 @@ async def send_help(self, *args): return None entity = args[0] - if entity is None: - return None - if isinstance(entity, str): entity = bot.get_cog(entity) or bot.get_command(entity) + if entity is None: + return None + try: entity.qualified_name except AttributeError: @@ -321,7 +609,7 @@ async def send_help(self, *args): await cmd.prepare_help_command(self, entity.qualified_name) try: - if hasattr(entity, '__cog_commands__'): + if is_cog(entity): injected = wrap_callback(cmd.send_cog_help) return await injected(entity) elif isinstance(entity, Group): @@ -335,6 +623,443 @@ async def send_help(self, *args): except CommandError as e: await cmd.on_help_command_error(self, e) - @discord.utils.copy_doc(discord.Message.reply) - async def reply(self, content=None, **kwargs): - return await self.message.reply(content, **kwargs) + @overload + async def reply( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embed: Embed = ..., + file: File = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def reply( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embed: Embed = ..., + files: Sequence[File] = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def reply( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embeds: Sequence[Embed] = ..., + file: File = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def reply( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embeds: Sequence[Embed] = ..., + files: Sequence[File] = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + async def reply(self, content: Optional[str] = None, **kwargs: Any) -> Message: + """|coro| + + A shortcut method to :meth:`send` to reply to the + :class:`~discord.Message` referenced by this context. + + For interaction based contexts, this is the same as :meth:`send`. + + .. versionadded:: 1.6 + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` or + :exc:`ValueError` instead of ``InvalidArgument``. + + Raises + -------- + ~discord.HTTPException + Sending the message failed. + ~discord.Forbidden + You do not have the proper permissions to send the message. + ValueError + The ``files`` list is not of the appropriate size + TypeError + You specified both ``file`` and ``files``. + + Returns + --------- + :class:`~discord.Message` + The message that was sent. + """ + if self.interaction is None: + return await self.send(content, reference=self.message, **kwargs) + else: + return await self.send(content, **kwargs) + + def typing(self, *, ephemeral: bool = False) -> Union[Typing, DeferTyping]: + """Returns an asynchronous context manager that allows you to send a typing indicator to + the destination for an indefinite period of time, or 10 seconds if the context manager + is called using ``await``. + + In an interaction based context, this is equivalent to a :meth:`defer` call and + does not do any typing calls. + + Example Usage: :: + + async with channel.typing(): + # simulate something heavy + await asyncio.sleep(20) + + await channel.send('Done!') + + Example Usage: :: + + await channel.typing() + # Do some computational magic for about 10 seconds + await channel.send('Done!') + + .. versionchanged:: 2.0 + This no longer works with the ``with`` syntax, ``async with`` must be used instead. + + .. versionchanged:: 2.0 + Added functionality to ``await`` the context manager to send a typing indicator for 10 seconds. + + Parameters + ----------- + ephemeral: :class:`bool` + Indicates whether the deferred message will eventually be ephemeral. + Only valid for interaction based contexts. + + .. versionadded:: 2.0 + """ + if self.interaction is None: + return Typing(self) + return DeferTyping(self, ephemeral=ephemeral) + + async def defer(self, *, ephemeral: bool = False) -> None: + """|coro| + + Defers the interaction based contexts. + + This is typically used when the interaction is acknowledged + and a secondary action will be done later. + + If this isn't an interaction based context then it does nothing. + + Parameters + ----------- + ephemeral: :class:`bool` + Indicates whether the deferred message will eventually be ephemeral. + + Raises + ------- + HTTPException + Deferring the interaction failed. + InteractionResponded + This interaction has already been responded to before. + """ + + if self.interaction: + await self.interaction.response.defer(ephemeral=ephemeral) + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embed: Embed = ..., + file: File = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embed: Embed = ..., + files: Sequence[File] = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embeds: Sequence[Embed] = ..., + file: File = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + content: Optional[str] = ..., + *, + tts: bool = ..., + embeds: Sequence[Embed] = ..., + files: Sequence[File] = ..., + stickers: Sequence[Union[GuildSticker, StickerItem]] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: View = ..., + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + async def send( + self, + content: Optional[str] = None, + *, + tts: bool = False, + embed: Optional[Embed] = None, + embeds: Optional[Sequence[Embed]] = None, + file: Optional[File] = None, + files: Optional[Sequence[File]] = None, + stickers: Optional[Sequence[Union[GuildSticker, StickerItem]]] = None, + delete_after: Optional[float] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[AllowedMentions] = None, + reference: Optional[Union[Message, MessageReference, PartialMessage]] = None, + mention_author: Optional[bool] = None, + view: Optional[View] = None, + suppress_embeds: bool = False, + ephemeral: bool = False, + silent: bool = False, + ) -> Message: + """|coro| + + Sends a message to the destination with the content given. + + This works similarly to :meth:`~discord.abc.Messageable.send` for non-interaction contexts. + + For interaction based contexts this does one of the following: + + - :meth:`discord.InteractionResponse.send_message` if no response has been given. + - A followup message if a response has been given. + - Regular send if the interaction has expired + + .. versionchanged:: 2.0 + This function will now raise :exc:`TypeError` or + :exc:`ValueError` instead of ``InvalidArgument``. + + Parameters + ------------ + content: Optional[:class:`str`] + The content of the message to send. + tts: :class:`bool` + Indicates if the message should be sent using text-to-speech. + embed: :class:`~discord.Embed` + The rich embed for the content. + file: :class:`~discord.File` + The file to upload. + files: List[:class:`~discord.File`] + A list of files to upload. Must be a maximum of 10. + nonce: :class:`int` + The nonce to use for sending this message. If the message was successfully sent, + then the message will have a nonce with this value. + delete_after: :class:`float` + If provided, the number of seconds to wait in the background + before deleting the message we just sent. If the deletion fails, + then it is silently ignored. + allowed_mentions: :class:`~discord.AllowedMentions` + Controls the mentions being processed in this message. If this is + passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`. + The merging behaviour only overrides attributes that have been explicitly passed + to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`. + If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions` + are used instead. + + .. versionadded:: 1.4 + + reference: Union[:class:`~discord.Message`, :class:`~discord.MessageReference`, :class:`~discord.PartialMessage`] + A reference to the :class:`~discord.Message` to which you are replying, this can be created using + :meth:`~discord.Message.to_reference` or passed directly as a :class:`~discord.Message`. You can control + whether this mentions the author of the referenced message using the :attr:`~discord.AllowedMentions.replied_user` + attribute of ``allowed_mentions`` or by setting ``mention_author``. + + This is ignored for interaction based contexts. + + .. versionadded:: 1.6 + + mention_author: Optional[:class:`bool`] + If set, overrides the :attr:`~discord.AllowedMentions.replied_user` attribute of ``allowed_mentions``. + This is ignored for interaction based contexts. + + .. versionadded:: 1.6 + view: :class:`discord.ui.View` + A Discord UI View to add to the message. + + .. versionadded:: 2.0 + embeds: List[:class:`~discord.Embed`] + A list of embeds to upload. Must be a maximum of 10. + + .. versionadded:: 2.0 + stickers: Sequence[Union[:class:`~discord.GuildSticker`, :class:`~discord.StickerItem`]] + A list of stickers to upload. Must be a maximum of 3. This is ignored for interaction based contexts. + + .. versionadded:: 2.0 + suppress_embeds: :class:`bool` + Whether to suppress embeds for the message. This sends the message without any embeds if set to ``True``. + + .. versionadded:: 2.0 + ephemeral: :class:`bool` + Indicates if the message should only be visible to the user who started the interaction. + If a view is sent with an ephemeral message and it has no timeout set then the timeout + is set to 15 minutes. **This is only applicable in contexts with an interaction**. + + .. versionadded:: 2.0 + silent: :class:`bool` + Whether to suppress push and desktop notifications for the message. This will increment the mention counter + in the UI, but will not actually send a notification. + + .. versionadded:: 2.2 + + Raises + -------- + ~discord.HTTPException + Sending the message failed. + ~discord.Forbidden + You do not have the proper permissions to send the message. + ValueError + The ``files`` list is not of the appropriate size. + TypeError + You specified both ``file`` and ``files``, + or you specified both ``embed`` and ``embeds``, + or the ``reference`` object is not a :class:`~discord.Message`, + :class:`~discord.MessageReference` or :class:`~discord.PartialMessage`. + + Returns + --------- + :class:`~discord.Message` + The message that was sent. + """ + + if self.interaction is None or self.interaction.is_expired(): + return await super().send( + content=content, + tts=tts, + embed=embed, + embeds=embeds, + file=file, + files=files, + stickers=stickers, + delete_after=delete_after, + nonce=nonce, + allowed_mentions=allowed_mentions, + reference=reference, + mention_author=mention_author, + view=view, + suppress_embeds=suppress_embeds, + silent=silent, + ) # type: ignore # The overloads don't support Optional but the implementation does + + # Convert the kwargs from None to MISSING to appease the remaining implementations + kwargs = { + 'content': content, + 'tts': tts, + 'embed': MISSING if embed is None else embed, + 'embeds': MISSING if embeds is None else embeds, + 'file': MISSING if file is None else file, + 'files': MISSING if files is None else files, + 'allowed_mentions': MISSING if allowed_mentions is None else allowed_mentions, + 'view': MISSING if view is None else view, + 'suppress_embeds': suppress_embeds, + 'ephemeral': ephemeral, + 'silent': silent, + } + + if self.interaction.response.is_done(): + msg = await self.interaction.followup.send(**kwargs, wait=True) + else: + await self.interaction.response.send_message(**kwargs) + msg = await self.interaction.original_response() + + if delete_after is not None: + await msg.delete(delay=delete_after) + return msg diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/converter.py b/dist/ba_data/python-site-packages/discord/ext/commands/converter.py index fdc7649b..7255f171 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/converter.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/converter.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,16 +22,44 @@ DEALINGS IN THE SOFTWARE. """ -import re +from __future__ import annotations + import inspect -import typing +import re +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Generic, + Iterable, + List, + Literal, + Optional, + overload, + Protocol, + Tuple, + Type, + TypeVar, + Union, + runtime_checkable, +) +import types import discord from .errors import * +if TYPE_CHECKING: + from discord.state import Channel + from discord.threads import Thread + + from .parameters import Parameter + from ._types import BotT, _Bot + from .context import Context + __all__ = ( 'Converter', + 'ObjectConverter', 'MemberConverter', 'UserConverter', 'MessageConverter', @@ -50,13 +76,20 @@ 'EmojiConverter', 'PartialEmojiConverter', 'CategoryChannelConverter', + 'ForumChannelConverter', 'IDConverter', - 'StoreChannelConverter', + 'ThreadConverter', + 'GuildChannelConverter', + 'GuildStickerConverter', + 'ScheduledEventConverter', 'clean_content', 'Greedy', + 'Range', + 'run_converters', ) -def _get_from_guilds(bot, getter, argument): + +def _get_from_guilds(bot: _Bot, getter: str, argument: Any) -> Any: result = None for guild in bot.guilds: result = getattr(guild, getter)(argument) @@ -64,9 +97,16 @@ def _get_from_guilds(bot, getter, argument): return result return result + _utils_get = discord.utils.get +T = TypeVar('T') +T_co = TypeVar('T_co', covariant=True) +CT = TypeVar('CT', bound=discord.abc.GuildChannel) +TT = TypeVar('TT', bound=discord.Thread) + -class Converter: +@runtime_checkable +class Converter(Protocol[T_co]): """The base class of custom converters that require the :class:`.Context` to be passed to be useful. @@ -77,7 +117,7 @@ class Converter: method to do its conversion logic. This method must be a :ref:`coroutine `. """ - async def convert(self, ctx, argument): + async def convert(self, ctx: Context[BotT], argument: str) -> T_co: """|coro| The method to override to do conversion logic. @@ -95,22 +135,48 @@ async def convert(self, ctx, argument): Raises ------- - :exc:`.CommandError` + CommandError A generic exception occurred when converting the argument. - :exc:`.BadArgument` + BadArgument The converter failed to convert the argument. """ raise NotImplementedError('Derived classes need to implement this.') -class IDConverter(Converter): - def __init__(self): - self._id_regex = re.compile(r'([0-9]{15,20})$') - super().__init__() - def _get_id_match(self, argument): - return self._id_regex.match(argument) +_ID_REGEX = re.compile(r'([0-9]{15,20})$') + + +class IDConverter(Converter[T_co]): + @staticmethod + def _get_id_match(argument): + return _ID_REGEX.match(argument) + + +class ObjectConverter(IDConverter[discord.Object]): + """Converts to a :class:`~discord.Object`. + + The argument must follow the valid ID or mention formats (e.g. ``<@80088516616269824>``). + + .. versionadded:: 2.0 + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by member, role, or channel mention. + """ + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Object: + match = self._get_id_match(argument) or re.match(r'<(?:@(?:!|&)?|#)([0-9]{15,20})>$', argument) + + if match is None: + raise ObjectNotFound(argument) + + result = int(match.group(1)) -class MemberConverter(IDConverter): + return discord.Object(id=result) + + +class MemberConverter(IDConverter[discord.Member]): """Converts to a :class:`~discord.Member`. All lookups are via the local guild. If in a DM context, then the lookup @@ -120,9 +186,11 @@ class MemberConverter(IDConverter): 1. Lookup by ID. 2. Lookup by mention. - 3. Lookup by name#discrim - 4. Lookup by name - 5. Lookup by nickname + 3. Lookup by username#discriminator (deprecated). + 4. Lookup by username#0 (deprecated, only gets users that migrated from their discriminator). + 5. Lookup by user name. + 6. Lookup by global name. + 7. Lookup by guild nickname. .. versionchanged:: 1.5 Raise :exc:`.MemberNotFound` instead of generic :exc:`.BadArgument` @@ -130,19 +198,31 @@ class MemberConverter(IDConverter): .. versionchanged:: 1.5.1 This converter now lazily fetches members from the gateway and HTTP APIs, optionally caching the result if :attr:`.MemberCacheFlags.joined` is enabled. + + .. deprecated:: 2.3 + Looking up users by discriminator will be removed in a future version due to + the removal of discriminators in an API change. """ - async def query_member_named(self, guild, argument): + async def query_member_named(self, guild: discord.Guild, argument: str) -> Optional[discord.Member]: cache = guild._state.member_cache_flags.joined - if len(argument) > 5 and argument[-5] == '#': - username, _, discriminator = argument.rpartition('#') - members = await guild.query_members(username, limit=100, cache=cache) - return discord.utils.get(members, name=username, discriminator=discriminator) + username, _, discriminator = argument.rpartition('#') + + # If # isn't found then "discriminator" actually has the username + if not username: + discriminator, username = username, discriminator + + if discriminator == '0' or (len(discriminator) == 4 and discriminator.isdigit()): + lookup = username + predicate = lambda m: m.name == username and m.discriminator == discriminator else: - members = await guild.query_members(argument, limit=100, cache=cache) - return discord.utils.find(lambda m: m.name == argument or m.nick == argument, members) + lookup = argument + predicate = lambda m: m.name == argument or m.global_name == argument or m.nick == argument - async def query_member_by_id(self, bot, guild, user_id): + members = await guild.query_members(lookup, limit=100, cache=cache) + return discord.utils.find(predicate, members) + + async def query_member_by_id(self, bot: _Bot, guild: discord.Guild, user_id: int) -> Optional[discord.Member]: ws = bot._get_websocket(shard_id=guild.shard_id) cache = guild._state.member_cache_flags.joined if ws.is_ratelimited(): @@ -163,12 +243,13 @@ async def query_member_by_id(self, bot, guild, user_id): return None return members[0] - async def convert(self, ctx, argument): + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Member: bot = ctx.bot - match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument) + match = self._get_id_match(argument) or re.match(r'<@!?([0-9]{15,20})>$', argument) guild = ctx.guild result = None user_id = None + if match is None: # not a mention... if guild: @@ -182,7 +263,7 @@ async def convert(self, ctx, argument): else: result = _get_from_guilds(bot, 'get_member', user_id) - if result is None: + if not isinstance(result, discord.Member): if guild is None: raise MemberNotFound(argument) @@ -196,7 +277,8 @@ async def convert(self, ctx, argument): return result -class UserConverter(IDConverter): + +class UserConverter(IDConverter[discord.User]): """Converts to a :class:`~discord.User`. All lookups are via the global user cache. @@ -205,8 +287,10 @@ class UserConverter(IDConverter): 1. Lookup by ID. 2. Lookup by mention. - 3. Lookup by name#discrim - 4. Lookup by name + 3. Lookup by username#discriminator (deprecated). + 4. Lookup by username#0 (deprecated, only gets users that migrated from their discriminator). + 5. Lookup by user name. + 6. Lookup by global name. .. versionchanged:: 1.5 Raise :exc:`.UserNotFound` instead of generic :exc:`.BadArgument` @@ -214,9 +298,14 @@ class UserConverter(IDConverter): .. versionchanged:: 1.6 This converter now lazily fetches users from the HTTP APIs if an ID is passed and it's not available in cache. + + .. deprecated:: 2.3 + Looking up users by discriminator will be removed in a future version due to + the removal of discriminators in an API change. """ - async def convert(self, ctx, argument): - match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument) + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.User: + match = self._get_id_match(argument) or re.match(r'<@!?([0-9]{15,20})>$', argument) result = None state = ctx._state @@ -229,33 +318,27 @@ async def convert(self, ctx, argument): except discord.HTTPException: raise UserNotFound(argument) from None - return result + return result # type: ignore - arg = argument + username, _, discriminator = argument.rpartition('#') - # Remove the '@' character if this is the first character from the argument - if arg[0] == '@': - # Remove first character - arg = arg[1:] + # If # isn't found then "discriminator" actually has the username + if not username: + discriminator, username = username, discriminator - # check for discriminator if it exists, - if len(arg) > 5 and arg[-5] == '#': - discrim = arg[-4:] - name = arg[:-5] - predicate = lambda u: u.name == name and u.discriminator == discrim - result = discord.utils.find(predicate, state._users.values()) - if result is not None: - return result + if discriminator == '0' or (len(discriminator) == 4 and discriminator.isdigit()): + predicate = lambda u: u.name == username and u.discriminator == discriminator + else: + predicate = lambda u: u.name == argument or u.global_name == argument - predicate = lambda u: u.name == arg result = discord.utils.find(predicate, state._users.values()) - if result is None: raise UserNotFound(argument) return result -class PartialMessageConverter(Converter): + +class PartialMessageConverter(Converter[discord.PartialMessage]): """Converts to a :class:`discord.PartialMessage`. .. versionadded:: 1.7 @@ -266,27 +349,55 @@ class PartialMessageConverter(Converter): 2. By message ID (The message is assumed to be in the context channel.) 3. By message URL """ - def _get_id_matches(self, argument): + + @staticmethod + def _get_id_matches(ctx: Context[BotT], argument: str) -> Tuple[Optional[int], int, int]: id_regex = re.compile(r'(?:(?P[0-9]{15,20})-)?(?P[0-9]{15,20})$') link_regex = re.compile( r'https?://(?:(ptb|canary|www)\.)?discord(?:app)?\.com/channels/' - r'(?:[0-9]{15,20}|@me)' + r'(?P[0-9]{15,20}|@me)' r'/(?P[0-9]{15,20})/(?P[0-9]{15,20})/?$' ) match = id_regex.match(argument) or link_regex.match(argument) if not match: raise MessageNotFound(argument) - channel_id = match.group("channel_id") - return int(match.group("message_id")), int(channel_id) if channel_id else None + data = match.groupdict() + channel_id = discord.utils._get_as_snowflake(data, 'channel_id') or ctx.channel.id + message_id = int(data['message_id']) + guild_id = data.get('guild_id') + if guild_id is None: + guild_id = ctx.guild and ctx.guild.id + elif guild_id == '@me': + guild_id = None + else: + guild_id = int(guild_id) + return guild_id, message_id, channel_id + + @staticmethod + def _resolve_channel( + ctx: Context[BotT], guild_id: Optional[int], channel_id: Optional[int] + ) -> Optional[Union[Channel, Thread]]: + if channel_id is None: + # we were passed just a message id so we can assume the channel is the current context channel + return ctx.channel + + if guild_id is not None: + guild = ctx.bot.get_guild(guild_id) + if guild is None: + return None + return guild._resolve_channel(channel_id) + + return ctx.bot.get_channel(channel_id) - async def convert(self, ctx, argument): - message_id, channel_id = self._get_id_matches(argument) - channel = ctx.bot.get_channel(channel_id) if channel_id else ctx.channel - if not channel: + async def convert(self, ctx: Context[BotT], argument: str) -> discord.PartialMessage: + guild_id, message_id, channel_id = self._get_id_matches(ctx, argument) + channel = self._resolve_channel(ctx, guild_id, channel_id) + if not channel or not isinstance(channel, discord.abc.Messageable): raise ChannelNotFound(channel_id) return discord.PartialMessage(channel=channel, id=message_id) -class MessageConverter(PartialMessageConverter): + +class MessageConverter(IDConverter[discord.Message]): """Converts to a :class:`discord.Message`. .. versionadded:: 1.1 @@ -300,23 +411,25 @@ class MessageConverter(PartialMessageConverter): .. versionchanged:: 1.5 Raise :exc:`.ChannelNotFound`, :exc:`.MessageNotFound` or :exc:`.ChannelNotReadable` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): - message_id, channel_id = self._get_id_matches(argument) + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Message: + guild_id, message_id, channel_id = PartialMessageConverter._get_id_matches(ctx, argument) message = ctx.bot._connection._get_message(message_id) if message: return message - channel = ctx.bot.get_channel(channel_id) if channel_id else ctx.channel - if not channel: + channel = PartialMessageConverter._resolve_channel(ctx, guild_id, channel_id) + if not channel or not isinstance(channel, discord.abc.Messageable): raise ChannelNotFound(channel_id) try: return await channel.fetch_message(message_id) except discord.NotFound: raise MessageNotFound(argument) except discord.Forbidden: - raise ChannelNotReadable(channel) + raise ChannelNotReadable(channel) # type: ignore # type-checker thinks channel could be a DMChannel at this point -class TextChannelConverter(IDConverter): - """Converts to a :class:`~discord.TextChannel`. + +class GuildChannelConverter(IDConverter[discord.abc.GuildChannel]): + """Converts to a :class:`~discord.abc.GuildChannel`. All lookups are via the local guild. If in a DM context, then the lookup is done by the global cache. @@ -325,40 +438,70 @@ class TextChannelConverter(IDConverter): 1. Lookup by ID. 2. Lookup by mention. - 3. Lookup by name + 3. Lookup by name. - .. versionchanged:: 1.5 - Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` + .. versionadded:: 2.0 """ - async def convert(self, ctx, argument): + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.abc.GuildChannel: + return self._resolve_channel(ctx, argument, 'channels', discord.abc.GuildChannel) + + @staticmethod + def _resolve_channel(ctx: Context[BotT], argument: str, attribute: str, type: Type[CT]) -> CT: bot = ctx.bot - match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) + match = IDConverter._get_id_match(argument) or re.match(r'<#([0-9]{15,20})>$', argument) result = None guild = ctx.guild if match is None: # not a mention if guild: - result = discord.utils.get(guild.text_channels, name=argument) + iterable: Iterable[CT] = getattr(guild, attribute) + result: Optional[CT] = discord.utils.get(iterable, name=argument) else: + def check(c): - return isinstance(c, discord.TextChannel) and c.name == argument - result = discord.utils.find(check, bot.get_all_channels()) + return isinstance(c, type) and c.name == argument + + result = discord.utils.find(check, bot.get_all_channels()) # type: ignore else: channel_id = int(match.group(1)) if guild: - result = guild.get_channel(channel_id) + # guild.get_channel returns an explicit union instead of the base class + result = guild.get_channel(channel_id) # type: ignore else: result = _get_from_guilds(bot, 'get_channel', channel_id) - if not isinstance(result, discord.TextChannel): + if not isinstance(result, type): raise ChannelNotFound(argument) return result -class VoiceChannelConverter(IDConverter): - """Converts to a :class:`~discord.VoiceChannel`. + @staticmethod + def _resolve_thread(ctx: Context[BotT], argument: str, attribute: str, type: Type[TT]) -> TT: + match = IDConverter._get_id_match(argument) or re.match(r'<#([0-9]{15,20})>$', argument) + result = None + guild = ctx.guild + + if match is None: + # not a mention + if guild: + iterable: Iterable[TT] = getattr(guild, attribute) + result: Optional[TT] = discord.utils.get(iterable, name=argument) + else: + thread_id = int(match.group(1)) + if guild: + result = guild.get_thread(thread_id) # type: ignore + + if not result or not isinstance(result, type): + raise ThreadNotFound(argument) + + return result + + +class TextChannelConverter(IDConverter[discord.TextChannel]): + """Converts to a :class:`~discord.TextChannel`. All lookups are via the local guild. If in a DM context, then the lookup is done by the global cache. @@ -372,33 +515,32 @@ class VoiceChannelConverter(IDConverter): .. versionchanged:: 1.5 Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): - bot = ctx.bot - match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) - result = None - guild = ctx.guild - if match is None: - # not a mention - if guild: - result = discord.utils.get(guild.voice_channels, name=argument) - else: - def check(c): - return isinstance(c, discord.VoiceChannel) and c.name == argument - result = discord.utils.find(check, bot.get_all_channels()) - else: - channel_id = int(match.group(1)) - if guild: - result = guild.get_channel(channel_id) - else: - result = _get_from_guilds(bot, 'get_channel', channel_id) + async def convert(self, ctx: Context[BotT], argument: str) -> discord.TextChannel: + return GuildChannelConverter._resolve_channel(ctx, argument, 'text_channels', discord.TextChannel) - if not isinstance(result, discord.VoiceChannel): - raise ChannelNotFound(argument) - return result +class VoiceChannelConverter(IDConverter[discord.VoiceChannel]): + """Converts to a :class:`~discord.VoiceChannel`. + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` + """ + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.VoiceChannel: + return GuildChannelConverter._resolve_channel(ctx, argument, 'voice_channels', discord.VoiceChannel) -class StageChannelConverter(IDConverter): + +class StageChannelConverter(IDConverter[discord.StageChannel]): """Converts to a :class:`~discord.StageChannel`. .. versionadded:: 1.7 @@ -412,33 +554,12 @@ class StageChannelConverter(IDConverter): 2. Lookup by mention. 3. Lookup by name """ - async def convert(self, ctx, argument): - bot = ctx.bot - match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) - result = None - guild = ctx.guild - - if match is None: - # not a mention - if guild: - result = discord.utils.get(guild.stage_channels, name=argument) - else: - def check(c): - return isinstance(c, discord.StageChannel) and c.name == argument - result = discord.utils.find(check, bot.get_all_channels()) - else: - channel_id = int(match.group(1)) - if guild: - result = guild.get_channel(channel_id) - else: - result = _get_from_guilds(bot, 'get_channel', channel_id) - if not isinstance(result, discord.StageChannel): - raise ChannelNotFound(argument) + async def convert(self, ctx: Context[BotT], argument: str) -> discord.StageChannel: + return GuildChannelConverter._resolve_channel(ctx, argument, 'stage_channels', discord.StageChannel) - return result -class CategoryChannelConverter(IDConverter): +class CategoryChannelConverter(IDConverter[discord.CategoryChannel]): """Converts to a :class:`~discord.CategoryChannel`. All lookups are via the local guild. If in a DM context, then the lookup @@ -453,35 +574,31 @@ class CategoryChannelConverter(IDConverter): .. versionchanged:: 1.5 Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): - bot = ctx.bot - match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) - result = None - guild = ctx.guild + async def convert(self, ctx: Context[BotT], argument: str) -> discord.CategoryChannel: + return GuildChannelConverter._resolve_channel(ctx, argument, 'categories', discord.CategoryChannel) - if match is None: - # not a mention - if guild: - result = discord.utils.get(guild.categories, name=argument) - else: - def check(c): - return isinstance(c, discord.CategoryChannel) and c.name == argument - result = discord.utils.find(check, bot.get_all_channels()) - else: - channel_id = int(match.group(1)) - if guild: - result = guild.get_channel(channel_id) - else: - result = _get_from_guilds(bot, 'get_channel', channel_id) - if not isinstance(result, discord.CategoryChannel): - raise ChannelNotFound(argument) +class ThreadConverter(IDConverter[discord.Thread]): + """Converts to a :class:`~discord.Thread`. - return result + All lookups are via the local guild. -class StoreChannelConverter(IDConverter): - """Converts to a :class:`~discord.StoreChannel`. + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name. + + .. versionadded: 2.0 + """ + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Thread: + return GuildChannelConverter._resolve_thread(ctx, argument, 'threads', discord.Thread) + + +class ForumChannelConverter(IDConverter[discord.ForumChannel]): + """Converts to a :class:`~discord.ForumChannel`. All lookups are via the local guild. If in a DM context, then the lookup is done by the global cache. @@ -490,38 +607,16 @@ class StoreChannelConverter(IDConverter): 1. Lookup by ID. 2. Lookup by mention. - 3. Lookup by name. + 3. Lookup by name - .. versionadded:: 1.7 + .. versionadded:: 2.0 """ - async def convert(self, ctx, argument): - bot = ctx.bot - match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) - result = None - guild = ctx.guild + async def convert(self, ctx: Context[BotT], argument: str) -> discord.ForumChannel: + return GuildChannelConverter._resolve_channel(ctx, argument, 'forums', discord.ForumChannel) - if match is None: - # not a mention - if guild: - result = discord.utils.get(guild.channels, name=argument) - else: - def check(c): - return isinstance(c, discord.StoreChannel) and c.name == argument - result = discord.utils.find(check, bot.get_all_channels()) - else: - channel_id = int(match.group(1)) - if guild: - result = guild.get_channel(channel_id) - else: - result = _get_from_guilds(bot, 'get_channel', channel_id) - - if not isinstance(result, discord.StoreChannel): - raise ChannelNotFound(argument) - - return result -class ColourConverter(Converter): +class ColourConverter(Converter[discord.Colour]): """Converts to a :class:`~discord.Colour`. .. versionchanged:: 1.5 @@ -533,7 +628,7 @@ class ColourConverter(Converter): - ``#`` - ``0x#`` - ``rgb(, , )`` - - Any of the ``classmethod`` in :class:`Colour` + - Any of the ``classmethod`` in :class:`~discord.Colour` - The ``_`` in the name can be optionally replaced with spaces. @@ -547,65 +642,21 @@ class ColourConverter(Converter): Added support for ``rgb`` function and 3-digit hex shortcuts """ - RGB_REGEX = re.compile(r'rgb\s*\((?P[0-9]{1,3}%?)\s*,\s*(?P[0-9]{1,3}%?)\s*,\s*(?P[0-9]{1,3}%?)\s*\)') - - def parse_hex_number(self, argument): - arg = ''.join(i * 2 for i in argument) if len(argument) == 3 else argument + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Colour: try: - value = int(arg, base=16) - if not (0 <= value <= 0xFFFFFF): - raise BadColourArgument(argument) + return discord.Colour.from_str(argument) except ValueError: - raise BadColourArgument(argument) - else: - return discord.Color(value=value) - - def parse_rgb_number(self, argument, number): - if number[-1] == '%': - value = int(number[:-1]) - if not (0 <= value <= 100): - raise BadColourArgument(argument) - return round(255 * (value / 100)) - - value = int(number) - if not (0 <= value <= 255): - raise BadColourArgument(argument) - return value - - def parse_rgb(self, argument, *, regex=RGB_REGEX): - match = regex.match(argument) - if match is None: - raise BadColourArgument(argument) - - red = self.parse_rgb_number(argument, match.group('r')) - green = self.parse_rgb_number(argument, match.group('g')) - blue = self.parse_rgb_number(argument, match.group('b')) - return discord.Color.from_rgb(red, green, blue) - - async def convert(self, ctx, argument): - if argument[0] == '#': - return self.parse_hex_number(argument[1:]) - - if argument[0:2] == '0x': - rest = argument[2:] - # Legacy backwards compatible syntax - if rest.startswith('#'): - return self.parse_hex_number(rest[1:]) - return self.parse_hex_number(rest) - - arg = argument.lower() - if arg[0:3] == 'rgb': - return self.parse_rgb(arg) - - arg = arg.replace(' ', '_') - method = getattr(discord.Colour, arg, None) - if arg.startswith('from_') or method is None or not inspect.ismethod(method): - raise BadColourArgument(arg) - return method() + arg = argument.lower().replace(' ', '_') + method = getattr(discord.Colour, arg, None) + if arg.startswith('from_') or method is None or not inspect.ismethod(method): + raise BadColourArgument(arg) + return method() + ColorConverter = ColourConverter -class RoleConverter(IDConverter): + +class RoleConverter(IDConverter[discord.Role]): """Converts to a :class:`~discord.Role`. All lookups are via the local guild. If in a DM context, the converter raises @@ -620,12 +671,13 @@ class RoleConverter(IDConverter): .. versionchanged:: 1.5 Raise :exc:`.RoleNotFound` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Role: guild = ctx.guild if not guild: raise NoPrivateMessage() - match = self._get_id_match(argument) or re.match(r'<@&([0-9]+)>$', argument) + match = self._get_id_match(argument) or re.match(r'<@&([0-9]{15,20})>$', argument) if match: result = guild.get_role(int(match.group(1))) else: @@ -635,12 +687,15 @@ async def convert(self, ctx, argument): raise RoleNotFound(argument) return result -class GameConverter(Converter): - """Converts to :class:`~discord.Game`.""" - async def convert(self, ctx, argument): + +class GameConverter(Converter[discord.Game]): + """Converts to a :class:`~discord.Game`.""" + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Game: return discord.Game(name=argument) -class InviteConverter(Converter): + +class InviteConverter(Converter[discord.Invite]): """Converts to a :class:`~discord.Invite`. This is done via an HTTP request using :meth:`.Bot.fetch_invite`. @@ -648,14 +703,16 @@ class InviteConverter(Converter): .. versionchanged:: 1.5 Raise :exc:`.BadInviteArgument` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Invite: try: invite = await ctx.bot.fetch_invite(argument) return invite except Exception as exc: - raise BadInviteArgument() from exc + raise BadInviteArgument(argument) from exc + -class GuildConverter(IDConverter): +class GuildConverter(IDConverter[discord.Guild]): """Converts to a :class:`~discord.Guild`. The lookup strategy is as follows (in order): @@ -666,7 +723,7 @@ class GuildConverter(IDConverter): .. versionadded:: 1.7 """ - async def convert(self, ctx, argument): + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Guild: match = self._get_id_match(argument) result = None @@ -681,7 +738,8 @@ async def convert(self, ctx, argument): raise GuildNotFound(argument) return result -class EmojiConverter(IDConverter): + +class EmojiConverter(IDConverter[discord.Emoji]): """Converts to a :class:`~discord.Emoji`. All lookups are done for the local guild first, if available. If that lookup @@ -696,8 +754,9 @@ class EmojiConverter(IDConverter): .. versionchanged:: 1.5 Raise :exc:`.EmojiNotFound` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): - match = self._get_id_match(argument) or re.match(r'$', argument) + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.Emoji: + match = self._get_id_match(argument) or re.match(r'$', argument) result = None bot = ctx.bot guild = ctx.guild @@ -713,18 +772,15 @@ async def convert(self, ctx, argument): emoji_id = int(match.group(1)) # Try to look up emoji by id. - if guild: - result = discord.utils.get(guild.emojis, id=emoji_id) - - if result is None: - result = discord.utils.get(bot.emojis, id=emoji_id) + result = bot.get_emoji(emoji_id) if result is None: raise EmojiNotFound(argument) return result -class PartialEmojiConverter(Converter): + +class PartialEmojiConverter(Converter[discord.PartialEmoji]): """Converts to a :class:`~discord.PartialEmoji`. This is done by extracting the animated flag, name and ID from the emoji. @@ -732,20 +788,121 @@ class PartialEmojiConverter(Converter): .. versionchanged:: 1.5 Raise :exc:`.PartialEmojiConversionFailure` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx, argument): - match = re.match(r'<(a?):([a-zA-Z0-9\_]+):([0-9]+)>$', argument) + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.PartialEmoji: + match = re.match(r'<(a?):([a-zA-Z0-9\_]{1,32}):([0-9]{15,20})>$', argument) if match: emoji_animated = bool(match.group(1)) emoji_name = match.group(2) emoji_id = int(match.group(3)) - return discord.PartialEmoji.with_state(ctx.bot._connection, animated=emoji_animated, name=emoji_name, - id=emoji_id) + return discord.PartialEmoji.with_state( + ctx.bot._connection, animated=emoji_animated, name=emoji_name, id=emoji_id + ) raise PartialEmojiConversionFailure(argument) -class clean_content(Converter): + +class GuildStickerConverter(IDConverter[discord.GuildSticker]): + """Converts to a :class:`~discord.GuildSticker`. + + All lookups are done for the local guild first, if available. If that lookup + fails, then it checks the client's global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by name. + + .. versionadded:: 2.0 + """ + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.GuildSticker: + match = self._get_id_match(argument) + result = None + bot = ctx.bot + guild = ctx.guild + + if match is None: + # Try to get the sticker by name. Try local guild first. + if guild: + result = discord.utils.get(guild.stickers, name=argument) + + if result is None: + result = discord.utils.get(bot.stickers, name=argument) + else: + sticker_id = int(match.group(1)) + + # Try to look up sticker by id. + result = bot.get_sticker(sticker_id) + + if result is None: + raise GuildStickerNotFound(argument) + + return result + + +class ScheduledEventConverter(IDConverter[discord.ScheduledEvent]): + """Converts to a :class:`~discord.ScheduledEvent`. + + Lookups are done for the local guild if available. Otherwise, for a DM context, + lookup is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by url. + 3. Lookup by name. + + .. versionadded:: 2.0 + """ + + async def convert(self, ctx: Context[BotT], argument: str) -> discord.ScheduledEvent: + guild = ctx.guild + match = self._get_id_match(argument) + result = None + + if match: + # ID match + event_id = int(match.group(1)) + if guild: + result = guild.get_scheduled_event(event_id) + else: + for guild in ctx.bot.guilds: + result = guild.get_scheduled_event(event_id) + if result: + break + else: + pattern = ( + r'https?://(?:(ptb|canary|www)\.)?discord\.com/events/' + r'(?P[0-9]{15,20})/' + r'(?P[0-9]{15,20})$' + ) + match = re.match(pattern, argument, flags=re.I) + if match: + # URL match + guild = ctx.bot.get_guild(int(match.group('guild_id'))) + + if guild: + event_id = int(match.group('event_id')) + result = guild.get_scheduled_event(event_id) + else: + # lookup by name + if guild: + result = discord.utils.get(guild.scheduled_events, name=argument) + else: + for guild in ctx.bot.guilds: + result = discord.utils.get(guild.scheduled_events, name=argument) + if result: + break + if result is None: + raise ScheduledEventNotFound(argument) + + return result + + +class clean_content(Converter[str]): """Converts the argument to mention scrubbed version of said content. @@ -764,59 +921,67 @@ class clean_content(Converter): .. versionadded:: 1.7 """ - def __init__(self, *, fix_channel_mentions=False, use_nicknames=True, escape_markdown=False, remove_markdown=False): + + def __init__( + self, + *, + fix_channel_mentions: bool = False, + use_nicknames: bool = True, + escape_markdown: bool = False, + remove_markdown: bool = False, + ) -> None: self.fix_channel_mentions = fix_channel_mentions self.use_nicknames = use_nicknames self.escape_markdown = escape_markdown self.remove_markdown = remove_markdown - async def convert(self, ctx, argument): - message = ctx.message - transformations = {} + async def convert(self, ctx: Context[BotT], argument: str) -> str: + msg = ctx.message - if self.fix_channel_mentions and ctx.guild: - def resolve_channel(id, *, _get=ctx.guild.get_channel): - ch = _get(id) - return ('<#%s>' % id), ('#' + ch.name if ch else '#deleted-channel') + if ctx.guild: + + def resolve_member(id: int) -> str: + m = _utils_get(msg.mentions, id=id) or ctx.guild.get_member(id) # type: ignore + return f'@{m.display_name if self.use_nicknames else m.name}' if m else '@deleted-user' - transformations.update(resolve_channel(channel) for channel in message.raw_channel_mentions) + def resolve_role(id: int) -> str: + r = _utils_get(msg.role_mentions, id=id) or ctx.guild.get_role(id) # type: ignore + return f'@{r.name}' if r else '@deleted-role' - if self.use_nicknames and ctx.guild: - def resolve_member(id, *, _get=ctx.guild.get_member): - m = _get(id) - return '@' + m.display_name if m else '@deleted-user' else: - def resolve_member(id, *, _get=ctx.bot.get_user): - m = _get(id) - return '@' + m.name if m else '@deleted-user' + def resolve_member(id: int) -> str: + m = _utils_get(msg.mentions, id=id) or ctx.bot.get_user(id) + return f'@{m.display_name}' if m else '@deleted-user' - transformations.update( - ('<@%s>' % member_id, resolve_member(member_id)) - for member_id in message.raw_mentions - ) + def resolve_role(id: int) -> str: + return '@deleted-role' - transformations.update( - ('<@!%s>' % member_id, resolve_member(member_id)) - for member_id in message.raw_mentions - ) + if self.fix_channel_mentions and ctx.guild: - if ctx.guild: - def resolve_role(_id, *, _find=ctx.guild.get_role): - r = _find(_id) - return '@' + r.name if r else '@deleted-role' + def resolve_channel(id: int) -> str: + c = ctx.guild._resolve_channel(id) # type: ignore + return f'#{c.name}' if c else '#deleted-channel' - transformations.update( - ('<@&%s>' % role_id, resolve_role(role_id)) - for role_id in message.raw_role_mentions - ) + else: - def repl(obj): - return transformations.get(obj.group(0), '') + def resolve_channel(id: int) -> str: + return f'<#{id}>' - pattern = re.compile('|'.join(transformations.keys())) - result = pattern.sub(repl, argument) + transforms = { + '@': resolve_member, + '@!': resolve_member, + '#': resolve_channel, + '@&': resolve_role, + } + def repl(match: re.Match) -> str: + type = match[1] + id = int(match[2]) + transformed = transforms[type](id) + return transformed + + result = re.sub(r'<(@[!&]?|#)([0-9]{15,20})>', repl, argument) if self.escape_markdown: result = discord.utils.escape_markdown(result) elif self.remove_markdown: @@ -825,28 +990,366 @@ def repl(obj): # Completely ensure no mentions escape: return discord.utils.escape_mentions(result) -class _Greedy: + +class Greedy(List[T]): + r"""A special converter that greedily consumes arguments until it can't. + As a consequence of this behaviour, most input errors are silently discarded, + since it is used as an indicator of when to stop parsing. + + When a parser error is met the greedy converter stops converting, undoes the + internal string parsing routine, and continues parsing regularly. + + For example, in the following code: + + .. code-block:: python3 + + @commands.command() + async def test(ctx, numbers: Greedy[int], reason: str): + await ctx.send("numbers: {}, reason: {}".format(numbers, reason)) + + An invocation of ``[p]test 1 2 3 4 5 6 hello`` would pass ``numbers`` with + ``[1, 2, 3, 4, 5, 6]`` and ``reason`` with ``hello``\. + + For more information, check :ref:`ext_commands_special_converters`. + + .. note:: + + For interaction based contexts the conversion error is propagated + rather than swallowed due to the difference in user experience with + application commands. + """ + __slots__ = ('converter',) - def __init__(self, *, converter=None): - self.converter = converter + def __init__(self, *, converter: T) -> None: + self.converter: T = converter - def __getitem__(self, params): + def __repr__(self) -> str: + converter = getattr(self.converter, '__name__', repr(self.converter)) + return f'Greedy[{converter}]' + + def __class_getitem__(cls, params: Union[Tuple[T], T]) -> Greedy[T]: if not isinstance(params, tuple): params = (params,) if len(params) != 1: raise TypeError('Greedy[...] only takes a single argument') converter = params[0] - if not (callable(converter) or isinstance(converter, Converter) or hasattr(converter, '__origin__')): + args = getattr(converter, '__args__', ()) + if discord.utils.PY_310 and converter.__class__ is types.UnionType: # type: ignore + converter = Union[args] # type: ignore + + origin = getattr(converter, '__origin__', None) + + if not (callable(converter) or isinstance(converter, Converter) or origin is not None): raise TypeError('Greedy[...] expects a type or a Converter instance.') - if converter is str or converter is type(None) or converter is _Greedy: - raise TypeError('Greedy[%s] is invalid.' % converter.__name__) + if converter in (str, type(None)) or origin is Greedy: + raise TypeError(f'Greedy[{converter.__name__}] is invalid.') # type: ignore + + if origin is Union and type(None) in args: + raise TypeError(f'Greedy[{converter!r}] is invalid.') + + return cls(converter=converter) + + @property + def constructed_converter(self) -> Any: + # Only construct a converter once in order to maintain state between convert calls + if ( + inspect.isclass(self.converter) + and issubclass(self.converter, Converter) + and not inspect.ismethod(self.converter.convert) + ): + return self.converter() + return self.converter + + +if TYPE_CHECKING: + from typing_extensions import Annotated as Range +else: + + class Range: + """A special converter that can be applied to a parameter to require a numeric + or string type to fit within the range provided. + + During type checking time this is equivalent to :obj:`typing.Annotated` so type checkers understand + the intent of the code. + + Some example ranges: + + - ``Range[int, 10]`` means the minimum is 10 with no maximum. + - ``Range[int, None, 10]`` means the maximum is 10 with no minimum. + - ``Range[int, 1, 10]`` means the minimum is 1 and the maximum is 10. + - ``Range[float, 1.0, 5.0]`` means the minimum is 1.0 and the maximum is 5.0. + - ``Range[str, 1, 10]`` means the minimum length is 1 and the maximum length is 10. + + Inside a :class:`HybridCommand` this functions equivalently to :class:`discord.app_commands.Range`. + + If the value cannot be converted to the provided type or is outside the given range, + :class:`~.ext.commands.BadArgument` or :class:`~.ext.commands.RangeError` is raised to + the appropriate error handlers respectively. + + .. versionadded:: 2.0 + + Examples + ---------- + + .. code-block:: python3 + + @bot.command() + async def range(ctx: commands.Context, value: commands.Range[int, 10, 12]): + await ctx.send(f'Your value is {value}') + """ + + def __init__( + self, + *, + annotation: Any, + min: Optional[Union[int, float]] = None, + max: Optional[Union[int, float]] = None, + ) -> None: + self.annotation: Any = annotation + self.min: Optional[Union[int, float]] = min + self.max: Optional[Union[int, float]] = max + + if min and max and min > max: + raise TypeError('minimum cannot be larger than maximum') + + async def convert(self, ctx: Context[BotT], value: str) -> Union[int, float]: + try: + count = converted = self.annotation(value) + except ValueError: + raise BadArgument( + f'Converting to "{self.annotation.__name__}" failed for parameter "{ctx.current_parameter.name}".' + ) + + if self.annotation is str: + count = len(value) + + if (self.min is not None and count < self.min) or (self.max is not None and count > self.max): + raise RangeError(converted, minimum=self.min, maximum=self.max) + + return converted + + def __call__(self) -> None: + # Trick to allow it inside typing.Union + pass + + def __or__(self, rhs) -> Any: + return Union[self, rhs] + + def __repr__(self) -> str: + return f'{self.__class__.__name__}[{self.annotation.__name__}, {self.min}, {self.max}]' + + def __class_getitem__(cls, obj) -> Range: + if not isinstance(obj, tuple): + raise TypeError(f'expected tuple for arguments, received {obj.__class__.__name__} instead') + + if len(obj) == 2: + obj = (*obj, None) + elif len(obj) != 3: + raise TypeError('Range accepts either two or three arguments with the first being the type of range.') - if getattr(converter, '__origin__', None) is typing.Union and type(None) in converter.__args__: - raise TypeError('Greedy[%r] is invalid.' % converter) + annotation, min, max = obj - return self.__class__(converter=converter) + if min is None and max is None: + raise TypeError('Range must not be empty') + + if min is not None and max is not None: + # At this point max and min are both not none + if type(min) != type(max): + raise TypeError('Both min and max in Range must be the same type') + + if annotation not in (int, float, str): + raise TypeError(f'expected int, float, or str as range type, received {annotation!r} instead') + + if annotation in (str, int): + cast = int + else: + cast = float + + return cls( + annotation=annotation, + min=cast(min) if min is not None else None, + max=cast(max) if max is not None else None, + ) + + +def _convert_to_bool(argument: str) -> bool: + lowered = argument.lower() + if lowered in ('yes', 'y', 'true', 't', '1', 'enable', 'on'): + return True + elif lowered in ('no', 'n', 'false', 'f', '0', 'disable', 'off'): + return False + else: + raise BadBoolArgument(lowered) + + +_GenericAlias = type(List[T]) + + +def is_generic_type(tp: Any, *, _GenericAlias: type = _GenericAlias) -> bool: + return isinstance(tp, type) and issubclass(tp, Generic) or isinstance(tp, _GenericAlias) + + +CONVERTER_MAPPING: Dict[type, Any] = { + discord.Object: ObjectConverter, + discord.Member: MemberConverter, + discord.User: UserConverter, + discord.Message: MessageConverter, + discord.PartialMessage: PartialMessageConverter, + discord.TextChannel: TextChannelConverter, + discord.Invite: InviteConverter, + discord.Guild: GuildConverter, + discord.Role: RoleConverter, + discord.Game: GameConverter, + discord.Colour: ColourConverter, + discord.VoiceChannel: VoiceChannelConverter, + discord.StageChannel: StageChannelConverter, + discord.Emoji: EmojiConverter, + discord.PartialEmoji: PartialEmojiConverter, + discord.CategoryChannel: CategoryChannelConverter, + discord.Thread: ThreadConverter, + discord.abc.GuildChannel: GuildChannelConverter, + discord.GuildSticker: GuildStickerConverter, + discord.ScheduledEvent: ScheduledEventConverter, + discord.ForumChannel: ForumChannelConverter, +} + + +async def _actual_conversion(ctx: Context[BotT], converter: Any, argument: str, param: inspect.Parameter): + if converter is bool: + return _convert_to_bool(argument) + + try: + module = converter.__module__ + except AttributeError: + pass + else: + if module is not None and (module.startswith('discord.') and not module.endswith('converter')): + converter = CONVERTER_MAPPING.get(converter, converter) + + try: + if inspect.isclass(converter) and issubclass(converter, Converter): + if inspect.ismethod(converter.convert): + return await converter.convert(ctx, argument) + else: + return await converter().convert(ctx, argument) + elif isinstance(converter, Converter): + return await converter.convert(ctx, argument) # type: ignore + except CommandError: + raise + except Exception as exc: + raise ConversionError(converter, exc) from exc # type: ignore + + try: + return converter(argument) + except CommandError: + raise + except Exception as exc: + try: + name = converter.__name__ + except AttributeError: + name = converter.__class__.__name__ -Greedy = _Greedy() + raise BadArgument(f'Converting to "{name}" failed for parameter "{param.name}".') from exc + + +@overload +async def run_converters( + ctx: Context[BotT], converter: Union[Type[Converter[T]], Converter[T]], argument: str, param: Parameter +) -> T: + ... + + +@overload +async def run_converters(ctx: Context[BotT], converter: Any, argument: str, param: Parameter) -> Any: + ... + + +async def run_converters(ctx: Context[BotT], converter: Any, argument: str, param: Parameter) -> Any: + """|coro| + + Runs converters for a given converter, argument, and parameter. + + This function does the same work that the library does under the hood. + + .. versionadded:: 2.0 + + Parameters + ------------ + ctx: :class:`Context` + The invocation context to run the converters under. + converter: Any + The converter to run, this corresponds to the annotation in the function. + argument: :class:`str` + The argument to convert to. + param: :class:`Parameter` + The parameter being converted. This is mainly for error reporting. + + Raises + ------- + CommandError + The converter failed to convert. + + Returns + -------- + Any + The resulting conversion. + """ + origin = getattr(converter, '__origin__', None) + + if origin is Union: + errors = [] + _NoneType = type(None) + union_args = converter.__args__ + for conv in union_args: + # if we got to this part in the code, then the previous conversions have failed + # so we should just undo the view, return the default, and allow parsing to continue + # with the other parameters + if conv is _NoneType and param.kind != param.VAR_POSITIONAL: + ctx.view.undo() + return None if param.required else await param.get_default(ctx) + + try: + value = await run_converters(ctx, conv, argument, param) + except CommandError as exc: + errors.append(exc) + else: + return value + + # if we're here, then we failed all the converters + raise BadUnionArgument(param, union_args, errors) + + if origin is Literal: + errors = [] + conversions = {} + literal_args = converter.__args__ + for literal in literal_args: + literal_type = type(literal) + try: + value = conversions[literal_type] + except KeyError: + try: + value = await _actual_conversion(ctx, literal_type, argument, param) + except CommandError as exc: + errors.append(exc) + conversions[literal_type] = object() + continue + else: + conversions[literal_type] = value + + if value == literal: + return value + + # if we're here, then we failed to match all the literals + raise BadLiteralArgument(param, literal_args, errors, argument) + + # This must be the last if-clause in the chain of origin checking + # Nearly every type is a generic type within the typing library + # So care must be taken to make sure a more specialised origin handle + # isn't overwritten by the widest if clause + if origin is not None and is_generic_type(converter): + converter = origin + + return await _actual_conversion(ctx, converter, argument, param) diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py b/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py index 54a53396..2af7cb01 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -24,6 +22,10 @@ DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations + + +from typing import Any, Callable, Deque, Dict, Optional, Union, Generic, TypeVar, TYPE_CHECKING from discord.enums import Enum import time import asyncio @@ -31,24 +33,35 @@ from ...abc import PrivateChannel from .errors import MaxConcurrencyReached +from .context import Context +from discord.app_commands import Cooldown as Cooldown + +if TYPE_CHECKING: + from typing_extensions import Self + + from ...message import Message __all__ = ( 'BucketType', 'Cooldown', 'CooldownMapping', + 'DynamicCooldownMapping', 'MaxConcurrency', ) +T_contra = TypeVar('T_contra', contravariant=True) + + class BucketType(Enum): - default = 0 - user = 1 - guild = 2 - channel = 3 - member = 4 + default = 0 + user = 1 + guild = 2 + channel = 3 + member = 4 category = 5 - role = 6 + role = 6 - def get_key(self, msg): + def get_key(self, msg: Union[Message, Context[Any]]) -> Any: if self is BucketType.user: return msg.author.id elif self is BucketType.guild: @@ -58,105 +71,52 @@ def get_key(self, msg): elif self is BucketType.member: return ((msg.guild and msg.guild.id), msg.author.id) elif self is BucketType.category: - return (msg.channel.category or msg.channel).id + return (msg.channel.category or msg.channel).id # type: ignore elif self is BucketType.role: # we return the channel id of a private-channel as there are only roles in guilds # and that yields the same result as for a guild with only the @everyone role # NOTE: PrivateChannel doesn't actually have an id attribute but we assume we are - # recieving a DMChannel or GroupChannel which inherit from PrivateChannel and do - return (msg.channel if isinstance(msg.channel, PrivateChannel) else msg.author.top_role).id + # receiving a DMChannel or GroupChannel which inherit from PrivateChannel and do + return (msg.channel if isinstance(msg.channel, PrivateChannel) else msg.author.top_role).id # type: ignore - def __call__(self, msg): + def __call__(self, msg: Union[Message, Context[Any]]) -> Any: return self.get_key(msg) -class Cooldown: - __slots__ = ('rate', 'per', 'type', '_window', '_tokens', '_last') - - def __init__(self, rate, per, type): - self.rate = int(rate) - self.per = float(per) - self.type = type - self._window = 0.0 - self._tokens = self.rate - self._last = 0.0 - - if not callable(self.type): +class CooldownMapping(Generic[T_contra]): + def __init__( + self, + original: Optional[Cooldown], + type: Callable[[T_contra], Any], + ) -> None: + if not callable(type): raise TypeError('Cooldown type must be a BucketType or callable') - def get_tokens(self, current=None): - if not current: - current = time.time() - - tokens = self._tokens - - if current > self._window + self.per: - tokens = self.rate - return tokens - - def get_retry_after(self, current=None): - current = current or time.time() - tokens = self.get_tokens(current) - - if tokens == 0: - return self.per - (current - self._window) - - return 0.0 - - def update_rate_limit(self, current=None): - current = current or time.time() - self._last = current - - self._tokens = self.get_tokens(current) - - # first token used means that we start a new rate limit window - if self._tokens == self.rate: - self._window = current + self._cache: Dict[Any, Cooldown] = {} + self._cooldown: Optional[Cooldown] = original + self._type: Callable[[T_contra], Any] = type - # check if we are rate limited - if self._tokens == 0: - return self.per - (current - self._window) - - # we're not so decrement our tokens - self._tokens -= 1 - - # see if we got rate limited due to this token change, and if - # so update the window to point to our current time frame - if self._tokens == 0: - self._window = current - - def reset(self): - self._tokens = self.rate - self._last = 0.0 - - def copy(self): - return Cooldown(self.rate, self.per, self.type) - - def __repr__(self): - return ''.format(self) - -class CooldownMapping: - def __init__(self, original): - self._cache = {} - self._cooldown = original - - def copy(self): - ret = CooldownMapping(self._cooldown) + def copy(self) -> CooldownMapping[T_contra]: + ret = CooldownMapping(self._cooldown, self._type) ret._cache = self._cache.copy() return ret @property - def valid(self): + def valid(self) -> bool: return self._cooldown is not None + @property + def type(self) -> Callable[[T_contra], Any]: + return self._type + @classmethod - def from_cooldown(cls, rate, per, type): - return cls(Cooldown(rate, per, type)) + def from_cooldown(cls, rate: float, per: float, type: Callable[[T_contra], Any]) -> Self: + return cls(Cooldown(rate, per), type) - def _bucket_key(self, msg): - return self._cooldown.type(msg) + def _bucket_key(self, msg: T_contra) -> Any: + return self._type(msg) - def _verify_cache_integrity(self, current=None): + def _verify_cache_integrity(self, current: Optional[float] = None) -> None: # we want to delete all cache objects that haven't been used # in a cooldown window. e.g. if we have a command that has a # cooldown of 60s and it has not been used in 60s then that key should be deleted @@ -165,23 +125,52 @@ def _verify_cache_integrity(self, current=None): for k in dead_keys: del self._cache[k] - def get_bucket(self, message, current=None): - if self._cooldown.type is BucketType.default: + def create_bucket(self, message: T_contra) -> Cooldown: + return self._cooldown.copy() # type: ignore + + def get_bucket(self, message: T_contra, current: Optional[float] = None) -> Optional[Cooldown]: + if self._type is BucketType.default: return self._cooldown self._verify_cache_integrity(current) key = self._bucket_key(message) if key not in self._cache: - bucket = self._cooldown.copy() - self._cache[key] = bucket + bucket = self.create_bucket(message) + if bucket is not None: + self._cache[key] = bucket else: bucket = self._cache[key] return bucket - def update_rate_limit(self, message, current=None): + def update_rate_limit(self, message: T_contra, current: Optional[float] = None, tokens: int = 1) -> Optional[float]: bucket = self.get_bucket(message, current) - return bucket.update_rate_limit(current) + if bucket is None: + return None + return bucket.update_rate_limit(current, tokens=tokens) + + +class DynamicCooldownMapping(CooldownMapping[T_contra]): + def __init__( + self, + factory: Callable[[T_contra], Optional[Cooldown]], + type: Callable[[T_contra], Any], + ) -> None: + super().__init__(None, type) + self._factory: Callable[[T_contra], Optional[Cooldown]] = factory + + def copy(self) -> DynamicCooldownMapping[T_contra]: + ret = DynamicCooldownMapping(self._factory, self._type) + ret._cache = self._cache.copy() + return ret + + @property + def valid(self) -> bool: + return True + + def create_bucket(self, message: T_contra) -> Optional[Cooldown]: + return self._factory(message) + class _Semaphore: """This class is a version of a semaphore. @@ -198,28 +187,28 @@ class _Semaphore: __slots__ = ('value', 'loop', '_waiters') - def __init__(self, number): - self.value = number - self.loop = asyncio.get_event_loop() - self._waiters = deque() + def __init__(self, number: int) -> None: + self.value: int = number + self.loop: asyncio.AbstractEventLoop = asyncio.get_running_loop() + self._waiters: Deque[asyncio.Future] = deque() - def __repr__(self): - return '<_Semaphore value={0.value} waiters={1}>'.format(self, len(self._waiters)) + def __repr__(self) -> str: + return f'<_Semaphore value={self.value} waiters={len(self._waiters)}>' - def locked(self): + def locked(self) -> bool: return self.value == 0 - def is_active(self): + def is_active(self) -> bool: return len(self._waiters) > 0 - def wake_up(self): + def wake_up(self) -> None: while self._waiters: future = self._waiters.popleft() if not future.done(): future.set_result(None) return - async def acquire(self, *, wait=False): + async def acquire(self, *, wait: bool = False) -> bool: if not wait and self.value <= 0: # signal that we're not acquiring return False @@ -238,35 +227,36 @@ async def acquire(self, *, wait=False): self.value -= 1 return True - def release(self): + def release(self) -> None: self.value += 1 self.wake_up() + class MaxConcurrency: __slots__ = ('number', 'per', 'wait', '_mapping') - def __init__(self, number, *, per, wait): - self._mapping = {} - self.per = per - self.number = number - self.wait = wait + def __init__(self, number: int, *, per: BucketType, wait: bool) -> None: + self._mapping: Dict[Any, _Semaphore] = {} + self.per: BucketType = per + self.number: int = number + self.wait: bool = wait if number <= 0: raise ValueError('max_concurrency \'number\' cannot be less than 1') if not isinstance(per, BucketType): - raise TypeError('max_concurrency \'per\' must be of type BucketType not %r' % type(per)) + raise TypeError(f'max_concurrency \'per\' must be of type BucketType not {type(per)!r}') - def copy(self): + def copy(self) -> Self: return self.__class__(self.number, per=self.per, wait=self.wait) - def __repr__(self): - return ''.format(self) + def __repr__(self) -> str: + return f'' - def get_key(self, message): + def get_key(self, message: Union[Message, Context[Any]]) -> Any: return self.per.get_key(message) - async def acquire(self, message): + async def acquire(self, message: Union[Message, Context[Any]]) -> None: key = self.get_key(message) try: @@ -278,7 +268,7 @@ async def acquire(self, message): if not acquired: raise MaxConcurrencyReached(self.number, self.per) - async def release(self, message): + async def release(self, message: Union[Message, Context[Any]]) -> None: # Technically there's no reason for this function to be async # But it might be more useful in the future key = self.get_key(message) diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/core.py b/dist/ba_data/python-site-packages/discord/ext/commands/core.py index 1c22ec0a..ffbefe28 100644 --- a/dist/ba_data/python-site-packages/discord/ext/commands/core.py +++ b/dist/ba_data/python-site-packages/discord/ext/commands/core.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """ The MIT License (MIT) @@ -23,20 +21,47 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from __future__ import annotations import asyncio +import datetime import functools import inspect -import typing -import datetime +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Generator, + Generic, + List, + Literal, + Optional, + Set, + Tuple, + Type, + TypeVar, + Union, + overload, +) +import re import discord -from .errors import * -from .cooldowns import Cooldown, BucketType, CooldownMapping, MaxConcurrency -from . import converter as converters -from ._types import _BaseCommand +from ._types import _BaseCommand, CogT from .cog import Cog +from .context import Context +from .converter import Greedy, run_converters +from .cooldowns import BucketType, Cooldown, CooldownMapping, DynamicCooldownMapping, MaxConcurrency +from .errors import * +from .parameters import Parameter, Signature +from discord.app_commands.commands import NUMPY_DOCSTRING_ARG_REGEX + +if TYPE_CHECKING: + from typing_extensions import Concatenate, ParamSpec, Self + + from ._types import BotT, Check, ContextT, Coro, CoroFunc, Error, Hook, UserCheck + __all__ = ( 'Command', @@ -55,18 +80,139 @@ 'bot_has_permissions', 'bot_has_any_role', 'cooldown', + 'dynamic_cooldown', 'max_concurrency', 'dm_only', 'guild_only', 'is_owner', 'is_nsfw', 'has_guild_permissions', - 'bot_has_guild_permissions' + 'bot_has_guild_permissions', ) -def wrap_callback(coro): +MISSING: Any = discord.utils.MISSING + +T = TypeVar('T') +CommandT = TypeVar('CommandT', bound='Command[Any, ..., Any]') +# CHT = TypeVar('CHT', bound='Check') +GroupT = TypeVar('GroupT', bound='Group[Any, ..., Any]') + +if TYPE_CHECKING: + P = ParamSpec('P') +else: + P = TypeVar('P') + + +def unwrap_function(function: Callable[..., Any], /) -> Callable[..., Any]: + partial = functools.partial + while True: + if hasattr(function, '__wrapped__'): + function = function.__wrapped__ + elif isinstance(function, partial): + function = function.func + else: + return function + + +def get_signature_parameters( + function: Callable[..., Any], + globalns: Dict[str, Any], + /, + *, + skip_parameters: Optional[int] = None, +) -> Dict[str, Parameter]: + signature = Signature.from_callable(function) + params: Dict[str, Parameter] = {} + cache: Dict[str, Any] = {} + eval_annotation = discord.utils.evaluate_annotation + required_params = discord.utils.is_inside_class(function) + 1 if skip_parameters is None else skip_parameters + if len(signature.parameters) < required_params: + raise TypeError(f'Command signature requires at least {required_params - 1} parameter(s)') + + iterator = iter(signature.parameters.items()) + for _ in range(0, required_params): + next(iterator) + + for name, parameter in iterator: + default = parameter.default + if isinstance(default, Parameter): # update from the default + if default.annotation is not Parameter.empty: + # There are a few cases to care about here. + # x: TextChannel = commands.CurrentChannel + # x = commands.CurrentChannel + # In both of these cases, the default parameter has an explicit annotation + # but in the second case it's only used as the fallback. + if default._fallback: + if parameter.annotation is Parameter.empty: + parameter._annotation = default.annotation + else: + parameter._annotation = default.annotation + + parameter._default = default.default + parameter._description = default._description + parameter._displayed_default = default._displayed_default + parameter._displayed_name = default._displayed_name + + annotation = parameter.annotation + + if annotation is None: + params[name] = parameter.replace(annotation=type(None)) + continue + + annotation = eval_annotation(annotation, globalns, globalns, cache) + if annotation is Greedy: + raise TypeError('Unparameterized Greedy[...] is disallowed in signature.') + + params[name] = parameter.replace(annotation=annotation) + + return params + + +PARAMETER_HEADING_REGEX = re.compile(r'Parameters?\n---+\n', re.I) + + +def _fold_text(input: str) -> str: + """Turns a single newline into a space, and multiple newlines into a newline.""" + + def replacer(m: re.Match[str]) -> str: + if len(m.group()) <= 1: + return ' ' + return '\n' + + return re.sub(r'\n+', replacer, inspect.cleandoc(input)) + + +def extract_descriptions_from_docstring(function: Callable[..., Any], params: Dict[str, Parameter], /) -> Optional[str]: + docstring = inspect.getdoc(function) + + if docstring is None: + return None + + divide = PARAMETER_HEADING_REGEX.split(docstring, 1) + if len(divide) == 1: + return docstring + + description, param_docstring = divide + for match in NUMPY_DOCSTRING_ARG_REGEX.finditer(param_docstring): + name = match.group('name') + + if name not in params: + is_display_name = discord.utils.get(params.values(), displayed_name=name) + if is_display_name: + name = is_display_name.name + else: + continue + + param = params[name] + if param.description is None: + param._description = _fold_text(match.group('description')) + + return _fold_text(description.strip()) + + +def wrap_callback(coro: Callable[P, Coro[T]], /) -> Callable[P, Coro[Optional[T]]]: @functools.wraps(coro) - async def wrapped(*args, **kwargs): + async def wrapped(*args: P.args, **kwargs: P.kwargs) -> Optional[T]: try: ret = await coro(*args, **kwargs) except CommandError: @@ -76,11 +222,15 @@ async def wrapped(*args, **kwargs): except Exception as exc: raise CommandInvokeError(exc) from exc return ret + return wrapped -def hooked_wrapped_callback(command, ctx, coro): + +def hooked_wrapped_callback( + command: Command[Any, ..., Any], ctx: Context[BotT], coro: Callable[P, Coro[T]], / +) -> Callable[P, Coro[Optional[T]]]: @functools.wraps(coro) - async def wrapped(*args, **kwargs): + async def wrapped(*args: P.args, **kwargs: P.kwargs) -> Optional[T]: try: ret = await coro(*args, **kwargs) except CommandError: @@ -94,20 +244,13 @@ async def wrapped(*args, **kwargs): raise CommandInvokeError(exc) from exc finally: if command._max_concurrency is not None: - await command._max_concurrency.release(ctx) + await command._max_concurrency.release(ctx.message) await command.call_after_hooks(ctx) return ret + return wrapped -def _convert_to_bool(argument): - lowered = argument.lower() - if lowered in ('yes', 'y', 'true', 't', '1', 'enable', 'on'): - return True - elif lowered in ('no', 'n', 'false', 'f', '0', 'disable', 'off'): - return False - else: - raise BadBoolArgument(lowered) class _CaseInsensitiveDict(dict): def __contains__(self, k): @@ -128,7 +271,29 @@ def pop(self, k, default=None): def __setitem__(self, k, v): super().__setitem__(k.casefold(), v) -class Command(_BaseCommand): + +class _AttachmentIterator: + def __init__(self, data: List[discord.Attachment]): + self.data: List[discord.Attachment] = data + self.index: int = 0 + + def __iter__(self) -> Self: + return self + + def __next__(self) -> discord.Attachment: + try: + value = self.data[self.index] + except IndexError: + raise StopIteration + else: + self.index += 1 + return value + + def is_empty(self) -> bool: + return self.index >= len(self.data) + + +class Command(_BaseCommand, Generic[CogT, P, T]): r"""A class that implements the protocol for a bot text command. These are not created manually, instead they are created via the @@ -140,7 +305,7 @@ class Command(_BaseCommand): The name of the command. callback: :ref:`coroutine ` The coroutine that is executed when the command is called. - help: :class:`str` + help: Optional[:class:`str`] The long help text for the command. brief: Optional[:class:`str`] The short help text for the command. @@ -153,8 +318,8 @@ class Command(_BaseCommand): If the command is invoked while it is disabled, then :exc:`.DisabledCommand` is raised to the :func:`.on_command_error` event. Defaults to ``True``. - parent: Optional[:class:`Command`] - The parent command that this command belongs to. ``None`` if there + parent: Optional[:class:`Group`] + The parent group that this command belongs to. ``None`` if there isn't one. cog: Optional[:class:`Cog`] The cog that this command belongs to. ``None`` if there isn't one. @@ -194,9 +359,18 @@ class Command(_BaseCommand): If ``True``\, cooldown processing is done after argument parsing, which calls converters. If ``False`` then cooldown processing is done first and then the converters are called second. Defaults to ``False``. + extras: :class:`dict` + A dict of user provided extras to attach to the Command. + + .. note:: + This object may be copied by the library. + + + .. versionadded:: 2.0 """ + __original_kwargs__: Dict[str, Any] - def __new__(cls, *args, **kwargs): + def __new__(cls, *args: Any, **kwargs: Any) -> Self: # if you're wondering why this is done, it's because we need to ensure # we have a complete original copy of **kwargs even for classes that # mess with it by popping before delegating to the subclass __init__. @@ -212,113 +386,145 @@ def __new__(cls, *args, **kwargs): self.__original_kwargs__ = kwargs.copy() return self - def __init__(self, func, **kwargs): + def __init__( + self, + func: Union[ + Callable[Concatenate[CogT, Context[Any], P], Coro[T]], + Callable[Concatenate[Context[Any], P], Coro[T]], + ], + /, + **kwargs: Any, + ) -> None: if not asyncio.iscoroutinefunction(func): raise TypeError('Callback must be a coroutine.') - self.name = name = kwargs.get('name') or func.__name__ + name = kwargs.get('name') or func.__name__ if not isinstance(name, str): raise TypeError('Name of a command must be a string.') + self.name: str = name self.callback = func - self.enabled = kwargs.get('enabled', True) + self.enabled: bool = kwargs.get('enabled', True) help_doc = kwargs.get('help') if help_doc is not None: help_doc = inspect.cleandoc(help_doc) else: - help_doc = inspect.getdoc(func) - if isinstance(help_doc, bytes): - help_doc = help_doc.decode('utf-8') + help_doc = extract_descriptions_from_docstring(func, self.params) - self.help = help_doc + self.help: Optional[str] = help_doc - self.brief = kwargs.get('brief') - self.usage = kwargs.get('usage') - self.rest_is_raw = kwargs.get('rest_is_raw', False) - self.aliases = kwargs.get('aliases', []) + self.brief: Optional[str] = kwargs.get('brief') + self.usage: Optional[str] = kwargs.get('usage') + self.rest_is_raw: bool = kwargs.get('rest_is_raw', False) + self.aliases: Union[List[str], Tuple[str]] = kwargs.get('aliases', []) + self.extras: Dict[Any, Any] = kwargs.get('extras', {}) if not isinstance(self.aliases, (list, tuple)): raise TypeError("Aliases of a command must be a list or a tuple of strings.") - self.description = inspect.cleandoc(kwargs.get('description', '')) - self.hidden = kwargs.get('hidden', False) + self.description: str = inspect.cleandoc(kwargs.get('description', '')) + self.hidden: bool = kwargs.get('hidden', False) try: checks = func.__commands_checks__ checks.reverse() except AttributeError: checks = kwargs.get('checks', []) - finally: - self.checks = checks + + self.checks: List[UserCheck[Context[Any]]] = checks try: cooldown = func.__commands_cooldown__ except AttributeError: cooldown = kwargs.get('cooldown') - finally: - self._buckets = CooldownMapping(cooldown) + + if cooldown is None: + buckets = CooldownMapping(cooldown, BucketType.default) + elif isinstance(cooldown, CooldownMapping): + buckets: CooldownMapping[Context[Any]] = cooldown + else: + raise TypeError("Cooldown must be an instance of CooldownMapping or None.") + self._buckets: CooldownMapping[Context[Any]] = buckets try: max_concurrency = func.__commands_max_concurrency__ except AttributeError: max_concurrency = kwargs.get('max_concurrency') - finally: - self._max_concurrency = max_concurrency - self.require_var_positional = kwargs.get('require_var_positional', False) - self.ignore_extra = kwargs.get('ignore_extra', True) - self.cooldown_after_parsing = kwargs.get('cooldown_after_parsing', False) - self.cog = None + self._max_concurrency: Optional[MaxConcurrency] = max_concurrency + + self.require_var_positional: bool = kwargs.get('require_var_positional', False) + self.ignore_extra: bool = kwargs.get('ignore_extra', True) + self.cooldown_after_parsing: bool = kwargs.get('cooldown_after_parsing', False) + self._cog: CogT = None # type: ignore # This breaks every other pyright release # bandaid for the fact that sometimes parent can be the bot instance - parent = kwargs.get('parent') - self.parent = parent if isinstance(parent, _BaseCommand) else None + parent: Optional[GroupMixin[Any]] = kwargs.get('parent') + self.parent: Optional[GroupMixin[Any]] = parent if isinstance(parent, _BaseCommand) else None # type: ignore # Does not recognise mixin usage + self._before_invoke: Optional[Hook] = None try: before_invoke = func.__before_invoke__ except AttributeError: - self._before_invoke = None + pass else: self.before_invoke(before_invoke) + self._after_invoke: Optional[Hook] = None try: after_invoke = func.__after_invoke__ except AttributeError: - self._after_invoke = None + pass else: self.after_invoke(after_invoke) @property - def callback(self): + def cog(self) -> CogT: + return self._cog + + @cog.setter + def cog(self, value: CogT) -> None: + self._cog = value + + @property + def callback( + self, + ) -> Union[Callable[Concatenate[CogT, Context[Any], P], Coro[T]], Callable[Concatenate[Context[Any], P], Coro[T]],]: return self._callback @callback.setter - def callback(self, function): + def callback( + self, + function: Union[ + Callable[Concatenate[CogT, Context[Any], P], Coro[T]], + Callable[Concatenate[Context[Any], P], Coro[T]], + ], + ) -> None: self._callback = function - self.module = function.__module__ - - signature = inspect.signature(function) - self.params = signature.parameters.copy() + unwrap = unwrap_function(function) + self.module: str = unwrap.__module__ - # PEP-563 allows postponing evaluation of annotations with a __future__ - # import. When postponed, Parameter.annotation will be a string and must - # be replaced with the real value for the converters to work later on - for key, value in self.params.items(): - if isinstance(value.annotation, str): - self.params[key] = value = value.replace(annotation=eval(value.annotation, function.__globals__)) + try: + globalns = unwrap.__globals__ + except AttributeError: + globalns = {} - # fail early for when someone passes an unparameterized Greedy type - if value.annotation is converters.Greedy: - raise TypeError('Unparameterized Greedy[...] is disallowed in signature.') + self.params: Dict[str, Parameter] = get_signature_parameters(function, globalns) - def add_check(self, func): + def add_check(self, func: UserCheck[Context[Any]], /) -> None: """Adds a check to the command. This is the non-decorator interface to :func:`.check`. .. versionadded:: 1.3 + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + + .. seealso:: The :func:`~discord.ext.commands.check` decorator + Parameters ----------- func @@ -327,7 +533,7 @@ def add_check(self, func): self.checks.append(func) - def remove_check(self, func): + def remove_check(self, func: UserCheck[Context[Any]], /) -> None: """Removes a check from the command. This function is idempotent and will not raise an exception @@ -335,6 +541,10 @@ def remove_check(self, func): .. versionadded:: 1.3 + .. versionchanged:: 2.0 + + ``func`` parameter is now positional-only. + Parameters ----------- func @@ -346,16 +556,18 @@ def remove_check(self, func): except ValueError: pass - def update(self, **kwargs): + def update(self, **kwargs: Any) -> None: """Updates :class:`Command` instance with updated attribute. - This works similarly to the :func:`.command` decorator in terms + This works similarly to the :func:`~discord.ext.commands.command` decorator in terms of parameters in that they are passed to the :class:`Command` or subclass constructors, sans the name and callback. """ + cog = self.cog self.__init__(self.callback, **dict(self.__original_kwargs__, **kwargs)) + self.cog = cog - async def __call__(self, *args, **kwargs): + async def __call__(self, context: Context[BotT], /, *args: P.args, **kwargs: P.kwargs) -> T: """|coro| Calls the internal callback that the command holds. @@ -367,20 +579,25 @@ async def __call__(self, *args, **kwargs): the proper arguments and types to this function. .. versionadded:: 1.3 + + .. versionchanged:: 2.0 + + ``context`` parameter is now positional-only. """ if self.cog is not None: - return await self.callback(self.cog, *args, **kwargs) + return await self.callback(self.cog, context, *args, **kwargs) # type: ignore else: - return await self.callback(*args, **kwargs) + return await self.callback(context, *args, **kwargs) # type: ignore - def _ensure_assignment_on_copy(self, other): + def _ensure_assignment_on_copy(self, other: Self) -> Self: other._before_invoke = self._before_invoke other._after_invoke = self._after_invoke + other.extras = self.extras if self.checks != other.checks: other.checks = self.checks.copy() if self._buckets.valid and not other._buckets.valid: other._buckets = self._buckets.copy() - if self._max_concurrency != other._max_concurrency: + if self._max_concurrency and self._max_concurrency != other._max_concurrency: other._max_concurrency = self._max_concurrency.copy() try: @@ -389,7 +606,7 @@ def _ensure_assignment_on_copy(self, other): pass return other - def copy(self): + def copy(self) -> Self: """Creates a copy of this command. Returns @@ -400,7 +617,7 @@ def copy(self): ret = self.__class__(self.callback, **self.__original_kwargs__) return self._ensure_assignment_on_copy(ret) - def _update_copy(self, kwargs): + def _update_copy(self, kwargs: Dict[str, Any]) -> Self: if kwargs: kw = kwargs.copy() kw.update(self.__original_kwargs__) @@ -409,7 +626,7 @@ def _update_copy(self, kwargs): else: return self.copy() - async def dispatch_error(self, ctx, error): + async def dispatch_error(self, ctx: Context[BotT], error: CommandError, /) -> None: ctx.command_failed = True cog = self.cog try: @@ -417,11 +634,11 @@ async def dispatch_error(self, ctx, error): except AttributeError: pass else: - injected = wrap_callback(coro) + injected = wrap_callback(coro) # type: ignore if cog is not None: await injected(cog, ctx, error) else: - await injected(ctx, error) + await injected(ctx, error) # type: ignore try: if cog is not None: @@ -432,126 +649,72 @@ async def dispatch_error(self, ctx, error): finally: ctx.bot.dispatch('command_error', ctx, error) - async def _actual_conversion(self, ctx, converter, argument, param): - if converter is bool: - return _convert_to_bool(argument) - - try: - module = converter.__module__ - except AttributeError: - pass - else: - if module is not None and (module.startswith('discord.') and not module.endswith('converter')): - converter = getattr(converters, converter.__name__ + 'Converter', converter) - - try: - if inspect.isclass(converter): - if issubclass(converter, converters.Converter): - instance = converter() - ret = await instance.convert(ctx, argument) - return ret - else: - method = getattr(converter, 'convert', None) - if method is not None and inspect.ismethod(method): - ret = await method(ctx, argument) - return ret - elif isinstance(converter, converters.Converter): - ret = await converter.convert(ctx, argument) - return ret - except CommandError: - raise - except Exception as exc: - raise ConversionError(converter, exc) from exc - - try: - return converter(argument) - except CommandError: - raise - except Exception as exc: - try: - name = converter.__name__ - except AttributeError: - name = converter.__class__.__name__ - - raise BadArgument('Converting to "{}" failed for parameter "{}".'.format(name, param.name)) from exc - - async def do_conversion(self, ctx, converter, argument, param): - try: - origin = converter.__origin__ - except AttributeError: - pass - else: - if origin is typing.Union: - errors = [] - _NoneType = type(None) - for conv in converter.__args__: - # if we got to this part in the code, then the previous conversions have failed - # so we should just undo the view, return the default, and allow parsing to continue - # with the other parameters - if conv is _NoneType and param.kind != param.VAR_POSITIONAL: - ctx.view.undo() - return None if param.default is param.empty else param.default - - try: - value = await self._actual_conversion(ctx, conv, argument, param) - except CommandError as exc: - errors.append(exc) - else: - return value - - # if we're here, then we failed all the converters - raise BadUnionArgument(param, converter.__args__, errors) - - return await self._actual_conversion(ctx, converter, argument, param) - - def _get_converter(self, param): - converter = param.annotation - if converter is param.empty: - if param.default is not param.empty: - converter = str if param.default is None else type(param.default) - else: - converter = str - return converter - - async def transform(self, ctx, param): - required = param.default is param.empty - converter = self._get_converter(param) + async def transform(self, ctx: Context[BotT], param: Parameter, attachments: _AttachmentIterator, /) -> Any: + converter = param.converter consume_rest_is_special = param.kind == param.KEYWORD_ONLY and not self.rest_is_raw view = ctx.view view.skip_ws() # The greedy converter is simple -- it keeps going until it fails in which case, # it undos the view ready for the next parameter to use instead - if type(converter) is converters._Greedy: - if param.kind == param.POSITIONAL_OR_KEYWORD or param.kind == param.POSITIONAL_ONLY: - return await self._transform_greedy_pos(ctx, param, required, converter.converter) + if isinstance(converter, Greedy): + # Special case for Greedy[discord.Attachment] to consume the attachments iterator + if converter.converter is discord.Attachment: + return list(attachments) + + if param.kind in (param.POSITIONAL_OR_KEYWORD, param.POSITIONAL_ONLY): + return await self._transform_greedy_pos(ctx, param, param.required, converter.constructed_converter) elif param.kind == param.VAR_POSITIONAL: - return await self._transform_greedy_var_pos(ctx, param, converter.converter) + return await self._transform_greedy_var_pos(ctx, param, converter.constructed_converter) else: # if we're here, then it's a KEYWORD_ONLY param type # since this is mostly useless, we'll helpfully transform Greedy[X] # into just X and do the parsing that way. - converter = converter.converter + converter = converter.constructed_converter + + # Try to detect Optional[discord.Attachment] or discord.Attachment special converter + if converter is discord.Attachment: + try: + return next(attachments) + except StopIteration: + raise MissingRequiredAttachment(param) + + if self._is_typing_optional(param.annotation) and param.annotation.__args__[0] is discord.Attachment: + if attachments.is_empty(): + # I have no idea who would be doing Optional[discord.Attachment] = 1 + # but for those cases then 1 should be returned instead of None + return None if param.default is param.empty else param.default + return next(attachments) if view.eof: if param.kind == param.VAR_POSITIONAL: - raise RuntimeError() # break the loop - if required: + raise RuntimeError() # break the loop + if param.required: if self._is_typing_optional(param.annotation): return None + if hasattr(converter, '__commands_is_flag__') and converter._can_be_constructible(): + return await converter._construct_default(ctx) raise MissingRequiredArgument(param) - return param.default + return await param.get_default(ctx) previous = view.index if consume_rest_is_special: - argument = view.read_rest().strip() + ctx.current_argument = argument = view.read_rest().strip() else: - argument = view.get_quoted_word() + try: + ctx.current_argument = argument = view.get_quoted_word() + except ArgumentParsingError as exc: + if self._is_typing_optional(param.annotation): + view.index = previous + return None if param.required else await param.get_default(ctx) + else: + raise exc view.previous = previous - return await self.do_conversion(ctx, converter, argument, param) + # type-checker fails to narrow argument + return await run_converters(ctx, converter, argument, param) # type: ignore - async def _transform_greedy_pos(self, ctx, param, required, converter): + async def _transform_greedy_pos(self, ctx: Context[BotT], param: Parameter, required: bool, converter: Any) -> Any: view = ctx.view result = [] while not view.eof: @@ -560,8 +723,8 @@ async def _transform_greedy_pos(self, ctx, param, required, converter): view.skip_ws() try: - argument = view.get_quoted_word() - value = await self.do_conversion(ctx, converter, argument, param) + ctx.current_argument = argument = view.get_quoted_word() + value = await run_converters(ctx, converter, argument, param) # type: ignore except (CommandError, ArgumentParsingError): view.index = previous break @@ -569,43 +732,41 @@ async def _transform_greedy_pos(self, ctx, param, required, converter): result.append(value) if not result and not required: - return param.default + return await param.get_default(ctx) return result - async def _transform_greedy_var_pos(self, ctx, param, converter): + async def _transform_greedy_var_pos(self, ctx: Context[BotT], param: Parameter, converter: Any) -> Any: view = ctx.view previous = view.index try: - argument = view.get_quoted_word() - value = await self.do_conversion(ctx, converter, argument, param) + ctx.current_argument = argument = view.get_quoted_word() + value = await run_converters(ctx, converter, argument, param) # type: ignore except (CommandError, ArgumentParsingError): view.index = previous - raise RuntimeError() from None # break loop + raise RuntimeError() from None # break loop else: return value @property - def clean_params(self): - """OrderedDict[:class:`str`, :class:`inspect.Parameter`]: - Retrieves the parameter OrderedDict without the context or self parameters. + def clean_params(self) -> Dict[str, Parameter]: + """Dict[:class:`str`, :class:`Parameter`]: + Retrieves the parameter dictionary without the context or self parameters. Useful for inspecting signature. """ - result = self.params.copy() - if self.cog is not None: - # first parameter is self - result.popitem(last=False) + return self.params.copy() - try: - # first/second parameter is context - result.popitem(last=False) - except Exception: - raise ValueError('Missing context parameter') from None + @property + def cooldown(self) -> Optional[Cooldown]: + """Optional[:class:`~discord.app_commands.Cooldown`]: The cooldown of a command when invoked + or ``None`` if the command doesn't have a registered cooldown. - return result + .. versionadded:: 2.0 + """ + return self._buckets._cooldown @property - def full_parent_name(self): + def full_parent_name(self) -> str: """:class:`str`: Retrieves the fully qualified parent command name. This the base command name required to execute it. For example, @@ -613,15 +774,16 @@ def full_parent_name(self): """ entries = [] command = self - while command.parent is not None: - command = command.parent - entries.append(command.name) + # command.parent is type-hinted as GroupMixin some attributes are resolved via MRO + while command.parent is not None: # type: ignore + command = command.parent # type: ignore + entries.append(command.name) # type: ignore return ' '.join(reversed(entries)) @property - def parents(self): - """List[:class:`Command`]: Retrieves the parents of this command. + def parents(self) -> List[Group[Any, ..., Any]]: + """List[:class:`Group`]: Retrieves the parents of this command. If the command has no parents then it returns an empty :class:`list`. @@ -631,15 +793,15 @@ def parents(self): """ entries = [] command = self - while command.parent is not None: - command = command.parent + while command.parent is not None: # type: ignore + command = command.parent # type: ignore entries.append(command) return entries @property - def root_parent(self): - """Optional[:class:`Command`]: Retrieves the root parent of this command. + def root_parent(self) -> Optional[Group[Any, ..., Any]]: + """Optional[:class:`Group`]: Retrieves the root parent of this command. If the command has no parents then it returns ``None``. @@ -650,7 +812,7 @@ def root_parent(self): return self.parents[-1] @property - def qualified_name(self): + def qualified_name(self) -> str: """:class:`str`: Retrieves the fully qualified command name. This is the full parent name with the command name as well. @@ -664,53 +826,38 @@ def qualified_name(self): else: return self.name - def __str__(self): + def __str__(self) -> str: return self.qualified_name - async def _parse_arguments(self, ctx): + async def _parse_arguments(self, ctx: Context[BotT]) -> None: ctx.args = [ctx] if self.cog is None else [self.cog, ctx] ctx.kwargs = {} args = ctx.args kwargs = ctx.kwargs + attachments = _AttachmentIterator(ctx.message.attachments) view = ctx.view iterator = iter(self.params.items()) - if self.cog is not None: - # we have 'self' as the first parameter so just advance - # the iterator and resume parsing - try: - next(iterator) - except StopIteration: - fmt = 'Callback for {0.name} command is missing "self" parameter.' - raise discord.ClientException(fmt.format(self)) - - # next we have the 'ctx' as the next parameter - try: - next(iterator) - except StopIteration: - fmt = 'Callback for {0.name} command is missing "ctx" parameter.' - raise discord.ClientException(fmt.format(self)) - for name, param in iterator: - if param.kind == param.POSITIONAL_OR_KEYWORD or param.kind == param.POSITIONAL_ONLY: - transformed = await self.transform(ctx, param) + ctx.current_parameter = param + if param.kind in (param.POSITIONAL_OR_KEYWORD, param.POSITIONAL_ONLY): + transformed = await self.transform(ctx, param, attachments) args.append(transformed) elif param.kind == param.KEYWORD_ONLY: # kwarg only param denotes "consume rest" semantics if self.rest_is_raw: - converter = self._get_converter(param) - argument = view.read_rest() - kwargs[name] = await self.do_conversion(ctx, converter, argument, param) + ctx.current_argument = argument = view.read_rest() + kwargs[name] = await run_converters(ctx, param.converter, argument, param) else: - kwargs[name] = await self.transform(ctx, param) + kwargs[name] = await self.transform(ctx, param, attachments) break elif param.kind == param.VAR_POSITIONAL: if view.eof and self.require_var_positional: raise MissingRequiredArgument(param) while not view.eof: try: - transformed = await self.transform(ctx, param) + transformed = await self.transform(ctx, param, attachments) args.append(transformed) except RuntimeError: break @@ -718,7 +865,7 @@ async def _parse_arguments(self, ctx): if not self.ignore_extra and not view.eof: raise TooManyArguments('Too many arguments passed to ' + self.qualified_name) - async def call_before_hooks(self, ctx): + async def call_before_hooks(self, ctx: Context[BotT], /) -> None: # now that we're done preparing we can call the pre-command hooks # first, call the command local hook: cog = self.cog @@ -728,9 +875,9 @@ async def call_before_hooks(self, ctx): # __self__ only exists for methods, not functions # however, if @command.before_invoke is used, it will be a function if instance: - await self._before_invoke(instance, ctx) + await self._before_invoke(instance, ctx) # type: ignore else: - await self._before_invoke(ctx) + await self._before_invoke(ctx) # type: ignore # call the cog local hook if applicable: if cog is not None: @@ -743,14 +890,14 @@ async def call_before_hooks(self, ctx): if hook is not None: await hook(ctx) - async def call_after_hooks(self, ctx): + async def call_after_hooks(self, ctx: Context[BotT], /) -> None: cog = self.cog if self._after_invoke is not None: instance = getattr(self._after_invoke, '__self__', cog) if instance: - await self._after_invoke(instance, ctx) + await self._after_invoke(instance, ctx) # type: ignore else: - await self._after_invoke(ctx) + await self._after_invoke(ctx) # type: ignore # call the cog local hook if applicable: if cog is not None: @@ -762,22 +909,24 @@ async def call_after_hooks(self, ctx): if hook is not None: await hook(ctx) - def _prepare_cooldowns(self, ctx): + def _prepare_cooldowns(self, ctx: Context[BotT]) -> None: if self._buckets.valid: dt = ctx.message.edited_at or ctx.message.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() - bucket = self._buckets.get_bucket(ctx.message, current) - retry_after = bucket.update_rate_limit(current) - if retry_after: - raise CommandOnCooldown(bucket, retry_after) + bucket = self._buckets.get_bucket(ctx, current) + if bucket is not None: + retry_after = bucket.update_rate_limit(current) + if retry_after: + raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # type: ignore - async def prepare(self, ctx): + async def prepare(self, ctx: Context[BotT], /) -> None: ctx.command = self if not await self.can_run(ctx): - raise CheckFailure('The check functions for command {0.qualified_name} failed.'.format(self)) + raise CheckFailure(f'The check functions for command {self.qualified_name} failed.') if self._max_concurrency is not None: + # For this application, context can be duck-typed as a Message await self._max_concurrency.acquire(ctx) try: @@ -794,9 +943,13 @@ async def prepare(self, ctx): await self._max_concurrency.release(ctx) raise - def is_on_cooldown(self, ctx): + def is_on_cooldown(self, ctx: Context[BotT], /) -> bool: """Checks whether the command is currently on cooldown. + .. versionchanged:: 2.0 + + ``ctx`` parameter is now positional-only. + Parameters ----------- ctx: :class:`.Context` @@ -810,28 +963,39 @@ def is_on_cooldown(self, ctx): if not self._buckets.valid: return False - bucket = self._buckets.get_bucket(ctx.message) + bucket = self._buckets.get_bucket(ctx) + if bucket is None: + return False dt = ctx.message.edited_at or ctx.message.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() return bucket.get_tokens(current) == 0 - def reset_cooldown(self, ctx): + def reset_cooldown(self, ctx: Context[BotT], /) -> None: """Resets the cooldown on this command. + .. versionchanged:: 2.0 + + ``ctx`` parameter is now positional-only. + Parameters ----------- ctx: :class:`.Context` The invocation context to reset the cooldown under. """ if self._buckets.valid: - bucket = self._buckets.get_bucket(ctx.message) - bucket.reset() + bucket = self._buckets.get_bucket(ctx) + if bucket is not None: + bucket.reset() - def get_cooldown_retry_after(self, ctx): + def get_cooldown_retry_after(self, ctx: Context[BotT], /) -> float: """Retrieves the amount of seconds before this command can be tried again. .. versionadded:: 1.4 + .. versionchanged:: 2.0 + + ``ctx`` parameter is now positional-only. + Parameters ----------- ctx: :class:`.Context` @@ -844,14 +1008,16 @@ def get_cooldown_retry_after(self, ctx): If this is ``0.0`` then the command isn't on cooldown. """ if self._buckets.valid: - bucket = self._buckets.get_bucket(ctx.message) + bucket = self._buckets.get_bucket(ctx) + if bucket is None: + return 0.0 dt = ctx.message.edited_at or ctx.message.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() return bucket.get_retry_after(current) return 0.0 - async def invoke(self, ctx): + async def invoke(self, ctx: Context[BotT], /) -> None: await self.prepare(ctx) # terminate the invoked_subcommand chain. @@ -859,10 +1025,10 @@ async def invoke(self, ctx): # the invoked subcommand is None. ctx.invoked_subcommand = None ctx.subcommand_passed = None - injected = hooked_wrapped_callback(self, ctx, self.callback) - await injected(*ctx.args, **ctx.kwargs) + injected = hooked_wrapped_callback(self, ctx, self.callback) # type: ignore + await injected(*ctx.args, **ctx.kwargs) # type: ignore - async def reinvoke(self, ctx, *, call_hooks=False): + async def reinvoke(self, ctx: Context[BotT], /, *, call_hooks: bool = False) -> None: ctx.command = self await self._parse_arguments(ctx) @@ -871,7 +1037,7 @@ async def reinvoke(self, ctx, *, call_hooks=False): ctx.invoked_subcommand = None try: - await self.callback(*ctx.args, **ctx.kwargs) + await self.callback(*ctx.args, **ctx.kwargs) # type: ignore except: ctx.command_failed = True raise @@ -879,13 +1045,17 @@ async def reinvoke(self, ctx, *, call_hooks=False): if call_hooks: await self.call_after_hooks(ctx) - def error(self, coro): + def error(self, coro: Error[CogT, ContextT], /) -> Error[CogT, ContextT]: """A decorator that registers a coroutine as a local error handler. A local error handler is an :func:`.on_command_error` event limited to a single command. However, the :func:`.on_command_error` is still invoked afterwards as the catch-all. + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Parameters ----------- coro: :ref:`coroutine ` @@ -900,17 +1070,17 @@ def error(self, coro): if not asyncio.iscoroutinefunction(coro): raise TypeError('The error handler must be a coroutine.') - self.on_error = coro + self.on_error: Error[CogT, Any] = coro return coro - def has_error_handler(self): + def has_error_handler(self) -> bool: """:class:`bool`: Checks whether the command has an error handler registered. .. versionadded:: 1.7 """ return hasattr(self, 'on_error') - def before_invoke(self, coro): + def before_invoke(self, coro: Hook[CogT, ContextT], /) -> Hook[CogT, ContextT]: """A decorator that registers a coroutine as a pre-invoke hook. A pre-invoke hook is called directly before the command is @@ -921,6 +1091,10 @@ def before_invoke(self, coro): See :meth:`.Bot.before_invoke` for more info. + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Parameters ----------- coro: :ref:`coroutine ` @@ -937,7 +1111,7 @@ def before_invoke(self, coro): self._before_invoke = coro return coro - def after_invoke(self, coro): + def after_invoke(self, coro: Hook[CogT, ContextT], /) -> Hook[CogT, ContextT]: """A decorator that registers a coroutine as a post-invoke hook. A post-invoke hook is called directly after the command is @@ -948,6 +1122,10 @@ def after_invoke(self, coro): See :meth:`.Bot.after_invoke` for more info. + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Parameters ----------- coro: :ref:`coroutine ` @@ -965,17 +1143,17 @@ def after_invoke(self, coro): return coro @property - def cog_name(self): + def cog_name(self) -> Optional[str]: """Optional[:class:`str`]: The name of the cog this command belongs to, if any.""" return type(self.cog).__cog_name__ if self.cog is not None else None @property - def short_doc(self): + def short_doc(self) -> str: """:class:`str`: Gets the "short" documentation of a command. - By default, this is the :attr:`brief` attribute. + By default, this is the :attr:`.brief` attribute. If that lookup leads to an empty string then the first line of the - :attr:`help` attribute is used instead. + :attr:`.help` attribute is used instead. """ if self.brief is not None: return self.brief @@ -983,67 +1161,90 @@ def short_doc(self): return self.help.split('\n', 1)[0] return '' - def _is_typing_optional(self, annotation): - try: - origin = annotation.__origin__ - except AttributeError: - return False - - if origin is not typing.Union: - return False - - return annotation.__args__[-1] is type(None) + def _is_typing_optional(self, annotation: Union[T, Optional[T]]) -> bool: + return getattr(annotation, '__origin__', None) is Union and type(None) in annotation.__args__ # type: ignore @property - def signature(self): + def signature(self) -> str: """:class:`str`: Returns a POSIX-like signature useful for help command output.""" if self.usage is not None: return self.usage - params = self.clean_params if not params: return '' result = [] - for name, param in params.items(): - greedy = isinstance(param.annotation, converters._Greedy) - - if param.default is not param.empty: + for param in params.values(): + name = param.displayed_name or param.name + + greedy = isinstance(param.converter, Greedy) + optional = False # postpone evaluation of if it's an optional argument + + annotation: Any = param.converter.converter if greedy else param.converter + origin = getattr(annotation, '__origin__', None) + if not greedy and origin is Union: + none_cls = type(None) + union_args = annotation.__args__ + optional = union_args[-1] is none_cls + if len(union_args) == 2 and optional: + annotation = union_args[0] + origin = getattr(annotation, '__origin__', None) + + if annotation is discord.Attachment: + # For discord.Attachment we need to signal to the user that it's an attachment + # It's not exactly pretty but it's enough to differentiate + if optional: + result.append(f'[{name} (upload a file)]') + elif greedy: + result.append(f'[{name} (upload files)]...') + else: + result.append(f'<{name} (upload a file)>') + continue + + # for typing.Literal[...], typing.Optional[typing.Literal[...]], and Greedy[typing.Literal[...]], the + # parameter signature is a literal list of it's values + if origin is Literal: + name = '|'.join(f'"{v}"' if isinstance(v, str) else str(v) for v in annotation.__args__) + if not param.required: # We don't want None or '' to trigger the [name=value] case and instead it should # do [name] since [name=None] or [name=] are not exactly useful for the user. - should_print = param.default if isinstance(param.default, str) else param.default is not None - if should_print: - result.append('[%s=%s]' % (name, param.default) if not greedy else - '[%s=%s]...' % (name, param.default)) + if param.displayed_default: + result.append( + f'[{name}={param.displayed_default}]' if not greedy else f'[{name}={param.displayed_default}]...' + ) continue else: - result.append('[%s]' % name) + result.append(f'[{name}]') elif param.kind == param.VAR_POSITIONAL: if self.require_var_positional: - result.append('<%s...>' % name) + result.append(f'<{name}...>') else: - result.append('[%s...]' % name) + result.append(f'[{name}...]') elif greedy: - result.append('[%s]...' % name) - elif self._is_typing_optional(param.annotation): - result.append('[%s]' % name) + result.append(f'[{name}]...') + elif optional: + result.append(f'[{name}]') else: - result.append('<%s>' % name) + result.append(f'<{name}>') return ' '.join(result) - async def can_run(self, ctx): + async def can_run(self, ctx: Context[BotT], /) -> bool: """|coro| Checks if the command can be executed by checking all the predicates - inside the :attr:`checks` attribute. This also checks whether the + inside the :attr:`~Command.checks` attribute. This also checks whether the command is disabled. .. versionchanged:: 1.3 Checks whether the command is disabled or not + .. versionchanged:: 2.0 + + ``ctx`` parameter is now positional-only. + Parameters ----------- ctx: :class:`.Context` @@ -1062,14 +1263,14 @@ async def can_run(self, ctx): """ if not self.enabled: - raise DisabledCommand('{0.name} command is disabled'.format(self)) + raise DisabledCommand(f'{self.name} command is disabled') original = ctx.command ctx.command = self try: if not await ctx.bot.can_run(ctx): - raise CheckFailure('The global check functions for command {0.qualified_name} failed.'.format(self)) + raise CheckFailure(f'The global check functions for command {self.qualified_name} failed.') cog = self.cog if cog is not None: @@ -1088,7 +1289,8 @@ async def can_run(self, ctx): finally: ctx.command = original -class GroupMixin: + +class GroupMixin(Generic[CogT]): """A mixin that implements common functionality for classes that behave similar to :class:`.Group` and are allowed to register commands. @@ -1100,24 +1302,25 @@ class GroupMixin: case_insensitive: :class:`bool` Whether the commands should be case insensitive. Defaults to ``False``. """ - def __init__(self, *args, **kwargs): + + def __init__(self, *args: Any, **kwargs: Any) -> None: case_insensitive = kwargs.get('case_insensitive', False) - self.all_commands = _CaseInsensitiveDict() if case_insensitive else {} - self.case_insensitive = case_insensitive + self.all_commands: Dict[str, Command[CogT, ..., Any]] = _CaseInsensitiveDict() if case_insensitive else {} + self.case_insensitive: bool = case_insensitive super().__init__(*args, **kwargs) @property - def commands(self): + def commands(self) -> Set[Command[CogT, ..., Any]]: """Set[:class:`.Command`]: A unique set of commands without aliases that are registered.""" return set(self.all_commands.values()) - def recursively_remove_all_commands(self): + def recursively_remove_all_commands(self) -> None: for command in self.all_commands.copy().values(): if isinstance(command, GroupMixin): command.recursively_remove_all_commands() self.remove_command(command.name) - def add_command(self, command): + def add_command(self, command: Command[CogT, ..., Any], /) -> None: """Adds a :class:`.Command` into the internal list of commands. This is usually not called, instead the :meth:`~.GroupMixin.command` or @@ -1126,6 +1329,10 @@ def add_command(self, command): .. versionchanged:: 1.4 Raise :exc:`.CommandRegistrationError` instead of generic :exc:`.ClientException` + .. versionchanged:: 2.0 + + ``command`` parameter is now positional-only. + Parameters ----------- command: :class:`Command` @@ -1133,7 +1340,7 @@ def add_command(self, command): Raises ------- - :exc:`.CommandRegistrationError` + CommandRegistrationError If the command or its alias is already registered by different command. TypeError If the command passed is not a subclass of :class:`.Command`. @@ -1155,12 +1362,16 @@ def add_command(self, command): raise CommandRegistrationError(alias, alias_conflict=True) self.all_commands[alias] = command - def remove_command(self, name): + def remove_command(self, name: str, /) -> Optional[Command[CogT, ..., Any]]: """Remove a :class:`.Command` from the internal list of commands. This could also be used as a way to remove aliases. + .. versionchanged:: 2.0 + + ``name`` parameter is now positional-only. + Parameters ----------- name: :class:`str` @@ -1188,11 +1399,11 @@ def remove_command(self, name): # in the case of a CommandRegistrationError, an alias might conflict # with an already existing command. If this is the case, we want to # make sure the pre-existing command is not removed. - if cmd not in (None, command): + if cmd is not None and cmd != command: self.all_commands[alias] = cmd return command - def walk_commands(self): + def walk_commands(self) -> Generator[Command[CogT, ..., Any], None, None]: """An iterator that recursively walks through all commands and subcommands. .. versionchanged:: 1.4 @@ -1208,7 +1419,7 @@ def walk_commands(self): if isinstance(command, GroupMixin): yield from command.walk_commands() - def get_command(self, name): + def get_command(self, name: str, /) -> Optional[Command[CogT, ..., Any]]: """Get a :class:`.Command` from the internal list of commands. @@ -1218,6 +1429,10 @@ def get_command(self, name): the subcommand ``bar`` of the group command ``foo``. If a subcommand is not found then ``None`` is returned just as usual. + .. versionchanged:: 2.0 + + ``name`` parameter is now positional-only. + Parameters ----------- name: :class:`str` @@ -1242,14 +1457,55 @@ def get_command(self, name): for name in names[1:]: try: - obj = obj.all_commands[name] + obj = obj.all_commands[name] # type: ignore except (AttributeError, KeyError): return None return obj - def command(self, *args, **kwargs): - """A shortcut decorator that invokes :func:`.command` and adds it to + @overload + def command( + self: GroupMixin[CogT], + name: str = ..., + *args: Any, + **kwargs: Any, + ) -> Callable[ + [ + Union[ + Callable[Concatenate[CogT, ContextT, P], Coro[T]], + Callable[Concatenate[ContextT, P], Coro[T]], + ] + ], + Command[CogT, P, T], + ]: + ... + + @overload + def command( + self: GroupMixin[CogT], + name: str = ..., + cls: Type[CommandT] = ..., # type: ignore # previous overload handles case where cls is not set + *args: Any, + **kwargs: Any, + ) -> Callable[ + [ + Union[ + Callable[Concatenate[CogT, ContextT, P], Coro[T]], + Callable[Concatenate[ContextT, P], Coro[T]], + ] + ], + CommandT, + ]: + ... + + def command( + self, + name: str = MISSING, + cls: Type[Command[Any, ..., Any]] = MISSING, + *args: Any, + **kwargs: Any, + ) -> Any: + """A shortcut decorator that invokes :func:`~discord.ext.commands.command` and adds it to the internal command list via :meth:`~.GroupMixin.add_command`. Returns @@ -1257,15 +1513,58 @@ def command(self, *args, **kwargs): Callable[..., :class:`Command`] A decorator that converts the provided method into a Command, adds it to the bot, then returns it. """ + def decorator(func): + kwargs.setdefault('parent', self) - result = command(*args, **kwargs)(func) + result = command(name=name, cls=cls, *args, **kwargs)(func) self.add_command(result) return result return decorator - def group(self, *args, **kwargs): + @overload + def group( + self: GroupMixin[CogT], + name: str = ..., + *args: Any, + **kwargs: Any, + ) -> Callable[ + [ + Union[ + Callable[Concatenate[CogT, ContextT, P], Coro[T]], + Callable[Concatenate[ContextT, P], Coro[T]], + ] + ], + Group[CogT, P, T], + ]: + ... + + @overload + def group( + self: GroupMixin[CogT], + name: str = ..., + cls: Type[GroupT] = ..., # type: ignore # previous overload handles case where cls is not set + *args: Any, + **kwargs: Any, + ) -> Callable[ + [ + Union[ + Callable[Concatenate[CogT, ContextT, P], Coro[T]], + Callable[Concatenate[ContextT, P], Coro[T]], + ] + ], + GroupT, + ]: + ... + + def group( + self, + name: str = MISSING, + cls: Type[Group[Any, ..., Any]] = MISSING, + *args: Any, + **kwargs: Any, + ) -> Any: """A shortcut decorator that invokes :func:`.group` and adds it to the internal command list via :meth:`~.GroupMixin.add_command`. @@ -1274,15 +1573,17 @@ def group(self, *args, **kwargs): Callable[..., :class:`Group`] A decorator that converts the provided method into a Group, adds it to the bot, then returns it. """ + def decorator(func): kwargs.setdefault('parent', self) - result = group(*args, **kwargs)(func) + result = group(name=name, cls=cls, *args, **kwargs)(func) self.add_command(result) return result return decorator -class Group(GroupMixin, Command): + +class Group(GroupMixin[CogT], Command[CogT, P, T]): """A class that implements a grouping protocol for commands to be executed as subcommands. @@ -1304,11 +1605,12 @@ class Group(GroupMixin, Command): Indicates if the group's commands should be case insensitive. Defaults to ``False``. """ - def __init__(self, *args, **attrs): - self.invoke_without_command = attrs.pop('invoke_without_command', False) + + def __init__(self, *args: Any, **attrs: Any) -> None: + self.invoke_without_command: bool = attrs.pop('invoke_without_command', False) super().__init__(*args, **attrs) - def copy(self): + def copy(self) -> Self: """Creates a copy of this :class:`Group`. Returns @@ -1321,7 +1623,7 @@ def copy(self): ret.add_command(cmd.copy()) return ret - async def invoke(self, ctx): + async def invoke(self, ctx: Context[BotT], /) -> None: ctx.invoked_subcommand = None ctx.subcommand_passed = None early_invoke = not self.invoke_without_command @@ -1338,10 +1640,10 @@ async def invoke(self, ctx): ctx.invoked_subcommand = self.all_commands.get(trigger, None) if early_invoke: - injected = hooked_wrapped_callback(self, ctx, self.callback) - await injected(*ctx.args, **ctx.kwargs) + injected = hooked_wrapped_callback(self, ctx, self.callback) # type: ignore + await injected(*ctx.args, **ctx.kwargs) # type: ignore - ctx.invoked_parents.append(ctx.invoked_with) + ctx.invoked_parents.append(ctx.invoked_with) # type: ignore if trigger and ctx.invoked_subcommand: ctx.invoked_with = trigger @@ -1352,7 +1654,7 @@ async def invoke(self, ctx): view.previous = previous await super().invoke(ctx) - async def reinvoke(self, ctx, *, call_hooks=False): + async def reinvoke(self, ctx: Context[BotT], /, *, call_hooks: bool = False) -> None: ctx.invoked_subcommand = None early_invoke = not self.invoke_without_command if early_invoke: @@ -1373,7 +1675,7 @@ async def reinvoke(self, ctx, *, call_hooks=False): if early_invoke: try: - await self.callback(*ctx.args, **ctx.kwargs) + await self.callback(*ctx.args, **ctx.kwargs) # type: ignore except: ctx.command_failed = True raise @@ -1381,7 +1683,7 @@ async def reinvoke(self, ctx, *, call_hooks=False): if call_hooks: await self.call_after_hooks(ctx) - ctx.invoked_parents.append(ctx.invoked_with) + ctx.invoked_parents.append(ctx.invoked_with) # type: ignore if trigger and ctx.invoked_subcommand: ctx.invoked_with = trigger @@ -1392,9 +1694,67 @@ async def reinvoke(self, ctx, *, call_hooks=False): view.previous = previous await super().reinvoke(ctx, call_hooks=call_hooks) + # Decorators -def command(name=None, cls=None, **attrs): +if TYPE_CHECKING: + # Using a class to emulate a function allows for overloading the inner function in the decorator. + + class _CommandDecorator: + @overload + def __call__(self, func: Callable[Concatenate[CogT, ContextT, P], Coro[T]], /) -> Command[CogT, P, T]: + ... + + @overload + def __call__(self, func: Callable[Concatenate[ContextT, P], Coro[T]], /) -> Command[None, P, T]: + ... + + def __call__(self, func: Callable[..., Coro[T]], /) -> Any: + ... + + class _GroupDecorator: + @overload + def __call__(self, func: Callable[Concatenate[CogT, ContextT, P], Coro[T]], /) -> Group[CogT, P, T]: + ... + + @overload + def __call__(self, func: Callable[Concatenate[ContextT, P], Coro[T]], /) -> Group[None, P, T]: + ... + + def __call__(self, func: Callable[..., Coro[T]], /) -> Any: + ... + + +@overload +def command( + name: str = ..., + **attrs: Any, +) -> _CommandDecorator: + ... + + +@overload +def command( + name: str = ..., + cls: Type[CommandT] = ..., # type: ignore # previous overload handles case where cls is not set + **attrs: Any, +) -> Callable[ + [ + Union[ + Callable[Concatenate[ContextT, P], Coro[Any]], + Callable[Concatenate[CogT, ContextT, P], Coro[Any]], # type: ignore # CogT is used here to allow covariance + ] + ], + CommandT, +]: + ... + + +def command( + name: str = MISSING, + cls: Type[Command[Any, ..., Any]] = MISSING, + **attrs: Any, +) -> Any: """A decorator that transforms a function into a :class:`.Command` or if called with :func:`.group`, :class:`.Group`. @@ -1424,7 +1784,7 @@ def command(name=None, cls=None, **attrs): TypeError If the function is not a coroutine or is already a command. """ - if cls is None: + if cls is MISSING: cls = Command def decorator(func): @@ -1434,20 +1794,52 @@ def decorator(func): return decorator -def group(name=None, **attrs): + +@overload +def group( + name: str = ..., + **attrs: Any, +) -> _GroupDecorator: + ... + + +@overload +def group( + name: str = ..., + cls: Type[GroupT] = ..., # type: ignore # previous overload handles case where cls is not set + **attrs: Any, +) -> Callable[ + [ + Union[ + Callable[Concatenate[CogT, ContextT, P], Coro[Any]], # type: ignore # CogT is used here to allow covariance + Callable[Concatenate[ContextT, P], Coro[Any]], + ] + ], + GroupT, +]: + ... + + +def group( + name: str = MISSING, + cls: Type[Group[Any, ..., Any]] = MISSING, + **attrs: Any, +) -> Any: """A decorator that transforms a function into a :class:`.Group`. - This is similar to the :func:`.command` decorator but the ``cls`` + This is similar to the :func:`~discord.ext.commands.command` decorator but the ``cls`` parameter is set to :class:`Group` by default. .. versionchanged:: 1.1 The ``cls`` parameter can now be passed. """ + if cls is MISSING: + cls = Group - attrs.setdefault('cls', Group) - return command(name=name, **attrs) + return command(name=name, cls=cls, **attrs) -def check(predicate): + +def check(predicate: UserCheck[ContextT], /) -> Check[ContextT]: r"""A decorator that adds a check to the :class:`.Command` or its subclasses. These checks could be accessed via :attr:`.Command.checks`. @@ -1512,15 +1904,19 @@ def predicate(ctx): async def only_me(ctx): await ctx.send('Only you!') + .. versionchanged:: 2.0 + + ``predicate`` parameter is now positional-only. + Parameters ----------- predicate: Callable[[:class:`Context`], :class:`bool`] The predicate to check if the command should be invoked. """ - def decorator(func): + def decorator(func: Union[Command[Any, ..., Any], CoroFunc]) -> Union[Command[Any, ..., Any], CoroFunc]: if isinstance(func, Command): - func.checks.append(predicate) + func.checks.append(predicate) # type: ignore else: if not hasattr(func, '__commands_checks__'): func.__commands_checks__ = [] @@ -1532,14 +1928,17 @@ def decorator(func): if inspect.iscoroutinefunction(predicate): decorator.predicate = predicate else: + @functools.wraps(predicate) - async def wrapper(ctx): + async def wrapper(ctx: ContextT): return predicate(ctx) + decorator.predicate = wrapper - return decorator + return decorator # type: ignore + -def check_any(*checks): +def check_any(*checks: Check[ContextT]) -> Check[ContextT]: r"""A :func:`check` that is added that checks if any of the checks passed will pass, i.e. using logical OR. @@ -1588,11 +1987,11 @@ async def only_for_owners(ctx): try: pred = wrapped.predicate except AttributeError: - raise TypeError('%r must be wrapped by commands.check decorator' % wrapped) from None + raise TypeError(f'{wrapped!r} must be wrapped by commands.check decorator') from None else: unwrapped.append(pred) - async def predicate(ctx): + async def predicate(ctx: Context[BotT]) -> bool: errors = [] for func in unwrapped: try: @@ -1605,9 +2004,10 @@ async def predicate(ctx): # if we're here, all checks failed raise CheckAnyFailure(unwrapped, errors) - return check(predicate) + return check(predicate) # type: ignore + -def has_role(item): +def has_role(item: Union[int, str], /) -> Check[Any]: """A :func:`.check` that is added that checks if the member invoking the command has the role specified via the name or ID specified. @@ -1628,30 +2028,36 @@ def has_role(item): Raise :exc:`.MissingRole` or :exc:`.NoPrivateMessage` instead of generic :exc:`.CheckFailure` + .. versionchanged:: 2.0 + + ``item`` parameter is now positional-only. + Parameters ----------- item: Union[:class:`int`, :class:`str`] The name or ID of the role to check. """ - def predicate(ctx): - if not isinstance(ctx.channel, discord.abc.GuildChannel): + def predicate(ctx: Context[BotT]) -> bool: + if ctx.guild is None: raise NoPrivateMessage() + # ctx.guild is None doesn't narrow ctx.author to Member if isinstance(item, int): - role = discord.utils.get(ctx.author.roles, id=item) + role = ctx.author.get_role(item) # type: ignore else: - role = discord.utils.get(ctx.author.roles, name=item) + role = discord.utils.get(ctx.author.roles, name=item) # type: ignore if role is None: raise MissingRole(item) return True return check(predicate) -def has_any_role(*items): + +def has_any_role(*items: Union[int, str]) -> Callable[[T], T]: r"""A :func:`.check` that is added that checks if the member invoking the command has **any** of the roles specified. This means that if they have - one out of the three roles specified, then this check will return `True`. + one out of the three roles specified, then this check will return ``True``. Similar to :func:`.has_role`\, the names or IDs passed in must be exact. @@ -1679,18 +2085,25 @@ def has_any_role(*items): async def cool(ctx): await ctx.send('You are cool indeed') """ + def predicate(ctx): - if not isinstance(ctx.channel, discord.abc.GuildChannel): + if ctx.guild is None: raise NoPrivateMessage() - getter = functools.partial(discord.utils.get, ctx.author.roles) - if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items): + # ctx.guild is None doesn't narrow ctx.author to Member + if any( + ctx.author.get_role(item) is not None + if isinstance(item, int) + else discord.utils.get(ctx.author.roles, name=item) is not None + for item in items + ): return True - raise MissingAnyRole(items) + raise MissingAnyRole(list(items)) return check(predicate) -def bot_has_role(item): + +def bot_has_role(item: int, /) -> Callable[[T], T]: """Similar to :func:`.has_role` except checks if the bot itself has the role. @@ -1702,24 +2115,28 @@ def bot_has_role(item): Raise :exc:`.BotMissingRole` or :exc:`.NoPrivateMessage` instead of generic :exc:`.CheckFailure` + + .. versionchanged:: 2.0 + + ``item`` parameter is now positional-only. """ def predicate(ctx): - ch = ctx.channel - if not isinstance(ch, discord.abc.GuildChannel): + if ctx.guild is None: raise NoPrivateMessage() - me = ch.guild.me if isinstance(item, int): - role = discord.utils.get(me.roles, id=item) + role = ctx.me.get_role(item) else: - role = discord.utils.get(me.roles, name=item) + role = discord.utils.get(ctx.me.roles, name=item) if role is None: raise BotMissingRole(item) return True + return check(predicate) -def bot_has_any_role(*items): + +def bot_has_any_role(*items: int) -> Callable[[T], T]: """Similar to :func:`.has_any_role` except checks if the bot itself has any of the roles listed. @@ -1732,19 +2149,23 @@ def bot_has_any_role(*items): Raise :exc:`.BotMissingAnyRole` or :exc:`.NoPrivateMessage` instead of generic checkfailure """ + def predicate(ctx): - ch = ctx.channel - if not isinstance(ch, discord.abc.GuildChannel): + if ctx.guild is None: raise NoPrivateMessage() - me = ch.guild.me - getter = functools.partial(discord.utils.get, me.roles) - if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items): + me = ctx.me + if any( + me.get_role(item) is not None if isinstance(item, int) else discord.utils.get(me.roles, name=item) is not None + for item in items + ): return True - raise BotMissingAnyRole(items) + raise BotMissingAnyRole(list(items)) + return check(predicate) -def has_permissions(**perms): + +def has_permissions(**perms: bool) -> Check[Any]: """A :func:`.check` that is added that checks if the member has all of the permissions necessary. @@ -1776,11 +2197,10 @@ async def test(ctx): invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) if invalid: - raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + raise TypeError(f"Invalid permission(s): {', '.join(invalid)}") - def predicate(ctx): - ch = ctx.channel - permissions = ch.permissions_for(ctx.author) + def predicate(ctx: Context[BotT]) -> bool: + permissions = ctx.permissions missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] @@ -1791,7 +2211,8 @@ def predicate(ctx): return check(predicate) -def bot_has_permissions(**perms): + +def bot_has_permissions(**perms: bool) -> Check[Any]: """Similar to :func:`.has_permissions` except checks if the bot itself has the permissions listed. @@ -1801,12 +2222,10 @@ def bot_has_permissions(**perms): invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) if invalid: - raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + raise TypeError(f"Invalid permission(s): {', '.join(invalid)}") - def predicate(ctx): - guild = ctx.guild - me = guild.me if guild is not None else ctx.bot.user - permissions = ctx.channel.permissions_for(me) + def predicate(ctx: Context[BotT]) -> bool: + permissions = ctx.bot_permissions missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] @@ -1817,7 +2236,8 @@ def predicate(ctx): return check(predicate) -def has_guild_permissions(**perms): + +def has_guild_permissions(**perms: bool) -> Check[Any]: """Similar to :func:`.has_permissions`, but operates on guild wide permissions instead of the current channel permissions. @@ -1829,13 +2249,13 @@ def has_guild_permissions(**perms): invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) if invalid: - raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + raise TypeError(f"Invalid permission(s): {', '.join(invalid)}") - def predicate(ctx): + def predicate(ctx: Context[BotT]) -> bool: if not ctx.guild: raise NoPrivateMessage - permissions = ctx.author.guild_permissions + permissions = ctx.author.guild_permissions # type: ignore missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] if not missing: @@ -1845,7 +2265,8 @@ def predicate(ctx): return check(predicate) -def bot_has_guild_permissions(**perms): + +def bot_has_guild_permissions(**perms: bool) -> Check[Any]: """Similar to :func:`.has_guild_permissions`, but checks the bot members guild permissions. @@ -1854,13 +2275,13 @@ def bot_has_guild_permissions(**perms): invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) if invalid: - raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + raise TypeError(f"Invalid permission(s): {', '.join(invalid)}") - def predicate(ctx): + def predicate(ctx: Context[BotT]) -> bool: if not ctx.guild: raise NoPrivateMessage - permissions = ctx.me.guild_permissions + permissions = ctx.me.guild_permissions # type: ignore missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] if not missing: @@ -1870,7 +2291,8 @@ def predicate(ctx): return check(predicate) -def dm_only(): + +def dm_only() -> Check[Any]: """A :func:`.check` that indicates this command must only be used in a DM context. Only private messages are allowed when using the command. @@ -1881,30 +2303,66 @@ def dm_only(): .. versionadded:: 1.1 """ - def predicate(ctx): + def predicate(ctx: Context[BotT]) -> bool: if ctx.guild is not None: raise PrivateMessageOnly() return True return check(predicate) -def guild_only(): + +def guild_only() -> Check[Any]: """A :func:`.check` that indicates this command must only be used in a guild context only. Basically, no private messages are allowed when using the command. This check raises a special exception, :exc:`.NoPrivateMessage` that is inherited from :exc:`.CheckFailure`. + + If used on hybrid commands, this will be equivalent to the + :func:`discord.app_commands.guild_only` decorator. In an unsupported + context, such as a subcommand, this will still fallback to applying the + check. """ - def predicate(ctx): + # Due to implementation quirks, this check has to be re-implemented completely + # to work with both app_commands and the command framework. + + def predicate(ctx: Context[BotT]) -> bool: if ctx.guild is None: raise NoPrivateMessage() return True - return check(predicate) + def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]: + if isinstance(func, Command): + func.checks.append(predicate) + if hasattr(func, '__commands_is_hybrid__'): + app_command = getattr(func, 'app_command', None) + if app_command: + app_command.guild_only = True + else: + if not hasattr(func, '__commands_checks__'): + func.__commands_checks__ = [] + + func.__commands_checks__.append(predicate) + func.__discord_app_commands_guild_only__ = True + + return func + + if inspect.iscoroutinefunction(predicate): + decorator.predicate = predicate + else: + + @functools.wraps(predicate) + async def wrapper(ctx: Context[BotT]): + return predicate(ctx) + + decorator.predicate = wrapper -def is_owner(): + return decorator # type: ignore + + +def is_owner() -> Check[Any]: """A :func:`.check` that checks if the person invoking this command is the owner of the bot. @@ -1914,32 +2372,76 @@ def is_owner(): from :exc:`.CheckFailure`. """ - async def predicate(ctx): + async def predicate(ctx: Context[BotT]) -> bool: if not await ctx.bot.is_owner(ctx.author): raise NotOwner('You do not own this bot.') return True return check(predicate) -def is_nsfw(): + +def is_nsfw() -> Check[Any]: """A :func:`.check` that checks if the channel is a NSFW channel. This check raises a special exception, :exc:`.NSFWChannelRequired` that is derived from :exc:`.CheckFailure`. + If used on hybrid commands, this will be equivalent to setting the + application command's ``nsfw`` attribute to ``True``. In an unsupported + context, such as a subcommand, this will still fallback to applying the + check. + .. versionchanged:: 1.1 Raise :exc:`.NSFWChannelRequired` instead of generic :exc:`.CheckFailure`. DM channels will also now pass this check. """ - def pred(ctx): + + # Due to implementation quirks, this check has to be re-implemented completely + # to work with both app_commands and the command framework. + + def predicate(ctx: Context[BotT]) -> bool: ch = ctx.channel - if ctx.guild is None or (isinstance(ch, discord.TextChannel) and ch.is_nsfw()): + if ctx.guild is None or ( + isinstance(ch, (discord.TextChannel, discord.Thread, discord.VoiceChannel)) and ch.is_nsfw() + ): return True - raise NSFWChannelRequired(ch) - return check(pred) + raise NSFWChannelRequired(ch) # type: ignore + + def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]: + if isinstance(func, Command): + func.checks.append(predicate) + if hasattr(func, '__commands_is_hybrid__'): + app_command = getattr(func, 'app_command', None) + if app_command: + app_command.nsfw = True + else: + if not hasattr(func, '__commands_checks__'): + func.__commands_checks__ = [] + + func.__commands_checks__.append(predicate) + func.__discord_app_commands_is_nsfw__ = True + + return func + + if inspect.iscoroutinefunction(predicate): + decorator.predicate = predicate + else: + + @functools.wraps(predicate) + async def wrapper(ctx: Context[BotT]): + return predicate(ctx) + + decorator.predicate = wrapper + + return decorator # type: ignore + -def cooldown(rate, per, type=BucketType.default): +def cooldown( + rate: int, + per: float, + type: Union[BucketType, Callable[[Context[Any]], Any]] = BucketType.default, +) -> Callable[[T], T]: """A decorator that adds a cooldown to a :class:`.Command` A cooldown allows a command to only be used a specific amount @@ -1959,22 +2461,76 @@ def cooldown(rate, per, type=BucketType.default): The number of times a command can be used before triggering a cooldown. per: :class:`float` The amount of seconds to wait for a cooldown when it's been triggered. - type: Union[:class:`.BucketType`, Callable[[:class:`.Message`], Any]] + type: Union[:class:`.BucketType`, Callable[[:class:`.Context`], Any]] The type of cooldown to have. If callable, should return a key for the mapping. - + .. versionchanged:: 1.7 Callables are now supported for custom bucket types. + + .. versionchanged:: 2.0 + When passing a callable, it now needs to accept :class:`.Context` + rather than :class:`~discord.Message` as its only argument. """ - def decorator(func): + def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]: if isinstance(func, Command): - func._buckets = CooldownMapping(Cooldown(rate, per, type)) + func._buckets = CooldownMapping(Cooldown(rate, per), type) else: - func.__commands_cooldown__ = Cooldown(rate, per, type) + func.__commands_cooldown__ = CooldownMapping(Cooldown(rate, per), type) return func - return decorator -def max_concurrency(number, per=BucketType.default, *, wait=False): + return decorator # type: ignore + + +def dynamic_cooldown( + cooldown: Callable[[Context[Any]], Optional[Cooldown]], + type: Union[BucketType, Callable[[Context[Any]], Any]], +) -> Callable[[T], T]: + """A decorator that adds a dynamic cooldown to a :class:`.Command` + + This differs from :func:`.cooldown` in that it takes a function that + accepts a single parameter of type :class:`.Context` and must + return a :class:`~discord.app_commands.Cooldown` or ``None``. + If ``None`` is returned then that cooldown is effectively bypassed. + + A cooldown allows a command to only be used a specific amount + of times in a specific time frame. These cooldowns can be based + either on a per-guild, per-channel, per-user, per-role or global basis. + Denoted by the third argument of ``type`` which must be of enum + type :class:`.BucketType`. + + If a cooldown is triggered, then :exc:`.CommandOnCooldown` is triggered in + :func:`.on_command_error` and the local error handler. + + A command can only have a single cooldown. + + .. versionadded:: 2.0 + + Parameters + ------------ + cooldown: Callable[[:class:`.Context`], Optional[:class:`~discord.app_commands.Cooldown`]] + A function that takes a message and returns a cooldown that will + apply to this invocation or ``None`` if the cooldown should be bypassed. + type: :class:`.BucketType` + The type of cooldown to have. + """ + if not callable(cooldown): + raise TypeError("A callable must be provided") + + if type is BucketType.default: + raise ValueError('BucketType.default cannot be used in dynamic cooldowns') + + def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]: + if isinstance(func, Command): + func._buckets = DynamicCooldownMapping(cooldown, type) + else: + func.__commands_cooldown__ = DynamicCooldownMapping(cooldown, type) + return func + + return decorator # type: ignore + + +def max_concurrency(number: int, per: BucketType = BucketType.default, *, wait: bool = False) -> Callable[[T], T]: """A decorator that adds a maximum concurrency to a :class:`.Command` or its subclasses. This enables you to only allow a certain number of command invocations at the same time, @@ -1998,16 +2554,18 @@ def max_concurrency(number, per=BucketType.default, *, wait=False): then the command waits until it can be executed. """ - def decorator(func): + def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]: value = MaxConcurrency(number, per=per, wait=wait) if isinstance(func, Command): func._max_concurrency = value else: func.__commands_max_concurrency__ = value return func - return decorator -def before_invoke(coro): + return decorator # type: ignore + + +def before_invoke(coro: Hook[CogT, ContextT], /) -> Callable[[T], T]: """A decorator that registers a coroutine as a pre-invoke hook. This allows you to refer to one before invoke hook for several commands that @@ -2015,6 +2573,10 @@ def before_invoke(coro): .. versionadded:: 1.4 + .. versionchanged:: 2.0 + + ``coro`` parameter is now positional-only. + Example --------- @@ -2033,7 +2595,7 @@ class What(commands.Cog): @commands.before_invoke(record_usage) @commands.command() async def when(self, ctx): # Output: used when at